| Message ID | 4c64e424fc741fd954076681ca08a0a73b5df737.1759334464.git.james@teledatics.com |
|---|---|
| State | New |
| Headers | show |
| Series | S1G bootstrap and scan plumbing | expand |
On Wed, Oct 01, 2025 at 12:50:01PM -0400, James Ewing wrote: > --- > tests/hwsim/test_s1g_assoc.py | 101 ++++++++++++++++++++++++++++++++++ > 1 file changed, 101 insertions(+) > create mode 100644 tests/hwsim/test_s1g_assoc.py Maybe a bit more information in the commit message would be good. > diff --git a/tests/hwsim/test_s1g_assoc.py b/tests/hwsim/test_s1g_assoc.py > new file mode 100644 > index 000000000..80ca3be31 > --- /dev/null > +++ b/tests/hwsim/test_s1g_assoc.py > @@ -0,0 +1,101 @@ > +# S1G association path coverage > +# > +# Validates that the supplicant can associate with an S1G-capable AP while > +# preserving kHz-level channel metadata inside the BSS cache. I am unable to run the test on the tip of wireless-next: 94aced6ed9e2 (origin/main, origin/HEAD) Merge tag 'wireless-next-2025-09-25' Test output: ============ ./vm-run.sh sta_assoc_s1g_channel Starting test run in a virtual machine ./run-all.sh: running inside a VM ./run-all.sh: passing the following args to run-tests.py: --long sta_assoc_s1g_channel START sta_assoc_s1g_channel 1/1 Exception during test execution: Failed to set hostapd parameter hw_mode Traceback (most recent call last): File "/home/osp-nuc/hostap/tests/hwsim/./run-tests.py", line 587, in main t(dev, apdev) ~^^^^^^^^^^^^ File "/home/osp-nuc/hostap/tests/hwsim/test_s1g_assoc.py", line 58, in test_sta_assoc_s1g_channel hapd = hostapd.add_ap(apdev[0], params, set_channel=False) File "/home/osp-nuc/hostap/tests/hwsim/hostapd.py", line 710, in add_ap hapd.set(f, v) ~~~~~~~~^^^^^^ File "/home/osp-nuc/hostap/tests/hwsim/hostapd.py", line 243, in set raise Exception("Failed to set hostapd parameter " + field) Exception: Failed to set hostapd parameter hw_mode FAIL sta_assoc_s1g_channel 0.000659 2025-10-02 01:59:37.446980 failed tests: sta_assoc_s1g_channel sta_assoc_s1g_channel.hostapd: ============================== 1759370600.884002: Using existing control interface directory. 1759370600.884800: Global ctrl_iface command: PING 1759370600.886400: Global ctrl_iface command: ATTACH 1759370600.886400: CTRL_IFACE monitor attached /tmp/wpa_ctrl_455-14\x00 1759370600.886404: Global ctrl_iface command: FLUSH 1759370600.886407: Global ctrl_iface command: INTERFACES 1759370600.886411: Global ctrl_iface command: REMOVE as-erp 1759370600.886411: Removing interface as-erp failed 1759370600.886414: Global ctrl_iface command: DETACH 1759370600.886414: CTRL_IFACE monitor detached /tmp/wpa_ctrl_455-14\x00 1759370600.886605: Global ctrl_iface command: ATTACH 1759370600.886605: CTRL_IFACE monitor attached /tmp/wpa_ctrl_455-16\x00 1759370600.886609: Global ctrl_iface command: REMOVE wlan3 1759370600.886609: Removing interface wlan3 failed 1759370600.886613: Global ctrl_iface command: ADD wlan3 /var/run/hostapd 1759370600.886614: Using existing control interface directory. 1759370600.886614: Add interface 'wlan3' 1759370600.886617: RX ctrl_iface - hexdump_ascii(len=6): 41 54 54 41 43 48 ATTACH 1759370600.886617: CTRL_IFACE monitor attached /tmp/wpa_ctrl_455-18\x00 1759370600.886624: RX ctrl_iface - hexdump_ascii(len=18): 53 45 54 20 64 72 69 76 65 72 20 6e 6c 38 30 32 SET driver nl802 31 31 11 1759370600.886624: CTRL_IFACE SET 'driver'='nl80211' 1759370600.886628: RX ctrl_iface - hexdump_ascii(len=20): 53 45 54 20 6c 6f 67 67 65 72 5f 73 74 64 6f 75 SET logger_stdou 74 20 2d 31 t -1 1759370600.886628: CTRL_IFACE SET 'logger_stdout'='-1' 1759370600.886632: RX ctrl_iface - hexdump_ascii(len=25): 53 45 54 20 6c 6f 67 67 65 72 5f 73 74 64 6f 75 SET logger_stdou 74 5f 6c 65 76 65 6c 20 30 t_level 0 1759370600.886632: CTRL_IFACE SET 'logger_stdout_level'='0' 1759370600.886635: RX ctrl_iface - hexdump_ascii(len=18): 53 45 54 20 73 73 69 64 20 73 31 67 2d 61 73 73 SET ssid s1g-ass 6f 63 oc 1759370600.886636: CTRL_IFACE SET 'ssid'='s1g-assoc' 1759370600.886639: RX ctrl_iface - hexdump_ascii(len=14): 53 45 54 20 68 77 5f 6d 6f 64 65 20 61 68 SET hw_mode ah 1759370600.886640: CTRL_IFACE SET 'hw_mode'='ah' 1759370600.886640: Line 0: unknown hw_mode 'ah' 1759370600.886640: Failed to set configuration field 'hw_mode' to value 'ah' 1759370600.886655: Global ctrl_iface command: DETACH 1759370600.886655: CTRL_IFACE monitor detached /tmp/wpa_ctrl_455-16\x00 1759370600.886658: RX ctrl_iface - hexdump_ascii(len=6): 44 45 54 41 43 48 DETACH 1759370600.886658: CTRL_IFACE monitor detached /tmp/wpa_ctrl_455-18\x00 1759370600.886867: Global ctrl_iface command: ATTACH 1759370600.886867: CTRL_IFACE monitor attached /tmp/wpa_ctrl_455-21\x00 1759370600.886871: Global ctrl_iface command: FLUSH 1759370600.886875: Global ctrl_iface command: INTERFACES 1759370600.886878: Global ctrl_iface command: REMOVE wlan3 1759370600.886878: Remove interface 'wlan3' 1759370600.886879: hostapd_interface_deinit_free(0x5500002b7ef0) 1759370600.886879: hostapd_interface_deinit_free: num_bss=1 conf->num_bss=1 1759370600.886879: hostapd_interface_deinit(0x5500002b7ef0) 1759370600.886879: wlan3: interface state UNINITIALIZED->DISABLED 1759370600.886880: hostapd_bss_deinit: deinit bss wlan3 1759370600.886880: wlan3: AP-DISABLED 1759370600.886880: CTRL_IFACE monitor send /tmp/wpa_ctrl_455-21\x00 1759370600.886880: hostapd_cleanup(hapd=0x5500002b9c40 (wlan3)) 1759370600.886881: wlan3: CTRL-EVENT-TERMINATING 1759370600.886881: CTRL_IFACE monitor send /tmp/wpa_ctrl_455-21\x00 1759370600.886882: Control interface directory not empty - leaving it behind 1759370600.886882: hostapd_free_hapd_data: Interface wlan3 wasn't started 1759370600.886883: hostapd_interface_deinit_free: driver=0x5500002ab2c0 drv_priv=(nil) -> hapd_deinit 1759370600.886883: hostapd_interface_free(0x5500002b7ef0) 1759370600.886883: hostapd_interface_free: free hapd 0x5500002b9c40 1759370600.886883: hostapd_cleanup_iface(0x5500002b7ef0) 1759370600.886884: hostapd_cleanup_iface_partial(0x5500002b7ef0) 1759370600.886884: hostapd_cleanup_iface: free iface=0x5500002b7ef0 1759370600.886888: Global ctrl_iface command: REMOVE as-erp 1759370600.886888: Removing interface as-erp failed 1759370600.886891: Global ctrl_iface command: DETACH 1759370600.886891: CTRL_IFACE monitor detached /tmp/wpa_ctrl_455-21\x00 1759370600.887000: Global ctrl_iface command: ATTACH 1759370600.887000: CTRL_IFACE monitor attached /tmp/wpa_ctrl_455-24\x00 1759370600.887005: Global ctrl_iface command: RELOG Seems to be some issue setting the hardware mode to ah. lachlan
This series updates wpa_supplicant. Test fails at hapd = hostapd.add_ap(...) because hostapd rejects hw_mode=ah. I can bundle hostapd S1G support into the same patchset with larger code changes, if preferred. james
On Wed, Oct 01, 2025 at 11:21:14PM -0400, James Ewing wrote: > This series updates wpa_supplicant. Test fails at hapd = hostapd.add_ap(...) > because hostapd rejects hw_mode=ah. I can bundle hostapd S1G support into > the same patchset with larger code changes, if preferred. Ah OK. Its not up to me but my preference would probably be a patchset that introduces the absolute minimum to get an AP and STA associated. However if we just did supplicant only maybe a scan based test? Im not sure. Either way Jouni or others may have a better idea on how to start integrating S1G. So I guess we can wait to see what others think :). lachlan
diff --git a/tests/hwsim/test_s1g_assoc.py b/tests/hwsim/test_s1g_assoc.py new file mode 100644 index 000000000..80ca3be31 --- /dev/null +++ b/tests/hwsim/test_s1g_assoc.py @@ -0,0 +1,101 @@ +# S1G association path coverage +# +# Validates that the supplicant can associate with an S1G-capable AP while +# preserving kHz-level channel metadata inside the BSS cache. + +import logging + +import hostapd + +from utils import HwsimSkip, list_s1g_capable_channels + + +logger = logging.getLogger() + + +def _pick_s1g_channel(): + channels = list_s1g_capable_channels() + if not channels: + raise HwsimSkip("mac80211_hwsim does not expose any S1G channels") + + for entry in channels: + if entry.get("channel"): + return entry + + # Fall back to the first entry even if iw does not report a channel number. + return channels[0] + + +def test_sta_assoc_s1g_channel(dev, apdev): + """Exercise STA association on an S1G channel and observe freq_khz plumbing""" + + channel_info = _pick_s1g_channel() + channel = channel_info.get("channel") + if channel is None: + raise HwsimSkip("iw phy did not report an S1G channel index") + + freq_khz = int(round(channel_info["freq_mhz"] * 1000)) + primary_freq_mhz = freq_khz // 1000 + freq_offset = freq_khz - primary_freq_mhz * 1000 + + logger.info( + "Using S1G channel %d at %.3f MHz (primary %d MHz, offset %d kHz)", + channel, + channel_info["freq_mhz"], + primary_freq_mhz, + freq_offset, + ) + + params = { + "ssid": "s1g-assoc", + "hw_mode": "ah", + "channel": str(channel), + "ieee80211n": "0", + "ieee80211ac": "0", + "ieee80211ax": "0", + } + + hapd = hostapd.add_ap(apdev[0], params, set_channel=False) + + dev[0].connect( + ssid="s1g-assoc", + key_mgmt="NONE", + scan_freq=str(primary_freq_mhz), + ) + + status = dev[0].get_status() + if status.get("freq") != str(primary_freq_mhz): + raise Exception( + "Supplicant reported freq %s, expected %d MHz" % + (status.get("freq"), primary_freq_mhz)) + + bss = dev[0].get_bss(hapd.own_addr()) + if not bss: + raise Exception("Failed to fetch BSS entry for associated S1G AP") + + if bss.get("freq") != str(primary_freq_mhz): + raise Exception( + "BSS table freq %s does not match primary %d MHz" % + (bss.get("freq"), primary_freq_mhz)) + + freq_khz_str = bss.get("freq_khz") + if freq_khz_str is None: + raise Exception("freq_khz missing from BSS table entry") + if int(freq_khz_str) != freq_khz: + raise Exception( + "freq_khz %s did not match expected %d" % + (freq_khz_str, freq_khz)) + + freq_offset_str = bss.get("freq_offset") + if freq_offset: + if freq_offset_str is None: + raise Exception("freq_offset missing from BSS table entry") + if int(freq_offset_str) != freq_offset: + raise Exception( + "freq_offset %s did not match expected %d" % + (freq_offset_str, freq_offset)) + elif freq_offset_str is not None and int(freq_offset_str) != 0: + raise Exception("Expected zero freq_offset, saw %s" % freq_offset_str) + + dev[0].request("DISCONNECT") +