[PATCH 2/2] tests: Add P2P persistent group peer channel preference test

Andrei Otcheretianski andrei.otcheretianski at intel.com
Thu Oct 8 04:30:49 PDT 2026


Verify that when re-invoking a persistent P2P group, the GO honors the
peer's operating channel preference instead of picking a random channel.

One thing to note here: the GO is intentionally limited here to 20Mhz
as a workaround for occasional timeouts due to overlapping BSS scan.
If the client manages to finish its 4 attempts to find the GO while
it is still in OBSS scan it falls back to a full scan, but that takes
so long (because the client is connected to the BSS) that the 10s
join timeout kills the whole thing.

Signed-off-by: Johannes Berg <johannes.berg at intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 tests/hwsim/test_p2p_concurrency.py | 53 +++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/tests/hwsim/test_p2p_concurrency.py b/tests/hwsim/test_p2p_concurrency.py
index 63a2c1da54..a7a54142c4 100644
--- a/tests/hwsim/test_p2p_concurrency.py
+++ b/tests/hwsim/test_p2p_concurrency.py
@@ -14,6 +14,8 @@ import hwsim_utils
 import hostapd
 from p2p_utils import *
 from utils import *
+from hwsim import HWSimRadio
+from wpasupplicant import WpaSupplicant
 
 @remote_compatible
 def test_concurrent_autogo(dev, apdev):
@@ -286,3 +288,54 @@ def test_concurrent_invitation_channel_mismatch(dev, apdev):
         raise Exception("P2P invitation result not received")
     if "status=7" not in ev:
         raise Exception("Unexpected P2P invitation result: " + ev)
+
+def test_concurrent_persistent_group_peer_channel_preference(dev, apdev):
+    """P2P persistent group re-invocation honors peer channel preference"""
+    # The client needs a multi-channel capable radio so that it keeps
+    # advertising its full channel list while associated to the AP. With a
+    # single channel radio the advertised list collapses to the AP channel,
+    # the intersection has a single entry, and the GO cannot pick anything
+    # else even when it ignores the peer preference.
+    with HWSimRadio(n_channels=2) as (radio, iface):
+        wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+        wpas.interface_add(iface)
+
+        # wpas = client (connected to AP on ch36), dev[1] = GO
+        wpas.global_request("SET p2p_no_group_iface 0")
+
+        hapd = None
+        try:
+            # Force a 20 MHz P2P GO. With a wider channel, the HT40 coex scan
+            # makes it take enough time that occasionally the client will do
+            # its scanning quicker than the GO's scan, causing the client to
+            # not discover the GO in the required time.
+            dev[1].global_request("SET p2p_go_vht 0")
+            dev[1].global_request("SET p2p_go_ht40 0")
+
+            # Form persistent group first (on any channel)
+            form(dev[1], wpas)
+
+            # Connect client to AP on channel 36 (5180 MHz)
+            hapd = hostapd.add_ap(apdev[0], {"ssid": "test-5ghz",
+                                             "hw_mode": "a",
+                                             "channel": "36",
+                                             "country_code": "US"})
+            wpas.connect("test-5ghz", key_mgmt="NONE", scan_freq="5180")
+
+            # Re-invoke multiple times - if peer preference is honored,
+            # all iterations should land on 5180 MHz. With random
+            # selection from 8 VHT channels, probability of always
+            # hitting 5180 is (1/8)^5.
+            for i in range(5):
+                [go_res, cli_res] = invite_from_cli(dev[1], wpas)
+                freq = int(go_res['freq'])
+                logger.info(f"Iteration {i + 1}: group re-invoked on freq {freq} MHz")
+                if freq != 5180:
+                    raise Exception(
+                        f"GO did not honor peer channel preference: "
+                        f"expected 5180 MHz, got {freq} MHz (iteration {i + 1})")
+        finally:
+            dev[1].global_request("SET p2p_go_vht 1")
+            dev[1].global_request("SET p2p_go_ht40 1")
+            disable_hapd(hapd)
+            clear_regdom_dev(dev, count=2)
-- 
2.53.0




More information about the Hostap mailing list