[PATCH v2 7/7] tests: add a few simple UHR tests
Johannes Berg
johannes at sipsolutions.net
Tue Mar 17 09:35:55 PDT 2026
From: Johannes Berg <johannes.berg at intel.com>
Just check that connections are possible and the
wifi version is 8.
Signed-off-by: Johannes Berg <johannes.berg at intel.com>
---
tests/hwsim/example-hostapd.config | 2 +
tests/hwsim/example-wpa_supplicant.config | 2 +
tests/hwsim/test_uhr.py | 145 ++++++++++++++++++++++
3 files changed, 149 insertions(+)
create mode 100644 tests/hwsim/test_uhr.py
diff --git a/tests/hwsim/example-hostapd.config b/tests/hwsim/example-hostapd.config
index 21e44017fb62..e17285240d75 100644
--- a/tests/hwsim/example-hostapd.config
+++ b/tests/hwsim/example-hostapd.config
@@ -53,6 +53,8 @@ CONFIG_LIBNL3_ROUTE=y
CONFIG_IEEE80211R=y
CONFIG_IEEE80211AC=y
CONFIG_IEEE80211AX=y
+CONFIG_IEEE80211BE=y
+CONFIG_IEEE80211BN=y
CONFIG_OCV=y
diff --git a/tests/hwsim/example-wpa_supplicant.config b/tests/hwsim/example-wpa_supplicant.config
index 20f3936294ce..aae5f7aff242 100644
--- a/tests/hwsim/example-wpa_supplicant.config
+++ b/tests/hwsim/example-wpa_supplicant.config
@@ -175,3 +175,5 @@ CONFIG_NAN=y
CONFIG_ENC_ASSOC=y
CONFIG_PMKSA_PRIVACY=y
+
+CONFIG_IEEE80211BN=y
diff --git a/tests/hwsim/test_uhr.py b/tests/hwsim/test_uhr.py
new file mode 100644
index 000000000000..a5dfea0aee35
--- /dev/null
+++ b/tests/hwsim/test_uhr.py
@@ -0,0 +1,145 @@
+# UHR tests
+# Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc.
+# Copyright (C) 2025 Intel Corporation
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+
+import binascii
+import subprocess
+import tempfile
+import time
+
+import hostapd
+from utils import *
+from hwsim import HWSimRadio
+import hwsim_utils
+from wpasupplicant import WpaSupplicant
+from test_eht import eht_verify_status, traffic_test
+
+def uhr_verify_wifi_version(dev):
+ status = dev.get_status()
+ logger.info("station status: " + str(status))
+
+ if 'wifi_generation' not in status:
+ raise Exception("Missing wifi_generation information")
+ if status['wifi_generation'] != "8":
+ raise Exception("Unexpected wifi_generation value: " + status['wifi_generation'])
+
+def uhr_verify_status(wpas, hapd, is_ht=False, is_vht=False):
+ status = hapd.get_status()
+
+ logger.info("hostapd STATUS: " + str(status))
+ if is_ht and status["ieee80211n"] != "1":
+ raise Exception("Unexpected STATUS ieee80211n value")
+ if is_vht and status["ieee80211ac"] != "1":
+ raise Exception("Unexpected STATUS ieee80211ac value")
+ if status["ieee80211ax"] != "1":
+ raise Exception("Unexpected STATUS ieee80211ax value")
+ if status["ieee80211be"] != "1":
+ raise Exception("Unexpected STATUS ieee80211be value")
+ if status["ieee80211bn"] != "1":
+ raise Exception("Unexpected STATUS ieee80211bn value")
+
+ sta = hapd.get_sta(wpas.own_addr())
+ logger.info("hostapd STA: " + str(sta))
+ if sta['addr'] == 'FAIL':
+ raise Exception("hostapd " + hapd.ifname + " did not have a STA entry for the STA " + wpas.own_addr())
+ if is_ht and "[HT]" not in sta['flags']:
+ raise Exception("Missing STA flag: HT")
+ if is_vht and "[VHT]" not in sta['flags']:
+ raise Exception("Missing STA flag: VHT")
+ if "[HE]" not in sta['flags']:
+ raise Exception("Missing STA flag: HE")
+ if "[EHT]" not in sta['flags']:
+ raise Exception("Missing STA flag: EHT")
+ if "[UHR]" not in sta['flags']:
+ raise Exception("Missing STA flag: UHR")
+
+def test_uhr_open(dev, apdev):
+ """UHR AP with open mode configuration"""
+ params = {
+ "ssid": "uhr",
+ "ieee80211ax": "1",
+ "ieee80211be": "1",
+ "ieee80211bn": "1",
+ "require_uhr": "1",
+ }
+ try:
+ hapd = hostapd.add_ap(apdev[0], params)
+ except Exception as e:
+ if isinstance(e, Exception) and \
+ str(e) == "Failed to set hostapd parameter ieee80211bn":
+ raise HwsimSkip("UHR not supported")
+ raise
+ if hapd.get_status_field("ieee80211bn") != "1":
+ raise Exception("AP STATUS did not indicate ieee80211bn=1")
+ dev[0].connect("uhr", key_mgmt="NONE", scan_freq="2412")
+ time.sleep(1)
+ sta = hapd.get_sta(dev[0].own_addr())
+ uhr_verify_status(dev[0], hapd, is_ht=True)
+ status = dev[0].request("STATUS")
+ if "wifi_generation=8" not in status:
+ raise Exception("STA STATUS did not indicate wifi_generation=7")
+
+def uhr_mld_ap_wpa2_params(ssid, passphrase=None, key_mgmt="WPA-PSK-SHA256",
+ mfp="2", pwe=None, beacon_prot="1", bridge=False):
+ params = hostapd.wpa2_params(ssid=ssid, passphrase=passphrase,
+ wpa_key_mgmt=key_mgmt, ieee80211w=mfp)
+ params['ieee80211n'] = '1'
+ params['ieee80211ax'] = '1'
+ params['ieee80211be'] = '1'
+ params['ieee80211bn'] = '1'
+ params['channel'] = '1'
+ params['hw_mode'] = 'g'
+ params['group_mgmt_cipher'] = "AES-128-CMAC"
+ params['beacon_prot'] = beacon_prot
+ if bridge:
+ params['bridge'] = 'ap-br0'
+
+ if pwe is not None:
+ params['sae_pwe'] = pwe
+
+ return params
+
+def uhr_mld_enable_ap(iface, link_id, params):
+ hapd = hostapd.add_mld_link(iface, link_id, params)
+ hapd.enable()
+
+ ev = hapd.wait_event(["AP-ENABLED", "AP-DISABLED"], timeout=1)
+ if ev is None:
+ raise Exception("AP startup timed out")
+ if "AP-ENABLED" not in ev:
+ raise Exception("AP startup failed")
+
+ return hapd
+
+def run_uhr_mld_sae_single_link(dev, apdev, anti_clogging_token=False):
+ with HWSimRadio(use_mlo=True) as (hapd_radio, hapd_iface), \
+ HWSimRadio(use_mlo=True) as (wpas_radio, wpas_iface):
+ wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
+ wpas.interface_add(wpas_iface)
+ check_sae_capab(wpas)
+
+ passphrase = 'qwertyuiop'
+ ssid = "mld_ap_sae_single_link"
+ params = uhr_mld_ap_wpa2_params(ssid, passphrase, key_mgmt="SAE",
+ mfp="2", pwe='2')
+ if anti_clogging_token:
+ params['sae_anti_clogging_threshold'] = '0'
+
+ hapd0 = uhr_mld_enable_ap(hapd_iface, 0, params)
+
+ wpas.set("sae_pwe", "1")
+ wpas.connect(ssid, sae_password=passphrase, scan_freq="2412",
+ key_mgmt="SAE", ieee80211w="2")
+
+ eht_verify_status(wpas, hapd0, 2412, 20, is_ht=True, mld=True,
+ valid_links=1, active_links=1)
+ uhr_verify_status(wpas, hapd0, is_ht=True)
+ uhr_verify_wifi_version(wpas)
+ traffic_test(wpas, hapd0)
+
+def test_uhr_mld_sae_single_link(dev, apdev):
+ """UHR MLD AP with MLD client SAE H2E connection using single link"""
+ run_uhr_mld_sae_single_link(dev, apdev)
--
2.53.0
More information about the Hostap
mailing list