2 # Copyright (c) 2013-2019, Jouni Malinen <j@w1.fi>
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
7 from remotehost
import remote_compatible
12 logger
= logging
.getLogger()
16 from wpasupplicant
import WpaSupplicant
18 from wlantest
import Wlantest
19 from datetime
import datetime
21 def clear_regdom_state(dev
, hapd
, hapd2
):
23 ev
= dev
[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout
=0.5)
24 if ev
is None or "init=COUNTRY_IE" in ev
:
27 hapd
.request("DISABLE")
29 hapd2
.request("DISABLE")
30 subprocess
.call(['iw', 'reg', 'set', '00'])
31 dev
[0].disconnect_and_stop_scan()
32 subprocess
.call(['iw', 'reg', 'set', '00'])
33 dev
[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout
=0.5)
34 dev
[0].flush_scan_cache()
37 def test_wnm_bss_transition_mgmt(dev
, apdev
):
38 """WNM BSS Transition Management"""
39 params
= {"ssid": "test-wnm",
40 "time_advertisement": "2",
42 "wnm_sleep_mode": "1",
43 "bss_transition": "1"}
44 hostapd
.add_ap(apdev
[0], params
)
46 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
47 dev
[0].request("WNM_BSS_QUERY 0")
49 def test_wnm_bss_transition_mgmt_oom(dev
, apdev
):
50 """WNM BSS Transition Management OOM"""
51 params
= {"ssid": "test-wnm", "bss_transition": "1"}
52 hapd
= hostapd
.add_ap(apdev
[0], params
)
54 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
55 with
alloc_fail(hapd
, 1, "ieee802_11_send_bss_trans_mgmt_request"):
56 dev
[0].request("WNM_BSS_QUERY 0")
57 wait_fail_trigger(hapd
, "GET_ALLOC_FAIL")
60 def test_wnm_disassoc_imminent(dev
, apdev
):
61 """WNM Disassociation Imminent"""
62 params
= {"ssid": "test-wnm",
63 "time_advertisement": "2",
65 "wnm_sleep_mode": "1",
66 "bss_transition": "1"}
67 hapd
= hostapd
.add_ap(apdev
[0], params
)
69 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
70 addr
= dev
[0].p2p_interface_addr()
71 hapd
.request("DISASSOC_IMMINENT " + addr
+ " 10")
72 ev
= dev
[0].wait_event(["WNM: Disassociation Imminent"])
74 raise Exception("Timeout while waiting for disassociation imminent")
75 if "Disassociation Timer 10" not in ev
:
76 raise Exception("Unexpected disassociation imminent contents")
77 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
79 raise Exception("Timeout while waiting for re-connection scan")
81 def test_wnm_disassoc_imminent_fail(dev
, apdev
):
82 """WNM Disassociation Imminent failure"""
83 params
= {"ssid": "test-wnm", "bss_transition": "1"}
84 hapd
= hostapd
.add_ap(apdev
[0], params
)
86 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
87 addr
= dev
[0].own_addr()
88 with
fail_test(hapd
, 1, "wnm_send_disassoc_imminent"):
89 if "FAIL" not in hapd
.request("DISASSOC_IMMINENT " + addr
+ " 10"):
90 raise Exception("DISASSOC_IMMINENT succeeded during failure testing")
93 def test_wnm_ess_disassoc_imminent(dev
, apdev
):
94 """WNM ESS Disassociation Imminent"""
95 params
= {"ssid": "test-wnm",
96 "time_advertisement": "2",
98 "wnm_sleep_mode": "1",
99 "bss_transition": "1"}
100 hapd
= hostapd
.add_ap(apdev
[0], params
)
102 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
103 addr
= dev
[0].p2p_interface_addr()
104 hapd
.request("ESS_DISASSOC " + addr
+ " 10 http://example.com/session-info")
105 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"])
107 raise Exception("Timeout while waiting for ESS disassociation imminent")
108 if "0 1024 http://example.com/session-info" not in ev
:
109 raise Exception("Unexpected ESS disassociation imminent message contents")
110 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
112 raise Exception("Timeout while waiting for re-connection scan")
114 def test_wnm_ess_disassoc_imminent_fail(dev
, apdev
):
115 """WNM ESS Disassociation Imminent failure"""
116 params
= {"ssid": "test-wnm", "bss_transition": "1"}
117 hapd
= hostapd
.add_ap(apdev
[0], params
)
119 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
120 addr
= dev
[0].own_addr()
121 if "FAIL" not in hapd
.request("ESS_DISASSOC " + addr
+ " 10 http://" + 256*'a'):
122 raise Exception("Invalid ESS_DISASSOC URL accepted")
123 with
fail_test(hapd
, 1, "wnm_send_ess_disassoc_imminent"):
124 if "FAIL" not in hapd
.request("ESS_DISASSOC " + addr
+ " 10 http://example.com/session-info"):
125 raise Exception("ESS_DISASSOC succeeded during failure testing")
127 def test_wnm_ess_disassoc_imminent_reject(dev
, apdev
):
128 """WNM ESS Disassociation Imminent getting rejected"""
129 params
= {"ssid": "test-wnm",
130 "bss_transition": "1"}
131 hapd
= hostapd
.add_ap(apdev
[0], params
)
133 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
134 addr
= dev
[0].own_addr()
135 if "OK" not in dev
[0].request("SET reject_btm_req_reason 123"):
136 raise Exception("Failed to set reject_btm_req_reason")
138 hapd
.request("ESS_DISASSOC " + addr
+ " 1 http://example.com/session-info")
139 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=10)
141 raise Exception("BSS-TM-RESP not seen")
142 if "status_code=123" not in ev
:
143 raise Exception("Unexpected response status: " + ev
)
144 dev
[0].wait_disconnected()
145 dev
[0].request("DISCONNECT")
148 def test_wnm_ess_disassoc_imminent_pmf(dev
, apdev
):
149 """WNM ESS Disassociation Imminent"""
150 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
151 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
152 params
["ieee80211w"] = "2"
153 params
["bss_transition"] = "1"
154 hapd
= hostapd
.add_ap(apdev
[0], params
)
156 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2",
157 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
158 addr
= dev
[0].p2p_interface_addr()
159 hapd
.request("ESS_DISASSOC " + addr
+ " 10 http://example.com/session-info")
160 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"])
162 raise Exception("Timeout while waiting for ESS disassociation imminent")
163 if "1 1024 http://example.com/session-info" not in ev
:
164 raise Exception("Unexpected ESS disassociation imminent message contents")
165 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
167 raise Exception("Timeout while waiting for re-connection scan")
169 def check_wnm_sleep_mode_enter_exit(hapd
, dev
, interval
=None, tfs_req
=None):
170 addr
= dev
.p2p_interface_addr()
171 sta
= hapd
.get_sta(addr
)
172 if "[WNM_SLEEP_MODE]" in sta
['flags']:
173 raise Exception("Station unexpectedly in WNM-Sleep Mode")
175 logger
.info("Going to WNM Sleep Mode")
177 if interval
is not None:
178 extra
+= " interval=" + str(interval
)
180 extra
+= " tfs_req=" + tfs_req
181 if "OK" not in dev
.request("WNM_SLEEP enter" + extra
):
182 raise Exception("WNM_SLEEP failed")
186 sta
= hapd
.get_sta(addr
)
187 if "[WNM_SLEEP_MODE]" in sta
['flags']:
191 raise Exception("Station failed to enter WNM-Sleep Mode")
193 logger
.info("Waking up from WNM Sleep Mode")
195 dev
.request("WNM_SLEEP exit")
198 sta
= hapd
.get_sta(addr
)
199 if "[WNM_SLEEP_MODE]" not in sta
['flags']:
203 raise Exception("Station failed to exit WNM-Sleep Mode")
206 def test_wnm_sleep_mode_open(dev
, apdev
):
207 """WNM Sleep Mode - open"""
208 params
= {"ssid": "test-wnm",
209 "time_advertisement": "2",
211 "wnm_sleep_mode": "1",
212 "bss_transition": "1"}
213 hapd
= hostapd
.add_ap(apdev
[0], params
)
215 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
216 ev
= hapd
.wait_event(["AP-STA-CONNECTED"], timeout
=5)
218 raise Exception("No connection event received from hostapd")
219 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
220 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0], interval
=100)
221 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0], tfs_req
="5b17010001130e110000071122334455661122334455661234")
224 "exit tfs_req=123 interval=10",
225 "enter tfs_req=qq interval=10"]
227 if "FAIL" not in dev
[0].request("WNM_SLEEP " + cmd
):
228 raise Exception("Invalid WNM_SLEEP accepted")
230 def test_wnm_sleep_mode_open_fail(dev
, apdev
):
231 """WNM Sleep Mode - open (fail)"""
232 params
= {"ssid": "test-wnm", "wnm_sleep_mode": "1"}
233 hapd
= hostapd
.add_ap(apdev
[0], params
)
235 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
236 with
fail_test(hapd
, 1, "nl80211_send_frame_cmd;ieee802_11_send_wnmsleep_resp"):
237 dev
[0].request("WNM_SLEEP enter")
238 wait_fail_trigger(hapd
, "GET_FAIL")
241 def test_wnm_sleep_mode_rsn(dev
, apdev
):
242 """WNM Sleep Mode - RSN"""
243 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
244 params
["time_advertisement"] = "2"
245 params
["time_zone"] = "EST5"
246 params
["wnm_sleep_mode"] = "1"
247 params
["bss_transition"] = "1"
248 hapd
= hostapd
.add_ap(apdev
[0], params
)
250 dev
[0].connect("test-wnm-rsn", psk
="12345678", scan_freq
="2412")
251 ev
= hapd
.wait_event(["AP-STA-CONNECTED"], timeout
=5)
253 raise Exception("No connection event received from hostapd")
254 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
257 def test_wnm_sleep_mode_ap_oom(dev
, apdev
):
258 """WNM Sleep Mode - AP side OOM"""
259 params
= {"ssid": "test-wnm",
260 "wnm_sleep_mode": "1"}
261 hapd
= hostapd
.add_ap(apdev
[0], params
)
263 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
264 ev
= hapd
.wait_event(["AP-STA-CONNECTED"], timeout
=5)
266 raise Exception("No connection event received from hostapd")
267 with
alloc_fail(hapd
, 1, "ieee802_11_send_wnmsleep_resp"):
268 dev
[0].request("WNM_SLEEP enter")
269 wait_fail_trigger(hapd
, "GET_ALLOC_FAIL")
270 with
alloc_fail(hapd
, 2, "ieee802_11_send_wnmsleep_resp"):
271 dev
[0].request("WNM_SLEEP exit")
272 wait_fail_trigger(hapd
, "GET_ALLOC_FAIL")
275 def test_wnm_sleep_mode_rsn_pmf(dev
, apdev
):
276 """WNM Sleep Mode - RSN with PMF"""
277 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
278 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
279 params
["ieee80211w"] = "2"
280 params
["time_advertisement"] = "2"
281 params
["time_zone"] = "EST5"
282 params
["wnm_sleep_mode"] = "1"
283 params
["bss_transition"] = "1"
284 hapd
= hostapd
.add_ap(apdev
[0], params
)
289 wt
.add_passphrase("12345678")
291 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2",
292 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
293 ev
= hapd
.wait_event(["AP-STA-CONNECTED"], timeout
=5)
295 raise Exception("No connection event received from hostapd")
296 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
299 def test_wnm_sleep_mode_rsn_ocv(dev
, apdev
):
300 """WNM Sleep Mode - RSN with OCV"""
301 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
302 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
303 params
["ieee80211w"] = "2"
305 params
["time_advertisement"] = "2"
306 params
["time_zone"] = "EST5"
307 params
["wnm_sleep_mode"] = "1"
308 params
["bss_transition"] = "1"
310 hapd
= hostapd
.add_ap(apdev
[0], params
)
311 except Exception as e
:
312 if "Failed to set hostapd parameter ocv" in str(e
):
313 raise HwsimSkip("OCV not supported")
319 wt
.add_passphrase("12345678")
321 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2", ocv
="1",
322 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
323 ev
= hapd
.wait_event(["AP-STA-CONNECTED"], timeout
=5)
325 raise Exception("No connection event received from hostapd")
326 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
328 # Check if OCV succeeded or failed
329 ev
= dev
[0].wait_event(["OCV failed"], timeout
=1)
331 raise Exception("OCI verification failed: " + ev
)
334 def test_wnm_sleep_mode_rsn_badocv(dev
, apdev
):
335 """WNM Sleep Mode - RSN with OCV and bad OCI elements"""
336 ssid
= "test-wnm-pmf"
337 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
338 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
339 params
["ieee80211w"] = "2"
341 params
['wnm_sleep_mode'] = '1'
343 hapd
= hostapd
.add_ap(apdev
[0], params
)
344 except Exception as e
:
345 if "Failed to set hostapd parameter ocv" in str(e
):
346 raise HwsimSkip("OCV not supported")
348 bssid
= apdev
[0]['bssid']
349 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK-SHA256", ocv
="1",
350 proto
="WPA2", ieee80211w
="2", scan_freq
="2412")
351 dev
[0].request("WNM_SLEEP enter")
354 msg
= {'fc': MGMT_SUBTYPE_ACTION
<< 4,
356 'sa': dev
[0].own_addr(),
359 logger
.debug("WNM Sleep Mode Request - Missing OCI element")
360 msg
['payload'] = struct
.pack("<BBBBBBBHBB",
361 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_REQ
, 0,
362 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
, 0, 0,
364 mgmt_tx(dev
[0], "MGMT_TX {} {} freq=2412 wait_time=200 no_cck=1 action={}".format(
365 msg
['da'], msg
['bssid'], binascii
.hexlify(msg
['payload']).decode()))
366 ev
= hapd
.wait_event(["OCV failed"], timeout
=5)
368 raise Exception("AP did not report missing OCI element")
370 logger
.debug("WNM Sleep Mode Request - Bad OCI element")
371 msg
['payload'] = struct
.pack("<BBBBBBBHBB",
372 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_REQ
, 0,
373 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
, 0,
376 oci_ie
= struct
.pack("<BBB", 81, 2, 0)
377 msg
['payload'] += struct
.pack("<BBB", WLAN_EID_EXTENSION
, 1 + len(oci_ie
),
378 WLAN_EID_EXT_OCV_OCI
) + oci_ie
379 mgmt_tx(dev
[0], "MGMT_TX {} {} freq=2412 wait_time=200 no_cck=1 action={}".format(
380 msg
['da'], msg
['bssid'], binascii
.hexlify(msg
['payload']).decode()))
381 ev
= hapd
.wait_event(["OCV failed"], timeout
=5)
383 raise Exception("AP did not report bad OCI element")
385 msg
= {'fc': MGMT_SUBTYPE_ACTION
<< 4,
386 'da': dev
[0].own_addr(),
389 hapd
.set("ext_mgmt_frame_handling", "1")
391 logger
.debug("WNM Sleep Mode Response - Missing OCI element")
392 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
393 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
395 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
396 WNM_STATUS_SLEEP_ACCEPT
, 0,
397 WLAN_EID_TFS_RESP
, 0)
398 dev
[0].request("WNM_SLEEP exit")
401 ev
= dev
[0].wait_event(["OCV failed"], timeout
=5)
403 raise Exception("STA did not report missing OCI element")
405 logger
.debug("WNM Sleep Mode Response - Bad OCI element")
406 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
407 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
409 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
410 WNM_STATUS_SLEEP_ACCEPT
, 0,
411 WLAN_EID_TFS_RESP
, 0)
412 oci_ie
= struct
.pack("<BBB", 81, 2, 0)
413 msg
['payload'] += struct
.pack("<BBB", WLAN_EID_EXTENSION
, 1 + len(oci_ie
),
414 WLAN_EID_EXT_OCV_OCI
) + oci_ie
417 ev
= dev
[0].wait_event(["OCV failed"], timeout
=5)
419 raise Exception("STA did not report bad OCI element")
421 def test_wnm_sleep_mode_rsn_ocv_failure(dev
, apdev
):
422 """WNM Sleep Mode - RSN with OCV - local failure"""
423 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
424 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
425 params
["ieee80211w"] = "2"
427 params
["time_advertisement"] = "2"
428 params
["time_zone"] = "EST5"
429 params
["wnm_sleep_mode"] = "1"
430 params
["bss_transition"] = "1"
432 hapd
= hostapd
.add_ap(apdev
[0], params
)
433 except Exception as e
:
434 if "Failed to set hostapd parameter ocv" in str(e
):
435 raise HwsimSkip("OCV not supported")
438 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2", ocv
="1",
439 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
440 # Failed to allocate buffer for OCI element in WNM-Sleep Mode frame
441 with
alloc_fail(hapd
, 2, "ieee802_11_send_wnmsleep_resp"):
442 if "OK" not in dev
[0].request("WNM_SLEEP enter"):
443 raise Exception("WNM_SLEEP failed")
444 wait_fail_trigger(hapd
, "GET_ALLOC_FAIL")
446 def test_wnm_sleep_mode_rsn_pmf_key_workaround(dev
, apdev
):
447 """WNM Sleep Mode - RSN with PMF and GTK/IGTK workaround"""
448 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
449 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
450 params
["ieee80211w"] = "2"
451 params
["time_advertisement"] = "2"
452 params
["time_zone"] = "EST5"
453 params
["wnm_sleep_mode"] = "1"
454 params
["wnm_sleep_mode_no_keys"] = "1"
455 params
["bss_transition"] = "1"
456 hapd
= hostapd
.add_ap(apdev
[0], params
)
461 wt
.add_passphrase("12345678")
463 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2",
464 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
465 ev
= hapd
.wait_event(["AP-STA-CONNECTED"], timeout
=5)
467 raise Exception("No connection event received from hostapd")
468 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
470 def test_wnm_sleep_mode_proto(dev
, apdev
):
471 """WNM Sleep Mode - protocol testing"""
472 params
= {"ssid": "test-wnm", "wnm_sleep_mode": "1"}
473 hapd
= hostapd
.add_ap(apdev
[0], params
)
474 bssid
= hapd
.own_addr()
475 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
476 addr
= dev
[0].own_addr()
478 hdr
= "d0003a01" + bssid
.replace(':', '') + addr
.replace(':', '') + bssid
.replace(':', '') + "1000"
479 hapd
.set("ext_mgmt_frame_handling", "1")
484 "0a10015d0400000000",
485 "0a1001" + 7*("5bff" + 255*"00") + "5d00",
488 if "OK" not in hapd
.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr
+ t
):
489 raise Exception("MGMT_RX_PROCESS failed")
491 hapd
.set("ext_mgmt_frame_handling", "0")
493 MGMT_SUBTYPE_ACTION
= 13
494 ACTION_CATEG_WNM
= 10
495 WNM_ACT_BSS_TM_REQ
= 7
496 WNM_ACT_BSS_TM_RESP
= 8
497 WNM_ACT_SLEEP_MODE_REQ
= 16
498 WNM_ACT_SLEEP_MODE_RESP
= 17
499 WNM_ACT_NOTIFICATION_REQ
= 26
500 WNM_ACT_NOTIFICATION_RESP
= 27
501 WNM_NOTIF_TYPE_FW_UPGRADE
= 0
502 WNM_NOTIF_TYPE_WFA
= 1
503 WLAN_EID_TFS_REQ
= 91
504 WLAN_EID_TFS_RESP
= 92
505 WLAN_EID_WNMSLEEP
= 93
506 WLAN_EID_EXTENSION
= 255
507 WLAN_EID_EXT_OCV_OCI
= 54
508 WNM_SLEEP_MODE_ENTER
= 0
509 WNM_SLEEP_MODE_EXIT
= 1
510 WNM_STATUS_SLEEP_ACCEPT
= 0
511 WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE
= 1
512 WNM_STATUS_DENIED_ACTION
= 2
513 WNM_STATUS_DENIED_TMP
= 3
514 WNM_STATUS_DENIED_KEY
= 4
515 WNM_STATUS_DENIED_OTHER_WNM_SERVICE
= 5
516 WNM_SLEEP_SUBELEM_GTK
= 0
517 WNM_SLEEP_SUBELEM_IGTK
= 1
519 def bss_tm_req(dst
, src
, dialog_token
=1, req_mode
=0, disassoc_timer
=0,
520 validity_interval
=1):
522 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
526 msg
['payload'] = struct
.pack("<BBBBHB",
527 ACTION_CATEG_WNM
, WNM_ACT_BSS_TM_REQ
,
528 dialog_token
, req_mode
, disassoc_timer
,
532 def rx_bss_tm_resp(hapd
, expect_dialog
=None, expect_status
=None):
533 for i
in range(0, 100):
534 resp
= hapd
.mgmt_rx()
536 raise Exception("No BSS TM Response received")
537 if resp
['subtype'] == MGMT_SUBTYPE_ACTION
:
540 raise Exception("Not an Action frame")
541 payload
= resp
['payload']
542 if len(payload
) < 2 + 3:
543 raise Exception("Too short payload")
544 (category
, action
) = struct
.unpack('BB', payload
[0:2])
545 if category
!= ACTION_CATEG_WNM
or action
!= WNM_ACT_BSS_TM_RESP
:
546 raise Exception("Not a BSS TM Response")
548 (dialog
, status
, bss_term_delay
) = struct
.unpack('BBB', pos
[0:3])
549 resp
['dialog'] = dialog
550 resp
['status'] = status
551 resp
['bss_term_delay'] = bss_term_delay
553 if len(pos
) >= 6 and status
== 0:
554 resp
['target_bssid'] = binascii
.hexlify(pos
[0:6])
556 resp
['candidates'] = pos
557 if expect_dialog
is not None and dialog
!= expect_dialog
:
558 raise Exception("Unexpected dialog token")
559 if expect_status
is not None and status
!= expect_status
:
560 raise Exception("Unexpected status code %d" % status
)
563 def expect_ack(hapd
):
564 ev
= hapd
.wait_event(["MGMT-TX-STATUS"], timeout
=5)
566 raise Exception("Missing TX status")
568 raise Exception("Action frame not acknowledged")
570 def mgmt_tx(dev
, msg
):
571 if "FAIL" in dev
.request(msg
):
572 raise Exception("Failed to send Action frame")
573 ev
= dev
.wait_event(["MGMT-TX-STATUS"], timeout
=10)
575 raise Exception("Timeout on MGMT-TX-STATUS")
576 if "result=SUCCESS" not in ev
:
577 raise Exception("Peer did not ack Action frame")
580 def test_wnm_bss_tm_req(dev
, apdev
):
581 """BSS Transition Management Request"""
582 params
= {"ssid": "test-wnm", "bss_transition": "1"}
583 hapd
= hostapd
.add_ap(apdev
[0], params
)
584 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
585 addr
= dev
[0].own_addr()
587 hapd
.set("ext_mgmt_frame_handling", "1")
589 # truncated BSS TM Request
590 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
592 req
['payload'] = struct
.pack("<BBBBH",
593 ACTION_CATEG_WNM
, WNM_ACT_BSS_TM_REQ
,
597 dev
[0].dump_monitor()
599 # no disassociation and no candidate list
600 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
603 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=2, expect_status
=1)
604 dev
[0].dump_monitor()
606 # truncated BSS Termination Duration
607 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
611 dev
[0].dump_monitor()
613 # BSS Termination Duration with TSF=0 and Duration=10
614 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
615 req_mode
=0x08, dialog_token
=3)
616 req
['payload'] += struct
.pack("<BBQH", 4, 10, 0, 10)
618 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=3, expect_status
=1)
619 dev
[0].dump_monitor()
621 # truncated Session Information URL
622 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
626 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
628 req
['payload'] += struct
.pack("<BBB", 3, 65, 66)
631 dev
[0].dump_monitor()
633 # Session Information URL
634 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
635 req_mode
=0x10, dialog_token
=4)
636 req
['payload'] += struct
.pack("<BBB", 2, 65, 66)
638 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=4, expect_status
=0)
639 dev
[0].dump_monitor()
641 # Preferred Candidate List without any entries
642 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
643 req_mode
=0x01, dialog_token
=5)
645 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=5, expect_status
=7)
646 dev
[0].dump_monitor()
648 # Preferred Candidate List with a truncated entry
649 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
651 req
['payload'] += struct
.pack("<BB", 52, 1)
654 dev
[0].dump_monitor()
656 # Preferred Candidate List with a too short entry
657 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
658 req_mode
=0x01, dialog_token
=6)
659 req
['payload'] += struct
.pack("<BB", 52, 0)
661 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=6, expect_status
=7)
662 dev
[0].dump_monitor()
664 # Preferred Candidate List with a non-matching entry
665 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
666 req_mode
=0x01, dialog_token
=6)
667 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13,
671 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=6, expect_status
=7)
672 dev
[0].dump_monitor()
674 # Preferred Candidate List with a truncated subelement
675 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
676 req_mode
=0x01, dialog_token
=7)
677 req
['payload'] += struct
.pack("<BB6BLBBBBB", 52, 13 + 2,
682 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=7, expect_status
=7)
683 dev
[0].dump_monitor()
685 # Preferred Candidate List with lots of invalid optional subelements
686 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
687 req_mode
=0x01, dialog_token
=8)
688 subelems
= struct
.pack("<BBHB", 1, 3, 0, 100)
689 subelems
+= struct
.pack("<BBB", 2, 1, 65)
690 subelems
+= struct
.pack("<BB", 3, 0)
691 subelems
+= struct
.pack("<BBQB", 4, 9, 0, 10)
692 subelems
+= struct
.pack("<BBHLB", 5, 7, 0, 0, 0)
693 subelems
+= struct
.pack("<BB", 66, 0)
694 subelems
+= struct
.pack("<BBBBBB", 70, 4, 0, 0, 0, 0)
695 subelems
+= struct
.pack("<BB", 71, 0)
696 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13 + len(subelems
),
698 0, 81, 1, 7) + subelems
700 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=8, expect_status
=7)
701 dev
[0].dump_monitor()
703 # Preferred Candidate List with lots of valid optional subelements (twice)
704 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
705 req_mode
=0x01, dialog_token
=8)
707 subelems
= struct
.pack("<BBHH", 1, 4, 0, 100)
708 # Condensed Country String
709 subelems
+= struct
.pack("<BBBB", 2, 2, 65, 66)
710 # BSS Transition Candidate Preference
711 subelems
+= struct
.pack("<BBB", 3, 1, 100)
712 # BSS Termination Duration
713 subelems
+= struct
.pack("<BBQH", 4, 10, 0, 10)
715 subelems
+= struct
.pack("<BBHLH", 5, 8, 0, 0, 0)
716 # Measurement Pilot Transmission
717 subelems
+= struct
.pack("<BBBBB", 66, 3, 0, 0, 0)
718 # RM Enabled Capabilities
719 subelems
+= struct
.pack("<BBBBBBB", 70, 5, 0, 0, 0, 0, 0)
721 subelems
+= struct
.pack("<BBBB", 71, 2, 0, 0)
722 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13 + len(subelems
) * 2,
724 0, 81, 1, 7) + subelems
+ subelems
726 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=8, expect_status
=7)
727 dev
[0].dump_monitor()
729 # Preferred Candidate List followed by vendor element
730 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
731 req_mode
=0x01, dialog_token
=8)
733 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13 + len(subelems
),
735 0, 81, 1, 7) + subelems
736 req
['payload'] += binascii
.unhexlify("DD0411223344")
738 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=8, expect_status
=7)
739 dev
[0].dump_monitor()
742 def test_wnm_bss_keep_alive(dev
, apdev
):
744 params
= {"ssid": "test-wnm",
745 "ap_max_inactivity": "1"}
746 hapd
= hostapd
.add_ap(apdev
[0], params
)
748 addr
= dev
[0].p2p_interface_addr()
749 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
750 start
= hapd
.get_sta(addr
)
751 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=2)
753 raise Exception("Unexpected disconnection")
754 end
= hapd
.get_sta(addr
)
755 if int(end
['rx_packets']) <= int(start
['rx_packets']):
756 raise Exception("No keep-alive packets received")
758 # Disable client keep-alive so that hostapd will verify connection
760 dev
[0].request("SET no_keep_alive 1")
762 sta
= hapd
.get_sta(addr
)
763 logger
.info("timeout_next=%s rx_packets=%s tx_packets=%s" % (sta
['timeout_next'], sta
['rx_packets'], sta
['tx_packets']))
764 if i
> 1 and sta
['timeout_next'] != "NULLFUNC POLL" and int(sta
['tx_packets']) > int(end
['tx_packets']):
766 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
768 raise Exception("Unexpected disconnection (client poll expected)")
770 dev
[0].request("SET no_keep_alive 0")
771 if int(sta
['tx_packets']) <= int(end
['tx_packets']):
772 raise Exception("No client poll packet seen")
774 def test_wnm_bss_tm(dev
, apdev
):
775 """WNM BSS Transition Management"""
779 params
= {"ssid": "test-wnm",
780 "country_code": "FI",
784 "bss_transition": "1"}
785 hapd
= hostapd
.add_ap(apdev
[0], params
)
787 id = dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
788 dev
[0].set_network(id, "scan_freq", "")
790 params
= {"ssid": "test-wnm",
791 "country_code": "FI",
795 "bss_transition": "1"}
796 hapd2
= hostapd
.add_ap(apdev
[1], params
)
798 addr
= dev
[0].p2p_interface_addr()
799 dev
[0].dump_monitor()
801 logger
.info("No neighbor list entries")
802 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
):
803 raise Exception("BSS_TM_REQ command failed")
804 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
806 raise Exception("No BSS Transition Management Response")
808 raise Exception("Unexpected BSS Transition Management Response address")
809 if "status_code=0" in ev
:
810 raise Exception("BSS transition accepted unexpectedly")
811 dev
[0].dump_monitor()
813 logger
.info("Neighbor list entry, but not claimed as Preferred Candidate List")
814 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " neighbor=11:22:33:44:55:66,0x0000,81,3,7"):
815 raise Exception("BSS_TM_REQ command failed")
816 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
818 raise Exception("No BSS Transition Management Response")
819 if "status_code=0" in ev
:
820 raise Exception("BSS transition accepted unexpectedly")
821 dev
[0].dump_monitor()
823 logger
.info("Preferred Candidate List (no matching neighbor) without Disassociation Imminent")
824 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " pref=1 neighbor=11:22:33:44:55:66,0x0000,81,3,7,0301ff neighbor=22:33:44:55:66:77,0x0000,1,44,7 neighbor=00:11:22:33:44:55,0x0000,81,4,7,03010a"):
825 raise Exception("BSS_TM_REQ command failed")
826 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
828 raise Exception("No BSS Transition Management Response")
829 if "status_code=0" in ev
:
830 raise Exception("BSS transition accepted unexpectedly")
831 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=5)
833 raise Exception("No scan started")
834 dev
[0].dump_monitor()
836 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
837 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[1]['bssid'] + ",0x0000,115,36,7,0301ff"):
838 raise Exception("BSS_TM_REQ command failed")
839 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
841 raise Exception("No BSS Transition Management Response")
842 if "status_code=0" not in ev
:
843 raise Exception("BSS transition request was not accepted: " + ev
)
844 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
845 raise Exception("Unexpected target BSS: " + ev
)
846 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
847 if apdev
[1]['bssid'] not in ev
:
848 raise Exception("Unexpected reassociation target: " + ev
)
849 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
851 raise Exception("Unexpected scan started")
852 dev
[0].dump_monitor()
854 logger
.info("Preferred Candidate List with two matches, no roam needed")
855 if "OK" not in hapd2
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[0]['bssid'] + ",0x0000,81,1,7,030101 neighbor=" + apdev
[1]['bssid'] + ",0x0000,115,36,7,0301ff"):
856 raise Exception("BSS_TM_REQ command failed")
857 ev
= hapd2
.wait_event(['BSS-TM-RESP'], timeout
=10)
859 raise Exception("No BSS Transition Management Response")
860 if "status_code=0" not in ev
:
861 raise Exception("BSS transition request was not accepted: " + ev
)
862 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
863 raise Exception("Unexpected target BSS: " + ev
)
864 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
866 raise Exception("Unexpected scan started")
867 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=0.5)
869 raise Exception("Unexpected reassociation")
871 logger
.info("Preferred Candidate List with two matches and extra frequency (160 MHz), no roam needed")
872 if "OK" not in hapd2
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[0]['bssid'] + ",0x0000,81,1,7,030101 neighbor=" + apdev
[1]['bssid'] + ",0x0000,115,36,7,0301ff" + ' neighbor=00:11:22:33:44:55,0x0000,129,36,7'):
873 raise Exception("BSS_TM_REQ command failed")
874 ev
= hapd2
.wait_event(['BSS-TM-RESP'], timeout
=10)
876 raise Exception("No BSS Transition Management Response")
877 if "status_code=0" not in ev
:
878 raise Exception("BSS transition request was not accepted: " + ev
)
879 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
880 raise Exception("Unexpected target BSS: " + ev
)
881 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
883 raise Exception("Unexpected scan started")
884 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=0.5)
886 raise Exception("Unexpected reassociation")
888 clear_regdom_state(dev
, hapd
, hapd2
)
890 def test_wnm_bss_tm_errors(dev
, apdev
):
891 """WNM BSS Transition Management errors"""
892 params
= {"ssid": "test-wnm",
895 "bss_transition": "1"}
896 hapd
= hostapd
.add_ap(apdev
[0], params
)
897 id = dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
898 addr
= dev
[0].own_addr()
900 tests
= ["BSS_TM_REQ q",
901 "BSS_TM_REQ 22:22:22:22:22:22",
902 "BSS_TM_REQ %s disassoc_timer=-1" % addr
,
903 "BSS_TM_REQ %s disassoc_timer=65536" % addr
,
904 "BSS_TM_REQ %s bss_term=foo" % addr
,
905 "BSS_TM_REQ %s neighbor=q" % addr
,
906 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55" % addr
,
907 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0" % addr
,
908 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0" % addr
,
909 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0" % addr
,
910 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0,0,q" % addr
,
911 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0,0,0q" % addr
,
912 "BSS_TM_REQ " + addr
+ " url=" + 256*'a',
913 "BSS_TM_REQ %s url=foo mbo=1:2" % addr
,
914 "BSS_TM_REQ %s url=foo mbo=100000:0:0" % addr
,
915 "BSS_TM_REQ %s url=foo mbo=0:0:254" % addr
,
916 "BSS_TM_REQ %s url=foo mbo=0:100000:0" % addr
]
918 if "FAIL" not in hapd
.request(t
):
919 raise Exception("Invalid command accepted: %s" % t
)
921 with
alloc_fail(hapd
, 1, "=hostapd_ctrl_iface_bss_tm_req"):
922 if "FAIL" not in hapd
.request("BSS_TM_REQ %s url=http://foo" % addr
):
923 raise Exception("BSS_TM_REQ accepted during OOM")
925 with
alloc_fail(hapd
, 1, "=wnm_send_bss_tm_req"):
926 if "FAIL" not in hapd
.request("BSS_TM_REQ %s url=http://foo" % addr
):
927 raise Exception("BSS_TM_REQ accepted during OOM")
929 with
fail_test(hapd
, 1, "wnm_send_bss_tm_req"):
930 if "FAIL" not in hapd
.request("BSS_TM_REQ %s url=http://foo" % addr
):
931 raise Exception("BSS_TM_REQ accepted during failure testing")
933 def test_wnm_bss_tm_termination(dev
, apdev
):
934 """WNM BSS Transition Management and BSS termination"""
935 params
= {"ssid": "test-wnm",
938 "bss_transition": "1"}
939 hapd
= hostapd
.add_ap(apdev
[0], params
)
940 id = dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
941 addr
= dev
[0].own_addr()
943 if "OK" not in hapd
.request("BSS_TM_REQ %s bss_term=0,1" % addr
):
944 raise Exception("BSS_TM_REQ failed")
945 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=5)
947 raise Exception("No BSS-TM-RESP event seen")
949 if "OK" not in hapd
.request("BSS_TM_REQ %s url=http://example.com/" % addr
):
950 raise Exception("BSS_TM_REQ failed")
951 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=5)
953 raise Exception("No BSS-TM-RESP event seen")
955 def test_wnm_bss_tm_scan_not_needed(dev
, apdev
):
956 """WNM BSS Transition Management and scan not needed"""
957 run_wnm_bss_tm_scan_not_needed(dev
, apdev
)
959 def test_wnm_bss_tm_nei_vht(dev
, apdev
):
960 """WNM BSS Transition Management and VHT neighbor"""
961 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, vht
=True, nei_info
="115,36,9")
963 def test_wnm_bss_tm_nei_11a(dev
, apdev
):
964 """WNM BSS Transition Management and 11a neighbor"""
965 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=False, nei_info
="115,36,4")
967 def test_wnm_bss_tm_nei_11g(dev
, apdev
):
968 """WNM BSS Transition Management and 11g neighbor"""
969 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=False, hwmode
='g',
970 channel
='2', freq
=2417, nei_info
="81,2,6")
972 def test_wnm_bss_tm_nei_11b(dev
, apdev
):
973 """WNM BSS Transition Management and 11g neighbor"""
974 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=False, hwmode
='b',
975 channel
='3', freq
=2422, nei_info
="81,2,5")
977 def run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=True, vht
=False, hwmode
='a',
978 channel
='36', freq
=5180,
979 nei_info
="115,36,7,0301ff"):
983 params
= {"ssid": "test-wnm",
984 "country_code": "FI",
988 "bss_transition": "1"}
989 hapd
= hostapd
.add_ap(apdev
[0], params
)
991 params
= {"ssid": "test-wnm",
992 "country_code": "FI",
996 "bss_transition": "1"}
998 params
['ieee80211n'] = '0'
1000 params
['ieee80211ac'] = "1"
1001 params
["vht_oper_chwidth"] = "0"
1002 params
["vht_oper_centr_freq_seg0_idx"] = "0"
1004 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1006 dev
[0].scan_for_bss(apdev
[1]['bssid'], freq
)
1008 id = dev
[0].connect("test-wnm", key_mgmt
="NONE",
1009 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1010 dev
[0].set_network(id, "scan_freq", "")
1011 dev
[0].set_network(id, "bssid", "")
1013 addr
= dev
[0].own_addr()
1014 dev
[0].dump_monitor()
1016 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1017 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[1]['bssid'] + ",0x0000," + nei_info
):
1018 raise Exception("BSS_TM_REQ command failed")
1019 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1021 raise Exception("No BSS Transition Management Response")
1022 if "status_code=0" not in ev
:
1023 raise Exception("BSS transition request was not accepted: " + ev
)
1024 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
1025 raise Exception("Unexpected target BSS: " + ev
)
1026 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
1027 if apdev
[1]['bssid'] not in ev
:
1028 raise Exception("Unexpected reassociation target: " + ev
)
1029 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
1031 raise Exception("Unexpected scan started")
1032 dev
[0].dump_monitor()
1034 clear_regdom_state(dev
, hapd
, hapd2
)
1036 def test_wnm_bss_tm_scan_needed(dev
, apdev
):
1037 """WNM BSS Transition Management and scan needed"""
1041 params
= {"ssid": "test-wnm",
1042 "country_code": "FI",
1046 "bss_transition": "1"}
1047 hapd
= hostapd
.add_ap(apdev
[0], params
)
1049 params
= {"ssid": "test-wnm",
1050 "country_code": "FI",
1054 "bss_transition": "1"}
1055 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1057 dev
[0].scan_for_bss(apdev
[1]['bssid'], 5180)
1059 id = dev
[0].connect("test-wnm", key_mgmt
="NONE",
1060 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1061 dev
[0].set_network(id, "scan_freq", "")
1062 dev
[0].set_network(id, "bssid", "")
1064 addr
= dev
[0].own_addr()
1065 dev
[0].dump_monitor()
1067 logger
.info("Wait 11 seconds for the last scan result to be too old, but still present in BSS table")
1069 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1070 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[1]['bssid'] + ",0x0000,115,36,7,0301ff"):
1071 raise Exception("BSS_TM_REQ command failed")
1072 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1074 raise Exception("No BSS Transition Management Response")
1075 if "status_code=0" not in ev
:
1076 raise Exception("BSS transition request was not accepted: " + ev
)
1077 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
1078 raise Exception("Unexpected target BSS: " + ev
)
1079 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
1080 if apdev
[1]['bssid'] not in ev
:
1081 raise Exception("Unexpected reassociation target: " + ev
)
1082 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
1084 raise Exception("Unexpected scan started")
1085 dev
[0].dump_monitor()
1087 clear_regdom_state(dev
, hapd
, hapd2
)
1089 def test_wnm_bss_tm_scan_needed_e4(dev
, apdev
):
1090 """WNM BSS Transition Management and scan needed (Table E-4)"""
1094 params
= {"ssid": "test-wnm",
1095 "country_code": "FI",
1100 "bss_transition": "1"}
1101 hapd
= hostapd
.add_ap(apdev
[0], params
)
1103 params
= {"ssid": "test-wnm",
1104 "country_code": "FI",
1109 "bss_transition": "1"}
1110 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1112 id = dev
[0].connect("test-wnm", key_mgmt
="NONE",
1113 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1114 dev
[0].set_network(id, "scan_freq", "")
1115 dev
[0].set_network(id, "bssid", "")
1117 addr
= dev
[0].own_addr()
1118 dev
[0].dump_monitor()
1120 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1121 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[1]['bssid'] + ",0x0000,115,36,7,0301ff"):
1122 raise Exception("BSS_TM_REQ command failed")
1123 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=4)
1125 raise Exception("No BSS Transition Management Response seen quickly enough - did scan optimization fail?")
1126 if "status_code=0" not in ev
:
1127 raise Exception("BSS transition request was not accepted: " + ev
)
1128 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
1129 # Wait for regdom change due to country IE to avoid issues with that
1130 # processing happening only after the disconnection and cfg80211 ending
1131 # up intersecting regdoms when we try to clear state back to world (00)
1134 ev
= dev
[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout
=0.5)
1135 if not ev
or "COUNTRY_IE" in ev
:
1137 dev
[0].dump_monitor()
1139 clear_regdom_state(dev
, hapd
, hapd2
)
1141 def start_wnm_tm(ap
, country
, dev
, country3
=None):
1142 params
= {"ssid": "test-wnm",
1143 "country_code": country
,
1147 "bss_transition": "1"}
1148 if country3
is not None:
1149 params
["country3"] = country3
1150 hapd
= hostapd
.add_ap(ap
, params
)
1151 id = dev
.connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1152 wait_regdom_changes(dev
)
1154 dev
.set_network(id, "scan_freq", "")
1157 def stop_wnm_tm(hapd
, dev
):
1159 hapd
.request("DISABLE")
1161 dev
[0].disconnect_and_stop_scan()
1162 subprocess
.call(['iw', 'reg', 'set', '00'])
1163 wait_regdom_changes(dev
[0])
1164 country
= dev
[0].get_driver_status_field("country")
1165 logger
.info("Country code at the end: " + country
)
1169 dev
[0].flush_scan_cache()
1171 def wnm_bss_tm_check(hapd
, dev
, data
):
1172 addr
= dev
.p2p_interface_addr()
1173 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " " + data
):
1174 raise Exception("BSS_TM_REQ command failed")
1175 ev
= dev
.wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=5)
1177 raise Exception("No scan started")
1178 ev
= dev
.wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
1180 raise Exception("Scan did not complete")
1182 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1184 raise Exception("No BSS Transition Management Response")
1185 if "status_code=7" not in ev
:
1186 raise Exception("Unexpected response: " + ev
)
1188 def test_wnm_bss_tm_country_us(dev
, apdev
):
1189 """WNM BSS Transition Management (US)"""
1192 hapd
, id = start_wnm_tm(apdev
[0], "US", dev
[0])
1194 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
1195 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=11:22:33:44:55:66,0x0000,12,3,7,0301ff neighbor=00:11:22:33:44:55,0x0000,2,52,7,03010a neighbor=00:11:22:33:44:57,0x0000,4,100,7 neighbor=00:11:22:33:44:59,0x0000,3,149,7 neighbor=00:11:22:33:44:5b,0x0000,34,1,7 neighbor=00:11:22:33:44:5d,0x0000,5,149,7")
1197 # Make the test take less time by limiting full scans
1198 dev
[0].set_network(id, "scan_freq", "2412")
1199 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1200 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=11:22:33:44:55:66,0x0000,12,0,7,0301ff neighbor=22:33:44:55:66:77,0x0000,12,12,7 neighbor=00:11:22:33:44:55,0x0000,2,35,7,03010a neighbor=00:11:22:33:44:56,0x0000,2,65,7 neighbor=00:11:22:33:44:57,0x0000,4,99,7 neighbor=00:11:22:33:44:58,0x0000,4,145,7")
1202 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1203 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=00:11:22:33:44:59,0x0000,3,148,7 neighbor=00:11:22:33:44:5a,0x0000,3,162,7 neighbor=00:11:22:33:44:5b,0x0000,34,0,7 neighbor=00:11:22:33:44:5c,0x0000,34,4,7 neighbor=00:11:22:33:44:5d,0x0000,5,148,7 neighbor=00:11:22:33:44:5e,0x0000,5,166,7 neighbor=00:11:22:33:44:5f,0x0000,0,0,7")
1205 stop_wnm_tm(hapd
, dev
)
1207 def test_wnm_bss_tm_country_fi(dev
, apdev
):
1208 """WNM BSS Transition Management (FI)"""
1209 addr
= dev
[0].p2p_interface_addr()
1212 hapd
, id = start_wnm_tm(apdev
[0], "FI", dev
[0])
1214 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
1215 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=11:22:33:44:55:66,0x0000,4,3,7,0301ff neighbor=00:11:22:33:44:55,0x0000,1,36,7,03010a neighbor=00:11:22:33:44:57,0x0000,3,100,7 neighbor=00:11:22:33:44:59,0x0000,17,149,7 neighbor=00:11:22:33:44:5c,0x0000,18,1,7")
1217 # Make the test take less time by limiting full scans
1218 dev
[0].set_network(id, "scan_freq", "2412")
1219 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1220 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=00:11:22:33:44:00,0x0000,4,0,7 neighbor=00:11:22:33:44:01,0x0000,4,14,7 neighbor=00:11:22:33:44:02,0x0000,1,35,7 neighbor=00:11:22:33:44:03,0x0000,1,65,7 neighbor=00:11:22:33:44:04,0x0000,3,99,7 neighbor=00:11:22:33:44:05,0x0000,3,141,7 neighbor=00:11:22:33:44:06,0x0000,17,148,7 neighbor=00:11:22:33:44:07,0x0000,17,170,7 neighbor=00:11:22:33:44:08,0x0000,18,0,7 neighbor=00:11:22:33:44:09,0x0000,18,5,7")
1222 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1223 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=00:11:22:33:44:00,0x0000,0,0,7")
1225 stop_wnm_tm(hapd
, dev
)
1227 def test_wnm_bss_tm_country_jp(dev
, apdev
):
1228 """WNM BSS Transition Management (JP)"""
1229 addr
= dev
[0].p2p_interface_addr()
1232 hapd
, id = start_wnm_tm(apdev
[0], "JP", dev
[0])
1234 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
1235 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=11:22:33:44:55:66,0x0000,30,3,7,0301ff neighbor=00:11:22:33:44:55,0x0000,31,14,7,03010a neighbor=00:11:22:33:44:57,0x0000,1,36,7 neighbor=00:11:22:33:44:59,0x0000,34,100,7 neighbor=00:11:22:33:44:5c,0x0000,59,1,7")
1237 # Make the test take less time by limiting full scans
1238 dev
[0].set_network(id, "scan_freq", "2412")
1239 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1240 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=11:22:33:44:55:66,0x0000,30,0,7,0301ff neighbor=22:33:44:55:66:77,0x0000,30,14,7 neighbor=00:11:22:33:44:56,0x0000,31,13,7 neighbor=00:11:22:33:44:57,0x0000,1,33,7 neighbor=00:11:22:33:44:58,0x0000,1,65,7 neighbor=00:11:22:33:44:5a,0x0000,34,99,7 neighbor=00:11:22:33:44:5b,0x0000,34,141,7 neighbor=00:11:22:33:44:5d,0x0000,59,0,7 neighbor=00:11:22:33:44:5e,0x0000,59,4,7 neighbor=00:11:22:33:44:5f,0x0000,0,0,7")
1242 stop_wnm_tm(hapd
, dev
)
1244 def test_wnm_bss_tm_country_cn(dev
, apdev
):
1245 """WNM BSS Transition Management (CN)"""
1246 addr
= dev
[0].p2p_interface_addr()
1249 hapd
, id = start_wnm_tm(apdev
[0], "CN", dev
[0])
1251 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
1252 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=11:22:33:44:55:66,0x0000,7,3,7,0301ff neighbor=00:11:22:33:44:55,0x0000,1,36,7,03010a neighbor=00:11:22:33:44:57,0x0000,3,149,7 neighbor=00:11:22:33:44:59,0x0000,6,149,7")
1254 # Make the test take less time by limiting full scans
1255 dev
[0].set_network(id, "scan_freq", "2412")
1256 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1257 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=11:22:33:44:55:66,0x0000,7,0,7,0301ff neighbor=22:33:44:55:66:77,0x0000,7,14,7 neighbor=00:11:22:33:44:56,0x0000,1,35,7 neighbor=00:11:22:33:44:57,0x0000,1,65,7 neighbor=00:11:22:33:44:58,0x0000,3,148,7 neighbor=00:11:22:33:44:5a,0x0000,3,166,7 neighbor=00:11:22:33:44:5f,0x0000,0,0,7")
1259 stop_wnm_tm(hapd
, dev
)
1261 def test_wnm_bss_tm_global(dev
, apdev
):
1262 """WNM BSS Transition Management (global)"""
1263 run_wnm_bss_tm_global(dev
, apdev
, "XX", None)
1265 def test_wnm_bss_tm_global4(dev
, apdev
):
1266 """WNM BSS Transition Management (global; indicate table E-4)"""
1267 run_wnm_bss_tm_global(dev
, apdev
, "FI", "0x04")
1269 def run_wnm_bss_tm_global(dev
, apdev
, country
, country3
):
1270 addr
= dev
[0].p2p_interface_addr()
1273 hapd
, id = start_wnm_tm(apdev
[0], country
, dev
[0], country3
=country3
)
1275 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
1276 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=11:22:33:44:55:66,0x0000,81,3,7,0301ff neighbor=00:11:22:33:44:55,0x0000,82,14,7,03010a neighbor=00:11:22:33:44:57,0x0000,83,1,7 neighbor=00:11:22:33:44:59,0x0000,115,36,7 neighbor=00:11:22:33:44:5a,0x0000,121,100,7 neighbor=00:11:22:33:44:5c,0x0000,124,149,7 neighbor=00:11:22:33:44:5d,0x0000,125,149,7 neighbor=00:11:22:33:44:5e,0x0000,128,42,7 neighbor=00:11:22:33:44:5f,0x0000,129,50,7 neighbor=00:11:22:33:44:60,0x0000,180,1,7")
1278 # Make the test take less time by limiting full scans
1279 dev
[0].set_network(id, "scan_freq", "2412")
1280 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1281 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=00:11:22:33:44:00,0x0000,81,0,7 neighbor=00:11:22:33:44:01,0x0000,81,14,7 neighbor=00:11:22:33:44:02,0x0000,82,13,7 neighbor=00:11:22:33:44:03,0x0000,83,0,7 neighbor=00:11:22:33:44:04,0x0000,83,14,7 neighbor=00:11:22:33:44:05,0x0000,115,35,7 neighbor=00:11:22:33:44:06,0x0000,115,65,7 neighbor=00:11:22:33:44:07,0x0000,121,99,7 neighbor=00:11:22:33:44:08,0x0000,121,141,7 neighbor=00:11:22:33:44:09,0x0000,124,148,7")
1283 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1284 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=00:11:22:33:44:00,0x0000,124,162,7 neighbor=00:11:22:33:44:01,0x0000,125,148,7 neighbor=00:11:22:33:44:02,0x0000,125,170,7 neighbor=00:11:22:33:44:03,0x0000,128,35,7 neighbor=00:11:22:33:44:04,0x0000,128,162,7 neighbor=00:11:22:33:44:05,0x0000,129,49,7 neighbor=00:11:22:33:44:06,0x0000,129,115,7 neighbor=00:11:22:33:44:07,0x0000,180,0,7 neighbor=00:11:22:33:44:08,0x0000,180,5,7 neighbor=00:11:22:33:44:09,0x0000,0,0,7")
1286 stop_wnm_tm(hapd
, dev
)
1288 def test_wnm_bss_tm_op_class_0(dev
, apdev
):
1289 """WNM BSS Transition Management with invalid operating class"""
1292 hapd
, id = start_wnm_tm(apdev
[0], "US", dev
[0])
1294 logger
.info("Preferred Candidate List (no matching neighbor, invalid op class specified for channels)")
1295 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=00:11:22:33:44:59,0x0000,0,149,7 neighbor=00:11:22:33:44:5b,0x0000,0,1,7")
1297 stop_wnm_tm(hapd
, dev
)
1299 def test_wnm_bss_tm_rsn(dev
, apdev
):
1300 """WNM BSS Transition Management with RSN"""
1304 params
= hostapd
.wpa2_params(ssid
="test-wnm", passphrase
="zxcvbnm,.-")
1305 params
["country_code"] = "FI"
1306 params
["ieee80211d"] = "1"
1307 params
["hw_mode"] = "g"
1308 params
["channel"] = "1"
1309 params
["bss_transition"] = "1"
1310 hapd
= hostapd
.add_ap(apdev
[0], params
)
1312 params
= hostapd
.wpa2_params(ssid
="test-wnm", passphrase
="zxcvbnm,.-")
1313 params
["country_code"] = "FI"
1314 params
["ieee80211d"] = "1"
1315 params
["hw_mode"] = "a"
1316 params
["channel"] = "36"
1317 params
["bss_transition"] = "1"
1318 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1320 dev
[0].scan_for_bss(apdev
[1]['bssid'], 5180)
1322 id = dev
[0].connect("test-wnm", psk
="zxcvbnm,.-",
1323 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1324 dev
[0].set_network(id, "scan_freq", "")
1325 dev
[0].set_network(id, "bssid", "")
1327 addr
= dev
[0].own_addr()
1328 dev
[0].dump_monitor()
1331 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1332 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[1]['bssid'] + ",0x0000," + "115,36,7,0301ff"):
1333 raise Exception("BSS_TM_REQ command failed")
1334 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1336 raise Exception("No BSS Transition Management Response")
1337 if "status_code=0" not in ev
:
1338 raise Exception("BSS transition request was not accepted: " + ev
)
1339 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
1340 raise Exception("Unexpected target BSS: " + ev
)
1341 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
1342 if apdev
[1]['bssid'] not in ev
:
1343 raise Exception("Unexpected reassociation target: " + ev
)
1345 clear_regdom_state(dev
, hapd
, hapd2
)
1347 def test_wnm_action_proto(dev
, apdev
):
1348 """WNM Action protocol testing"""
1349 params
= {"ssid": "test-wnm"}
1350 params
['wnm_sleep_mode'] = '1'
1351 hapd
= hostapd
.add_ap(apdev
[0], params
)
1352 bssid
= apdev
[0]['bssid']
1353 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1354 dev
[0].request("WNM_SLEEP enter")
1356 hapd
.set("ext_mgmt_frame_handling", "1")
1359 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
1360 msg
['da'] = dev
[0].own_addr()
1362 msg
['bssid'] = bssid
1366 logger
.debug("Unexpected WNM-Notification Response")
1367 # Note: This is actually not registered for user space processing in
1368 # driver_nl80211.c nl80211_mgmt_subscribe_non_ap() and as such, won't make
1369 # it to wpa_supplicant.
1370 msg
['payload'] = struct
.pack("<BBBB",
1371 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_RESP
,
1376 logger
.debug("Truncated WNM-Notification Request (no Type field)")
1377 msg
['payload'] = struct
.pack("<BBB",
1378 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1383 logger
.debug("WFA WNM-Notification Request with truncated IE (min)")
1384 msg
['payload'] = struct
.pack("<BBBBBB",
1385 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1386 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0, 1)
1390 logger
.debug("WFA WNM-Notification Request with truncated IE (max)")
1391 msg
['payload'] = struct
.pack("<BBBBBB",
1392 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1393 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0, 255)
1397 logger
.debug("WFA WNM-Notification Request with too short IE")
1398 msg
['payload'] = struct
.pack("<BBBBBB",
1399 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1400 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0, 0)
1404 logger
.debug("WFA WNM-Notification Request with truncated Sub Rem URL")
1405 msg
['payload'] = struct
.pack(">BBBBBBLB",
1406 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1407 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 5,
1412 logger
.debug("WFA WNM-Notification Request with truncated Sub Rem URL(2)")
1413 msg
['payload'] = struct
.pack(">BBBBBBLBB",
1414 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1415 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 6,
1420 logger
.debug("WFA WNM-Notification Request with truncated Sub Rem URL(3)")
1421 msg
['payload'] = struct
.pack(">BBBBBBLB",
1422 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1423 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 5,
1428 logger
.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(min)")
1429 msg
['payload'] = struct
.pack(">BBBBBBLBHB",
1430 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1431 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 8,
1432 0x506f9a01, 0, 0, 1)
1436 logger
.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(max)")
1437 msg
['payload'] = struct
.pack(">BBBBBBLBHB",
1438 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1439 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 8,
1440 0x506f9a01, 0, 0, 0xff)
1444 logger
.debug("WFA WNM-Notification Request with unsupported IE")
1445 msg
['payload'] = struct
.pack("<BBBBBBL",
1446 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1447 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 4, 0)
1451 logger
.debug("WNM-Notification Request with unknown WNM-Notification type 0")
1452 msg
['payload'] = struct
.pack("<BBBB",
1453 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1454 dialog_token
, WNM_NOTIF_TYPE_FW_UPGRADE
)
1458 logger
.debug("Truncated WNM Sleep Mode Response - no Dialog Token")
1459 msg
['payload'] = struct
.pack("<BB",
1460 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
)
1464 logger
.debug("Truncated WNM Sleep Mode Response - no Key Data Length")
1465 msg
['payload'] = struct
.pack("<BBB",
1466 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0)
1470 logger
.debug("Truncated WNM Sleep Mode Response - truncated Key Data (min)")
1471 msg
['payload'] = struct
.pack("<BBBH",
1472 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1477 logger
.debug("Truncated WNM Sleep Mode Response - truncated Key Data (max)")
1478 msg
['payload'] = struct
.pack("<BBBH",
1479 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1484 logger
.debug("WNM Sleep Mode Response - truncated IE header")
1485 msg
['payload'] = struct
.pack("<BBBHB",
1486 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1491 logger
.debug("WNM Sleep Mode Response - truncated IE")
1492 msg
['payload'] = struct
.pack("<BBBHBB",
1493 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1498 logger
.debug("WNM Sleep Mode Response - Empty TFS Response")
1499 msg
['payload'] = struct
.pack("<BBBHBB",
1500 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1501 0, WLAN_EID_TFS_RESP
, 0)
1505 logger
.debug("WNM Sleep Mode Response - EID 0 not recognized")
1506 msg
['payload'] = struct
.pack("<BBBHBB",
1507 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1512 logger
.debug("WNM Sleep Mode Response - Empty WNM Sleep Mode element and TFS Response element")
1513 msg
['payload'] = struct
.pack("<BBBHBBBB",
1514 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1515 0, WLAN_EID_WNMSLEEP
, 0, WLAN_EID_TFS_RESP
, 0)
1519 logger
.debug("WNM Sleep Mode Response - WNM Sleep Mode element and empty TFS Response element")
1520 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
1521 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1522 0, WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_ENTER
,
1523 WNM_STATUS_SLEEP_ACCEPT
, 0,
1524 WLAN_EID_TFS_RESP
, 0)
1528 logger
.debug("WNM Sleep Mode Response - WNM Sleep Mode element(exit, deny key) and empty TFS Response element")
1529 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
1530 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1531 0, WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1532 WNM_STATUS_DENIED_KEY
, 0,
1533 WLAN_EID_TFS_RESP
, 0)
1537 logger
.debug("WNM Sleep Mode Response - WNM Sleep Mode element(enter, deny key) and empty TFS Response element")
1538 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
1539 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1540 0, WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_ENTER
,
1541 WNM_STATUS_DENIED_KEY
, 0,
1542 WLAN_EID_TFS_RESP
, 0)
1547 def test_wnm_action_proto_pmf(dev
, apdev
):
1548 """WNM Action protocol testing (PMF enabled)"""
1549 ssid
= "test-wnm-pmf"
1550 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
1551 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
1552 params
["ieee80211w"] = "2"
1553 params
['wnm_sleep_mode'] = '1'
1554 hapd
= hostapd
.add_ap(apdev
[0], params
)
1555 bssid
= apdev
[0]['bssid']
1556 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK-SHA256",
1557 proto
="WPA2", ieee80211w
="2", scan_freq
="2412")
1558 dev
[0].request("WNM_SLEEP enter")
1560 hapd
.set("ext_mgmt_frame_handling", "1")
1563 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
1564 msg
['da'] = dev
[0].own_addr()
1566 msg
['bssid'] = bssid
1568 logger
.debug("WNM Sleep Mode Response - Invalid Key Data element length")
1569 keydata
= struct
.pack("<BB", 0, 1)
1570 msg
['payload'] = struct
.pack("<BBBH",
1571 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1573 msg
['payload'] += keydata
1574 msg
['payload'] += struct
.pack("<BBBBHBB",
1575 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1576 WNM_STATUS_SLEEP_ACCEPT
, 0,
1577 WLAN_EID_TFS_RESP
, 0)
1581 logger
.debug("WNM Sleep Mode Response - Too short GTK subelem")
1582 keydata
= struct
.pack("<BB", WNM_SLEEP_SUBELEM_GTK
, 0)
1583 msg
['payload'] = struct
.pack("<BBBH",
1584 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1586 msg
['payload'] += keydata
1587 msg
['payload'] += struct
.pack("<BBBBHBB",
1588 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1589 WNM_STATUS_SLEEP_ACCEPT
, 0,
1590 WLAN_EID_TFS_RESP
, 0)
1594 logger
.debug("WNM Sleep Mode Response - Invalid GTK subelem")
1595 keydata
= struct
.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK
, 11 + 16,
1596 0, 17, 0, 0, 0, 0, 0, 0)
1597 msg
['payload'] = struct
.pack("<BBBH",
1598 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1600 msg
['payload'] += keydata
1601 msg
['payload'] += struct
.pack("<BBBBHBB",
1602 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1603 WNM_STATUS_SLEEP_ACCEPT
, 0,
1604 WLAN_EID_TFS_RESP
, 0)
1608 logger
.debug("WNM Sleep Mode Response - Invalid GTK subelem (2)")
1609 keydata
= struct
.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK
, 11 + 16,
1610 0, 0, 0, 0, 0, 0, 0, 0)
1611 msg
['payload'] = struct
.pack("<BBBH",
1612 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1614 msg
['payload'] += keydata
1615 msg
['payload'] += struct
.pack("<BBBBHBB",
1616 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1617 WNM_STATUS_SLEEP_ACCEPT
, 0,
1618 WLAN_EID_TFS_RESP
, 0)
1622 logger
.debug("WNM Sleep Mode Response - GTK subelem and too short IGTK subelem")
1623 keydata
= struct
.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK
, 11 + 16, 0, 16)
1624 keydata
+= struct
.pack(">2L4L", 0x01020304, 0x05060708,
1625 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1626 keydata
+= struct
.pack("<BB", WNM_SLEEP_SUBELEM_IGTK
, 0)
1627 msg
['payload'] = struct
.pack("<BBBH",
1628 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1630 msg
['payload'] += keydata
1631 msg
['payload'] += struct
.pack("<BBBBHBB",
1632 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1633 WNM_STATUS_SLEEP_ACCEPT
, 0,
1634 WLAN_EID_TFS_RESP
, 0)
1638 logger
.debug("WNM Sleep Mode Response - Unknown subelem")
1639 keydata
= struct
.pack("<BB", 255, 0)
1640 msg
['payload'] = struct
.pack("<BBBH",
1641 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1643 msg
['payload'] += keydata
1644 msg
['payload'] += struct
.pack("<BBBBHBB",
1645 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1646 WNM_STATUS_SLEEP_ACCEPT
, 0,
1647 WLAN_EID_TFS_RESP
, 0)
1652 def test_wnm_action_proto_no_pmf(dev
, apdev
):
1653 """WNM Action protocol testing (PMF disabled)"""
1654 ssid
= "test-wnm-no-pmf"
1655 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
1656 params
['wnm_sleep_mode'] = '1'
1657 hapd
= hostapd
.add_ap(apdev
[0], params
)
1658 bssid
= apdev
[0]['bssid']
1659 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK",
1660 proto
="WPA2", ieee80211w
="0", scan_freq
="2412")
1661 dev
[0].request("WNM_SLEEP enter")
1663 hapd
.set("ext_mgmt_frame_handling", "1")
1665 dev
[0].request("WNM_SLEEP exit")
1666 ev
= hapd
.wait_event(['MGMT-RX'], timeout
=5)
1668 raise Exception("WNM-Sleep Mode Request not seen")
1671 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
1672 msg
['da'] = dev
[0].own_addr()
1674 msg
['bssid'] = bssid
1676 logger
.debug("WNM Sleep Mode Response - GTK subelem and IGTK subelem")
1677 keydata
= struct
.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK
, 11 + 16, 0, 16)
1678 keydata
+= struct
.pack(">2L4L", 0x01020304, 0x05060708,
1679 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1680 keydata
+= struct
.pack("<BBHLH4L", WNM_SLEEP_SUBELEM_IGTK
, 2 + 6 + 16, 0,
1682 0xf1f2f3f4, 0xf5f6f7f8, 0xf9f0fafb, 0xfcfdfeff)
1683 msg
['payload'] = struct
.pack("<BBBH",
1684 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1686 msg
['payload'] += keydata
1687 msg
['payload'] += struct
.pack("<BBBBHBB",
1688 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1689 WNM_STATUS_SLEEP_ACCEPT
, 0,
1690 WLAN_EID_TFS_RESP
, 0)
1694 ev
= dev
[0].wait_event(["WNM: Ignore Key Data"], timeout
=5)
1696 raise Exception("Key Data not ignored")
1698 def test_wnm_bss_tm_req_with_mbo_ie(dev
, apdev
):
1699 """WNM BSS transition request with MBO IE and reassociation delay attribute"""
1700 ssid
= "test-wnm-mbo"
1701 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
1702 params
['bss_transition'] = "1"
1703 hapd
= hostapd
.add_ap(apdev
[0], params
)
1704 bssid
= apdev
[0]['bssid']
1705 if "OK" not in dev
[0].request("SET mbo_cell_capa 1"):
1706 raise Exception("Failed to set STA as cellular data capable")
1708 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK",
1709 proto
="WPA2", ieee80211w
="0", scan_freq
="2412")
1711 logger
.debug("BTM request with MBO reassociation delay when disassoc imminent is not set")
1712 if 'FAIL' not in hapd
.request("BSS_TM_REQ " + dev
[0].own_addr() + " mbo=3:2:1"):
1713 raise Exception("BSS transition management succeeded unexpectedly")
1715 logger
.debug("BTM request with invalid MBO transition reason code")
1716 if 'FAIL' not in hapd
.request("BSS_TM_REQ " + dev
[0].own_addr() + " mbo=10:2:1"):
1717 raise Exception("BSS transition management succeeded unexpectedly")
1719 logger
.debug("BTM request with MBO reassociation retry delay of 5 seconds")
1720 if 'OK' not in hapd
.request("BSS_TM_REQ " + dev
[0].own_addr() + " disassoc_imminent=1 disassoc_timer=3 mbo=3:5:1"):
1721 raise Exception("BSS transition management command failed")
1723 ev
= dev
[0].wait_event(['MBO-CELL-PREFERENCE'], 1)
1724 if ev
is None or "preference=1" not in ev
:
1725 raise Exception("Timeout waiting for MBO-CELL-PREFERENCE event")
1727 ev
= dev
[0].wait_event(['MBO-TRANSITION-REASON'], 1)
1728 if ev
is None or "reason=3" not in ev
:
1729 raise Exception("Timeout waiting for MBO-TRANSITION-REASON event")
1733 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1735 raise Exception("No BSS Transition Management Response")
1736 if dev
[0].own_addr() not in ev
:
1737 raise Exception("Unexpected BSS Transition Management Response address")
1739 ev
= dev
[0].wait_event(['CTRL-EVENT-DISCONNECTED'], 5)
1741 raise Exception("Station did not disconnect although disassoc imminent was set")
1743 # Set the scan interval to make dev[0] look for connections
1744 if 'OK' not in dev
[0].request("SCAN_INTERVAL 1"):
1745 raise Exception("Failed to set scan interval")
1747 # Wait until connected
1748 ev
= dev
[0].wait_event(['CTRL-EVENT-CONNECTED'], 10)
1750 raise Exception("Station did not connect")
1752 # Make sure no connection is made during the retry delay
1753 time_diff
= datetime
.now() - t0
1754 if time_diff
.total_seconds() < 5:
1755 raise Exception("Station connected before assoc retry delay was over")
1757 if "OK" not in dev
[0].request("SET mbo_cell_capa 3"):
1758 raise Exception("Failed to set STA as cellular data not-capable")
1761 def test_wnm_bss_transition_mgmt_query(dev
, apdev
):
1762 """WNM BSS Transition Management query"""
1763 params
= {"ssid": "test-wnm",
1764 "bss_transition": "1"}
1765 hapd
= hostapd
.add_ap(apdev
[0], params
)
1766 params
= {"ssid": "another"}
1767 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1769 dev
[0].scan_for_bss(apdev
[1]['bssid'], 2412)
1770 dev
[0].scan_for_bss(apdev
[0]['bssid'], 2412)
1772 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1773 dev
[0].request("WNM_BSS_QUERY 0 list")
1775 ev
= dev
[0].wait_event(["WNM: BSS Transition Management Request"],
1778 raise Exception("No BSS Transition Management Request frame seen")
1780 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=5)
1782 raise Exception("No BSS Transition Management Response frame seen")
1785 def test_wnm_bss_tm_security_mismatch(dev
, apdev
):
1786 """WNM BSS Transition Management and security mismatch"""
1787 params
= {"ssid": "test-wnm",
1789 "wpa_key_mgmt": "WPA-PSK",
1790 "rsn_pairwise": "CCMP",
1791 "wpa_passphrase": "12345678",
1794 "bss_transition": "1"}
1795 hapd
= hostapd
.add_ap(apdev
[0], params
)
1797 params
= {"ssid": "test-wnm",
1800 "bss_transition": "1"}
1801 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1803 dev
[0].scan_for_bss(apdev
[1]['bssid'], 2462)
1805 id = dev
[0].connect("test-wnm", psk
="12345678",
1806 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1807 dev
[0].set_network(id, "scan_freq", "")
1808 dev
[0].set_network(id, "bssid", "")
1810 addr
= dev
[0].own_addr()
1811 dev
[0].dump_monitor()
1813 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1814 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[1]['bssid'] + ",0x0000,115,36,7,0301ff"):
1815 raise Exception("BSS_TM_REQ command failed")
1816 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1818 raise Exception("No BSS Transition Management Response")
1819 if "status_code=7" not in ev
:
1820 raise Exception("Unexpected BSS transition request response: " + ev
)
1822 def test_wnm_bss_tm_connect_cmd(dev
, apdev
):
1823 """WNM BSS Transition Management and cfg80211 connect command"""
1824 params
= {"ssid": "test-wnm",
1827 "bss_transition": "1"}
1828 hapd
= hostapd
.add_ap(apdev
[0], params
)
1830 params
= {"ssid": "test-wnm",
1833 "bss_transition": "1"}
1834 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1836 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
1837 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
1839 wpas
.scan_for_bss(apdev
[1]['bssid'], 2462)
1841 id = wpas
.connect("test-wnm", key_mgmt
="NONE",
1842 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1843 wpas
.set_network(id, "scan_freq", "")
1844 wpas
.set_network(id, "bssid", "")
1846 addr
= wpas
.own_addr()
1849 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1850 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[1]['bssid'] + ",0x0000,115,36,7,0301ff"):
1851 raise Exception("BSS_TM_REQ command failed")
1852 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1854 raise Exception("No BSS Transition Management Response")
1855 if "status_code=0" not in ev
:
1856 raise Exception("BSS transition request was not accepted: " + ev
)
1857 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
1858 raise Exception("Unexpected target BSS: " + ev
)
1859 ev
= wpas
.wait_event(["CTRL-EVENT-CONNECTED",
1860 "CTRL-EVENT-DISCONNECTED"], timeout
=10)
1862 raise Exception("No reassociation seen")
1863 if "CTRL-EVENT-DISCONNECTED" in ev
:
1864 raise Exception("Unexpected disconnection reported")
1865 if apdev
[1]['bssid'] not in ev
:
1866 raise Exception("Unexpected reassociation target: " + ev
)
1868 def test_wnm_bss_tm_reject(dev
, apdev
):
1869 """WNM BSS Transition Management request getting rejected"""
1872 params
= {"ssid": "test-wnm",
1873 "country_code": "FI",
1877 "bss_transition": "1"}
1878 hapd
= hostapd
.add_ap(apdev
[0], params
)
1880 id = dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1881 addr
= dev
[0].own_addr()
1882 dev
[0].dump_monitor()
1884 if "OK" not in dev
[0].request("SET reject_btm_req_reason 123"):
1885 raise Exception("Failed to set reject_btm_req_reason")
1887 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " disassoc_timer=1"):
1888 raise Exception("BSS_TM_REQ command failed")
1889 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1891 raise Exception("No BSS Transition Management Response")
1893 raise Exception("Unexpected BSS Transition Management Response address")
1894 if "status_code=123" not in ev
:
1895 raise Exception("Unexpected BSS Transition Management Response status: " + ev
)
1896 dev
[0].wait_disconnected()
1897 dev
[0].wait_connected()
1900 hapd
.request("DISABLE")
1901 dev
[0].disconnect_and_stop_scan()
1902 subprocess
.call(['iw', 'reg', 'set', '00'])
1903 dev
[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout
=0.5)
1904 dev
[0].flush_scan_cache()
1906 def test_wnm_bss_tm_ap_proto(dev
, apdev
):
1907 """WNM BSS TM - protocol testing for AP message parsing"""
1908 params
= {"ssid": "test-wnm", "bss_transition": "1"}
1909 hapd
= hostapd
.add_ap(apdev
[0], params
)
1910 bssid
= hapd
.own_addr()
1911 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1912 addr
= dev
[0].own_addr()
1914 hdr
= "d0003a01" + bssid
.replace(':', '') + addr
.replace(':', '') + bssid
.replace(':', '') + "1000"
1915 hapd
.set("ext_mgmt_frame_handling", "1")
1922 "0a080000001122334455",
1923 "0a08000000112233445566",
1924 "0a08000000112233445566112233445566778899",
1926 "0a08ffffff112233445566778899",
1932 if "OK" not in hapd
.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr
+ t
):
1933 raise Exception("MGMT_RX_PROCESS failed")
1935 hapd
.set("ext_mgmt_frame_handling", "0")
1937 def test_wnm_bss_transition_mgmt_query_with_unknown_candidates(dev
, apdev
):
1938 """WNM BSS Transition Management query with unknown candidates"""
1939 params
= {"ssid": "test-wnm",
1940 "bss_transition": "1"}
1941 hapd
= hostapd
.add_ap(apdev
[0], params
)
1943 dev
[0].scan_for_bss(apdev
[0]['bssid'], 2412)
1945 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1946 dev
[0].request("WNM_BSS_QUERY 0 neighbor=00:11:22:33:44:55,0,81,1,4")
1948 ev
= dev
[0].wait_event(["WNM: BSS Transition Management Request"],
1951 raise Exception("No BSS Transition Management Request frame seen")
1953 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=5)
1955 raise Exception("No BSS Transition Management Response frame seen")
1957 def test_wnm_time_adv_without_time_zone(dev
, apdev
):
1958 """WNM Time Advertisement without time zone configuration"""
1959 params
= {"ssid": "test-wnm",
1960 "time_advertisement": "2"}
1961 hostapd
.add_ap(apdev
[0], params
)
1963 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1965 def test_wnm_coloc_intf_reporting(dev
, apdev
):
1966 """WNM Collocated Interference Reporting"""
1967 params
= {"ssid": "test-wnm",
1968 "coloc_intf_reporting": "1"}
1969 hapd
= hostapd
.add_ap(apdev
[0], params
)
1971 no_intf
= struct
.pack("<BBBBBLLLLH", 96, 21, 0, 127, 0x0f, 0, 0, 0, 0, 0)
1974 dev
[0].set("coloc_intf_reporting", "1")
1975 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1976 addr
= dev
[0].own_addr()
1977 if "OK" not in hapd
.request("COLOC_INTF_REQ %s 1 5" % addr
):
1978 raise Exception("Could not send Collocated Interference Request")
1979 ev
= dev
[0].wait_event(["COLOC-INTF-REQ"], timeout
=2)
1981 raise Exception("No Collocated Interference Request frame seen")
1982 vals
= ev
.split(' ')
1983 if vals
[2] != '1' or vals
[3] != '5':
1984 raise Exception("Unexpected request values: " + ev
)
1985 dev
[0].set("coloc_intf_elems", binascii
.hexlify(no_intf
).decode())
1986 ev
= hapd
.wait_event(["COLOC-INTF-REPORT"], timeout
=1)
1988 raise Exception("No Collocated Interference Report frame seen")
1989 if addr
+ " 1 " + binascii
.hexlify(no_intf
).decode() not in ev
:
1990 raise Exception("Unexpected report values: " + ev
)
1992 if "OK" not in hapd
.request("COLOC_INTF_REQ %s 0 0" % addr
):
1993 raise Exception("Could not send Collocated Interference Request")
1994 ev
= dev
[0].wait_event(["COLOC-INTF-REQ"], timeout
=2)
1996 raise Exception("No Collocated Interference Request frame seen")
1997 vals
= ev
.split(' ')
1998 if vals
[2] != '0' or vals
[3] != '0':
1999 raise Exception("Unexpected request values: " + ev
)
2001 res
= dev
[0].request("COLOC_INTF_REPORT " + binascii
.hexlify(no_intf
).decode())
2003 raise Exception("Could not send unsolicited report")
2004 ev
= hapd
.wait_event(["COLOC-INTF-REPORT"], timeout
=1)
2006 raise Exception("No Collocated Interference Report frame seen")
2007 if addr
+ " 0 " + binascii
.hexlify(no_intf
).decode() not in ev
:
2008 raise Exception("Unexpected report values: " + ev
)
2010 dev
[0].set("coloc_intf_reporting", "0")
2011 dev
[0].set("coloc_intf_elems", "")