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 dev
[0].request("DISCONNECT")
31 dev
[0].request("ABORT_SCAN")
32 dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
34 subprocess
.call(['iw', 'reg', 'set', '00'])
35 dev
[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout
=0.5)
36 dev
[0].flush_scan_cache()
39 def test_wnm_bss_transition_mgmt(dev
, apdev
):
40 """WNM BSS Transition Management"""
41 params
= { "ssid": "test-wnm",
42 "time_advertisement": "2",
44 "wnm_sleep_mode": "1",
45 "bss_transition": "1" }
46 hostapd
.add_ap(apdev
[0], params
)
48 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
49 dev
[0].request("WNM_BSS_QUERY 0")
51 def test_wnm_bss_transition_mgmt_oom(dev
, apdev
):
52 """WNM BSS Transition Management OOM"""
53 params
= { "ssid": "test-wnm", "bss_transition": "1" }
54 hapd
= hostapd
.add_ap(apdev
[0], params
)
56 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
57 with
alloc_fail(hapd
, 1, "ieee802_11_send_bss_trans_mgmt_request"):
58 dev
[0].request("WNM_BSS_QUERY 0")
59 wait_fail_trigger(hapd
, "GET_ALLOC_FAIL")
62 def test_wnm_disassoc_imminent(dev
, apdev
):
63 """WNM Disassociation Imminent"""
64 params
= { "ssid": "test-wnm",
65 "time_advertisement": "2",
67 "wnm_sleep_mode": "1",
68 "bss_transition": "1" }
69 hapd
= hostapd
.add_ap(apdev
[0], params
)
71 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
72 addr
= dev
[0].p2p_interface_addr()
73 hapd
.request("DISASSOC_IMMINENT " + addr
+ " 10")
74 ev
= dev
[0].wait_event(["WNM: Disassociation Imminent"])
76 raise Exception("Timeout while waiting for disassociation imminent")
77 if "Disassociation Timer 10" not in ev
:
78 raise Exception("Unexpected disassociation imminent contents")
79 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
81 raise Exception("Timeout while waiting for re-connection scan")
83 def test_wnm_disassoc_imminent_fail(dev
, apdev
):
84 """WNM Disassociation Imminent failure"""
85 params
= { "ssid": "test-wnm", "bss_transition": "1" }
86 hapd
= hostapd
.add_ap(apdev
[0], params
)
88 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
89 addr
= dev
[0].own_addr()
90 with
fail_test(hapd
, 1, "wnm_send_disassoc_imminent"):
91 if "FAIL" not in hapd
.request("DISASSOC_IMMINENT " + addr
+ " 10"):
92 raise Exception("DISASSOC_IMMINENT succeeded during failure testing")
95 def test_wnm_ess_disassoc_imminent(dev
, apdev
):
96 """WNM ESS Disassociation Imminent"""
97 params
= { "ssid": "test-wnm",
98 "time_advertisement": "2",
100 "wnm_sleep_mode": "1",
101 "bss_transition": "1" }
102 hapd
= hostapd
.add_ap(apdev
[0], params
)
104 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
105 addr
= dev
[0].p2p_interface_addr()
106 hapd
.request("ESS_DISASSOC " + addr
+ " 10 http://example.com/session-info")
107 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"])
109 raise Exception("Timeout while waiting for ESS disassociation imminent")
110 if "0 1024 http://example.com/session-info" not in ev
:
111 raise Exception("Unexpected ESS disassociation imminent message contents")
112 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
114 raise Exception("Timeout while waiting for re-connection scan")
116 def test_wnm_ess_disassoc_imminent_fail(dev
, apdev
):
117 """WNM ESS Disassociation Imminent failure"""
118 params
= { "ssid": "test-wnm", "bss_transition": "1" }
119 hapd
= hostapd
.add_ap(apdev
[0], params
)
121 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
122 addr
= dev
[0].own_addr()
123 if "FAIL" not in hapd
.request("ESS_DISASSOC " + addr
+ " 10 http://" + 256*'a'):
124 raise Exception("Invalid ESS_DISASSOC URL accepted")
125 with
fail_test(hapd
, 1, "wnm_send_ess_disassoc_imminent"):
126 if "FAIL" not in hapd
.request("ESS_DISASSOC " + addr
+ " 10 http://example.com/session-info"):
127 raise Exception("ESS_DISASSOC succeeded during failure testing")
129 def test_wnm_ess_disassoc_imminent_reject(dev
, apdev
):
130 """WNM ESS Disassociation Imminent getting rejected"""
131 params
= { "ssid": "test-wnm",
132 "bss_transition": "1" }
133 hapd
= hostapd
.add_ap(apdev
[0], params
)
135 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
136 addr
= dev
[0].own_addr()
137 if "OK" not in dev
[0].request("SET reject_btm_req_reason 123"):
138 raise Exception("Failed to set reject_btm_req_reason")
140 hapd
.request("ESS_DISASSOC " + addr
+ " 1 http://example.com/session-info")
141 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=10)
143 raise Exception("BSS-TM-RESP not seen")
144 if "status_code=123" not in ev
:
145 raise Exception("Unexpected response status: " + ev
)
146 dev
[0].wait_disconnected()
147 dev
[0].request("DISCONNECT")
150 def test_wnm_ess_disassoc_imminent_pmf(dev
, apdev
):
151 """WNM ESS Disassociation Imminent"""
152 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
153 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
154 params
["ieee80211w"] = "2"
155 params
["bss_transition"] = "1"
156 hapd
= hostapd
.add_ap(apdev
[0], params
)
158 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2",
159 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
160 addr
= dev
[0].p2p_interface_addr()
161 hapd
.request("ESS_DISASSOC " + addr
+ " 10 http://example.com/session-info")
162 ev
= dev
[0].wait_event(["ESS-DISASSOC-IMMINENT"])
164 raise Exception("Timeout while waiting for ESS disassociation imminent")
165 if "1 1024 http://example.com/session-info" not in ev
:
166 raise Exception("Unexpected ESS disassociation imminent message contents")
167 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
169 raise Exception("Timeout while waiting for re-connection scan")
171 def check_wnm_sleep_mode_enter_exit(hapd
, dev
, interval
=None, tfs_req
=None):
172 addr
= dev
.p2p_interface_addr()
173 sta
= hapd
.get_sta(addr
)
174 if "[WNM_SLEEP_MODE]" in sta
['flags']:
175 raise Exception("Station unexpectedly in WNM-Sleep Mode")
177 logger
.info("Going to WNM Sleep Mode")
179 if interval
is not None:
180 extra
+= " interval=" + str(interval
)
182 extra
+= " tfs_req=" + tfs_req
183 if "OK" not in dev
.request("WNM_SLEEP enter" + extra
):
184 raise Exception("WNM_SLEEP failed")
188 sta
= hapd
.get_sta(addr
)
189 if "[WNM_SLEEP_MODE]" in sta
['flags']:
193 raise Exception("Station failed to enter WNM-Sleep Mode")
195 logger
.info("Waking up from WNM Sleep Mode")
197 dev
.request("WNM_SLEEP exit")
200 sta
= hapd
.get_sta(addr
)
201 if "[WNM_SLEEP_MODE]" not in sta
['flags']:
205 raise Exception("Station failed to exit WNM-Sleep Mode")
208 def test_wnm_sleep_mode_open(dev
, apdev
):
209 """WNM Sleep Mode - open"""
210 params
= { "ssid": "test-wnm",
211 "time_advertisement": "2",
213 "wnm_sleep_mode": "1",
214 "bss_transition": "1" }
215 hapd
= hostapd
.add_ap(apdev
[0], params
)
217 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
218 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
220 raise Exception("No connection event received from hostapd")
221 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
222 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0], interval
=100)
223 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0], tfs_req
="5b17010001130e110000071122334455661122334455661234")
226 "exit tfs_req=123 interval=10",
227 "enter tfs_req=qq interval=10" ]
229 if "FAIL" not in dev
[0].request("WNM_SLEEP " + cmd
):
230 raise Exception("Invalid WNM_SLEEP accepted")
232 def test_wnm_sleep_mode_open_fail(dev
, apdev
):
233 """WNM Sleep Mode - open (fail)"""
234 params
= { "ssid": "test-wnm", "wnm_sleep_mode": "1" }
235 hapd
= hostapd
.add_ap(apdev
[0], params
)
237 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
238 with
fail_test(hapd
, 1, "nl80211_send_frame_cmd;ieee802_11_send_wnmsleep_resp"):
239 dev
[0].request("WNM_SLEEP enter")
240 wait_fail_trigger(hapd
, "GET_FAIL")
243 def test_wnm_sleep_mode_rsn(dev
, apdev
):
244 """WNM Sleep Mode - RSN"""
245 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
246 params
["time_advertisement"] = "2"
247 params
["time_zone"] = "EST5"
248 params
["wnm_sleep_mode"] = "1"
249 params
["bss_transition"] = "1"
250 hapd
= hostapd
.add_ap(apdev
[0], params
)
252 dev
[0].connect("test-wnm-rsn", psk
="12345678", scan_freq
="2412")
253 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
255 raise Exception("No connection event received from hostapd")
256 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
259 def test_wnm_sleep_mode_ap_oom(dev
, apdev
):
260 """WNM Sleep Mode - AP side OOM"""
261 params
= { "ssid": "test-wnm",
262 "wnm_sleep_mode": "1" }
263 hapd
= hostapd
.add_ap(apdev
[0], params
)
265 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
266 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
268 raise Exception("No connection event received from hostapd")
269 with
alloc_fail(hapd
, 1, "ieee802_11_send_wnmsleep_resp"):
270 dev
[0].request("WNM_SLEEP enter")
271 wait_fail_trigger(hapd
, "GET_ALLOC_FAIL")
272 with
alloc_fail(hapd
, 2, "ieee802_11_send_wnmsleep_resp"):
273 dev
[0].request("WNM_SLEEP exit")
274 wait_fail_trigger(hapd
, "GET_ALLOC_FAIL")
277 def test_wnm_sleep_mode_rsn_pmf(dev
, apdev
):
278 """WNM Sleep Mode - RSN with PMF"""
279 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
280 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
281 params
["ieee80211w"] = "2"
282 params
["time_advertisement"] = "2"
283 params
["time_zone"] = "EST5"
284 params
["wnm_sleep_mode"] = "1"
285 params
["bss_transition"] = "1"
286 hapd
= hostapd
.add_ap(apdev
[0], params
)
291 wt
.add_passphrase("12345678")
293 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2",
294 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
295 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
297 raise Exception("No connection event received from hostapd")
298 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
301 def test_wnm_sleep_mode_rsn_ocv(dev
, apdev
):
302 """WNM Sleep Mode - RSN with OCV"""
303 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
304 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
305 params
["ieee80211w"] = "2"
307 params
["time_advertisement"] = "2"
308 params
["time_zone"] = "EST5"
309 params
["wnm_sleep_mode"] = "1"
310 params
["bss_transition"] = "1"
312 hapd
= hostapd
.add_ap(apdev
[0], params
)
313 except Exception as e
:
314 if "Failed to set hostapd parameter ocv" in str(e
):
315 raise HwsimSkip("OCV not supported")
321 wt
.add_passphrase("12345678")
323 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2", ocv
="1",
324 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
325 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
327 raise Exception("No connection event received from hostapd")
328 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
330 # Check if OCV succeeded or failed
331 ev
= dev
[0].wait_event([ "OCV failed" ], timeout
=1)
333 raise Exception("OCI verification failed: " + ev
)
336 def test_wnm_sleep_mode_rsn_badocv(dev
, apdev
):
337 """WNM Sleep Mode - RSN with OCV and bad OCI elements"""
338 ssid
= "test-wnm-pmf"
339 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
340 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
341 params
["ieee80211w"] = "2"
343 params
['wnm_sleep_mode'] = '1'
345 hapd
= hostapd
.add_ap(apdev
[0], params
)
346 except Exception as e
:
347 if "Failed to set hostapd parameter ocv" in str(e
):
348 raise HwsimSkip("OCV not supported")
350 bssid
= apdev
[0]['bssid']
351 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK-SHA256", ocv
="1",
352 proto
="WPA2", ieee80211w
="2", scan_freq
="2412")
353 dev
[0].request("WNM_SLEEP enter")
356 msg
= { 'fc': MGMT_SUBTYPE_ACTION
<< 4,
358 'sa': dev
[0].own_addr(),
361 logger
.debug("WNM Sleep Mode Request - Missing OCI element")
362 msg
['payload'] = struct
.pack("<BBBBBBBHBB",
363 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_REQ
, 0,
364 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
, 0, 0,
366 mgmt_tx(dev
[0], "MGMT_TX {} {} freq=2412 wait_time=200 no_cck=1 action={}".format(msg
['da'], msg
['bssid'], binascii
.hexlify(msg
['payload'])))
367 ev
= hapd
.wait_event([ "OCV failed" ], timeout
=5)
369 raise Exception("AP did not report missing OCI element")
371 logger
.debug("WNM Sleep Mode Request - Bad OCI element")
372 msg
['payload'] = struct
.pack("<BBBBBBBHBB",
373 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_REQ
, 0,
374 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
, 0,
377 oci_ie
= struct
.pack("<BBB", 81, 2, 0)
378 msg
['payload'] += struct
.pack("<BBB", WLAN_EID_EXTENSION
, 1 + len(oci_ie
),
379 WLAN_EID_EXT_OCV_OCI
) + oci_ie
380 mgmt_tx(dev
[0], "MGMT_TX {} {} freq=2412 wait_time=200 no_cck=1 action={}".format(msg
['da'], msg
['bssid'] , binascii
.hexlify(msg
['payload'])))
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_pmf_key_workaround(dev
, apdev
):
422 """WNM Sleep Mode - RSN with PMF and GTK/IGTK workaround"""
423 params
= hostapd
.wpa2_params("test-wnm-rsn", "12345678")
424 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
425 params
["ieee80211w"] = "2"
426 params
["time_advertisement"] = "2"
427 params
["time_zone"] = "EST5"
428 params
["wnm_sleep_mode"] = "1"
429 params
["wnm_sleep_mode_no_keys"] = "1"
430 params
["bss_transition"] = "1"
431 hapd
= hostapd
.add_ap(apdev
[0], params
)
436 wt
.add_passphrase("12345678")
438 dev
[0].connect("test-wnm-rsn", psk
="12345678", ieee80211w
="2",
439 key_mgmt
="WPA-PSK-SHA256", proto
="WPA2", scan_freq
="2412")
440 ev
= hapd
.wait_event([ "AP-STA-CONNECTED" ], timeout
=5)
442 raise Exception("No connection event received from hostapd")
443 check_wnm_sleep_mode_enter_exit(hapd
, dev
[0])
445 def test_wnm_sleep_mode_proto(dev
, apdev
):
446 """WNM Sleep Mode - protocol testing"""
447 params
= { "ssid": "test-wnm", "wnm_sleep_mode": "1" }
448 hapd
= hostapd
.add_ap(apdev
[0], params
)
449 bssid
= hapd
.own_addr()
450 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
451 addr
= dev
[0].own_addr()
453 hdr
= "d0003a01" + bssid
.replace(':', '') + addr
.replace(':', '') + bssid
.replace(':', '') + "1000"
454 hapd
.set("ext_mgmt_frame_handling", "1")
458 "0a10015d0400000000",
459 "0a1001" + 7*("5bff" + 255*"00") + "5d00",
462 if "OK" not in hapd
.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr
+ t
):
463 raise Exception("MGMT_RX_PROCESS failed")
465 hapd
.set("ext_mgmt_frame_handling", "0")
467 MGMT_SUBTYPE_ACTION
= 13
468 ACTION_CATEG_WNM
= 10
469 WNM_ACT_BSS_TM_REQ
= 7
470 WNM_ACT_BSS_TM_RESP
= 8
471 WNM_ACT_SLEEP_MODE_REQ
= 16
472 WNM_ACT_SLEEP_MODE_RESP
= 17
473 WNM_ACT_NOTIFICATION_REQ
= 26
474 WNM_ACT_NOTIFICATION_RESP
= 27
475 WNM_NOTIF_TYPE_FW_UPGRADE
= 0
476 WNM_NOTIF_TYPE_WFA
= 1
477 WLAN_EID_TFS_REQ
= 91
478 WLAN_EID_TFS_RESP
= 92
479 WLAN_EID_WNMSLEEP
= 93
480 WLAN_EID_EXTENSION
= 255
481 WLAN_EID_EXT_OCV_OCI
= 54
482 WNM_SLEEP_MODE_ENTER
= 0
483 WNM_SLEEP_MODE_EXIT
= 1
484 WNM_STATUS_SLEEP_ACCEPT
= 0
485 WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE
= 1
486 WNM_STATUS_DENIED_ACTION
= 2
487 WNM_STATUS_DENIED_TMP
= 3
488 WNM_STATUS_DENIED_KEY
= 4
489 WNM_STATUS_DENIED_OTHER_WNM_SERVICE
= 5
490 WNM_SLEEP_SUBELEM_GTK
= 0
491 WNM_SLEEP_SUBELEM_IGTK
= 1
493 def bss_tm_req(dst
, src
, dialog_token
=1, req_mode
=0, disassoc_timer
=0,
494 validity_interval
=1):
496 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
500 msg
['payload'] = struct
.pack("<BBBBHB",
501 ACTION_CATEG_WNM
, WNM_ACT_BSS_TM_REQ
,
502 dialog_token
, req_mode
, disassoc_timer
,
506 def rx_bss_tm_resp(hapd
, expect_dialog
=None, expect_status
=None):
507 for i
in range(0, 100):
508 resp
= hapd
.mgmt_rx()
510 raise Exception("No BSS TM Response received")
511 if resp
['subtype'] == MGMT_SUBTYPE_ACTION
:
514 raise Exception("Not an Action frame")
515 payload
= resp
['payload']
516 if len(payload
) < 2 + 3:
517 raise Exception("Too short payload")
518 (category
, action
) = struct
.unpack('BB', payload
[0:2])
519 if category
!= ACTION_CATEG_WNM
or action
!= WNM_ACT_BSS_TM_RESP
:
520 raise Exception("Not a BSS TM Response")
522 (dialog
, status
, bss_term_delay
) = struct
.unpack('BBB', pos
[0:3])
523 resp
['dialog'] = dialog
524 resp
['status'] = status
525 resp
['bss_term_delay'] = bss_term_delay
527 if len(pos
) >= 6 and status
== 0:
528 resp
['target_bssid'] = binascii
.hexlify(pos
[0:6])
530 resp
['candidates'] = pos
531 if expect_dialog
is not None and dialog
!= expect_dialog
:
532 raise Exception("Unexpected dialog token")
533 if expect_status
is not None and status
!= expect_status
:
534 raise Exception("Unexpected status code %d" % status
)
537 def expect_ack(hapd
):
538 ev
= hapd
.wait_event(["MGMT-TX-STATUS"], timeout
=5)
540 raise Exception("Missing TX status")
542 raise Exception("Action frame not acknowledged")
544 def mgmt_tx(dev
, msg
):
545 if "FAIL" in dev
.request(msg
):
546 raise Exception("Failed to send Action frame")
547 ev
= dev
.wait_event(["MGMT-TX-STATUS"], timeout
=10)
549 raise Exception("Timeout on MGMT-TX-STATUS")
550 if "result=SUCCESS" not in ev
:
551 raise Exception("Peer did not ack Action frame")
554 def test_wnm_bss_tm_req(dev
, apdev
):
555 """BSS Transition Management Request"""
556 params
= { "ssid": "test-wnm", "bss_transition": "1" }
557 hapd
= hostapd
.add_ap(apdev
[0], params
)
558 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
559 addr
= dev
[0].own_addr()
561 hapd
.set("ext_mgmt_frame_handling", "1")
563 # truncated BSS TM Request
564 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
566 req
['payload'] = struct
.pack("<BBBBH",
567 ACTION_CATEG_WNM
, WNM_ACT_BSS_TM_REQ
,
571 dev
[0].dump_monitor()
573 # no disassociation and no candidate list
574 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
577 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=2, expect_status
=1)
578 dev
[0].dump_monitor()
580 # truncated BSS Termination Duration
581 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
585 dev
[0].dump_monitor()
587 # BSS Termination Duration with TSF=0 and Duration=10
588 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
589 req_mode
=0x08, dialog_token
=3)
590 req
['payload'] += struct
.pack("<BBQH", 4, 10, 0, 10)
592 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=3, expect_status
=1)
593 dev
[0].dump_monitor()
595 # truncated Session Information URL
596 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
600 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
602 req
['payload'] += struct
.pack("<BBB", 3, 65, 66)
605 dev
[0].dump_monitor()
607 # Session Information URL
608 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
609 req_mode
=0x10, dialog_token
=4)
610 req
['payload'] += struct
.pack("<BBB", 2, 65, 66)
612 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=4, expect_status
=0)
613 dev
[0].dump_monitor()
615 # Preferred Candidate List without any entries
616 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
617 req_mode
=0x01, dialog_token
=5)
619 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=5, expect_status
=7)
620 dev
[0].dump_monitor()
622 # Preferred Candidate List with a truncated entry
623 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
625 req
['payload'] += struct
.pack("<BB", 52, 1)
628 dev
[0].dump_monitor()
630 # Preferred Candidate List with a too short entry
631 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
632 req_mode
=0x01, dialog_token
=6)
633 req
['payload'] += struct
.pack("<BB", 52, 0)
635 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=6, expect_status
=7)
636 dev
[0].dump_monitor()
638 # Preferred Candidate List with a non-matching entry
639 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
640 req_mode
=0x01, dialog_token
=6)
641 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13,
645 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=6, expect_status
=7)
646 dev
[0].dump_monitor()
648 # Preferred Candidate List with a truncated subelement
649 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
650 req_mode
=0x01, dialog_token
=7)
651 req
['payload'] += struct
.pack("<BB6BLBBBBB", 52, 13 + 2,
656 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=7, expect_status
=7)
657 dev
[0].dump_monitor()
659 # Preferred Candidate List with lots of invalid optional subelements
660 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
661 req_mode
=0x01, dialog_token
=8)
662 subelems
= struct
.pack("<BBHB", 1, 3, 0, 100)
663 subelems
+= struct
.pack("<BBB", 2, 1, 65)
664 subelems
+= struct
.pack("<BB", 3, 0)
665 subelems
+= struct
.pack("<BBQB", 4, 9, 0, 10)
666 subelems
+= struct
.pack("<BBHLB", 5, 7, 0, 0, 0)
667 subelems
+= struct
.pack("<BB", 66, 0)
668 subelems
+= struct
.pack("<BBBBBB", 70, 4, 0, 0, 0, 0)
669 subelems
+= struct
.pack("<BB", 71, 0)
670 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13 + len(subelems
),
672 0, 81, 1, 7) + subelems
674 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=8, expect_status
=7)
675 dev
[0].dump_monitor()
677 # Preferred Candidate List with lots of valid optional subelements (twice)
678 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
679 req_mode
=0x01, dialog_token
=8)
681 subelems
= struct
.pack("<BBHH", 1, 4, 0, 100)
682 # Condensed Country String
683 subelems
+= struct
.pack("<BBBB", 2, 2, 65, 66)
684 # BSS Transition Candidate Preference
685 subelems
+= struct
.pack("<BBB", 3, 1, 100)
686 # BSS Termination Duration
687 subelems
+= struct
.pack("<BBQH", 4, 10, 0, 10)
689 subelems
+= struct
.pack("<BBHLH", 5, 8, 0, 0, 0)
690 # Measurement Pilot Transmission
691 subelems
+= struct
.pack("<BBBBB", 66, 3, 0, 0, 0)
692 # RM Enabled Capabilities
693 subelems
+= struct
.pack("<BBBBBBB", 70, 5, 0, 0, 0, 0, 0)
695 subelems
+= struct
.pack("<BBBB", 71, 2, 0, 0)
696 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13 + len(subelems
) * 2,
698 0, 81, 1, 7) + subelems
+ subelems
700 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=8, expect_status
=7)
701 dev
[0].dump_monitor()
703 # Preferred Candidate List followed by vendor element
704 req
= bss_tm_req(addr
, apdev
[0]['bssid'],
705 req_mode
=0x01, dialog_token
=8)
707 req
['payload'] += struct
.pack("<BB6BLBBB", 52, 13 + len(subelems
),
709 0, 81, 1, 7) + subelems
710 req
['payload'] += binascii
.unhexlify("DD0411223344")
712 resp
= rx_bss_tm_resp(hapd
, expect_dialog
=8, expect_status
=7)
713 dev
[0].dump_monitor()
716 def test_wnm_bss_keep_alive(dev
, apdev
):
718 params
= { "ssid": "test-wnm",
719 "ap_max_inactivity": "1" }
720 hapd
= hostapd
.add_ap(apdev
[0], params
)
722 addr
= dev
[0].p2p_interface_addr()
723 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
724 start
= hapd
.get_sta(addr
)
725 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=2)
727 raise Exception("Unexpected disconnection")
728 end
= hapd
.get_sta(addr
)
729 if int(end
['rx_packets']) <= int(start
['rx_packets']):
730 raise Exception("No keep-alive packets received")
732 # Disable client keep-alive so that hostapd will verify connection
734 dev
[0].request("SET no_keep_alive 1")
736 sta
= hapd
.get_sta(addr
)
737 logger
.info("timeout_next=%s rx_packets=%s tx_packets=%s" % (sta
['timeout_next'], sta
['rx_packets'], sta
['tx_packets']))
738 if i
> 1 and sta
['timeout_next'] != "NULLFUNC POLL" and int(sta
['tx_packets']) > int(end
['tx_packets']):
740 ev
= dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
742 raise Exception("Unexpected disconnection (client poll expected)")
744 dev
[0].request("SET no_keep_alive 0")
745 if int(sta
['tx_packets']) <= int(end
['tx_packets']):
746 raise Exception("No client poll packet seen")
748 def test_wnm_bss_tm(dev
, apdev
):
749 """WNM BSS Transition Management"""
753 params
= { "ssid": "test-wnm",
754 "country_code": "FI",
758 "bss_transition": "1" }
759 hapd
= hostapd
.add_ap(apdev
[0], params
)
761 id = dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
762 dev
[0].set_network(id, "scan_freq", "")
764 params
= { "ssid": "test-wnm",
765 "country_code": "FI",
769 "bss_transition": "1" }
770 hapd2
= hostapd
.add_ap(apdev
[1], params
)
772 addr
= dev
[0].p2p_interface_addr()
773 dev
[0].dump_monitor()
775 logger
.info("No neighbor list entries")
776 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
):
777 raise Exception("BSS_TM_REQ command failed")
778 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
780 raise Exception("No BSS Transition Management Response")
782 raise Exception("Unexpected BSS Transition Management Response address")
783 if "status_code=0" in ev
:
784 raise Exception("BSS transition accepted unexpectedly")
785 dev
[0].dump_monitor()
787 logger
.info("Neighbor list entry, but not claimed as Preferred Candidate List")
788 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " neighbor=11:22:33:44:55:66,0x0000,81,3,7"):
789 raise Exception("BSS_TM_REQ command failed")
790 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
792 raise Exception("No BSS Transition Management Response")
793 if "status_code=0" in ev
:
794 raise Exception("BSS transition accepted unexpectedly")
795 dev
[0].dump_monitor()
797 logger
.info("Preferred Candidate List (no matching neighbor) without Disassociation Imminent")
798 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"):
799 raise Exception("BSS_TM_REQ command failed")
800 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
802 raise Exception("No BSS Transition Management Response")
803 if "status_code=0" in ev
:
804 raise Exception("BSS transition accepted unexpectedly")
805 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=5)
807 raise Exception("No scan started")
808 dev
[0].dump_monitor()
810 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
811 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"):
812 raise Exception("BSS_TM_REQ command failed")
813 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
815 raise Exception("No BSS Transition Management Response")
816 if "status_code=0" not in ev
:
817 raise Exception("BSS transition request was not accepted: " + ev
)
818 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
819 raise Exception("Unexpected target BSS: " + ev
)
820 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
821 if apdev
[1]['bssid'] not in ev
:
822 raise Exception("Unexpected reassociation target: " + ev
)
823 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
825 raise Exception("Unexpected scan started")
826 dev
[0].dump_monitor()
828 logger
.info("Preferred Candidate List with two matches, no roam needed")
829 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"):
830 raise Exception("BSS_TM_REQ command failed")
831 ev
= hapd2
.wait_event(['BSS-TM-RESP'], timeout
=10)
833 raise Exception("No BSS Transition Management Response")
834 if "status_code=0" not in ev
:
835 raise Exception("BSS transition request was not accepted: " + ev
)
836 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
837 raise Exception("Unexpected target BSS: " + ev
)
838 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
840 raise Exception("Unexpected scan started")
841 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=0.5)
843 raise Exception("Unexpected reassociation")
845 logger
.info("Preferred Candidate List with two matches and extra frequency (160 MHz), no roam needed")
846 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'):
847 raise Exception("BSS_TM_REQ command failed")
848 ev
= hapd2
.wait_event(['BSS-TM-RESP'], timeout
=10)
850 raise Exception("No BSS Transition Management Response")
851 if "status_code=0" not in ev
:
852 raise Exception("BSS transition request was not accepted: " + ev
)
853 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
854 raise Exception("Unexpected target BSS: " + ev
)
855 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
857 raise Exception("Unexpected scan started")
858 ev
= dev
[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout
=0.5)
860 raise Exception("Unexpected reassociation")
862 clear_regdom_state(dev
, hapd
, hapd2
)
864 def test_wnm_bss_tm_errors(dev
, apdev
):
865 """WNM BSS Transition Management errors"""
866 params
= { "ssid": "test-wnm",
869 "bss_transition": "1" }
870 hapd
= hostapd
.add_ap(apdev
[0], params
)
871 id = dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
872 addr
= dev
[0].own_addr()
874 tests
= [ "BSS_TM_REQ q",
875 "BSS_TM_REQ 22:22:22:22:22:22",
876 "BSS_TM_REQ %s disassoc_timer=-1" % addr
,
877 "BSS_TM_REQ %s disassoc_timer=65536" % addr
,
878 "BSS_TM_REQ %s bss_term=foo" % addr
,
879 "BSS_TM_REQ %s neighbor=q" % addr
,
880 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55" % addr
,
881 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0" % addr
,
882 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0" % addr
,
883 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0" % addr
,
884 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0,0,q" % addr
,
885 "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0,0,0q" % addr
,
886 "BSS_TM_REQ " + addr
+ " url=" + 256*'a',
887 "BSS_TM_REQ %s url=foo mbo=1:2" % addr
,
888 "BSS_TM_REQ %s url=foo mbo=100000:0:0" % addr
,
889 "BSS_TM_REQ %s url=foo mbo=0:0:254" % addr
,
890 "BSS_TM_REQ %s url=foo mbo=0:100000:0" % addr
]
892 if "FAIL" not in hapd
.request(t
):
893 raise Exception("Invalid command accepted: %s" % t
)
895 with
alloc_fail(hapd
, 1, "=hostapd_ctrl_iface_bss_tm_req"):
896 if "FAIL" not in hapd
.request("BSS_TM_REQ %s url=http://foo" % addr
):
897 raise Exception("BSS_TM_REQ accepted during OOM")
899 with
alloc_fail(hapd
, 1, "=wnm_send_bss_tm_req"):
900 if "FAIL" not in hapd
.request("BSS_TM_REQ %s url=http://foo" % addr
):
901 raise Exception("BSS_TM_REQ accepted during OOM")
903 with
fail_test(hapd
, 1, "wnm_send_bss_tm_req"):
904 if "FAIL" not in hapd
.request("BSS_TM_REQ %s url=http://foo" % addr
):
905 raise Exception("BSS_TM_REQ accepted during failure testing")
907 def test_wnm_bss_tm_termination(dev
, apdev
):
908 """WNM BSS Transition Management and BSS termination"""
909 params
= { "ssid": "test-wnm",
912 "bss_transition": "1" }
913 hapd
= hostapd
.add_ap(apdev
[0], params
)
914 id = dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
915 addr
= dev
[0].own_addr()
917 if "OK" not in hapd
.request("BSS_TM_REQ %s bss_term=0,1" % addr
):
918 raise Exception("BSS_TM_REQ failed")
919 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=5)
921 raise Exception("No BSS-TM-RESP event seen")
923 if "OK" not in hapd
.request("BSS_TM_REQ %s url=http://example.com/" % addr
):
924 raise Exception("BSS_TM_REQ failed")
925 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=5)
927 raise Exception("No BSS-TM-RESP event seen")
929 def test_wnm_bss_tm_scan_not_needed(dev
, apdev
):
930 """WNM BSS Transition Management and scan not needed"""
931 run_wnm_bss_tm_scan_not_needed(dev
, apdev
)
933 def test_wnm_bss_tm_nei_vht(dev
, apdev
):
934 """WNM BSS Transition Management and VHT neighbor"""
935 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, vht
=True, nei_info
="115,36,9")
937 def test_wnm_bss_tm_nei_11a(dev
, apdev
):
938 """WNM BSS Transition Management and 11a neighbor"""
939 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=False, nei_info
="115,36,4")
941 def test_wnm_bss_tm_nei_11g(dev
, apdev
):
942 """WNM BSS Transition Management and 11g neighbor"""
943 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=False, hwmode
='g',
944 channel
='2', freq
=2417, nei_info
="81,2,6")
946 def test_wnm_bss_tm_nei_11b(dev
, apdev
):
947 """WNM BSS Transition Management and 11g neighbor"""
948 run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=False, hwmode
='b',
949 channel
='3', freq
=2422, nei_info
="81,2,5")
951 def run_wnm_bss_tm_scan_not_needed(dev
, apdev
, ht
=True, vht
=False, hwmode
='a',
952 channel
='36', freq
=5180,
953 nei_info
="115,36,7,0301ff"):
957 params
= { "ssid": "test-wnm",
958 "country_code": "FI",
962 "bss_transition": "1" }
963 hapd
= hostapd
.add_ap(apdev
[0], params
)
965 params
= { "ssid": "test-wnm",
966 "country_code": "FI",
970 "bss_transition": "1" }
972 params
['ieee80211n'] = '0'
974 params
['ieee80211ac'] = "1"
975 params
["vht_oper_chwidth"] = "0"
976 params
["vht_oper_centr_freq_seg0_idx"] = "0"
978 hapd2
= hostapd
.add_ap(apdev
[1], params
)
980 dev
[0].scan_for_bss(apdev
[1]['bssid'], freq
)
982 id = dev
[0].connect("test-wnm", key_mgmt
="NONE",
983 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
984 dev
[0].set_network(id, "scan_freq", "")
985 dev
[0].set_network(id, "bssid", "")
987 addr
= dev
[0].own_addr()
988 dev
[0].dump_monitor()
990 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
991 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " pref=1 abridged=1 valid_int=255 neighbor=" + apdev
[1]['bssid'] + ",0x0000," + nei_info
):
992 raise Exception("BSS_TM_REQ command failed")
993 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
995 raise Exception("No BSS Transition Management Response")
996 if "status_code=0" not in ev
:
997 raise Exception("BSS transition request was not accepted: " + ev
)
998 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
999 raise Exception("Unexpected target BSS: " + ev
)
1000 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
1001 if apdev
[1]['bssid'] not in ev
:
1002 raise Exception("Unexpected reassociation target: " + ev
)
1003 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
1005 raise Exception("Unexpected scan started")
1006 dev
[0].dump_monitor()
1008 clear_regdom_state(dev
, hapd
, hapd2
)
1010 def test_wnm_bss_tm_scan_needed(dev
, apdev
):
1011 """WNM BSS Transition Management and scan needed"""
1015 params
= { "ssid": "test-wnm",
1016 "country_code": "FI",
1020 "bss_transition": "1" }
1021 hapd
= hostapd
.add_ap(apdev
[0], params
)
1023 params
= { "ssid": "test-wnm",
1024 "country_code": "FI",
1028 "bss_transition": "1" }
1029 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1031 dev
[0].scan_for_bss(apdev
[1]['bssid'], 5180)
1033 id = dev
[0].connect("test-wnm", key_mgmt
="NONE",
1034 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1035 dev
[0].set_network(id, "scan_freq", "")
1036 dev
[0].set_network(id, "bssid", "")
1038 addr
= dev
[0].own_addr()
1039 dev
[0].dump_monitor()
1041 logger
.info("Wait 11 seconds for the last scan result to be too old, but still present in BSS table")
1043 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1044 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"):
1045 raise Exception("BSS_TM_REQ command failed")
1046 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1048 raise Exception("No BSS Transition Management Response")
1049 if "status_code=0" not in ev
:
1050 raise Exception("BSS transition request was not accepted: " + ev
)
1051 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
1052 raise Exception("Unexpected target BSS: " + ev
)
1053 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
1054 if apdev
[1]['bssid'] not in ev
:
1055 raise Exception("Unexpected reassociation target: " + ev
)
1056 ev
= dev
[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=0.1)
1058 raise Exception("Unexpected scan started")
1059 dev
[0].dump_monitor()
1061 clear_regdom_state(dev
, hapd
, hapd2
)
1063 def test_wnm_bss_tm_scan_needed_e4(dev
, apdev
):
1064 """WNM BSS Transition Management and scan needed (Table E-4)"""
1068 params
= { "ssid": "test-wnm",
1069 "country_code": "FI",
1074 "bss_transition": "1" }
1075 hapd
= hostapd
.add_ap(apdev
[0], params
)
1077 params
= { "ssid": "test-wnm",
1078 "country_code": "FI",
1083 "bss_transition": "1" }
1084 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1086 id = dev
[0].connect("test-wnm", key_mgmt
="NONE",
1087 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1088 dev
[0].set_network(id, "scan_freq", "")
1089 dev
[0].set_network(id, "bssid", "")
1091 addr
= dev
[0].own_addr()
1092 dev
[0].dump_monitor()
1094 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1095 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"):
1096 raise Exception("BSS_TM_REQ command failed")
1097 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=4)
1099 raise Exception("No BSS Transition Management Response seen quickly enough - did scan optimization fail?")
1100 if "status_code=0" not in ev
:
1101 raise Exception("BSS transition request was not accepted: " + ev
)
1102 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
1103 # Wait for regdom change due to country IE to avoid issues with that
1104 # processing happening only after the disconnection and cfg80211 ending
1105 # up intersecting regdoms when we try to clear state back to world (00)
1108 ev
= dev
[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout
=0.5)
1109 if not ev
or "COUNTRY_IE" in ev
:
1111 dev
[0].dump_monitor()
1113 clear_regdom_state(dev
, hapd
, hapd2
)
1115 def start_wnm_tm(ap
, country
, dev
, country3
=None):
1116 params
= { "ssid": "test-wnm",
1117 "country_code": country
,
1121 "bss_transition": "1" }
1122 if country3
is not None:
1123 params
["country3"] = country3
1124 hapd
= hostapd
.add_ap(ap
, params
)
1125 id = dev
.connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1126 wait_regdom_changes(dev
)
1128 dev
.set_network(id, "scan_freq", "")
1131 def stop_wnm_tm(hapd
, dev
):
1133 hapd
.request("DISABLE")
1135 dev
[0].request("DISCONNECT")
1136 dev
[0].request("ABORT_SCAN")
1138 dev
[0].wait_disconnected()
1141 subprocess
.call(['iw', 'reg', 'set', '00'])
1142 wait_regdom_changes(dev
[0])
1143 country
= dev
[0].get_driver_status_field("country")
1144 logger
.info("Country code at the end: " + country
)
1148 dev
[0].flush_scan_cache()
1150 def wnm_bss_tm_check(hapd
, dev
, data
):
1151 addr
= dev
.p2p_interface_addr()
1152 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " " + data
):
1153 raise Exception("BSS_TM_REQ command failed")
1154 ev
= dev
.wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout
=5)
1156 raise Exception("No scan started")
1157 ev
= dev
.wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
1159 raise Exception("Scan did not complete")
1161 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1163 raise Exception("No BSS Transition Management Response")
1164 if "status_code=7" not in ev
:
1165 raise Exception("Unexpected response: " + ev
)
1167 def test_wnm_bss_tm_country_us(dev
, apdev
):
1168 """WNM BSS Transition Management (US)"""
1171 hapd
, id = start_wnm_tm(apdev
[0], "US", dev
[0])
1173 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
1174 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")
1176 # Make the test take less time by limiting full scans
1177 dev
[0].set_network(id, "scan_freq", "2412")
1178 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1179 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")
1181 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1182 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")
1184 stop_wnm_tm(hapd
, dev
)
1186 def test_wnm_bss_tm_country_fi(dev
, apdev
):
1187 """WNM BSS Transition Management (FI)"""
1188 addr
= dev
[0].p2p_interface_addr()
1191 hapd
, id = start_wnm_tm(apdev
[0], "FI", dev
[0])
1193 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
1194 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")
1196 # Make the test take less time by limiting full scans
1197 dev
[0].set_network(id, "scan_freq", "2412")
1198 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1199 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")
1201 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1202 wnm_bss_tm_check(hapd
, dev
[0], "pref=1 neighbor=00:11:22:33:44:00,0x0000,0,0,7")
1204 stop_wnm_tm(hapd
, dev
)
1206 def test_wnm_bss_tm_country_jp(dev
, apdev
):
1207 """WNM BSS Transition Management (JP)"""
1208 addr
= dev
[0].p2p_interface_addr()
1211 hapd
, id = start_wnm_tm(apdev
[0], "JP", dev
[0])
1213 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
1214 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")
1216 # Make the test take less time by limiting full scans
1217 dev
[0].set_network(id, "scan_freq", "2412")
1218 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1219 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")
1221 stop_wnm_tm(hapd
, dev
)
1223 def test_wnm_bss_tm_country_cn(dev
, apdev
):
1224 """WNM BSS Transition Management (CN)"""
1225 addr
= dev
[0].p2p_interface_addr()
1228 hapd
, id = start_wnm_tm(apdev
[0], "CN", dev
[0])
1230 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
1231 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")
1233 # Make the test take less time by limiting full scans
1234 dev
[0].set_network(id, "scan_freq", "2412")
1235 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1236 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")
1238 stop_wnm_tm(hapd
, dev
)
1240 def test_wnm_bss_tm_global(dev
, apdev
):
1241 """WNM BSS Transition Management (global)"""
1242 run_wnm_bss_tm_global(dev
, apdev
, "XX", None)
1244 def test_wnm_bss_tm_global4(dev
, apdev
):
1245 """WNM BSS Transition Management (global; indicate table E-4)"""
1246 run_wnm_bss_tm_global(dev
, apdev
, "FI", "0x04")
1248 def run_wnm_bss_tm_global(dev
, apdev
, country
, country3
):
1249 addr
= dev
[0].p2p_interface_addr()
1252 hapd
, id = start_wnm_tm(apdev
[0], country
, dev
[0], country3
=country3
)
1254 logger
.info("Preferred Candidate List (no matching neighbor, known channels)")
1255 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")
1257 # Make the test take less time by limiting full scans
1258 dev
[0].set_network(id, "scan_freq", "2412")
1259 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1260 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")
1262 logger
.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1263 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")
1265 stop_wnm_tm(hapd
, dev
)
1267 def test_wnm_bss_tm_op_class_0(dev
, apdev
):
1268 """WNM BSS Transition Management with invalid operating class"""
1271 hapd
, id = start_wnm_tm(apdev
[0], "US", dev
[0])
1273 logger
.info("Preferred Candidate List (no matching neighbor, invalid op class specified for channels)")
1274 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")
1276 stop_wnm_tm(hapd
, dev
)
1278 def test_wnm_bss_tm_rsn(dev
, apdev
):
1279 """WNM BSS Transition Management with RSN"""
1283 params
= hostapd
.wpa2_params(ssid
="test-wnm", passphrase
="zxcvbnm,.-")
1284 params
["country_code"] = "FI"
1285 params
["ieee80211d"] = "1"
1286 params
["hw_mode"] = "g"
1287 params
["channel"] = "1"
1288 params
["bss_transition"] = "1"
1289 hapd
= hostapd
.add_ap(apdev
[0], params
)
1291 params
= hostapd
.wpa2_params(ssid
="test-wnm", passphrase
="zxcvbnm,.-")
1292 params
["country_code"] = "FI"
1293 params
["ieee80211d"] = "1"
1294 params
["hw_mode"] = "a"
1295 params
["channel"] = "36"
1296 params
["bss_transition"] = "1"
1297 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1299 dev
[0].scan_for_bss(apdev
[1]['bssid'], 5180)
1301 id = dev
[0].connect("test-wnm", psk
="zxcvbnm,.-",
1302 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1303 dev
[0].set_network(id, "scan_freq", "")
1304 dev
[0].set_network(id, "bssid", "")
1306 addr
= dev
[0].own_addr()
1307 dev
[0].dump_monitor()
1310 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1311 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"):
1312 raise Exception("BSS_TM_REQ command failed")
1313 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1315 raise Exception("No BSS Transition Management Response")
1316 if "status_code=0" not in ev
:
1317 raise Exception("BSS transition request was not accepted: " + ev
)
1318 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
1319 raise Exception("Unexpected target BSS: " + ev
)
1320 dev
[0].wait_connected(timeout
=15, error
="No reassociation seen")
1321 if apdev
[1]['bssid'] not in ev
:
1322 raise Exception("Unexpected reassociation target: " + ev
)
1324 clear_regdom_state(dev
, hapd
, hapd2
)
1326 def test_wnm_action_proto(dev
, apdev
):
1327 """WNM Action protocol testing"""
1328 params
= { "ssid": "test-wnm" }
1329 params
['wnm_sleep_mode'] = '1'
1330 hapd
= hostapd
.add_ap(apdev
[0], params
)
1331 bssid
= apdev
[0]['bssid']
1332 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1333 dev
[0].request("WNM_SLEEP enter")
1335 hapd
.set("ext_mgmt_frame_handling", "1")
1338 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
1339 msg
['da'] = dev
[0].own_addr()
1341 msg
['bssid'] = bssid
1345 logger
.debug("Unexpected WNM-Notification Response")
1346 # Note: This is actually not registered for user space processing in
1347 # driver_nl80211.c nl80211_mgmt_subscribe_non_ap() and as such, won't make
1348 # it to wpa_supplicant.
1349 msg
['payload'] = struct
.pack("<BBBB",
1350 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_RESP
,
1355 logger
.debug("Truncated WNM-Notification Request (no Type field)")
1356 msg
['payload'] = struct
.pack("<BBB",
1357 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1362 logger
.debug("WFA WNM-Notification Request with truncated IE (min)")
1363 msg
['payload'] = struct
.pack("<BBBBBB",
1364 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1365 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0, 1)
1369 logger
.debug("WFA WNM-Notification Request with truncated IE (max)")
1370 msg
['payload'] = struct
.pack("<BBBBBB",
1371 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1372 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0, 255)
1376 logger
.debug("WFA WNM-Notification Request with too short IE")
1377 msg
['payload'] = struct
.pack("<BBBBBB",
1378 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1379 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0, 0)
1383 logger
.debug("WFA WNM-Notification Request with truncated Sub Rem URL")
1384 msg
['payload'] = struct
.pack(">BBBBBBLB",
1385 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1386 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 5,
1391 logger
.debug("WFA WNM-Notification Request with truncated Sub Rem URL(2)")
1392 msg
['payload'] = struct
.pack(">BBBBBBLBB",
1393 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1394 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 6,
1399 logger
.debug("WFA WNM-Notification Request with truncated Sub Rem URL(3)")
1400 msg
['payload'] = struct
.pack(">BBBBBBLB",
1401 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1402 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 5,
1407 logger
.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(min)")
1408 msg
['payload'] = struct
.pack(">BBBBBBLBHB",
1409 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1410 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 8,
1411 0x506f9a01, 0, 0, 1)
1415 logger
.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(max)")
1416 msg
['payload'] = struct
.pack(">BBBBBBLBHB",
1417 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1418 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 8,
1419 0x506f9a01, 0, 0, 0xff)
1423 logger
.debug("WFA WNM-Notification Request with unsupported IE")
1424 msg
['payload'] = struct
.pack("<BBBBBBL",
1425 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1426 dialog_token
, WNM_NOTIF_TYPE_WFA
, 0xdd, 4, 0)
1430 logger
.debug("WNM-Notification Request with unknown WNM-Notification type 0")
1431 msg
['payload'] = struct
.pack("<BBBB",
1432 ACTION_CATEG_WNM
, WNM_ACT_NOTIFICATION_REQ
,
1433 dialog_token
, WNM_NOTIF_TYPE_FW_UPGRADE
)
1437 logger
.debug("Truncated WNM Sleep Mode Response - no Dialog Token")
1438 msg
['payload'] = struct
.pack("<BB",
1439 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
)
1443 logger
.debug("Truncated WNM Sleep Mode Response - no Key Data Length")
1444 msg
['payload'] = struct
.pack("<BBB",
1445 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0)
1449 logger
.debug("Truncated WNM Sleep Mode Response - truncated Key Data (min)")
1450 msg
['payload'] = struct
.pack("<BBBH",
1451 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1456 logger
.debug("Truncated WNM Sleep Mode Response - truncated Key Data (max)")
1457 msg
['payload'] = struct
.pack("<BBBH",
1458 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1463 logger
.debug("WNM Sleep Mode Response - truncated IE header")
1464 msg
['payload'] = struct
.pack("<BBBHB",
1465 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1470 logger
.debug("WNM Sleep Mode Response - truncated IE")
1471 msg
['payload'] = struct
.pack("<BBBHBB",
1472 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1477 logger
.debug("WNM Sleep Mode Response - Empty TFS Response")
1478 msg
['payload'] = struct
.pack("<BBBHBB",
1479 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1480 0, WLAN_EID_TFS_RESP
, 0)
1484 logger
.debug("WNM Sleep Mode Response - EID 0 not recognized")
1485 msg
['payload'] = struct
.pack("<BBBHBB",
1486 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1491 logger
.debug("WNM Sleep Mode Response - Empty WNM Sleep Mode element and TFS Response element")
1492 msg
['payload'] = struct
.pack("<BBBHBBBB",
1493 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1494 0, WLAN_EID_WNMSLEEP
, 0, WLAN_EID_TFS_RESP
, 0)
1498 logger
.debug("WNM Sleep Mode Response - WNM Sleep Mode element and empty TFS Response element")
1499 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
1500 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1501 0, WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_ENTER
,
1502 WNM_STATUS_SLEEP_ACCEPT
, 0,
1503 WLAN_EID_TFS_RESP
, 0)
1507 logger
.debug("WNM Sleep Mode Response - WNM Sleep Mode element(exit, deny key) and empty TFS Response element")
1508 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
1509 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1510 0, WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1511 WNM_STATUS_DENIED_KEY
, 0,
1512 WLAN_EID_TFS_RESP
, 0)
1516 logger
.debug("WNM Sleep Mode Response - WNM Sleep Mode element(enter, deny key) and empty TFS Response element")
1517 msg
['payload'] = struct
.pack("<BBBHBBBBHBB",
1518 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1519 0, WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_ENTER
,
1520 WNM_STATUS_DENIED_KEY
, 0,
1521 WLAN_EID_TFS_RESP
, 0)
1526 def test_wnm_action_proto_pmf(dev
, apdev
):
1527 """WNM Action protocol testing (PMF enabled)"""
1528 ssid
= "test-wnm-pmf"
1529 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
1530 params
["wpa_key_mgmt"] = "WPA-PSK-SHA256"
1531 params
["ieee80211w"] = "2"
1532 params
['wnm_sleep_mode'] = '1'
1533 hapd
= hostapd
.add_ap(apdev
[0], params
)
1534 bssid
= apdev
[0]['bssid']
1535 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK-SHA256",
1536 proto
="WPA2", ieee80211w
="2", scan_freq
="2412")
1537 dev
[0].request("WNM_SLEEP enter")
1539 hapd
.set("ext_mgmt_frame_handling", "1")
1542 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
1543 msg
['da'] = dev
[0].own_addr()
1545 msg
['bssid'] = bssid
1547 logger
.debug("WNM Sleep Mode Response - Invalid Key Data element length")
1548 keydata
= struct
.pack("<BB", 0, 1)
1549 msg
['payload'] = struct
.pack("<BBBH",
1550 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1552 msg
['payload'] += keydata
1553 msg
['payload'] += struct
.pack("<BBBBHBB",
1554 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1555 WNM_STATUS_SLEEP_ACCEPT
, 0,
1556 WLAN_EID_TFS_RESP
, 0)
1560 logger
.debug("WNM Sleep Mode Response - Too short GTK subelem")
1561 keydata
= struct
.pack("<BB", WNM_SLEEP_SUBELEM_GTK
, 0)
1562 msg
['payload'] = struct
.pack("<BBBH",
1563 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1565 msg
['payload'] += keydata
1566 msg
['payload'] += struct
.pack("<BBBBHBB",
1567 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1568 WNM_STATUS_SLEEP_ACCEPT
, 0,
1569 WLAN_EID_TFS_RESP
, 0)
1573 logger
.debug("WNM Sleep Mode Response - Invalid GTK subelem")
1574 keydata
= struct
.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK
, 11 + 16,
1575 0, 17, 0, 0, 0, 0, 0, 0)
1576 msg
['payload'] = struct
.pack("<BBBH",
1577 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1579 msg
['payload'] += keydata
1580 msg
['payload'] += struct
.pack("<BBBBHBB",
1581 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1582 WNM_STATUS_SLEEP_ACCEPT
, 0,
1583 WLAN_EID_TFS_RESP
, 0)
1587 logger
.debug("WNM Sleep Mode Response - Invalid GTK subelem (2)")
1588 keydata
= struct
.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK
, 11 + 16,
1589 0, 0, 0, 0, 0, 0, 0, 0)
1590 msg
['payload'] = struct
.pack("<BBBH",
1591 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1593 msg
['payload'] += keydata
1594 msg
['payload'] += struct
.pack("<BBBBHBB",
1595 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1596 WNM_STATUS_SLEEP_ACCEPT
, 0,
1597 WLAN_EID_TFS_RESP
, 0)
1601 logger
.debug("WNM Sleep Mode Response - GTK subelem and too short IGTK subelem")
1602 keydata
= struct
.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK
, 11 + 16, 0, 16)
1603 keydata
+= struct
.pack(">2L4L", 0x01020304, 0x05060708,
1604 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1605 keydata
+= struct
.pack("<BB", WNM_SLEEP_SUBELEM_IGTK
, 0)
1606 msg
['payload'] = struct
.pack("<BBBH",
1607 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1609 msg
['payload'] += keydata
1610 msg
['payload'] += struct
.pack("<BBBBHBB",
1611 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1612 WNM_STATUS_SLEEP_ACCEPT
, 0,
1613 WLAN_EID_TFS_RESP
, 0)
1617 logger
.debug("WNM Sleep Mode Response - Unknown subelem")
1618 keydata
= struct
.pack("<BB", 255, 0)
1619 msg
['payload'] = struct
.pack("<BBBH",
1620 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1622 msg
['payload'] += keydata
1623 msg
['payload'] += struct
.pack("<BBBBHBB",
1624 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1625 WNM_STATUS_SLEEP_ACCEPT
, 0,
1626 WLAN_EID_TFS_RESP
, 0)
1631 def test_wnm_action_proto_no_pmf(dev
, apdev
):
1632 """WNM Action protocol testing (PMF disabled)"""
1633 ssid
= "test-wnm-no-pmf"
1634 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
1635 params
['wnm_sleep_mode'] = '1'
1636 hapd
= hostapd
.add_ap(apdev
[0], params
)
1637 bssid
= apdev
[0]['bssid']
1638 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK",
1639 proto
="WPA2", ieee80211w
="0", scan_freq
="2412")
1640 dev
[0].request("WNM_SLEEP enter")
1642 hapd
.set("ext_mgmt_frame_handling", "1")
1644 dev
[0].request("WNM_SLEEP exit")
1645 ev
= hapd
.wait_event(['MGMT-RX'], timeout
=5)
1647 raise Exception("WNM-Sleep Mode Request not seen")
1650 msg
['fc'] = MGMT_SUBTYPE_ACTION
<< 4
1651 msg
['da'] = dev
[0].own_addr()
1653 msg
['bssid'] = bssid
1655 logger
.debug("WNM Sleep Mode Response - GTK subelem and IGTK subelem")
1656 keydata
= struct
.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK
, 11 + 16, 0, 16)
1657 keydata
+= struct
.pack(">2L4L", 0x01020304, 0x05060708,
1658 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1659 keydata
+= struct
.pack("<BBHLH4L", WNM_SLEEP_SUBELEM_IGTK
, 2 + 6 + 16, 0,
1661 0xf1f2f3f4, 0xf5f6f7f8, 0xf9f0fafb, 0xfcfdfeff)
1662 msg
['payload'] = struct
.pack("<BBBH",
1663 ACTION_CATEG_WNM
, WNM_ACT_SLEEP_MODE_RESP
, 0,
1665 msg
['payload'] += keydata
1666 msg
['payload'] += struct
.pack("<BBBBHBB",
1667 WLAN_EID_WNMSLEEP
, 4, WNM_SLEEP_MODE_EXIT
,
1668 WNM_STATUS_SLEEP_ACCEPT
, 0,
1669 WLAN_EID_TFS_RESP
, 0)
1673 ev
= dev
[0].wait_event(["WNM: Ignore Key Data"], timeout
=5)
1675 raise Exception("Key Data not ignored")
1677 def test_wnm_bss_tm_req_with_mbo_ie(dev
, apdev
):
1678 """WNM BSS transition request with MBO IE and reassociation delay attribute"""
1679 ssid
= "test-wnm-mbo"
1680 params
= hostapd
.wpa2_params(ssid
=ssid
, passphrase
="12345678")
1681 params
['bss_transition'] = "1"
1682 hapd
= hostapd
.add_ap(apdev
[0], params
)
1683 bssid
= apdev
[0]['bssid']
1684 if "OK" not in dev
[0].request("SET mbo_cell_capa 1"):
1685 raise Exception("Failed to set STA as cellular data capable")
1687 dev
[0].connect(ssid
, psk
="12345678", key_mgmt
="WPA-PSK",
1688 proto
="WPA2", ieee80211w
="0", scan_freq
="2412")
1690 logger
.debug("BTM request with MBO reassociation delay when disassoc imminent is not set")
1691 if 'FAIL' not in hapd
.request("BSS_TM_REQ " + dev
[0].own_addr() + " mbo=3:2:1"):
1692 raise Exception("BSS transition management succeeded unexpectedly")
1694 logger
.debug("BTM request with invalid MBO transition reason code")
1695 if 'FAIL' not in hapd
.request("BSS_TM_REQ " + dev
[0].own_addr() + " mbo=10:2:1"):
1696 raise Exception("BSS transition management succeeded unexpectedly")
1698 logger
.debug("BTM request with MBO reassociation retry delay of 5 seconds")
1699 if 'OK' not in hapd
.request("BSS_TM_REQ " + dev
[0].own_addr() + " disassoc_imminent=1 disassoc_timer=3 mbo=3:5:1"):
1700 raise Exception("BSS transition management command failed")
1702 ev
= dev
[0].wait_event(['MBO-CELL-PREFERENCE'], 1)
1703 if ev
is None or "preference=1" not in ev
:
1704 raise Exception("Timeout waiting for MBO-CELL-PREFERENCE event")
1706 ev
= dev
[0].wait_event(['MBO-TRANSITION-REASON'], 1)
1707 if ev
is None or "reason=3" not in ev
:
1708 raise Exception("Timeout waiting for MBO-TRANSITION-REASON event")
1712 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1714 raise Exception("No BSS Transition Management Response")
1715 if dev
[0].own_addr() not in ev
:
1716 raise Exception("Unexpected BSS Transition Management Response address")
1718 ev
= dev
[0].wait_event(['CTRL-EVENT-DISCONNECTED'], 5)
1720 raise Exception("Station did not disconnect although disassoc imminent was set")
1722 # Set the scan interval to make dev[0] look for connections
1723 if 'OK' not in dev
[0].request("SCAN_INTERVAL 1"):
1724 raise Exception("Failed to set scan interval")
1726 # Wait until connected
1727 ev
= dev
[0].wait_event(['CTRL-EVENT-CONNECTED'], 10)
1729 raise Exception("Station did not connect")
1731 # Make sure no connection is made during the retry delay
1732 time_diff
= datetime
.now() - t0
1733 if time_diff
.total_seconds() < 5:
1734 raise Exception("Station connected before assoc retry delay was over")
1736 if "OK" not in dev
[0].request("SET mbo_cell_capa 3"):
1737 raise Exception("Failed to set STA as cellular data not-capable")
1740 def test_wnm_bss_transition_mgmt_query(dev
, apdev
):
1741 """WNM BSS Transition Management query"""
1742 params
= { "ssid": "test-wnm",
1743 "bss_transition": "1" }
1744 hapd
= hostapd
.add_ap(apdev
[0], params
)
1745 params
= { "ssid": "another" }
1746 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1748 dev
[0].scan_for_bss(apdev
[1]['bssid'], 2412)
1749 dev
[0].scan_for_bss(apdev
[0]['bssid'], 2412)
1751 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1752 dev
[0].request("WNM_BSS_QUERY 0 list")
1754 ev
= dev
[0].wait_event(["WNM: BSS Transition Management Request"],
1757 raise Exception("No BSS Transition Management Request frame seen")
1759 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=5)
1761 raise Exception("No BSS Transition Management Response frame seen")
1764 def test_wnm_bss_tm_security_mismatch(dev
, apdev
):
1765 """WNM BSS Transition Management and security mismatch"""
1766 params
= { "ssid": "test-wnm",
1768 "wpa_key_mgmt": "WPA-PSK",
1769 "rsn_pairwise": "CCMP",
1770 "wpa_passphrase": "12345678",
1773 "bss_transition": "1" }
1774 hapd
= hostapd
.add_ap(apdev
[0], params
)
1776 params
= { "ssid": "test-wnm",
1779 "bss_transition": "1" }
1780 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1782 dev
[0].scan_for_bss(apdev
[1]['bssid'], 2462)
1784 id = dev
[0].connect("test-wnm", psk
="12345678",
1785 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1786 dev
[0].set_network(id, "scan_freq", "")
1787 dev
[0].set_network(id, "bssid", "")
1789 addr
= dev
[0].own_addr()
1790 dev
[0].dump_monitor()
1792 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1793 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"):
1794 raise Exception("BSS_TM_REQ command failed")
1795 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1797 raise Exception("No BSS Transition Management Response")
1798 if "status_code=7" not in ev
:
1799 raise Exception("Unexpected BSS transition request response: " + ev
)
1801 def test_wnm_bss_tm_connect_cmd(dev
, apdev
):
1802 """WNM BSS Transition Management and cfg80211 connect command"""
1803 params
= { "ssid": "test-wnm",
1806 "bss_transition": "1" }
1807 hapd
= hostapd
.add_ap(apdev
[0], params
)
1809 params
= { "ssid": "test-wnm",
1812 "bss_transition": "1" }
1813 hapd2
= hostapd
.add_ap(apdev
[1], params
)
1815 wpas
= WpaSupplicant(global_iface
='/tmp/wpas-wlan5')
1816 wpas
.interface_add("wlan5", drv_params
="force_connect_cmd=1")
1818 wpas
.scan_for_bss(apdev
[1]['bssid'], 2462)
1820 id = wpas
.connect("test-wnm", key_mgmt
="NONE",
1821 bssid
=apdev
[0]['bssid'], scan_freq
="2412")
1822 wpas
.set_network(id, "scan_freq", "")
1823 wpas
.set_network(id, "bssid", "")
1825 addr
= wpas
.own_addr()
1828 logger
.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1829 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"):
1830 raise Exception("BSS_TM_REQ command failed")
1831 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1833 raise Exception("No BSS Transition Management Response")
1834 if "status_code=0" not in ev
:
1835 raise Exception("BSS transition request was not accepted: " + ev
)
1836 if "target_bssid=" + apdev
[1]['bssid'] not in ev
:
1837 raise Exception("Unexpected target BSS: " + ev
)
1838 ev
= wpas
.wait_event(["CTRL-EVENT-CONNECTED",
1839 "CTRL-EVENT-DISCONNECTED"], timeout
=10)
1841 raise Exception("No reassociation seen")
1842 if "CTRL-EVENT-DISCONNECTED" in ev
:
1843 raise Exception("Unexpected disconnection reported")
1844 if apdev
[1]['bssid'] not in ev
:
1845 raise Exception("Unexpected reassociation target: " + ev
)
1847 def test_wnm_bss_tm_reject(dev
, apdev
):
1848 """WNM BSS Transition Management request getting rejected"""
1851 params
= { "ssid": "test-wnm",
1852 "country_code": "FI",
1856 "bss_transition": "1" }
1857 hapd
= hostapd
.add_ap(apdev
[0], params
)
1859 id = dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1860 addr
= dev
[0].own_addr()
1861 dev
[0].dump_monitor()
1863 if "OK" not in dev
[0].request("SET reject_btm_req_reason 123"):
1864 raise Exception("Failed to set reject_btm_req_reason")
1866 if "OK" not in hapd
.request("BSS_TM_REQ " + addr
+ " disassoc_timer=1"):
1867 raise Exception("BSS_TM_REQ command failed")
1868 ev
= hapd
.wait_event(['BSS-TM-RESP'], timeout
=10)
1870 raise Exception("No BSS Transition Management Response")
1872 raise Exception("Unexpected BSS Transition Management Response address")
1873 if "status_code=123" not in ev
:
1874 raise Exception("Unexpected BSS Transition Management Response status: " + ev
)
1875 dev
[0].wait_disconnected()
1876 dev
[0].wait_connected()
1879 hapd
.request("DISABLE")
1880 dev
[0].request("DISCONNECT")
1881 dev
[0].request("ABORT_SCAN")
1882 dev
[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout
=0.5)
1883 subprocess
.call(['iw', 'reg', 'set', '00'])
1884 dev
[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout
=0.5)
1885 dev
[0].flush_scan_cache()
1887 def test_wnm_bss_tm_ap_proto(dev
, apdev
):
1888 """WNM BSS TM - protocol testing for AP message parsing"""
1889 params
= { "ssid": "test-wnm", "bss_transition": "1" }
1890 hapd
= hostapd
.add_ap(apdev
[0], params
)
1891 bssid
= hapd
.own_addr()
1892 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1893 addr
= dev
[0].own_addr()
1895 hdr
= "d0003a01" + bssid
.replace(':', '') + addr
.replace(':', '') + bssid
.replace(':', '') + "1000"
1896 hapd
.set("ext_mgmt_frame_handling", "1")
1903 "0a080000001122334455",
1904 "0a08000000112233445566",
1905 "0a08000000112233445566112233445566778899",
1907 "0a08ffffff112233445566778899",
1913 if "OK" not in hapd
.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr
+ t
):
1914 raise Exception("MGMT_RX_PROCESS failed")
1916 hapd
.set("ext_mgmt_frame_handling", "0")
1918 def test_wnm_bss_transition_mgmt_query_with_unknown_candidates(dev
, apdev
):
1919 """WNM BSS Transition Management query with unknown candidates"""
1920 params
= { "ssid": "test-wnm",
1921 "bss_transition": "1" }
1922 hapd
= hostapd
.add_ap(apdev
[0], params
)
1924 dev
[0].scan_for_bss(apdev
[0]['bssid'], 2412)
1926 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1927 dev
[0].request("WNM_BSS_QUERY 0 neighbor=00:11:22:33:44:55,0,81,1,4")
1929 ev
= dev
[0].wait_event(["WNM: BSS Transition Management Request"],
1932 raise Exception("No BSS Transition Management Request frame seen")
1934 ev
= hapd
.wait_event(["BSS-TM-RESP"], timeout
=5)
1936 raise Exception("No BSS Transition Management Response frame seen")
1938 def test_wnm_time_adv_without_time_zone(dev
, apdev
):
1939 """WNM Time Advertisement without time zone configuration"""
1940 params
= { "ssid": "test-wnm",
1941 "time_advertisement": "2" }
1942 hostapd
.add_ap(apdev
[0], params
)
1944 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1946 def test_wnm_coloc_intf_reporting(dev
, apdev
):
1947 """WNM Collocated Interference Reporting"""
1948 params
= { "ssid": "test-wnm",
1949 "coloc_intf_reporting": "1" }
1950 hapd
= hostapd
.add_ap(apdev
[0], params
)
1952 no_intf
= struct
.pack("<BBBBBLLLLH", 96, 21, 0, 127, 0x0f, 0, 0, 0, 0, 0)
1955 dev
[0].set("coloc_intf_reporting", "1")
1956 dev
[0].connect("test-wnm", key_mgmt
="NONE", scan_freq
="2412")
1957 addr
= dev
[0].own_addr()
1958 if "OK" not in hapd
.request("COLOC_INTF_REQ %s 1 5" % addr
):
1959 raise Exception("Could not send Collocated Interference Request")
1960 ev
= dev
[0].wait_event(["COLOC-INTF-REQ"], timeout
=2)
1962 raise Exception("No Collocated Interference Request frame seen")
1963 vals
= ev
.split(' ')
1964 if vals
[2] != '1' or vals
[3] != '5':
1965 raise Exception("Unexpected request values: " + ev
)
1966 dev
[0].set("coloc_intf_elems", binascii
.hexlify(no_intf
))
1967 ev
= hapd
.wait_event(["COLOC-INTF-REPORT"], timeout
=1)
1969 raise Exception("No Collocated Interference Report frame seen")
1970 if addr
+ " 1 " + binascii
.hexlify(no_intf
) not in ev
:
1971 raise Exception("Unexpected report values: " + ev
)
1973 if "OK" not in hapd
.request("COLOC_INTF_REQ %s 0 0" % addr
):
1974 raise Exception("Could not send Collocated Interference Request")
1975 ev
= dev
[0].wait_event(["COLOC-INTF-REQ"], timeout
=2)
1977 raise Exception("No Collocated Interference Request frame seen")
1978 vals
= ev
.split(' ')
1979 if vals
[2] != '0' or vals
[3] != '0':
1980 raise Exception("Unexpected request values: " + ev
)
1982 res
= dev
[0].request("COLOC_INTF_REPORT " + binascii
.hexlify(no_intf
))
1984 raise Exception("Could not send unsolicited report")
1985 ev
= hapd
.wait_event(["COLOC-INTF-REPORT"], timeout
=1)
1987 raise Exception("No Collocated Interference Report frame seen")
1988 if addr
+ " 0 " + binascii
.hexlify(no_intf
) not in ev
:
1989 raise Exception("Unexpected report values: " + ev
)
1991 dev
[0].set("coloc_intf_reporting", "0")
1992 dev
[0].set("coloc_intf_elems", "")