]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_wnm.py
tests: Mark 525 tests as remote compatible
[thirdparty/hostap.git] / tests / hwsim / test_wnm.py
1 # WNM tests
2 # Copyright (c) 2013-2014, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 from remotehost import remote_compatible
8 import binascii
9 import struct
10 import time
11 import logging
12 logger = logging.getLogger()
13 import subprocess
14
15 import hostapd
16 from wpasupplicant import WpaSupplicant
17 from utils import alloc_fail, wait_fail_trigger
18 from wlantest import Wlantest
19
20 @remote_compatible
21 def test_wnm_bss_transition_mgmt(dev, apdev):
22 """WNM BSS Transition Management"""
23 params = { "ssid": "test-wnm",
24 "time_advertisement": "2",
25 "time_zone": "EST5",
26 "wnm_sleep_mode": "1",
27 "bss_transition": "1" }
28 hostapd.add_ap(apdev[0], params)
29
30 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
31 dev[0].request("WNM_BSS_QUERY 0")
32
33 @remote_compatible
34 def test_wnm_disassoc_imminent(dev, apdev):
35 """WNM Disassociation Imminent"""
36 params = { "ssid": "test-wnm",
37 "time_advertisement": "2",
38 "time_zone": "EST5",
39 "wnm_sleep_mode": "1",
40 "bss_transition": "1" }
41 hapd = hostapd.add_ap(apdev[0], params)
42
43 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
44 addr = dev[0].p2p_interface_addr()
45 hapd.request("DISASSOC_IMMINENT " + addr + " 10")
46 ev = dev[0].wait_event(["WNM: Disassociation Imminent"])
47 if ev is None:
48 raise Exception("Timeout while waiting for disassociation imminent")
49 if "Disassociation Timer 10" not in ev:
50 raise Exception("Unexpected disassociation imminent contents")
51 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
52 if ev is None:
53 raise Exception("Timeout while waiting for re-connection scan")
54
55 @remote_compatible
56 def test_wnm_ess_disassoc_imminent(dev, apdev):
57 """WNM ESS Disassociation Imminent"""
58 params = { "ssid": "test-wnm",
59 "time_advertisement": "2",
60 "time_zone": "EST5",
61 "wnm_sleep_mode": "1",
62 "bss_transition": "1" }
63 hapd = hostapd.add_ap(apdev[0], params)
64
65 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
66 addr = dev[0].p2p_interface_addr()
67 hapd.request("ESS_DISASSOC " + addr + " 10 http://example.com/session-info")
68 ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"])
69 if ev is None:
70 raise Exception("Timeout while waiting for ESS disassociation imminent")
71 if "0 1024 http://example.com/session-info" not in ev:
72 raise Exception("Unexpected ESS disassociation imminent message contents")
73 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
74 if ev is None:
75 raise Exception("Timeout while waiting for re-connection scan")
76
77 @remote_compatible
78 def test_wnm_ess_disassoc_imminent_pmf(dev, apdev):
79 """WNM ESS Disassociation Imminent"""
80 params = hostapd.wpa2_params("test-wnm-rsn", "12345678")
81 params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
82 params["ieee80211w"] = "2";
83 params["bss_transition"] = "1"
84 hapd = hostapd.add_ap(apdev[0], params)
85
86 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
87 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
88 addr = dev[0].p2p_interface_addr()
89 hapd.request("ESS_DISASSOC " + addr + " 10 http://example.com/session-info")
90 ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"])
91 if ev is None:
92 raise Exception("Timeout while waiting for ESS disassociation imminent")
93 if "1 1024 http://example.com/session-info" not in ev:
94 raise Exception("Unexpected ESS disassociation imminent message contents")
95 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
96 if ev is None:
97 raise Exception("Timeout while waiting for re-connection scan")
98
99 def check_wnm_sleep_mode_enter_exit(hapd, dev, interval=None, tfs_req=None):
100 addr = dev.p2p_interface_addr()
101 sta = hapd.get_sta(addr)
102 if "[WNM_SLEEP_MODE]" in sta['flags']:
103 raise Exception("Station unexpectedly in WNM-Sleep Mode")
104
105 logger.info("Going to WNM Sleep Mode")
106 extra = ""
107 if interval is not None:
108 extra += " interval=" + str(interval)
109 if tfs_req:
110 extra += " tfs_req=" + tfs_req
111 if "OK" not in dev.request("WNM_SLEEP enter" + extra):
112 raise Exception("WNM_SLEEP failed")
113 ok = False
114 for i in range(20):
115 time.sleep(0.1)
116 sta = hapd.get_sta(addr)
117 if "[WNM_SLEEP_MODE]" in sta['flags']:
118 ok = True
119 break
120 if not ok:
121 raise Exception("Station failed to enter WNM-Sleep Mode")
122
123 logger.info("Waking up from WNM Sleep Mode")
124 ok = False
125 dev.request("WNM_SLEEP exit")
126 for i in range(20):
127 time.sleep(0.1)
128 sta = hapd.get_sta(addr)
129 if "[WNM_SLEEP_MODE]" not in sta['flags']:
130 ok = True
131 break
132 if not ok:
133 raise Exception("Station failed to exit WNM-Sleep Mode")
134
135 @remote_compatible
136 def test_wnm_sleep_mode_open(dev, apdev):
137 """WNM Sleep Mode - open"""
138 params = { "ssid": "test-wnm",
139 "time_advertisement": "2",
140 "time_zone": "EST5",
141 "wnm_sleep_mode": "1",
142 "bss_transition": "1" }
143 hapd = hostapd.add_ap(apdev[0], params)
144
145 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
146 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
147 if ev is None:
148 raise Exception("No connection event received from hostapd")
149 check_wnm_sleep_mode_enter_exit(hapd, dev[0])
150 check_wnm_sleep_mode_enter_exit(hapd, dev[0], interval=100)
151 check_wnm_sleep_mode_enter_exit(hapd, dev[0], tfs_req="5b17010001130e110000071122334455661122334455661234")
152
153 cmds = [ "foo",
154 "exit tfs_req=123 interval=10",
155 "enter tfs_req=qq interval=10" ]
156 for cmd in cmds:
157 if "FAIL" not in dev[0].request("WNM_SLEEP " + cmd):
158 raise Exception("Invalid WNM_SLEEP accepted")
159
160 @remote_compatible
161 def test_wnm_sleep_mode_rsn(dev, apdev):
162 """WNM Sleep Mode - RSN"""
163 params = hostapd.wpa2_params("test-wnm-rsn", "12345678")
164 params["time_advertisement"] = "2"
165 params["time_zone"] = "EST5"
166 params["wnm_sleep_mode"] = "1"
167 params["bss_transition"] = "1"
168 hapd = hostapd.add_ap(apdev[0], params)
169
170 dev[0].connect("test-wnm-rsn", psk="12345678", scan_freq="2412")
171 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
172 if ev is None:
173 raise Exception("No connection event received from hostapd")
174 check_wnm_sleep_mode_enter_exit(hapd, dev[0])
175
176 @remote_compatible
177 def test_wnm_sleep_mode_ap_oom(dev, apdev):
178 """WNM Sleep Mode - AP side OOM"""
179 params = { "ssid": "test-wnm",
180 "wnm_sleep_mode": "1" }
181 hapd = hostapd.add_ap(apdev[0], params)
182
183 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
184 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
185 if ev is None:
186 raise Exception("No connection event received from hostapd")
187 with alloc_fail(hapd, 1, "ieee802_11_send_wnmsleep_resp"):
188 dev[0].request("WNM_SLEEP enter")
189 wait_fail_trigger(hapd, "GET_ALLOC_FAIL")
190 with alloc_fail(hapd, 2, "ieee802_11_send_wnmsleep_resp"):
191 dev[0].request("WNM_SLEEP exit")
192 wait_fail_trigger(hapd, "GET_ALLOC_FAIL")
193
194 @remote_compatible
195 def test_wnm_sleep_mode_rsn_pmf(dev, apdev):
196 """WNM Sleep Mode - RSN with PMF"""
197 params = hostapd.wpa2_params("test-wnm-rsn", "12345678")
198 params["wpa_key_mgmt"] = "WPA-PSK-SHA256";
199 params["ieee80211w"] = "2";
200 params["time_advertisement"] = "2"
201 params["time_zone"] = "EST5"
202 params["wnm_sleep_mode"] = "1"
203 params["bss_transition"] = "1"
204 hapd = hostapd.add_ap(apdev[0], params)
205
206 Wlantest.setup(hapd)
207 wt = Wlantest()
208 wt.flush()
209 wt.add_passphrase("12345678")
210
211 dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
212 key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
213 ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
214 if ev is None:
215 raise Exception("No connection event received from hostapd")
216 check_wnm_sleep_mode_enter_exit(hapd, dev[0])
217
218 MGMT_SUBTYPE_ACTION = 13
219 ACTION_CATEG_WNM = 10
220 WNM_ACT_BSS_TM_REQ = 7
221 WNM_ACT_BSS_TM_RESP = 8
222 WNM_ACT_SLEEP_MODE_REQ = 16
223 WNM_ACT_SLEEP_MODE_RESP = 17
224 WNM_ACT_NOTIFICATION_REQ = 26
225 WNM_ACT_NOTIFICATION_RESP = 27
226 WNM_NOTIF_TYPE_FW_UPGRADE = 0
227 WNM_NOTIF_TYPE_WFA = 1
228 WLAN_EID_TFS_RESP = 92
229 WLAN_EID_WNMSLEEP = 93
230 WNM_SLEEP_MODE_ENTER = 0
231 WNM_SLEEP_MODE_EXIT = 1
232 WNM_STATUS_SLEEP_ACCEPT = 0
233 WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE = 1
234 WNM_STATUS_DENIED_ACTION = 2
235 WNM_STATUS_DENIED_TMP = 3
236 WNM_STATUS_DENIED_KEY = 4
237 WNM_STATUS_DENIED_OTHER_WNM_SERVICE = 5
238 WNM_SLEEP_SUBELEM_GTK = 0
239 WNM_SLEEP_SUBELEM_IGTK = 1
240
241 def bss_tm_req(dst, src, dialog_token=1, req_mode=0, disassoc_timer=0,
242 validity_interval=1):
243 msg = {}
244 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
245 msg['da'] = dst
246 msg['sa'] = src
247 msg['bssid'] = src
248 msg['payload'] = struct.pack("<BBBBHB",
249 ACTION_CATEG_WNM, WNM_ACT_BSS_TM_REQ,
250 dialog_token, req_mode, disassoc_timer,
251 validity_interval)
252 return msg
253
254 def rx_bss_tm_resp(hapd, expect_dialog=None, expect_status=None):
255 for i in range(0, 100):
256 resp = hapd.mgmt_rx()
257 if resp is None:
258 raise Exception("No BSS TM Response received")
259 if resp['subtype'] == MGMT_SUBTYPE_ACTION:
260 break
261 if i == 99:
262 raise Exception("Not an Action frame")
263 payload = resp['payload']
264 if len(payload) < 2 + 3:
265 raise Exception("Too short payload")
266 (category, action) = struct.unpack('BB', payload[0:2])
267 if category != ACTION_CATEG_WNM or action != WNM_ACT_BSS_TM_RESP:
268 raise Exception("Not a BSS TM Response")
269 pos = payload[2:]
270 (dialog, status, bss_term_delay) = struct.unpack('BBB', pos[0:3])
271 resp['dialog'] = dialog
272 resp['status'] = status
273 resp['bss_term_delay'] = bss_term_delay
274 pos = pos[3:]
275 if len(pos) >= 6 and status == 0:
276 resp['target_bssid'] = binascii.hexlify(pos[0:6])
277 pos = pos[6:]
278 resp['candidates'] = pos
279 if expect_dialog is not None and dialog != expect_dialog:
280 raise Exception("Unexpected dialog token")
281 if expect_status is not None and status != expect_status:
282 raise Exception("Unexpected status code %d" % status)
283 return resp
284
285 def expect_ack(hapd):
286 ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
287 if ev is None:
288 raise Exception("Missing TX status")
289 if "ok=1" not in ev:
290 raise Exception("Action frame not acknowledged")
291
292 @remote_compatible
293 def test_wnm_bss_tm_req(dev, apdev):
294 """BSS Transition Management Request"""
295 params = { "ssid": "test-wnm", "bss_transition": "1" }
296 hapd = hostapd.add_ap(apdev[0], params)
297 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
298 hapd2 = hostapd.add_ap(apdev[1], params)
299
300 hapd.set("ext_mgmt_frame_handling", "1")
301
302 # truncated BSS TM Request
303 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
304 req_mode=0x08)
305 req['payload'] = struct.pack("<BBBBH",
306 ACTION_CATEG_WNM, WNM_ACT_BSS_TM_REQ,
307 1, 0, 0)
308 hapd.mgmt_tx(req)
309 expect_ack(hapd)
310
311 # no disassociation and no candidate list
312 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
313 dialog_token=2)
314 hapd.mgmt_tx(req)
315 resp = rx_bss_tm_resp(hapd, expect_dialog=2, expect_status=1)
316
317 # truncated BSS Termination Duration
318 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
319 req_mode=0x08)
320 hapd.mgmt_tx(req)
321 expect_ack(hapd)
322
323 # BSS Termination Duration with TSF=0 and Duration=10
324 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
325 req_mode=0x08, dialog_token=3)
326 req['payload'] += struct.pack("<BBQH", 4, 10, 0, 10)
327 hapd.mgmt_tx(req)
328 resp = rx_bss_tm_resp(hapd, expect_dialog=3, expect_status=1)
329
330 # truncated Session Information URL
331 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
332 req_mode=0x10)
333 hapd.mgmt_tx(req)
334 expect_ack(hapd)
335 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
336 req_mode=0x10)
337 req['payload'] += struct.pack("<BBB", 3, 65, 66)
338 hapd.mgmt_tx(req)
339 expect_ack(hapd)
340
341 # Session Information URL
342 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
343 req_mode=0x10, dialog_token=4)
344 req['payload'] += struct.pack("<BBB", 2, 65, 66)
345 hapd.mgmt_tx(req)
346 resp = rx_bss_tm_resp(hapd, expect_dialog=4, expect_status=0)
347
348 # Preferred Candidate List without any entries
349 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
350 req_mode=0x01, dialog_token=5)
351 hapd.mgmt_tx(req)
352 resp = rx_bss_tm_resp(hapd, expect_dialog=5, expect_status=7)
353
354 # Preferred Candidate List with a truncated entry
355 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
356 req_mode=0x01)
357 req['payload'] += struct.pack("<BB", 52, 1)
358 hapd.mgmt_tx(req)
359 expect_ack(hapd)
360
361 # Preferred Candidate List with a too short entry
362 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
363 req_mode=0x01, dialog_token=6)
364 req['payload'] += struct.pack("<BB", 52, 0)
365 hapd.mgmt_tx(req)
366 resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7)
367
368 # Preferred Candidate List with a non-matching entry
369 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
370 req_mode=0x01, dialog_token=6)
371 req['payload'] += struct.pack("<BB6BLBBB", 52, 13,
372 1, 2, 3, 4, 5, 6,
373 0, 81, 1, 7)
374 hapd.mgmt_tx(req)
375 resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7)
376
377 # Preferred Candidate List with a truncated subelement
378 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
379 req_mode=0x01, dialog_token=7)
380 req['payload'] += struct.pack("<BB6BLBBBBB", 52, 13 + 2,
381 1, 2, 3, 4, 5, 6,
382 0, 81, 1, 7,
383 1, 1)
384 hapd.mgmt_tx(req)
385 resp = rx_bss_tm_resp(hapd, expect_dialog=7, expect_status=7)
386
387 # Preferred Candidate List with lots of invalid optional subelements
388 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
389 req_mode=0x01, dialog_token=8)
390 subelems = struct.pack("<BBHB", 1, 3, 0, 100)
391 subelems += struct.pack("<BBB", 2, 1, 65)
392 subelems += struct.pack("<BB", 3, 0)
393 subelems += struct.pack("<BBQB", 4, 9, 0, 10)
394 subelems += struct.pack("<BBHLB", 5, 7, 0, 0, 0)
395 subelems += struct.pack("<BB", 66, 0)
396 subelems += struct.pack("<BBBBBB", 70, 4, 0, 0, 0, 0)
397 subelems += struct.pack("<BB", 71, 0)
398 req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems),
399 1, 2, 3, 4, 5, 6,
400 0, 81, 1, 7) + subelems
401 hapd.mgmt_tx(req)
402 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
403
404 # Preferred Candidate List with lots of valid optional subelements (twice)
405 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
406 req_mode=0x01, dialog_token=8)
407 # TSF Information
408 subelems = struct.pack("<BBHH", 1, 4, 0, 100)
409 # Condensed Country String
410 subelems += struct.pack("<BBBB", 2, 2, 65, 66)
411 # BSS Transition Candidate Preference
412 subelems += struct.pack("<BBB", 3, 1, 100)
413 # BSS Termination Duration
414 subelems += struct.pack("<BBQH", 4, 10, 0, 10)
415 # Bearing
416 subelems += struct.pack("<BBHLH", 5, 8, 0, 0, 0)
417 # Measurement Pilot Transmission
418 subelems += struct.pack("<BBBBB", 66, 3, 0, 0, 0)
419 # RM Enabled Capabilities
420 subelems += struct.pack("<BBBBBBB", 70, 5, 0, 0, 0, 0, 0)
421 # Multiple BSSID
422 subelems += struct.pack("<BBBB", 71, 2, 0, 0)
423 req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems) * 2,
424 1, 2, 3, 4, 5, 6,
425 0, 81, 1, 7) + subelems + subelems
426 hapd.mgmt_tx(req)
427 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
428
429 # Preferred Candidate List followed by vendor element
430 req = bss_tm_req(dev[0].p2p_interface_addr(), apdev[0]['bssid'],
431 req_mode=0x01, dialog_token=8)
432 subelems = ""
433 req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems),
434 1, 2, 3, 4, 5, 6,
435 0, 81, 1, 7) + subelems
436 req['payload'] += binascii.unhexlify("DD0411223344")
437 hapd.mgmt_tx(req)
438 resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
439
440 @remote_compatible
441 def test_wnm_bss_keep_alive(dev, apdev):
442 """WNM keep-alive"""
443 params = { "ssid": "test-wnm",
444 "ap_max_inactivity": "1" }
445 hapd = hostapd.add_ap(apdev[0], params)
446
447 addr = dev[0].p2p_interface_addr()
448 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
449 start = hapd.get_sta(addr)
450 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=2)
451 if ev is not None:
452 raise Exception("Unexpected disconnection")
453 end = hapd.get_sta(addr)
454 if int(end['rx_packets']) <= int(start['rx_packets']):
455 raise Exception("No keep-alive packets received")
456 try:
457 # Disable client keep-alive so that hostapd will verify connection
458 # with client poll
459 dev[0].request("SET no_keep_alive 1")
460 for i in range(60):
461 sta = hapd.get_sta(addr)
462 logger.info("timeout_next=%s rx_packets=%s tx_packets=%s" % (sta['timeout_next'], sta['rx_packets'], sta['tx_packets']))
463 if i > 1 and sta['timeout_next'] != "NULLFUNC POLL" and int(sta['tx_packets']) > int(end['tx_packets']):
464 break
465 ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
466 if ev is not None:
467 raise Exception("Unexpected disconnection (client poll expected)")
468 finally:
469 dev[0].request("SET no_keep_alive 0")
470 if int(sta['tx_packets']) <= int(end['tx_packets']):
471 raise Exception("No client poll packet seen")
472
473 def test_wnm_bss_tm(dev, apdev):
474 """WNM BSS Transition Management"""
475 try:
476 hapd = None
477 hapd2 = None
478 params = { "ssid": "test-wnm",
479 "country_code": "FI",
480 "ieee80211d": "1",
481 "hw_mode": "g",
482 "channel": "1",
483 "bss_transition": "1" }
484 hapd = hostapd.add_ap(apdev[0], params)
485
486 id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
487 dev[0].set_network(id, "scan_freq", "")
488
489 params = { "ssid": "test-wnm",
490 "country_code": "FI",
491 "ieee80211d": "1",
492 "hw_mode": "a",
493 "channel": "36",
494 "bss_transition": "1" }
495 hapd2 = hostapd.add_ap(apdev[1], params)
496
497 addr = dev[0].p2p_interface_addr()
498 dev[0].dump_monitor()
499
500 logger.info("No neighbor list entries")
501 if "OK" not in hapd.request("BSS_TM_REQ " + addr):
502 raise Exception("BSS_TM_REQ command failed")
503 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
504 if ev is None:
505 raise Exception("No BSS Transition Management Response")
506 if addr not in ev:
507 raise Exception("Unexpected BSS Transition Management Response address")
508 if "status_code=0" in ev:
509 raise Exception("BSS transition accepted unexpectedly")
510 dev[0].dump_monitor()
511
512 logger.info("Neighbor list entry, but not claimed as Preferred Candidate List")
513 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " neighbor=11:22:33:44:55:66,0x0000,81,3,7"):
514 raise Exception("BSS_TM_REQ command failed")
515 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
516 if ev is None:
517 raise Exception("No BSS Transition Management Response")
518 if "status_code=0" in ev:
519 raise Exception("BSS transition accepted unexpectedly")
520 dev[0].dump_monitor()
521
522 logger.info("Preferred Candidate List (no matching neighbor) without Disassociation Imminent")
523 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,36,7 neighbor=00:11:22:33:44:55,0x0000,81,4,7,03010a"):
524 raise Exception("BSS_TM_REQ command failed")
525 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
526 if ev is None:
527 raise Exception("No BSS Transition Management Response")
528 if "status_code=0" in ev:
529 raise Exception("BSS transition accepted unexpectedly")
530 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5)
531 if ev is None:
532 raise Exception("No scan started")
533 dev[0].dump_monitor()
534
535 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
536 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"):
537 raise Exception("BSS_TM_REQ command failed")
538 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
539 if ev is None:
540 raise Exception("No BSS Transition Management Response")
541 if "status_code=0" not in ev:
542 raise Exception("BSS transition request was not accepted: " + ev)
543 if "target_bssid=" + apdev[1]['bssid'] not in ev:
544 raise Exception("Unexpected target BSS: " + ev)
545 dev[0].wait_connected(timeout=15, error="No reassociation seen")
546 if apdev[1]['bssid'] not in ev:
547 raise Exception("Unexpected reassociation target: " + ev)
548 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
549 if ev is not None:
550 raise Exception("Unexpected scan started")
551 dev[0].dump_monitor()
552
553 logger.info("Preferred Candidate List with two matches, no roam needed")
554 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"):
555 raise Exception("BSS_TM_REQ command failed")
556 ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10)
557 if ev is None:
558 raise Exception("No BSS Transition Management Response")
559 if "status_code=0" not in ev:
560 raise Exception("BSS transition request was not accepted: " + ev)
561 if "target_bssid=" + apdev[1]['bssid'] not in ev:
562 raise Exception("Unexpected target BSS: " + ev)
563 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
564 if ev is not None:
565 raise Exception("Unexpected scan started")
566 ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5)
567 if ev is not None:
568 raise Exception("Unexpected reassociation");
569 finally:
570 dev[0].request("DISCONNECT")
571 if hapd:
572 hapd.request("DISABLE")
573 if hapd2:
574 hapd2.request("DISABLE")
575 subprocess.call(['iw', 'reg', 'set', '00'])
576 dev[0].flush_scan_cache()
577
578 def test_wnm_bss_tm_scan_not_needed(dev, apdev):
579 """WNM BSS Transition Management and scan not needed"""
580 run_wnm_bss_tm_scan_not_needed(dev, apdev)
581
582 def test_wnm_bss_tm_nei_vht(dev, apdev):
583 """WNM BSS Transition Management and VHT neighbor"""
584 run_wnm_bss_tm_scan_not_needed(dev, apdev, vht=True, nei_info="115,36,9")
585
586 def test_wnm_bss_tm_nei_11a(dev, apdev):
587 """WNM BSS Transition Management and 11a neighbor"""
588 run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, nei_info="115,36,4")
589
590 def test_wnm_bss_tm_nei_11g(dev, apdev):
591 """WNM BSS Transition Management and 11g neighbor"""
592 run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, hwmode='g',
593 channel='2', freq=2417, nei_info="81,2,6")
594
595 def test_wnm_bss_tm_nei_11b(dev, apdev):
596 """WNM BSS Transition Management and 11g neighbor"""
597 run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, hwmode='b',
598 channel='3', freq=2422, nei_info="81,2,5")
599
600 def run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=True, vht=False, hwmode='a',
601 channel='36', freq=5180,
602 nei_info="115,36,7,0301ff"):
603 try:
604 hapd = None
605 hapd2 = None
606 params = { "ssid": "test-wnm",
607 "country_code": "FI",
608 "ieee80211d": "1",
609 "hw_mode": "g",
610 "channel": "1",
611 "bss_transition": "1" }
612 hapd = hostapd.add_ap(apdev[0], params)
613
614 params = { "ssid": "test-wnm",
615 "country_code": "FI",
616 "ieee80211d": "1",
617 "hw_mode": hwmode,
618 "channel": channel,
619 "bss_transition": "1" }
620 if not ht:
621 params['ieee80211n'] = '0'
622 if vht:
623 params['ieee80211ac'] = "1"
624 params["vht_oper_chwidth"] = "0"
625 params["vht_oper_centr_freq_seg0_idx"] = "0"
626
627 hapd2 = hostapd.add_ap(apdev[1], params)
628
629 dev[0].scan_for_bss(apdev[1]['bssid'], freq)
630
631 id = dev[0].connect("test-wnm", key_mgmt="NONE",
632 bssid=apdev[0]['bssid'], scan_freq="2412")
633 dev[0].set_network(id, "scan_freq", "")
634 dev[0].set_network(id, "bssid", "")
635
636 addr = dev[0].own_addr()
637 dev[0].dump_monitor()
638
639 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
640 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000," + nei_info):
641 raise Exception("BSS_TM_REQ command failed")
642 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
643 if ev is None:
644 raise Exception("No BSS Transition Management Response")
645 if "status_code=0" not in ev:
646 raise Exception("BSS transition request was not accepted: " + ev)
647 if "target_bssid=" + apdev[1]['bssid'] not in ev:
648 raise Exception("Unexpected target BSS: " + ev)
649 dev[0].wait_connected(timeout=15, error="No reassociation seen")
650 if apdev[1]['bssid'] not in ev:
651 raise Exception("Unexpected reassociation target: " + ev)
652 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
653 if ev is not None:
654 raise Exception("Unexpected scan started")
655 dev[0].dump_monitor()
656 finally:
657 dev[0].request("DISCONNECT")
658 if hapd:
659 hapd.request("DISABLE")
660 if hapd2:
661 hapd2.request("DISABLE")
662 subprocess.call(['iw', 'reg', 'set', '00'])
663 dev[0].flush_scan_cache()
664
665 def test_wnm_bss_tm_scan_needed(dev, apdev):
666 """WNM BSS Transition Management and scan needed"""
667 try:
668 hapd = None
669 hapd2 = None
670 params = { "ssid": "test-wnm",
671 "country_code": "FI",
672 "ieee80211d": "1",
673 "hw_mode": "g",
674 "channel": "1",
675 "bss_transition": "1" }
676 hapd = hostapd.add_ap(apdev[0], params)
677
678 params = { "ssid": "test-wnm",
679 "country_code": "FI",
680 "ieee80211d": "1",
681 "hw_mode": "a",
682 "channel": "36",
683 "bss_transition": "1" }
684 hapd2 = hostapd.add_ap(apdev[1], params)
685
686 dev[0].scan_for_bss(apdev[1]['bssid'], 5180)
687
688 id = dev[0].connect("test-wnm", key_mgmt="NONE",
689 bssid=apdev[0]['bssid'], scan_freq="2412")
690 dev[0].set_network(id, "scan_freq", "")
691 dev[0].set_network(id, "bssid", "")
692
693 addr = dev[0].own_addr()
694 dev[0].dump_monitor()
695
696 logger.info("Wait 11 seconds for the last scan result to be too old, but still present in BSS table")
697 time.sleep(11)
698 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
699 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"):
700 raise Exception("BSS_TM_REQ command failed")
701 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
702 if ev is None:
703 raise Exception("No BSS Transition Management Response")
704 if "status_code=0" not in ev:
705 raise Exception("BSS transition request was not accepted: " + ev)
706 if "target_bssid=" + apdev[1]['bssid'] not in ev:
707 raise Exception("Unexpected target BSS: " + ev)
708 dev[0].wait_connected(timeout=15, error="No reassociation seen")
709 if apdev[1]['bssid'] not in ev:
710 raise Exception("Unexpected reassociation target: " + ev)
711 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
712 if ev is not None:
713 raise Exception("Unexpected scan started")
714 dev[0].dump_monitor()
715 finally:
716 dev[0].request("DISCONNECT")
717 if hapd:
718 hapd.request("DISABLE")
719 if hapd2:
720 hapd2.request("DISABLE")
721 subprocess.call(['iw', 'reg', 'set', '00'])
722 dev[0].flush_scan_cache()
723
724 def start_wnm_tm(ap, country, dev):
725 params = { "ssid": "test-wnm",
726 "country_code": country,
727 "ieee80211d": "1",
728 "hw_mode": "g",
729 "channel": "1",
730 "bss_transition": "1" }
731 hapd = hostapd.add_ap(ap, params)
732 id = dev.connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
733 dev.dump_monitor()
734 dev.set_network(id, "scan_freq", "")
735 return hapd, id
736
737 def stop_wnm_tm(hapd, dev):
738 dev.request("DISCONNECT")
739 try:
740 dev.wait_disconnected()
741 except:
742 pass
743 if hapd:
744 hapd.request("DISABLE")
745 subprocess.call(['iw', 'reg', 'set', '00'])
746 dev.flush_scan_cache()
747
748 def wnm_bss_tm_check(hapd, dev, data):
749 addr = dev.p2p_interface_addr()
750 if "OK" not in hapd.request("BSS_TM_REQ " + addr + " " + data):
751 raise Exception("BSS_TM_REQ command failed")
752 ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5)
753 if ev is None:
754 raise Exception("No scan started")
755 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
756 if ev is None:
757 raise Exception("Scan did not complete")
758
759 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
760 if ev is None:
761 raise Exception("No BSS Transition Management Response")
762 if "status_code=7" not in ev:
763 raise Exception("Unexpected response: " + ev)
764
765 def test_wnm_bss_tm_country_us(dev, apdev):
766 """WNM BSS Transition Management (US)"""
767 try:
768 hapd = None
769 hapd, id = start_wnm_tm(apdev[0], "US", dev[0])
770
771 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
772 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")
773
774 # Make the test take less time by limiting full scans
775 dev[0].set_network(id, "scan_freq", "2412")
776 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
777 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")
778
779 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
780 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")
781 finally:
782 stop_wnm_tm(hapd, dev[0])
783
784 def test_wnm_bss_tm_country_fi(dev, apdev):
785 """WNM BSS Transition Management (FI)"""
786 addr = dev[0].p2p_interface_addr()
787 try:
788 hapd = None
789 hapd, id = start_wnm_tm(apdev[0], "FI", dev[0])
790
791 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
792 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")
793
794 # Make the test take less time by limiting full scans
795 dev[0].set_network(id, "scan_freq", "2412")
796 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
797 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")
798
799 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
800 wnm_bss_tm_check(hapd, dev[0], "pref=1 neighbor=00:11:22:33:44:00,0x0000,0,0,7")
801 finally:
802 stop_wnm_tm(hapd, dev[0])
803
804 def test_wnm_bss_tm_country_jp(dev, apdev):
805 """WNM BSS Transition Management (JP)"""
806 addr = dev[0].p2p_interface_addr()
807 try:
808 hapd = None
809 hapd, id = start_wnm_tm(apdev[0], "JP", dev[0])
810
811 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
812 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")
813
814 # Make the test take less time by limiting full scans
815 dev[0].set_network(id, "scan_freq", "2412")
816 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
817 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")
818 finally:
819 stop_wnm_tm(hapd, dev[0])
820
821 def test_wnm_bss_tm_country_cn(dev, apdev):
822 """WNM BSS Transition Management (CN)"""
823 addr = dev[0].p2p_interface_addr()
824 try:
825 hapd = None
826 hapd, id = start_wnm_tm(apdev[0], "CN", dev[0])
827
828 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
829 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")
830
831 # Make the test take less time by limiting full scans
832 dev[0].set_network(id, "scan_freq", "2412")
833 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
834 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")
835 finally:
836 stop_wnm_tm(hapd, dev[0])
837
838 def test_wnm_bss_tm_global(dev, apdev):
839 """WNM BSS Transition Management (global)"""
840 addr = dev[0].p2p_interface_addr()
841 try:
842 hapd = None
843 hapd, id = start_wnm_tm(apdev[0], "XX", dev[0])
844
845 logger.info("Preferred Candidate List (no matching neighbor, known channels)")
846 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")
847
848 # Make the test take less time by limiting full scans
849 dev[0].set_network(id, "scan_freq", "2412")
850 logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
851 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")
852
853 logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
854 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")
855 finally:
856 stop_wnm_tm(hapd, dev[0])
857
858 def test_wnm_bss_tm_op_class_0(dev, apdev):
859 """WNM BSS Transition Management with invalid operating class"""
860 try:
861 hapd = None
862 hapd, id = start_wnm_tm(apdev[0], "US", dev[0])
863
864 logger.info("Preferred Candidate List (no matching neighbor, invalid op class specified for channels)")
865 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")
866 finally:
867 stop_wnm_tm(hapd, dev[0])
868
869 def test_wnm_action_proto(dev, apdev):
870 """WNM Action protocol testing"""
871 params = { "ssid": "test-wnm" }
872 params['wnm_sleep_mode'] = '1'
873 hapd = hostapd.add_ap(apdev[0], params)
874 bssid = apdev[0]['bssid']
875 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
876 dev[0].request("WNM_SLEEP enter")
877 time.sleep(0.1)
878 hapd.set("ext_mgmt_frame_handling", "1")
879
880 msg = {}
881 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
882 msg['da'] = dev[0].own_addr()
883 msg['sa'] = bssid
884 msg['bssid'] = bssid
885
886 dialog_token = 1
887
888 logger.debug("Unexpected WNM-Notification Response")
889 # Note: This is actually not registered for user space processing in
890 # driver_nl80211.c nl80211_mgmt_subscribe_non_ap() and as such, won't make
891 # it to wpa_supplicant.
892 msg['payload'] = struct.pack("<BBBB",
893 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_RESP,
894 dialog_token, 0)
895 hapd.mgmt_tx(msg)
896 expect_ack(hapd)
897
898 logger.debug("Truncated WNM-Notification Request (no Type field)")
899 msg['payload'] = struct.pack("<BBB",
900 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
901 dialog_token)
902 hapd.mgmt_tx(msg)
903 expect_ack(hapd)
904
905 logger.debug("WFA WNM-Notification Request with truncated IE (min)")
906 msg['payload'] = struct.pack("<BBBBBB",
907 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
908 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 1)
909 hapd.mgmt_tx(msg)
910 expect_ack(hapd)
911
912 logger.debug("WFA WNM-Notification Request with truncated IE (max)")
913 msg['payload'] = struct.pack("<BBBBBB",
914 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
915 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 255)
916 hapd.mgmt_tx(msg)
917 expect_ack(hapd)
918
919 logger.debug("WFA WNM-Notification Request with too short IE")
920 msg['payload'] = struct.pack("<BBBBBB",
921 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
922 dialog_token, WNM_NOTIF_TYPE_WFA, 0, 0)
923 hapd.mgmt_tx(msg)
924 expect_ack(hapd)
925
926 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL")
927 msg['payload'] = struct.pack(">BBBBBBLB",
928 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
929 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 5,
930 0x506f9a00, 1)
931 hapd.mgmt_tx(msg)
932 expect_ack(hapd)
933
934 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL(2)")
935 msg['payload'] = struct.pack(">BBBBBBLBB",
936 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
937 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 6,
938 0x506f9a00, 1, 0)
939 hapd.mgmt_tx(msg)
940 expect_ack(hapd)
941
942 logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL(3)")
943 msg['payload'] = struct.pack(">BBBBBBLB",
944 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
945 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 5,
946 0x506f9a00, 0xff)
947 hapd.mgmt_tx(msg)
948 expect_ack(hapd)
949
950 logger.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(min)")
951 msg['payload'] = struct.pack(">BBBBBBLBHB",
952 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
953 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 8,
954 0x506f9a01, 0, 0, 1)
955 hapd.mgmt_tx(msg)
956 expect_ack(hapd)
957
958 logger.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(max)")
959 msg['payload'] = struct.pack(">BBBBBBLBHB",
960 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
961 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 8,
962 0x506f9a01, 0, 0, 0xff)
963 hapd.mgmt_tx(msg)
964 expect_ack(hapd)
965
966 logger.debug("WFA WNM-Notification Request with unsupported IE")
967 msg['payload'] = struct.pack("<BBBBBBL",
968 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
969 dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 4, 0)
970 hapd.mgmt_tx(msg)
971 expect_ack(hapd)
972
973 logger.debug("WNM-Notification Request with unknown WNM-Notification type 0")
974 msg['payload'] = struct.pack("<BBBB",
975 ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
976 dialog_token, WNM_NOTIF_TYPE_FW_UPGRADE)
977 hapd.mgmt_tx(msg)
978 expect_ack(hapd)
979
980 logger.debug("Truncated WNM Sleep Mode Response - no Dialog Token")
981 msg['payload'] = struct.pack("<BB",
982 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP)
983 hapd.mgmt_tx(msg)
984 expect_ack(hapd)
985
986 logger.debug("Truncated WNM Sleep Mode Response - no Key Data Length")
987 msg['payload'] = struct.pack("<BBB",
988 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0)
989 hapd.mgmt_tx(msg)
990 expect_ack(hapd)
991
992 logger.debug("Truncated WNM Sleep Mode Response - truncated Key Data (min)")
993 msg['payload'] = struct.pack("<BBBH",
994 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
995 1)
996 hapd.mgmt_tx(msg)
997 expect_ack(hapd)
998
999 logger.debug("Truncated WNM Sleep Mode Response - truncated Key Data (max)")
1000 msg['payload'] = struct.pack("<BBBH",
1001 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1002 0xffff)
1003 hapd.mgmt_tx(msg)
1004 expect_ack(hapd)
1005
1006 logger.debug("WNM Sleep Mode Response - truncated IE header")
1007 msg['payload'] = struct.pack("<BBBHB",
1008 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1009 0, 0)
1010 hapd.mgmt_tx(msg)
1011 expect_ack(hapd)
1012
1013 logger.debug("WNM Sleep Mode Response - truncated IE")
1014 msg['payload'] = struct.pack("<BBBHBB",
1015 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1016 0, 0, 1)
1017 hapd.mgmt_tx(msg)
1018 expect_ack(hapd)
1019
1020 logger.debug("WNM Sleep Mode Response - Empty TFS Response")
1021 msg['payload'] = struct.pack("<BBBHBB",
1022 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1023 0, WLAN_EID_TFS_RESP, 0)
1024 hapd.mgmt_tx(msg)
1025 expect_ack(hapd)
1026
1027 logger.debug("WNM Sleep Mode Response - EID 0 not recognized")
1028 msg['payload'] = struct.pack("<BBBHBB",
1029 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1030 0, 0, 0)
1031 hapd.mgmt_tx(msg)
1032 expect_ack(hapd)
1033
1034 logger.debug("WNM Sleep Mode Response - Empty WNM Sleep Mode element and TFS Response element")
1035 msg['payload'] = struct.pack("<BBBHBBBB",
1036 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1037 0, WLAN_EID_WNMSLEEP, 0, WLAN_EID_TFS_RESP, 0)
1038 hapd.mgmt_tx(msg)
1039 expect_ack(hapd)
1040
1041 logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element and empty TFS Response element")
1042 msg['payload'] = struct.pack("<BBBHBBBBHBB",
1043 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1044 0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_ENTER,
1045 WNM_STATUS_SLEEP_ACCEPT, 0,
1046 WLAN_EID_TFS_RESP, 0)
1047 hapd.mgmt_tx(msg)
1048 expect_ack(hapd)
1049
1050 logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element(exit, deny key) and empty TFS Response element")
1051 msg['payload'] = struct.pack("<BBBHBBBBHBB",
1052 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1053 0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1054 WNM_STATUS_DENIED_KEY, 0,
1055 WLAN_EID_TFS_RESP, 0)
1056 hapd.mgmt_tx(msg)
1057 expect_ack(hapd)
1058
1059 logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element(enter, deny key) and empty TFS Response element")
1060 msg['payload'] = struct.pack("<BBBHBBBBHBB",
1061 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1062 0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_ENTER,
1063 WNM_STATUS_DENIED_KEY, 0,
1064 WLAN_EID_TFS_RESP, 0)
1065 hapd.mgmt_tx(msg)
1066 expect_ack(hapd)
1067
1068 @remote_compatible
1069 def test_wnm_action_proto_pmf(dev, apdev):
1070 """WNM Action protocol testing (PMF enabled)"""
1071 ssid = "test-wnm-pmf"
1072 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
1073 params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
1074 params["ieee80211w"] = "2"
1075 params['wnm_sleep_mode'] = '1'
1076 hapd = hostapd.add_ap(apdev[0], params)
1077 bssid = apdev[0]['bssid']
1078 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256",
1079 proto="WPA2", ieee80211w="2", scan_freq="2412")
1080 dev[0].request("WNM_SLEEP enter")
1081 time.sleep(0.1)
1082 hapd.set("ext_mgmt_frame_handling", "1")
1083
1084 msg = {}
1085 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1086 msg['da'] = dev[0].own_addr()
1087 msg['sa'] = bssid
1088 msg['bssid'] = bssid
1089
1090 logger.debug("WNM Sleep Mode Response - Invalid Key Data element length")
1091 keydata = struct.pack("<BB", 0, 1)
1092 msg['payload'] = struct.pack("<BBBH",
1093 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1094 len(keydata))
1095 msg['payload'] += keydata
1096 msg['payload'] += struct.pack("<BBBBHBB",
1097 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1098 WNM_STATUS_SLEEP_ACCEPT, 0,
1099 WLAN_EID_TFS_RESP, 0)
1100 hapd.mgmt_tx(msg)
1101 expect_ack(hapd)
1102
1103 logger.debug("WNM Sleep Mode Response - Too short GTK subelem")
1104 keydata = struct.pack("<BB", WNM_SLEEP_SUBELEM_GTK, 0)
1105 msg['payload'] = struct.pack("<BBBH",
1106 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1107 len(keydata))
1108 msg['payload'] += keydata
1109 msg['payload'] += struct.pack("<BBBBHBB",
1110 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1111 WNM_STATUS_SLEEP_ACCEPT, 0,
1112 WLAN_EID_TFS_RESP, 0)
1113 hapd.mgmt_tx(msg)
1114 expect_ack(hapd)
1115
1116 logger.debug("WNM Sleep Mode Response - Invalid GTK subelem")
1117 keydata = struct.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK, 11 + 16,
1118 0, 17, 0, 0, 0, 0, 0, 0)
1119 msg['payload'] = struct.pack("<BBBH",
1120 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1121 len(keydata))
1122 msg['payload'] += keydata
1123 msg['payload'] += struct.pack("<BBBBHBB",
1124 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1125 WNM_STATUS_SLEEP_ACCEPT, 0,
1126 WLAN_EID_TFS_RESP, 0)
1127 hapd.mgmt_tx(msg)
1128 expect_ack(hapd)
1129
1130 logger.debug("WNM Sleep Mode Response - Invalid GTK subelem (2)")
1131 keydata = struct.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK, 11 + 16,
1132 0, 0, 0, 0, 0, 0, 0, 0)
1133 msg['payload'] = struct.pack("<BBBH",
1134 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1135 len(keydata))
1136 msg['payload'] += keydata
1137 msg['payload'] += struct.pack("<BBBBHBB",
1138 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1139 WNM_STATUS_SLEEP_ACCEPT, 0,
1140 WLAN_EID_TFS_RESP, 0)
1141 hapd.mgmt_tx(msg)
1142 expect_ack(hapd)
1143
1144 logger.debug("WNM Sleep Mode Response - GTK subelem and too short IGTK subelem")
1145 keydata = struct.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 0, 16)
1146 keydata += struct.pack(">2L4L", 0x01020304, 0x05060708,
1147 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1148 keydata += struct.pack("<BB", WNM_SLEEP_SUBELEM_IGTK, 0)
1149 msg['payload'] = struct.pack("<BBBH",
1150 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1151 len(keydata))
1152 msg['payload'] += keydata
1153 msg['payload'] += struct.pack("<BBBBHBB",
1154 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1155 WNM_STATUS_SLEEP_ACCEPT, 0,
1156 WLAN_EID_TFS_RESP, 0)
1157 hapd.mgmt_tx(msg)
1158 expect_ack(hapd)
1159
1160 logger.debug("WNM Sleep Mode Response - Unknown subelem")
1161 keydata = struct.pack("<BB", 255, 0)
1162 msg['payload'] = struct.pack("<BBBH",
1163 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1164 len(keydata))
1165 msg['payload'] += keydata
1166 msg['payload'] += struct.pack("<BBBBHBB",
1167 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1168 WNM_STATUS_SLEEP_ACCEPT, 0,
1169 WLAN_EID_TFS_RESP, 0)
1170 hapd.mgmt_tx(msg)
1171 expect_ack(hapd)
1172
1173 @remote_compatible
1174 def test_wnm_action_proto_no_pmf(dev, apdev):
1175 """WNM Action protocol testing (PMF disabled)"""
1176 ssid = "test-wnm-no-pmf"
1177 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
1178 params['wnm_sleep_mode'] = '1'
1179 hapd = hostapd.add_ap(apdev[0], params)
1180 bssid = apdev[0]['bssid']
1181 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
1182 proto="WPA2", ieee80211w="0", scan_freq="2412")
1183 dev[0].request("WNM_SLEEP enter")
1184 time.sleep(0.1)
1185 hapd.set("ext_mgmt_frame_handling", "1")
1186
1187 msg = {}
1188 msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1189 msg['da'] = dev[0].own_addr()
1190 msg['sa'] = bssid
1191 msg['bssid'] = bssid
1192
1193 logger.debug("WNM Sleep Mode Response - GTK subelem and IGTK subelem")
1194 keydata = struct.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 0, 16)
1195 keydata += struct.pack(">2L4L", 0x01020304, 0x05060708,
1196 0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1197 keydata += struct.pack("<BBHLH4L", WNM_SLEEP_SUBELEM_IGTK, 2 + 6 + 16, 0,
1198 0x10203040, 0x5060,
1199 0xf1f2f3f4, 0xf5f6f7f8, 0xf9f0fafb, 0xfcfdfeff)
1200 msg['payload'] = struct.pack("<BBBH",
1201 ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1202 len(keydata))
1203 msg['payload'] += keydata
1204 msg['payload'] += struct.pack("<BBBBHBB",
1205 WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1206 WNM_STATUS_SLEEP_ACCEPT, 0,
1207 WLAN_EID_TFS_RESP, 0)
1208 hapd.mgmt_tx(msg)
1209 expect_ack(hapd)
1210
1211 ev = dev[0].wait_event(["WNM: Ignore Key Data"], timeout=5)
1212 if ev is None:
1213 raise Exception("Key Data not ignored")
1214
1215 def test_wnm_bss_tm_req_with_mbo_ie(dev, apdev):
1216 """WNM BSS transition request with MBO IE and reassociation delay attribute"""
1217 ssid = "test-wnm-mbo"
1218 params = hostapd.wpa2_params(ssid=ssid, passphrase="12345678")
1219 hapd = hostapd.add_ap(apdev[0], params)
1220 bssid = apdev[0]['bssid']
1221 if "OK" not in dev[0].request("SET mbo_cell_capa 1"):
1222 raise Exception("Failed to set STA as cellular data capable")
1223
1224 dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
1225 proto="WPA2", ieee80211w="0", scan_freq="2412")
1226
1227 logger.debug("BTM request with MBO reassociation delay when disassoc imminent is not set")
1228 if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=3:2:1"):
1229 raise Exception("BSS transition management succeeded unexpectedly")
1230
1231 logger.debug("BTM request with invalid MBO transition reason code")
1232 if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=10:2:1"):
1233 raise Exception("BSS transition management succeeded unexpectedly")
1234
1235 logger.debug("BTM request with MBO reassociation retry delay of 5 seconds")
1236 if 'OK' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " disassoc_imminent=1 disassoc_timer=3 mbo=3:5:1"):
1237 raise Exception("BSS transition management command failed")
1238
1239 ev = dev[0].wait_event(['MBO-CELL-PREFERENCE'], 1)
1240 if ev is None or "preference=1" not in ev:
1241 raise Exception("Timeout waiting for MBO-CELL-PREFERENCE event")
1242
1243 ev = dev[0].wait_event(['MBO-TRANSITION-REASON'], 1)
1244 if ev is None or "reason=3" not in ev:
1245 raise Exception("Timeout waiting for MBO-TRANSITION-REASON event")
1246
1247 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1248 if ev is None:
1249 raise Exception("No BSS Transition Management Response")
1250 if dev[0].own_addr() not in ev:
1251 raise Exception("Unexpected BSS Transition Management Response address")
1252
1253 ev = dev[0].wait_event(['CTRL-EVENT-DISCONNECTED'], 5)
1254 if ev is None:
1255 raise Exception("Station did not disconnect although disassoc imminent was set")
1256
1257 # Set the scan interval to make dev[0] look for connections
1258 if 'OK' not in dev[0].request("SCAN_INTERVAL 1"):
1259 raise Exception("Failed to set scan interval")
1260
1261 # Make sure no connection is made during the retry delay
1262 ev = dev[0].wait_event(['CTRL-EVENT-CONNECTED'], 5)
1263 if ev is not None:
1264 raise Exception("Station connected before assoc retry delay was over")
1265
1266 # After the assoc retry delay is over, we can reconnect
1267 ev = dev[0].wait_event(['CTRL-EVENT-CONNECTED'], 5)
1268 if ev is None:
1269 raise Exception("Station did not connect after assoc retry delay is over")
1270
1271 if "OK" not in dev[0].request("SET mbo_cell_capa 3"):
1272 raise Exception("Failed to set STA as cellular data not-capable")
1273
1274 @remote_compatible
1275 def test_wnm_bss_transition_mgmt_query(dev, apdev):
1276 """WNM BSS Transition Management query"""
1277 params = { "ssid": "test-wnm",
1278 "bss_transition": "1" }
1279 hapd = hostapd.add_ap(apdev[0], params)
1280 params = { "ssid": "another" }
1281 hapd2 = hostapd.add_ap(apdev[1], params)
1282
1283 dev[0].scan_for_bss(apdev[1]['bssid'], 2412)
1284 dev[0].scan_for_bss(apdev[0]['bssid'], 2412)
1285
1286 dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1287 dev[0].request("WNM_BSS_QUERY 0 list")
1288
1289 ev = dev[0].wait_event(["WNM: BSS Transition Management Request"],
1290 timeout=5)
1291 if ev is None:
1292 raise Exception("No BSS Transition Management Request frame seen")
1293
1294 ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5)
1295 if ev is None:
1296 raise Exception("No BSS Transition Management Response frame seen")
1297
1298 @remote_compatible
1299 def test_wnm_bss_tm_security_mismatch(dev, apdev):
1300 """WNM BSS Transition Management and security mismatch"""
1301 params = { "ssid": "test-wnm",
1302 "wpa": "2",
1303 "wpa_key_mgmt": "WPA-PSK",
1304 "rsn_pairwise": "CCMP",
1305 "wpa_passphrase": "12345678",
1306 "hw_mode": "g",
1307 "channel": "1",
1308 "bss_transition": "1" }
1309 hapd = hostapd.add_ap(apdev[0], params)
1310
1311 params = { "ssid": "test-wnm",
1312 "hw_mode": "g",
1313 "channel": "11",
1314 "bss_transition": "1" }
1315 hapd2 = hostapd.add_ap(apdev[1], params)
1316
1317 dev[0].scan_for_bss(apdev[1]['bssid'], 2462)
1318
1319 id = dev[0].connect("test-wnm", psk="12345678",
1320 bssid=apdev[0]['bssid'], scan_freq="2412")
1321 dev[0].set_network(id, "scan_freq", "")
1322 dev[0].set_network(id, "bssid", "")
1323
1324 addr = dev[0].own_addr()
1325 dev[0].dump_monitor()
1326
1327 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1328 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"):
1329 raise Exception("BSS_TM_REQ command failed")
1330 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1331 if ev is None:
1332 raise Exception("No BSS Transition Management Response")
1333 if "status_code=7" not in ev:
1334 raise Exception("Unexpected BSS transition request response: " + ev)
1335
1336 def test_wnm_bss_tm_connect_cmd(dev, apdev):
1337 """WNM BSS Transition Management and cfg80211 connect command"""
1338 params = { "ssid": "test-wnm",
1339 "hw_mode": "g",
1340 "channel": "1",
1341 "bss_transition": "1" }
1342 hapd = hostapd.add_ap(apdev[0], params)
1343
1344 params = { "ssid": "test-wnm",
1345 "hw_mode": "g",
1346 "channel": "11",
1347 "bss_transition": "1" }
1348 hapd2 = hostapd.add_ap(apdev[1], params)
1349
1350 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1351 wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
1352
1353 wpas.scan_for_bss(apdev[1]['bssid'], 2462)
1354
1355 id = wpas.connect("test-wnm", key_mgmt="NONE",
1356 bssid=apdev[0]['bssid'], scan_freq="2412")
1357 wpas.set_network(id, "scan_freq", "")
1358 wpas.set_network(id, "bssid", "")
1359
1360 addr = wpas.own_addr()
1361 wpas.dump_monitor()
1362
1363 logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1364 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"):
1365 raise Exception("BSS_TM_REQ command failed")
1366 ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1367 if ev is None:
1368 raise Exception("No BSS Transition Management Response")
1369 if "status_code=0" not in ev:
1370 raise Exception("BSS transition request was not accepted: " + ev)
1371 if "target_bssid=" + apdev[1]['bssid'] not in ev:
1372 raise Exception("Unexpected target BSS: " + ev)
1373 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED",
1374 "CTRL-EVENT-DISCONNECTED"], timeout=10)
1375 if ev is None:
1376 raise Exception("No reassociation seen")
1377 if "CTRL-EVENT-DISCONNECTED" in ev:
1378 #TODO: Uncomment this once kernel side changes for Connect command
1379 #reassociation are in upstream.
1380 #raise Exception("Unexpected disconnection reported")
1381 logger.info("Unexpected disconnection reported")
1382 ev = wpas.wait_event(["CTRL-EVENT-CONNECTED"], timeout=10)
1383 if ev is None:
1384 raise Exception("No reassociation seen")
1385 if apdev[1]['bssid'] not in ev:
1386 raise Exception("Unexpected reassociation target: " + ev)