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