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