1 # WNM tests
2 # Copyright (c) 2013-2019, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6 
7 from remotehost import remote_compatible
8 import binascii
9 import struct
10 import time
11 import logging
12 logger = logging.getLogger()
13 import subprocess
14 
15 import hostapd
16 from wpasupplicant import WpaSupplicant
17 from utils import *
18 from wlantest import Wlantest
19 from datetime import datetime
20 
21 def clear_regdom_state(dev, hapd, hapd2):
22     for i in range(0, 3):
23         ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
24         if ev is None or "init=COUNTRY_IE" in ev:
25             break
26     if hapd:
27         hapd.request("DISABLE")
28     if hapd2:
29         hapd2.request("DISABLE")
30     subprocess.call(['iw', 'reg', 'set', '00'])
31     dev[0].disconnect_and_stop_scan()
32     subprocess.call(['iw', 'reg', 'set', '00'])
33     dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
34     dev[0].flush_scan_cache()
35 
36 def start_wnm_ap(apdev, bss_transition=True, time_adv=False, ssid=None,
37                  wnm_sleep_mode=False, wnm_sleep_mode_no_keys=False, rsn=False,
38                  ocv=False, ap_max_inactivity=0, coloc_intf_reporting=False,
39                  hw_mode=None, channel=None, country_code=None, country3=None,
40                  pmf=True, passphrase=None, ht=True, vht=False, mbo=False,
41                  beacon_prot=False, he=False, bss_max_idle=None,
42                  wpa_group_rekey=None, no_disconnect_on_group_keyerror=False,
43                  max_acceptable_idle_period=None):
44     if rsn:
45         if not ssid:
46             ssid = "test-wnm-rsn"
47         if not passphrase:
48             passphrase = "12345678"
49         params = hostapd.wpa2_params(ssid, passphrase)
50         if pmf:
51             params["wpa_key_mgmt"] = "WPA-PSK-SHA256"
52             params["ieee80211w"] = "2"
53             if beacon_prot:
54                 params["beacon_prot"] = "1"
55     else:
56         params = {"ssid": "test-wnm"}
57     if bss_transition:
58         params["bss_transition"] = "1"
59     if time_adv:
60         params["time_advertisement"] = "2"
61         params["time_zone"] = "EST5"
62     if wnm_sleep_mode:
63         params["wnm_sleep_mode"] = "1"
64     if wnm_sleep_mode_no_keys:
65         params["wnm_sleep_mode_no_keys"] = "1"
66     if ocv:
67         params["ocv"] = "1"
68     if ap_max_inactivity:
69         params["ap_max_inactivity"] = str(ap_max_inactivity)
70     if coloc_intf_reporting:
71         params["coloc_intf_reporting"] = "1"
72     if hw_mode:
73         params["hw_mode"] = hw_mode
74     if channel:
75         params["channel"] = channel
76     if country_code:
77         params["country_code"] = country_code
78         params["ieee80211d"] = "1"
79     if country3:
80         params["country3"] = country3
81     if not ht:
82         params['ieee80211n'] = '0'
83     if vht:
84         params['ieee80211ac'] = "1"
85         params["vht_oper_chwidth"] = "0"
86         params["vht_oper_centr_freq_seg0_idx"] = "0"
87     if he:
88         params["ieee80211ax"] = "1"
89         params["he_bss_color"] = "42"
90     if mbo:
91         params["mbo"] = "1"
92     if bss_max_idle is not None:
93         params["bss_max_idle"] = str(bss_max_idle)
94     if wpa_group_rekey:
95         params["wpa_group_rekey"] = str(wpa_group_rekey)
96     if no_disconnect_on_group_keyerror:
97         params["no_disconnect_on_group_keyerror"] = "1"
98     if max_acceptable_idle_period is not None:
99         params["max_acceptable_idle_period"] = str(max_acceptable_idle_period)
100     try:
101         hapd = hostapd.add_ap(apdev, params)
102     except Exception as e:
103         if "Failed to set hostapd parameter ocv" in str(e):
104             raise HwsimSkip("OCV not supported")
105         raise
106     if rsn:
107         Wlantest.setup(hapd)
108         wt = Wlantest()
109         wt.flush()
110         wt.add_passphrase("12345678")
111     return hapd
112 
113 @remote_compatible
114 def test_wnm_bss_transition_mgmt(dev, apdev):
115     """WNM BSS Transition Management"""
116     start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True)
117     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
118     dev[0].request("WNM_BSS_QUERY 0")
119 
120 def test_wnm_bss_transition_mgmt_oom(dev, apdev):
121     """WNM BSS Transition Management OOM"""
122     hapd = start_wnm_ap(apdev[0])
123     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
124     with alloc_fail(hapd, 1, "ieee802_11_send_bss_trans_mgmt_request"):
125         dev[0].request("WNM_BSS_QUERY 0")
126         wait_fail_trigger(hapd, "GET_ALLOC_FAIL")
127 
128 @remote_compatible
129 def test_wnm_disassoc_imminent(dev, apdev):
130     """WNM Disassociation Imminent"""
131     hapd = start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True)
132     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
133     addr = dev[0].p2p_interface_addr()
134     hapd.request("DISASSOC_IMMINENT " + addr + " 10")
135     ev = dev[0].wait_event(["WNM: Disassociation Imminent"])
136     if ev is None:
137         raise Exception("Timeout while waiting for disassociation imminent")
138     if "Disassociation Timer 10" not in ev:
139         raise Exception("Unexpected disassociation imminent contents")
140     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
141     if ev is None:
142         raise Exception("Timeout while waiting for re-connection scan")
143 
144 def test_wnm_disassoc_imminent_bssid_set(dev, apdev):
145     """WNM Disassociation Imminent and bssid set"""
146     hapd = start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True)
147     hapd2 = start_wnm_ap(apdev[1], time_adv=True, wnm_sleep_mode=True)
148     dev[0].connect("test-wnm", key_mgmt="NONE", bssid=hapd.own_addr(),
149                    scan_freq="2412")
150     addr = dev[0].own_addr()
151     cmd = "BSS_TM_REQ " + addr + " pref=1 disassoc_imminent=1 disassoc_timer=100 neighbor=" + apdev[1]['bssid'] + ",0x0000," + "81,1,7,0301ff"
152     if "OK" not in hapd.request(cmd):
153         raise Exception("BSS_TM_REQ command failed")
154 
155     ev = dev[0].wait_event(["WNM: Disassociation Imminent"])
156     if ev is None:
157         raise Exception("Timeout while waiting for disassociation imminent")
158     if "Disassociation Timer 100" not in ev:
159         raise Exception("Unexpected disassociation imminent contents")
160 
161     ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
162     if ev is None:
163         raise Exception("No BSS Transition Management Response")
164     if "status_code=7" not in ev:
165         raise Exception("Unexpected BSS TM response status: " + ev)
166 
167     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=2)
168     if ev is not None:
169         raise Exception("Unexpected scan started")
170 
171     dev[0].request("DISCONNECT")
172     dev[0].wait_disconnected()
173 
174 def test_wnm_disassoc_imminent_fail(dev, apdev):
175     """WNM Disassociation Imminent failure"""
176     hapd = start_wnm_ap(apdev[0])
177     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
178     addr = dev[0].own_addr()
179     with fail_test(hapd, 1, "wnm_send_disassoc_imminent"):
180         if "FAIL" not in hapd.request("DISASSOC_IMMINENT " + addr + " 10"):
181             raise Exception("DISASSOC_IMMINENT succeeded during failure testing")
182 
183 @remote_compatible
184 def test_wnm_ess_disassoc_imminent(dev, apdev):
185     """WNM ESS Disassociation Imminent"""
186     hapd = start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True)
187     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
188     addr = dev[0].p2p_interface_addr()
189     hapd.request("ESS_DISASSOC " + addr + " 10 http://example.com/session-info")
190     ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"])
191     if ev is None:
192         raise Exception("Timeout while waiting for ESS disassociation imminent")
193     if "0 1024 http://example.com/session-info" not in ev:
194         raise Exception("Unexpected ESS disassociation imminent message contents")
195     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
196     if ev is None:
197         raise Exception("Timeout while waiting for re-connection scan")
198 
199 def test_wnm_ess_disassoc_imminent_fail(dev, apdev):
200     """WNM ESS Disassociation Imminent failure"""
201     hapd = start_wnm_ap(apdev[0])
202     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
203     addr = dev[0].own_addr()
204     if "FAIL" not in hapd.request("ESS_DISASSOC " + addr + " 10 http://" + 256*'a'):
205         raise Exception("Invalid ESS_DISASSOC URL accepted")
206     with fail_test(hapd, 1, "wnm_send_ess_disassoc_imminent"):
207         if "FAIL" not in hapd.request("ESS_DISASSOC " + addr + " 10 http://example.com/session-info"):
208             raise Exception("ESS_DISASSOC succeeded during failure testing")
209 
210 def test_wnm_ess_disassoc_imminent_reject(dev, apdev):
211     """WNM ESS Disassociation Imminent getting rejected"""
212     hapd = start_wnm_ap(apdev[0])
213     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
214     addr = dev[0].own_addr()
215     if "OK" not in dev[0].request("SET reject_btm_req_reason 123"):
216         raise Exception("Failed to set reject_btm_req_reason")
217 
218     hapd.request("ESS_DISASSOC " + addr + " 1 http://example.com/session-info")
219     ev = hapd.wait_event(["BSS-TM-RESP"], timeout=10)
220     if ev is None:
221         raise Exception("BSS-TM-RESP not seen")
222     if "status_code=123" not in ev:
223         raise Exception("Unexpected response status: " + ev)
224     dev[0].wait_disconnected()
225     dev[0].request("DISCONNECT")
226 
227 @remote_compatible
228 def test_wnm_ess_disassoc_imminent_pmf(dev, apdev):
229     """WNM ESS Disassociation Imminent"""
230     hapd = start_wnm_ap(apdev[0], rsn=True)
231     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
232                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
233     addr = dev[0].p2p_interface_addr()
234     hapd.wait_sta(wait_4way_hs=True)
235     hapd.request("ESS_DISASSOC " + addr + " 10 http://example.com/session-info")
236     ev = dev[0].wait_event(["ESS-DISASSOC-IMMINENT"])
237     if ev is None:
238         raise Exception("Timeout while waiting for ESS disassociation imminent")
239     if "1 1024 http://example.com/session-info" not in ev:
240         raise Exception("Unexpected ESS disassociation imminent message contents")
241     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
242     if ev is None:
243         raise Exception("Timeout while waiting for re-connection scan")
244 
245 def check_wnm_sleep_mode_enter_exit(hapd, dev, interval=None, tfs_req=None,
246                                     rekey=False):
247     addr = dev.p2p_interface_addr()
248     sta = hapd.get_sta(addr)
249     if "[WNM_SLEEP_MODE]" in sta['flags']:
250         raise Exception("Station unexpectedly in WNM-Sleep Mode")
251 
252     logger.info("Going to WNM Sleep Mode")
253     extra = ""
254     if interval is not None:
255         extra += " interval=" + str(interval)
256     if tfs_req:
257         extra += " tfs_req=" + tfs_req
258     if "OK" not in dev.request("WNM_SLEEP enter" + extra):
259         raise Exception("WNM_SLEEP failed")
260     ok = False
261     for i in range(20):
262         time.sleep(0.1)
263         sta = hapd.get_sta(addr)
264         if "[WNM_SLEEP_MODE]" in sta['flags']:
265             ok = True
266             break
267     if not ok:
268         raise Exception("Station failed to enter WNM-Sleep Mode")
269 
270     if rekey:
271         time.sleep(0.1)
272         if "OK" not in hapd.request("REKEY_GTK"):
273             raise Exception("REKEY_GTK failed")
274         ev = dev.wait_event(["RSN: Group rekeying completed"], timeout=0.1)
275         if ev is not None:
276                 raise Exception("Unexpected report of GTK rekey during WNM-Sleep Mode")
277 
278     logger.info("Waking up from WNM Sleep Mode")
279     ok = False
280     dev.request("WNM_SLEEP exit")
281     for i in range(20):
282         time.sleep(0.1)
283         sta = hapd.get_sta(addr)
284         if "[WNM_SLEEP_MODE]" not in sta['flags']:
285             ok = True
286             break
287     if not ok:
288         raise Exception("Station failed to exit WNM-Sleep Mode")
289 
290     if rekey:
291         time.sleep(0.1)
292         if "OK" not in hapd.request("REKEY_GTK"):
293             raise Exception("REKEY_GTK failed")
294         ev = dev.wait_event(["RSN: Group rekeying completed"], timeout=2)
295         if ev is None:
296                 raise Exception("GTK rekey timed out")
297 
298 @remote_compatible
299 def test_wnm_sleep_mode_open(dev, apdev):
300     """WNM Sleep Mode - open"""
301     hapd = start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True)
302     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
303     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
304     if ev is None:
305         raise Exception("No connection event received from hostapd")
306     check_wnm_sleep_mode_enter_exit(hapd, dev[0])
307     check_wnm_sleep_mode_enter_exit(hapd, dev[0], interval=100)
308     check_wnm_sleep_mode_enter_exit(hapd, dev[0], tfs_req="5b17010001130e110000071122334455661122334455661234")
309 
310     cmds = ["foo",
311             "exit tfs_req=123 interval=10",
312             "enter tfs_req=qq interval=10"]
313     for cmd in cmds:
314         if "FAIL" not in dev[0].request("WNM_SLEEP " + cmd):
315             raise Exception("Invalid WNM_SLEEP accepted")
316 
317 def test_wnm_sleep_mode_open_fail(dev, apdev):
318     """WNM Sleep Mode - open (fail)"""
319     hapd = start_wnm_ap(apdev[0], wnm_sleep_mode=True)
320     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
321     with fail_test(hapd, 1, "nl80211_send_frame_cmd;ieee802_11_send_wnmsleep_resp"):
322         dev[0].request("WNM_SLEEP enter")
323         wait_fail_trigger(hapd, "GET_FAIL")
324 
325 def test_wnm_sleep_mode_disabled_on_ap(dev, apdev):
326     """WNM Sleep Mode disabled on AP"""
327     hapd = start_wnm_ap(apdev[0], wnm_sleep_mode=False)
328     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
329     # Ignore WNM-Sleep Mode Request from 02:00:00:00:00:00 since WNM-Sleep Mode is disabled
330     dev[0].request("WNM_SLEEP enter")
331     time.sleep(0.1)
332 
333 @remote_compatible
334 def test_wnm_sleep_mode_rsn(dev, apdev):
335     """WNM Sleep Mode - RSN"""
336     hapd = start_wnm_ap(apdev[0], time_adv=True, wnm_sleep_mode=True, rsn=True,
337                         pmf=False)
338     dev[0].connect("test-wnm-rsn", psk="12345678", scan_freq="2412")
339     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
340     if ev is None:
341         raise Exception("No connection event received from hostapd")
342     check_wnm_sleep_mode_enter_exit(hapd, dev[0])
343 
344 @remote_compatible
345 def test_wnm_sleep_mode_ap_oom(dev, apdev):
346     """WNM Sleep Mode - AP side OOM"""
347     hapd = start_wnm_ap(apdev[0], bss_transition=False, wnm_sleep_mode=True)
348     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
349     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
350     if ev is None:
351         raise Exception("No connection event received from hostapd")
352     with alloc_fail(hapd, 1, "ieee802_11_send_wnmsleep_resp"):
353         dev[0].request("WNM_SLEEP enter")
354         wait_fail_trigger(hapd, "GET_ALLOC_FAIL")
355     with alloc_fail(hapd, 2, "ieee802_11_send_wnmsleep_resp"):
356         dev[0].request("WNM_SLEEP exit")
357         wait_fail_trigger(hapd, "GET_ALLOC_FAIL")
358 
359 @remote_compatible
360 def test_wnm_sleep_mode_rsn_pmf(dev, apdev):
361     """WNM Sleep Mode - RSN with PMF"""
362     hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, time_adv=True)
363     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
364                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
365     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
366     if ev is None:
367         raise Exception("No connection event received from hostapd")
368     check_wnm_sleep_mode_enter_exit(hapd, dev[0])
369 
370 def test_wnm_sleep_mode_rsn_beacon_prot(dev, apdev):
371     """WNM Sleep Mode - RSN with PMF and beacon protection"""
372     hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, time_adv=True,
373                         beacon_prot=True)
374     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
375                    beacon_prot="1",
376                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
377     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
378     if ev is None:
379         raise Exception("No connection event received from hostapd")
380     check_wnm_sleep_mode_enter_exit(hapd, dev[0])
381     check_wnm_sleep_mode_enter_exit(hapd, dev[0], rekey=True)
382 
383 @remote_compatible
384 def test_wnm_sleep_mode_rsn_ocv(dev, apdev):
385     """WNM Sleep Mode - RSN with OCV"""
386     hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True,
387                         time_adv=True, ocv=True)
388 
389     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", ocv="1",
390                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
391     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
392     if ev is None:
393         raise Exception("No connection event received from hostapd")
394     check_wnm_sleep_mode_enter_exit(hapd, dev[0])
395 
396     # Check if OCV succeeded or failed
397     ev = dev[0].wait_event(["OCV failed"], timeout=1)
398     if ev is not None:
399         raise Exception("OCI verification failed: " + ev)
400 
401 @remote_compatible
402 def test_wnm_sleep_mode_rsn_badocv(dev, apdev):
403     """WNM Sleep Mode - RSN with OCV and bad OCI elements"""
404     ssid = "test-wnm-rsn"
405     hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, ocv=True)
406     bssid = apdev[0]['bssid']
407     dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256", ocv="1",
408                    proto="WPA2", ieee80211w="2", scan_freq="2412")
409     dev[0].request("WNM_SLEEP enter")
410     time.sleep(0.1)
411 
412     msg = {'fc': MGMT_SUBTYPE_ACTION << 4,
413            'da': bssid,
414            'sa': dev[0].own_addr(),
415            'bssid': bssid}
416 
417     logger.debug("WNM Sleep Mode Request - Missing OCI element")
418     msg['payload'] = struct.pack("<BBBBBBBHBB",
419                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_REQ, 0,
420                                  WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 0, 0,
421                                  WLAN_EID_TFS_REQ, 0)
422     mgmt_tx(dev[0], "MGMT_TX {} {} freq=2412 wait_time=200 no_cck=1 action={}".format(
423         msg['da'], msg['bssid'], binascii.hexlify(msg['payload']).decode()))
424     ev = hapd.wait_event(["OCV failed"], timeout=5)
425     if ev is None:
426         raise Exception("AP did not report missing OCI element")
427 
428     logger.debug("WNM Sleep Mode Request - Bad OCI element")
429     msg['payload'] = struct.pack("<BBBBBBBHBB",
430                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_REQ, 0,
431                                  WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT, 0,
432                                  0,
433                                  WLAN_EID_TFS_REQ, 0)
434     oci_ie = struct.pack("<BBB", 81, 2, 0)
435     msg['payload'] += struct.pack("<BBB", WLAN_EID_EXTENSION, 1 + len(oci_ie),
436                                   WLAN_EID_EXT_OCV_OCI) + oci_ie
437     mgmt_tx(dev[0], "MGMT_TX {} {} freq=2412 wait_time=200 no_cck=1 action={}".format(
438         msg['da'], msg['bssid'], binascii.hexlify(msg['payload']).decode()))
439     ev = hapd.wait_event(["OCV failed"], timeout=5)
440     if ev is None:
441         raise Exception("AP did not report bad OCI element")
442 
443     msg = {'fc': MGMT_SUBTYPE_ACTION << 4,
444            'da': dev[0].own_addr(),
445            'sa': bssid,
446            'bssid': bssid}
447     hapd.set("ext_mgmt_frame_handling", "1")
448 
449     logger.debug("WNM Sleep Mode Response - Missing OCI element")
450     msg['payload'] = struct.pack("<BBBHBBBBHBB",
451                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
452                                  0,
453                                  WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
454                                  WNM_STATUS_SLEEP_ACCEPT, 0,
455                                  WLAN_EID_TFS_RESP, 0)
456     dev[0].request("WNM_SLEEP exit")
457     hapd.mgmt_tx(msg)
458     expect_ack(hapd)
459     ev = dev[0].wait_event(["OCV failed"], timeout=5)
460     if ev is None:
461         raise Exception("STA did not report missing OCI element")
462 
463     logger.debug("WNM Sleep Mode Response - Bad OCI element")
464     msg['payload'] = struct.pack("<BBBHBBBBHBB",
465                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
466                                  0,
467                                  WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
468                                  WNM_STATUS_SLEEP_ACCEPT, 0,
469                                  WLAN_EID_TFS_RESP, 0)
470     oci_ie = struct.pack("<BBB", 81, 2, 0)
471     msg['payload'] += struct.pack("<BBB", WLAN_EID_EXTENSION, 1 + len(oci_ie),
472                                   WLAN_EID_EXT_OCV_OCI) + oci_ie
473     hapd.mgmt_tx(msg)
474     expect_ack(hapd)
475     ev = dev[0].wait_event(["OCV failed"], timeout=5)
476     if ev is None:
477         raise Exception("STA did not report bad OCI element")
478 
479 def test_wnm_sleep_mode_rsn_ocv_failure(dev, apdev):
480     """WNM Sleep Mode - RSN with OCV - local failure"""
481     hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True,
482                         time_adv=True, ocv=True)
483 
484     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2", ocv="1",
485                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
486     hapd.wait_sta()
487     # Failed to allocate buffer for OCI element in WNM-Sleep Mode frame
488     with alloc_fail(hapd, 2, "ieee802_11_send_wnmsleep_resp"):
489             if "OK" not in dev[0].request("WNM_SLEEP enter"):
490                     raise Exception("WNM_SLEEP failed")
491             wait_fail_trigger(hapd, "GET_ALLOC_FAIL")
492 
493 def test_wnm_sleep_mode_rsn_pmf_key_workaround(dev, apdev):
494     """WNM Sleep Mode - RSN with PMF and GTK/IGTK workaround"""
495     hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True,
496                         wnm_sleep_mode_no_keys=True,
497                         time_adv=True, ocv=True)
498     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
499                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
500     ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=5)
501     if ev is None:
502         raise Exception("No connection event received from hostapd")
503     check_wnm_sleep_mode_enter_exit(hapd, dev[0])
504 
505 def test_wnm_sleep_mode_proto(dev, apdev):
506     """WNM Sleep Mode - protocol testing"""
507     hapd = start_wnm_ap(apdev[0], wnm_sleep_mode=True, bss_transition=False)
508     bssid = hapd.own_addr()
509     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
510     addr = dev[0].own_addr()
511 
512     hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000"
513     hapd.set("ext_mgmt_frame_handling", "1")
514     tests = ["0a10",
515              "0a1001",
516              "0a10015d00",
517              "0a10015d01",
518              "0a10015d0400000000",
519              "0a1001" + 7*("5bff" + 255*"00") + "5d00",
520              "0a1001ff00"]
521     for t in tests:
522         if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
523             raise Exception("MGMT_RX_PROCESS failed")
524 
525     hapd.set("ext_mgmt_frame_handling", "0")
526 
527 MGMT_SUBTYPE_ACTION = 13
528 ACTION_CATEG_WNM = 10
529 WNM_ACT_EVENT_REPORT = 1
530 WNM_ACT_BSS_TM_REQ = 7
531 WNM_ACT_BSS_TM_RESP = 8
532 WNM_ACT_SLEEP_MODE_REQ = 16
533 WNM_ACT_SLEEP_MODE_RESP = 17
534 WNM_ACT_NOTIFICATION_REQ = 26
535 WNM_ACT_NOTIFICATION_RESP = 27
536 WNM_NOTIF_TYPE_FW_UPGRADE = 0
537 WNM_NOTIF_TYPE_WFA = 1
538 WLAN_EID_EVENT_REPORT = 79
539 WLAN_EID_TFS_REQ = 91
540 WLAN_EID_TFS_RESP = 92
541 WLAN_EID_WNMSLEEP = 93
542 WLAN_EID_EXTENSION = 255
543 WLAN_EID_EXT_OCV_OCI = 54
544 WNM_SLEEP_MODE_ENTER = 0
545 WNM_SLEEP_MODE_EXIT = 1
546 WNM_STATUS_SLEEP_ACCEPT = 0
547 WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE = 1
548 WNM_STATUS_DENIED_ACTION = 2
549 WNM_STATUS_DENIED_TMP = 3
550 WNM_STATUS_DENIED_KEY = 4
551 WNM_STATUS_DENIED_OTHER_WNM_SERVICE = 5
552 WNM_SLEEP_SUBELEM_GTK = 0
553 WNM_SLEEP_SUBELEM_IGTK = 1
554 
555 def bss_tm_req(dst, src, dialog_token=1, req_mode=0, disassoc_timer=0,
556                validity_interval=1):
557     msg = {}
558     msg['fc'] = MGMT_SUBTYPE_ACTION << 4
559     msg['da'] = dst
560     msg['sa'] = src
561     msg['bssid'] = src
562     msg['payload'] = struct.pack("<BBBBHB",
563                                  ACTION_CATEG_WNM, WNM_ACT_BSS_TM_REQ,
564                                  dialog_token, req_mode, disassoc_timer,
565                                  validity_interval)
566     return msg
567 
568 def rx_bss_tm_resp(hapd, expect_dialog=None, expect_status=None):
569     for i in range(0, 100):
570         resp = hapd.mgmt_rx()
571         if resp is None:
572             raise Exception("No BSS TM Response received")
573         if resp['subtype'] == MGMT_SUBTYPE_ACTION:
574             break
575     if i == 99:
576         raise Exception("Not an Action frame")
577     payload = resp['payload']
578     if len(payload) < 2 + 3:
579         raise Exception("Too short payload")
580     (category, action) = struct.unpack('BB', payload[0:2])
581     if category != ACTION_CATEG_WNM or action != WNM_ACT_BSS_TM_RESP:
582         raise Exception("Not a BSS TM Response")
583     pos = payload[2:]
584     (dialog, status, bss_term_delay) = struct.unpack('BBB', pos[0:3])
585     resp['dialog'] = dialog
586     resp['status'] = status
587     resp['bss_term_delay'] = bss_term_delay
588     pos = pos[3:]
589     if len(pos) >= 6 and status == 0:
590         resp['target_bssid'] = binascii.hexlify(pos[0:6])
591         pos = pos[6:]
592     resp['candidates'] = pos
593     if expect_dialog is not None and dialog != expect_dialog:
594         raise Exception("Unexpected dialog token")
595     if expect_status is not None and status != expect_status:
596         raise Exception("Unexpected status code %d" % status)
597     return resp
598 
599 def expect_ack(hapd):
600     ev = hapd.wait_event(["MGMT-TX-STATUS"], timeout=5)
601     if ev is None:
602         raise Exception("Missing TX status")
603     if "ok=1" not in ev:
604         raise Exception("Action frame not acknowledged")
605 
606 def mgmt_tx(dev, msg):
607     if "FAIL" in dev.request(msg):
608         raise Exception("Failed to send Action frame")
609     ev = dev.wait_event(["MGMT-TX-STATUS"], timeout=10)
610     if ev is None:
611         raise Exception("Timeout on MGMT-TX-STATUS")
612     if "result=SUCCESS" not in ev:
613         raise Exception("Peer did not ack Action frame")
614 
615 @remote_compatible
616 def test_wnm_bss_tm_req(dev, apdev):
617     """BSS Transition Management Request"""
618     hapd = start_wnm_ap(apdev[0])
619     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
620     addr = dev[0].own_addr()
621 
622     hapd.set("ext_mgmt_frame_handling", "1")
623 
624     # truncated BSS TM Request
625     req = bss_tm_req(addr, apdev[0]['bssid'],
626                      req_mode=0x0a)
627     req['payload'] = struct.pack("<BBBBH",
628                                  ACTION_CATEG_WNM, WNM_ACT_BSS_TM_REQ,
629                                  1, 0, 0)
630     hapd.mgmt_tx(req)
631     expect_ack(hapd)
632     dev[0].dump_monitor()
633 
634     # no disassociation and no candidate list
635     req = bss_tm_req(addr, apdev[0]['bssid'],
636                      dialog_token=2, req_mode=0x02)
637     hapd.mgmt_tx(req)
638     resp = rx_bss_tm_resp(hapd, expect_dialog=2, expect_status=1)
639     dev[0].dump_monitor()
640 
641     # truncated BSS Termination Duration
642     req = bss_tm_req(addr, apdev[0]['bssid'],
643                      req_mode=0x0a)
644     hapd.mgmt_tx(req)
645     expect_ack(hapd)
646     dev[0].dump_monitor()
647 
648     # BSS Termination Duration with TSF=0 and Duration=10
649     req = bss_tm_req(addr, apdev[0]['bssid'],
650                      req_mode=0x0a, dialog_token=3)
651     req['payload'] += struct.pack("<BBQH", 4, 10, 0, 10)
652     hapd.mgmt_tx(req)
653     resp = rx_bss_tm_resp(hapd, expect_dialog=3, expect_status=1)
654     dev[0].dump_monitor()
655 
656     # truncated Session Information URL
657     req = bss_tm_req(addr, apdev[0]['bssid'],
658                      req_mode=0x12)
659     hapd.mgmt_tx(req)
660     expect_ack(hapd)
661     req = bss_tm_req(addr, apdev[0]['bssid'],
662                      req_mode=0x12)
663     req['payload'] += struct.pack("<BBB", 3, 65, 66)
664     hapd.mgmt_tx(req)
665     expect_ack(hapd)
666     dev[0].dump_monitor()
667 
668     # Session Information URL
669     req = bss_tm_req(addr, apdev[0]['bssid'],
670                      req_mode=0x12, dialog_token=4)
671     req['payload'] += struct.pack("<BBB", 2, 65, 66)
672     hapd.mgmt_tx(req)
673     resp = rx_bss_tm_resp(hapd, expect_dialog=4, expect_status=0)
674     dev[0].dump_monitor()
675 
676     # Preferred Candidate List without any entries
677     req = bss_tm_req(addr, apdev[0]['bssid'],
678                      req_mode=0x03, dialog_token=5)
679     hapd.mgmt_tx(req)
680     resp = rx_bss_tm_resp(hapd, expect_dialog=5, expect_status=7)
681     dev[0].dump_monitor()
682 
683     # Preferred Candidate List with a truncated entry
684     req = bss_tm_req(addr, apdev[0]['bssid'],
685                      req_mode=0x03)
686     req['payload'] += struct.pack("<BB", 52, 1)
687     hapd.mgmt_tx(req)
688     expect_ack(hapd)
689     dev[0].dump_monitor()
690 
691     # Preferred Candidate List with a too short entry
692     req = bss_tm_req(addr, apdev[0]['bssid'],
693                      req_mode=0x03, dialog_token=6)
694     req['payload'] += struct.pack("<BB", 52, 0)
695     hapd.mgmt_tx(req)
696     resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7)
697     dev[0].dump_monitor()
698 
699     # Preferred Candidate List with a non-matching entry
700     req = bss_tm_req(addr, apdev[0]['bssid'],
701                      req_mode=0x03, dialog_token=6)
702     req['payload'] += struct.pack("<BB6BLBBB", 52, 13,
703                                   1, 2, 3, 4, 5, 6,
704                                   0, 81, 1, 7)
705     hapd.mgmt_tx(req)
706     resp = rx_bss_tm_resp(hapd, expect_dialog=6, expect_status=7)
707     dev[0].dump_monitor()
708 
709     # Preferred Candidate List with a truncated subelement
710     req = bss_tm_req(addr, apdev[0]['bssid'],
711                      req_mode=0x03, dialog_token=7)
712     req['payload'] += struct.pack("<BB6BLBBBBB", 52, 13 + 2,
713                                   1, 2, 3, 4, 5, 6,
714                                   0, 81, 1, 7,
715                                   1, 1)
716     hapd.mgmt_tx(req)
717     resp = rx_bss_tm_resp(hapd, expect_dialog=7, expect_status=7)
718     dev[0].dump_monitor()
719 
720     # Preferred Candidate List with lots of invalid optional subelements
721     req = bss_tm_req(addr, apdev[0]['bssid'],
722                      req_mode=0x03, dialog_token=8)
723     subelems = struct.pack("<BBHB", 1, 3, 0, 100)
724     subelems += struct.pack("<BBB", 2, 1, 65)
725     subelems += struct.pack("<BB", 3, 0)
726     subelems += struct.pack("<BBQB", 4, 9, 0, 10)
727     subelems += struct.pack("<BBHLB", 5, 7, 0, 0, 0)
728     subelems += struct.pack("<BB", 66, 0)
729     subelems += struct.pack("<BBBBBB", 70, 4, 0, 0, 0, 0)
730     subelems += struct.pack("<BB", 71, 0)
731     req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems),
732                                   1, 2, 3, 4, 5, 6,
733                                   0, 81, 1, 7) + subelems
734     hapd.mgmt_tx(req)
735     resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
736     dev[0].dump_monitor()
737 
738     # Preferred Candidate List with lots of valid optional subelements (twice)
739     req = bss_tm_req(addr, apdev[0]['bssid'],
740                      req_mode=0x03, dialog_token=8)
741     # TSF Information
742     subelems = struct.pack("<BBHH", 1, 4, 0, 100)
743     # Condensed Country String
744     subelems += struct.pack("<BBBB", 2, 2, 65, 66)
745     # BSS Transition Candidate Preference
746     subelems += struct.pack("<BBB", 3, 1, 100)
747     # BSS Termination Duration
748     subelems += struct.pack("<BBQH", 4, 10, 0, 10)
749     # Bearing
750     subelems += struct.pack("<BBHLH", 5, 8, 0, 0, 0)
751     # Measurement Pilot Transmission
752     subelems += struct.pack("<BBBBB", 66, 3, 0, 0, 0)
753     # RM Enabled Capabilities
754     subelems += struct.pack("<BBBBBBB", 70, 5, 0, 0, 0, 0, 0)
755     # Multiple BSSID
756     subelems += struct.pack("<BBBB", 71, 2, 0, 0)
757     req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems) * 2,
758                                   1, 2, 3, 4, 5, 6,
759                                   0, 81, 1, 7) + subelems + subelems
760     hapd.mgmt_tx(req)
761     resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
762     dev[0].dump_monitor()
763 
764     # Preferred Candidate List with truncated BSS Termination Duration
765     # WNM: Too short BSS termination duration
766     req = bss_tm_req(addr, apdev[0]['bssid'],
767                      req_mode=0x03, dialog_token=8)
768     # BSS Termination Duration (truncated)
769     subelems = struct.pack("<BBQB", 4, 9, 0, 10)
770     req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems),
771                                   1, 2, 3, 4, 5, 6,
772                                   0, 81, 1, 7) + subelems
773     hapd.mgmt_tx(req)
774     resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
775     dev[0].dump_monitor()
776 
777     # Preferred Candidate List followed by vendor element
778     req = bss_tm_req(addr, apdev[0]['bssid'],
779                      req_mode=0x03, dialog_token=8)
780     subelems = b''
781     req['payload'] += struct.pack("<BB6BLBBB", 52, 13 + len(subelems),
782                                   1, 2, 3, 4, 5, 6,
783                                   0, 81, 1, 7) + subelems
784     req['payload'] += binascii.unhexlify("DD0411223344")
785     hapd.mgmt_tx(req)
786     resp = rx_bss_tm_resp(hapd, expect_dialog=8, expect_status=7)
787     dev[0].dump_monitor()
788 
789 @remote_compatible
790 @disable_ipv6
791 def test_wnm_bss_keep_alive(dev, apdev):
792     """WNM keep-alive"""
793     run_wnm_bss_keep_alive(dev, apdev, False)
794 
795 def test_wnm_bss_protected_keep_alive(dev, apdev):
796     """WNM protected keep-alive"""
797     run_wnm_bss_keep_alive(dev, apdev, True)
798 
799 def run_wnm_bss_keep_alive(dev, apdev, protected):
800     hapd = start_wnm_ap(apdev[0], bss_transition=False, ap_max_inactivity=1,
801                         bss_max_idle=2 if protected else 1, rsn=True)
802     addr = dev[0].p2p_interface_addr()
803     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
804                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
805     start = hapd.get_sta(addr)
806     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=2)
807     if ev is not None:
808         raise Exception("Unexpected disconnection")
809     end = hapd.get_sta(addr)
810     if int(end['rx_packets']) <= int(start['rx_packets']):
811         raise Exception("No keep-alive packets received")
812     try:
813         # Disable client keep-alive so that hostapd will verify connection
814         # with client poll
815         dev[0].request("SET no_keep_alive 1")
816         for i in range(60):
817             sta = hapd.get_sta(addr)
818             logger.info("timeout_next=%s rx_packets=%s tx_packets=%s" % (sta['timeout_next'], sta['rx_packets'], sta['tx_packets']))
819             if i > 1 and sta['timeout_next'] != "NULLFUNC POLL" and int(sta['tx_packets']) > int(end['tx_packets']):
820                 break
821             ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"], timeout=0.5)
822             if ev is not None:
823                 raise Exception("Unexpected disconnection (client poll expected)")
824     finally:
825         dev[0].request("SET no_keep_alive 0")
826     if int(sta['tx_packets']) <= int(end['tx_packets']):
827         raise Exception("No client poll packet seen")
828 
829 def test_wnm_bss_max_idle_period_management(dev, apdev):
830     """WNM BSS max idle period management"""
831     hapd = start_wnm_ap(apdev[0], bss_transition=False, ap_max_inactivity=10,
832                         max_acceptable_idle_period=1000, rsn=True)
833     addr = dev[0].own_addr()
834     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
835                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412",
836                    max_idle="1500")
837     addr1 = dev[1].own_addr()
838     dev[1].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
839                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
840 
841     ap_val = hapd.get_sta(addr)['max_idle_period']
842     if ap_val != '1000':
843         raise Exception("AP reported unexpected value: " + ap_val)
844 
845     sta_val = dev[0].get_status_field("bss_max_idle_period")
846     if sta_val != '1000':
847         raise Exception("STA reported unexpected value: " + sta_val)
848 
849     sta = hapd.get_sta(addr1)
850     if 'max_idle_period' in sta:
851         raise Exception("AP reported unexpected value(2): " + sta['max_idle_period'])
852 
853     sta_val = dev[1].get_status_field("bss_max_idle_period")
854     if sta_val != '9':
855         raise Exception("STA reported unexpected value(2): " + sta_val)
856 
857 def test_wnm_bss_group_rekey(dev, apdev):
858     """WNM BSS max idle period and group rekey"""
859     hapd = start_wnm_ap(apdev[0], bss_transition=False, ap_max_inactivity=100,
860                         wpa_group_rekey=2, rsn=True)
861     addr = dev[0].own_addr()
862     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
863                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
864     start = hapd.get_sta(addr)
865     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
866                             "RSN: Group rekeying completed"], timeout=3)
867     if ev is None:
868         raise Exception("No group rekeying")
869     if "CTRL-EVENT-DISCONNECTED" in ev:
870         raise Exception("Unexpected disconnection")
871 
872     hapd.set("ext_eapol_frame_io", "1")
873     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
874                             "RSN: Group rekeying completed"], timeout=20)
875     if ev is None or "CTRL-EVENT-DISCONNECTED" not in ev:
876         raise Exception("No disconnection reported on missing group rekeying")
877     dev[0].request("DISCONNECT")
878 
879 def test_wnm_bss_group_rekey_skip(dev, apdev):
880     """WNM BSS max idle period and group rekey skip allowed"""
881     hapd = start_wnm_ap(apdev[0], bss_transition=False, ap_max_inactivity=100,
882                         wpa_group_rekey=2, rsn=True,
883                         no_disconnect_on_group_keyerror=True)
884     addr = dev[0].own_addr()
885     dev[0].connect("test-wnm-rsn", psk="12345678", ieee80211w="2",
886                    key_mgmt="WPA-PSK-SHA256", proto="WPA2", scan_freq="2412")
887     start = hapd.get_sta(addr)
888     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
889                             "RSN: Group rekeying completed"], timeout=3)
890     if ev is None:
891         raise Exception("No group rekeying")
892     if "CTRL-EVENT-DISCONNECTED" in ev:
893         raise Exception("Unexpected disconnection")
894 
895     hapd.set("ext_eapol_frame_io", "1")
896     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED",
897                             "RSN: Group rekeying completed"], timeout=20)
898     if ev:
899         raise Exception("Unexpected event reported: " + ev)
900     dev[0].request("DISCONNECT")
901 
902 def test_wnm_bss_tm(dev, apdev):
903     """WNM BSS Transition Management"""
904     try:
905         hapd = None
906         hapd2 = None
907         hapd = start_wnm_ap(apdev[0], country_code="FI")
908         dev[0].flush_scan_cache()
909         id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
910         dev[0].set_network(id, "scan_freq", "")
911 
912         hapd2 = start_wnm_ap(apdev[1], country_code="FI", hw_mode="a",
913                              channel="36")
914 
915         addr = dev[0].p2p_interface_addr()
916         dev[0].dump_monitor()
917 
918         logger.info("No neighbor list entries")
919         if "OK" not in hapd.request("BSS_TM_REQ " + addr + " abridged=1"):
920             raise Exception("BSS_TM_REQ command failed")
921         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
922         if ev is None:
923             raise Exception("No BSS Transition Management Response")
924         if addr not in ev:
925             raise Exception("Unexpected BSS Transition Management Response address")
926         if "status_code=0" in ev:
927             raise Exception("BSS transition accepted unexpectedly")
928         dev[0].dump_monitor()
929 
930         logger.info("Neighbor list entry, but not claimed as Preferred Candidate List")
931         if "OK" not in hapd.request("BSS_TM_REQ " + addr + " abridged=1 dialog_token=123 neighbor=11:22:33:44:55:66,0x0000,81,3,7"):
932             raise Exception("BSS_TM_REQ command failed")
933         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
934         if ev is None:
935             raise Exception("No BSS Transition Management Response")
936         if "status_code=0" in ev:
937             raise Exception("BSS transition accepted unexpectedly")
938         dev[0].dump_monitor()
939 
940         logger.info("Preferred Candidate List (no matching neighbor) without Disassociation Imminent")
941         if "OK" not in hapd.request("BSS_TM_REQ " + addr + " abridged=1 pref=1 neighbor=11:22:33:44:55:66,0x0000,81,3,7,0301ff neighbor=22:33:44:55:66:77,0x0000,1,44,7 neighbor=00:11:22:33:44:55,0x0000,81,4,7,03010a"):
942             raise Exception("BSS_TM_REQ command failed")
943         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
944         if ev is None:
945             raise Exception("No BSS Transition Management Response")
946         if "status_code=0" in ev:
947             raise Exception("BSS transition accepted unexpectedly")
948         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5)
949         if ev is None:
950             raise Exception("No scan started")
951         dev[0].dump_monitor()
952 
953         logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
954         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"):
955             raise Exception("BSS_TM_REQ command failed")
956         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
957         if ev is None:
958             raise Exception("No BSS Transition Management Response")
959         if "status_code=0" not in ev:
960             raise Exception("BSS transition request was not accepted: " + ev)
961         if "target_bssid=" + apdev[1]['bssid'] not in ev:
962             raise Exception("Unexpected target BSS: " + ev)
963         dev[0].wait_connected(timeout=15, error="No reassociation seen")
964         if apdev[1]['bssid'] not in ev:
965             raise Exception("Unexpected reassociation target: " + ev)
966         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
967         if ev is not None:
968             raise Exception("Unexpected scan started")
969         dev[0].dump_monitor()
970 
971         logger.info("Preferred Candidate List with two matches, no roam needed")
972         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"):
973             raise Exception("BSS_TM_REQ command failed")
974         ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10)
975         if ev is None:
976             raise Exception("No BSS Transition Management Response")
977         if "status_code=0" not in ev:
978             raise Exception("BSS transition request was not accepted: " + ev)
979         if "target_bssid=" + apdev[1]['bssid'] not in ev:
980             raise Exception("Unexpected target BSS: " + ev)
981         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
982         if ev is not None:
983             raise Exception("Unexpected scan started")
984         ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5)
985         if ev is not None:
986             raise Exception("Unexpected reassociation")
987 
988         logger.info("Preferred Candidate List with two matches and extra frequency (160 MHz), no roam needed")
989         if "OK" not in hapd2.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[0]['bssid'] + ",0x0000,81,1,7,030101 neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff" + ' neighbor=00:11:22:33:44:55,0x0000,129,36,7'):
990             raise Exception("BSS_TM_REQ command failed")
991         ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10)
992         if ev is None:
993             raise Exception("No BSS Transition Management Response")
994         if "status_code=0" not in ev:
995             raise Exception("BSS transition request was not accepted: " + ev)
996         if "target_bssid=" + apdev[1]['bssid'] not in ev:
997             raise Exception("Unexpected target BSS: " + ev)
998         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
999         if ev is not None:
1000             raise Exception("Unexpected scan started")
1001         ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.5)
1002         if ev is not None:
1003             raise Exception("Unexpected reassociation")
1004 
1005         dev[0].flush_scan_cache()
1006         logger.info("Candidate list is used even if not required by spec (pref=0, abridged=0)")
1007         if "OK" not in hapd2.request("BSS_TM_REQ " + addr + " pref=0 abridged=0 valid_int=255 neighbor=" + apdev[0]['bssid'] + ",0x0000,81,1,7,0301ff" + ' neighbor=' + apdev[1]['bssid'] + ",0x0000,115,36,7,030100"):
1008             raise Exception("BSS_TM_REQ command failed")
1009         ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10)
1010         if ev is None:
1011             raise Exception("No BSS Transition Management Response")
1012         if "status_code=0" not in ev:
1013             raise Exception("BSS transition request was not accepted: " + ev)
1014         if "target_bssid=" + apdev[0]['bssid'] not in ev:
1015             raise Exception("Unexpected target BSS: " + ev)
1016         # This scans only one frequency
1017         scan_ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0)
1018         if scan_ev is None:
1019             raise Exception("Expected scan started")
1020         dev[0].wait_connected(timeout=15, error="No reassociation seen")
1021         if apdev[0]['bssid'] not in ev:
1022             raise Exception("Unexpected reassociation target: " + ev)
1023         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
1024         if ev is not None:
1025             raise Exception("Unexpected scan started")
1026 
1027     finally:
1028         clear_regdom_state(dev, hapd, hapd2)
1029 
1030 def test_wnm_bss_tm_drv_processing(dev, apdev):
1031     """WNM BSS Transition Management - driver processing of candidates"""
1032     try:
1033         hapd = None
1034         hapd2 = None
1035         hapd = start_wnm_ap(apdev[0], country_code="FI")
1036         dev[0].flush_scan_cache()
1037         id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1038         dev[0].set_network(id, "scan_freq", "")
1039 
1040         hapd2 = start_wnm_ap(apdev[1], country_code="FI", hw_mode="a",
1041                              channel="36")
1042 
1043         addr = dev[0].own_addr()
1044         dev[0].dump_monitor()
1045         # The following two tests exercise the MBO target querying to the driver
1046         dev[0].flush_scan_cache()
1047         logger.info("BTM request with candidate list and all are valid, roams because MBO is enabled and the driver rejects current")
1048         with fail_test(dev[0], 1, "simulate;nl80211_get_bss_transition_status",
1049                        1, apdev[0]['bssid'] + ";nl80211_get_bss_transition_status",
1050                        # Second time post-scan
1051                        1, "simulate;nl80211_get_bss_transition_status",
1052                        1, apdev[0]['bssid'] + ";nl80211_get_bss_transition_status"):
1053             if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 mbo=3:0:1 valid_int=255 neighbor=" + apdev[0]['bssid'] + ",0x0000,81,1,7,0301ff neighbor=" + apdev[1]['bssid'] + ",0x0000,115,36,7,0301ff"):
1054                 raise Exception("BSS_TM_REQ command failed")
1055             ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1056             if ev is None:
1057                 raise Exception("No BSS Transition Management Response")
1058         if "status_code=0" not in ev:
1059             raise Exception("BSS transition request was not accepted: " + ev)
1060         if "target_bssid=" + apdev[1]['bssid'] not in ev:
1061             raise Exception("Unexpected target BSS: " + ev)
1062         # This scans only one frequency
1063         scan_ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=1)
1064         if scan_ev is None:
1065             raise Exception("Expected scan not started")
1066         dev[0].wait_connected(timeout=15, error="No reassociation seen")
1067         if apdev[1]['bssid'] not in ev:
1068             raise Exception("Unexpected reassociation target: " + ev)
1069         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
1070         if ev is not None:
1071             raise Exception("Unexpected scan started")
1072 
1073         dev[0].flush_scan_cache()
1074         logger.info("BTM request with candidate list forcing other AP through disassoc imminent, the driver does MBO reject, but still roams")
1075         with fail_test(dev[0], 1, "simulate;nl80211_get_bss_transition_status",
1076                        1, apdev[0]['bssid'] + ";nl80211_get_bss_transition_status",
1077                        # And a second time post-scan
1078                        1, "simulate;nl80211_get_bss_transition_status",
1079                        1, apdev[0]['bssid'] + ";nl80211_get_bss_transition_status"):
1080             if "OK" not in hapd2.request("BSS_TM_REQ " + addr + " disassoc_imminent=1 pref=1 abridged=1 mbo=3:5:1 valid_int=255 neighbor=" + apdev[0]['bssid'] + ",0x0000,81,1,7,0301ff"):
1081                 raise Exception("BSS_TM_REQ command failed")
1082             ev = hapd2.wait_event(['BSS-TM-RESP'], timeout=10)
1083             if ev is None:
1084                 raise Exception("No BSS Transition Management Response")
1085         if "status_code=0" not in ev:
1086             raise Exception("BSS transition request was not accepted: " + ev)
1087         if "target_bssid=" + apdev[0]['bssid'] not in ev:
1088             raise Exception("Unexpected target BSS: " + ev)
1089         # This scans only one frequency
1090         scan_ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=1)
1091         if scan_ev is None:
1092             raise Exception("Expected scan not started")
1093         dev[0].wait_connected(timeout=15, error="No reassociation seen")
1094         if apdev[0]['bssid'] not in ev:
1095             raise Exception("Unexpected reassociation target: " + ev)
1096         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
1097         if ev is not None:
1098             raise Exception("Unexpected scan started")
1099 
1100     finally:
1101         clear_regdom_state(dev, hapd, hapd2)
1102 
1103 def test_wnm_bss_tm_steering_timeout(dev, apdev):
1104     """WNM BSS Transition Management and steering timeout"""
1105     hapd = start_wnm_ap(apdev[0])
1106     dev[0].flush_scan_cache()
1107     id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1108     hapd2 = start_wnm_ap(apdev[1])
1109     dev[0].scan_for_bss(apdev[1]['bssid'], 2412)
1110     hapd2.disable()
1111     addr = dev[0].own_addr()
1112     if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000,81,1,7,0301ff"):
1113         raise Exception("BSS_TM_REQ command failed")
1114     ev = hapd.wait_event(['BSS-TM-RESP'], timeout=5)
1115     if ev is None:
1116         raise Exception("No BSS Transition Management Response")
1117     if "status_code=0" not in ev:
1118         raise Exception("BSS transition request was not accepted: " + ev)
1119     # Wait for the ap_sta_reset_steer_flag_timer timeout to occur
1120     # "Reset steering flag for STA 02:00:00:00:00:00"
1121     time.sleep(2.1)
1122 
1123     ev = dev[0].wait_event(["Trying to authenticate"], timeout=5)
1124     if ev is None:
1125         raise Exception("No authentication attempt seen")
1126     if hapd2.own_addr() not in ev:
1127         raise Exception("Unexpected authentication target: " + ev)
1128     # Wait for return back to the previous AP
1129     dev[0].wait_connected()
1130 
1131 def test_wnm_bss_tm_errors(dev, apdev):
1132     """WNM BSS Transition Management errors"""
1133     hapd = start_wnm_ap(apdev[0])
1134     id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1135     addr = dev[0].own_addr()
1136 
1137     tests = ["BSS_TM_REQ q",
1138              "BSS_TM_REQ 22:22:22:22:22:22",
1139              "BSS_TM_REQ %s disassoc_timer=-1" % addr,
1140              "BSS_TM_REQ %s disassoc_timer=65536" % addr,
1141              "BSS_TM_REQ %s bss_term=foo" % addr,
1142              "BSS_TM_REQ %s neighbor=q" % addr,
1143              "BSS_TM_REQ %s neighbor=02:11:22:33:44:55" % addr,
1144              "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0" % addr,
1145              "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0" % addr,
1146              "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0" % addr,
1147              "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0,0,q" % addr,
1148              "BSS_TM_REQ %s neighbor=02:11:22:33:44:55,0,0,0,0,0q" % addr,
1149              "BSS_TM_REQ " + addr + " url=" + 256*'a',
1150              "BSS_TM_REQ %s url=foo mbo=1:2" % addr,
1151              "BSS_TM_REQ %s url=foo mbo=100000:0:0" % addr,
1152              "BSS_TM_REQ %s url=foo mbo=0:0:254" % addr,
1153              "BSS_TM_REQ %s url=foo mbo=0:100000:0" % addr]
1154     for t in tests:
1155         if "FAIL" not in hapd.request(t):
1156             raise Exception("Invalid command accepted: %s" % t)
1157 
1158     with alloc_fail(hapd, 1, "=hostapd_ctrl_iface_bss_tm_req"):
1159         if "FAIL" not in hapd.request("BSS_TM_REQ %s url=http://foo" % addr):
1160             raise Exception("BSS_TM_REQ accepted during OOM")
1161 
1162     with alloc_fail(hapd, 1, "=wnm_send_bss_tm_req"):
1163         if "FAIL" not in hapd.request("BSS_TM_REQ %s url=http://foo" % addr):
1164             raise Exception("BSS_TM_REQ accepted during OOM")
1165 
1166     with fail_test(hapd, 1, "wnm_send_bss_tm_req"):
1167         if "FAIL" not in hapd.request("BSS_TM_REQ %s url=http://foo" % addr):
1168             raise Exception("BSS_TM_REQ accepted during failure testing")
1169 
1170 def test_wnm_bss_tm_termination(dev, apdev):
1171     """WNM BSS Transition Management and BSS termination"""
1172     hapd = start_wnm_ap(apdev[0])
1173     id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1174     addr = dev[0].own_addr()
1175 
1176     if "OK" not in hapd.request("BSS_TM_REQ %s bss_term=0,1" % addr):
1177         raise Exception("BSS_TM_REQ failed")
1178     ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5)
1179     if ev is None:
1180         raise Exception("No BSS-TM-RESP event seen")
1181 
1182     if "OK" not in hapd.request("BSS_TM_REQ %s url=http://example.com/" % addr):
1183         raise Exception("BSS_TM_REQ failed")
1184     ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5)
1185     if ev is None:
1186         raise Exception("No BSS-TM-RESP event seen")
1187 
1188 def test_wnm_bss_tm_scan_not_needed(dev, apdev):
1189     """WNM BSS Transition Management and scan not needed"""
1190     run_wnm_bss_tm_scan_not_needed(dev, apdev)
1191 
1192 def test_wnm_bss_tm_nei_vht(dev, apdev):
1193     """WNM BSS Transition Management and VHT neighbor"""
1194     run_wnm_bss_tm_scan_not_needed(dev, apdev, vht=True, nei_info="115,36,9")
1195 
1196 def test_wnm_bss_tm_nei_11a(dev, apdev):
1197     """WNM BSS Transition Management and 11a neighbor"""
1198     run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, nei_info="115,36,4")
1199 
1200 def test_wnm_bss_tm_nei_11g(dev, apdev):
1201     """WNM BSS Transition Management and 11g neighbor"""
1202     run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, hwmode='g',
1203                                    channel='2', freq=2417, nei_info="81,2,6")
1204 
1205 def test_wnm_bss_tm_nei_11b(dev, apdev):
1206     """WNM BSS Transition Management and 11g neighbor"""
1207     run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=False, hwmode='b',
1208                                    channel='3', freq=2422, nei_info="81,2,5")
1209 
1210 def run_wnm_bss_tm_scan_not_needed(dev, apdev, ht=True, vht=False, hwmode='a',
1211                                    channel='36', freq=5180,
1212                                    nei_info="115,36,7,0301ff"):
1213     try:
1214         hapd = None
1215         hapd2 = None
1216         hapd = start_wnm_ap(apdev[0], country_code="FI", hw_mode="g",
1217                             channel="1")
1218         hapd2 = start_wnm_ap(apdev[1], country_code="FI", hw_mode=hwmode,
1219                              channel=channel, ht=ht, vht=vht)
1220         dev[0].scan_for_bss(apdev[1]['bssid'], freq)
1221 
1222         id = dev[0].connect("test-wnm", key_mgmt="NONE",
1223                             bssid=apdev[0]['bssid'], scan_freq="2412")
1224         dev[0].set_network(id, "scan_freq", "")
1225         dev[0].set_network(id, "bssid", "")
1226 
1227         addr = dev[0].own_addr()
1228         dev[0].dump_monitor()
1229 
1230         logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1231         if "OK" not in hapd.request("BSS_TM_REQ " + addr + " pref=1 abridged=1 valid_int=255 neighbor=" + apdev[1]['bssid'] + ",0x0000," + nei_info):
1232             raise Exception("BSS_TM_REQ command failed")
1233         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1234         if ev is None:
1235             raise Exception("No BSS Transition Management Response")
1236         if "status_code=0" not in ev:
1237             raise Exception("BSS transition request was not accepted: " + ev)
1238         if "target_bssid=" + apdev[1]['bssid'] not in ev:
1239             raise Exception("Unexpected target BSS: " + ev)
1240         dev[0].wait_connected(timeout=15, error="No reassociation seen")
1241         if apdev[1]['bssid'] not in ev:
1242             raise Exception("Unexpected reassociation target: " + ev)
1243         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
1244         if ev is not None:
1245             raise Exception("Unexpected scan started")
1246         dev[0].dump_monitor()
1247     finally:
1248         clear_regdom_state(dev, hapd, hapd2)
1249 
1250 def test_wnm_bss_tm_scan_needed(dev, apdev):
1251     """WNM BSS Transition Management and scan needed"""
1252     try:
1253         hapd = None
1254         hapd2 = None
1255         hapd = start_wnm_ap(apdev[0], country_code="FI", hw_mode="g",
1256                             channel="1")
1257         hapd2 = start_wnm_ap(apdev[1], country_code="FI", hw_mode="a",
1258                              channel="36")
1259 
1260         dev[0].flush_scan_cache()
1261         dev[0].scan_for_bss(apdev[1]['bssid'], 5180)
1262 
1263         id = dev[0].connect("test-wnm", key_mgmt="NONE",
1264                             bssid=apdev[0]['bssid'], scan_freq="2412")
1265         dev[0].set_network(id, "scan_freq", "")
1266         dev[0].set_network(id, "bssid", "")
1267 
1268         addr = dev[0].own_addr()
1269         dev[0].dump_monitor()
1270 
1271         logger.info("Wait 11 seconds for the last scan result to be too old, but still present in BSS table")
1272         time.sleep(11)
1273         logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1274         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"):
1275             raise Exception("BSS_TM_REQ command failed")
1276         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1277         if ev is None:
1278             raise Exception("No BSS Transition Management Response")
1279         if "status_code=0" not in ev:
1280             raise Exception("BSS transition request was not accepted: " + ev)
1281         if "target_bssid=" + apdev[1]['bssid'] not in ev:
1282             raise Exception("Unexpected target BSS: " + ev)
1283         dev[0].wait_connected(timeout=15, error="No reassociation seen")
1284         if apdev[1]['bssid'] not in ev:
1285             raise Exception("Unexpected reassociation target: " + ev)
1286         ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.1)
1287         if ev is not None:
1288             raise Exception("Unexpected scan started")
1289         dev[0].dump_monitor()
1290     finally:
1291         clear_regdom_state(dev, hapd, hapd2)
1292 
1293 def test_wnm_bss_tm_scan_needed_e4(dev, apdev):
1294     """WNM BSS Transition Management and scan needed (Table E-4)"""
1295     try:
1296         hapd = None
1297         hapd2 = None
1298         hapd = start_wnm_ap(apdev[0], country_code="FI", country3="0x04",
1299                             hw_mode="g", channel="1")
1300         hapd2 = start_wnm_ap(apdev[1], country_code="FI", country3="0x04",
1301                              hw_mode="a", channel="36")
1302         dev[0].flush_scan_cache()
1303         id = dev[0].connect("test-wnm", key_mgmt="NONE",
1304                             bssid=apdev[0]['bssid'], scan_freq="2412")
1305         dev[0].set_network(id, "scan_freq", "")
1306         dev[0].set_network(id, "bssid", "")
1307 
1308         addr = dev[0].own_addr()
1309         dev[0].dump_monitor()
1310 
1311         logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1312         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"):
1313             raise Exception("BSS_TM_REQ command failed")
1314         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=4)
1315         if ev is None:
1316             raise Exception("No BSS Transition Management Response seen quickly enough - did scan optimization fail?")
1317         if "status_code=0" not in ev:
1318             raise Exception("BSS transition request was not accepted: " + ev)
1319         dev[0].wait_connected(timeout=15, error="No reassociation seen")
1320         # Wait for regdom change due to country IE to avoid issues with that
1321         # processing happening only after the disconnection and cfg80211 ending
1322         # up intersecting regdoms when we try to clear state back to world (00)
1323         # regdom below.
1324         while True:
1325             ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
1326             if not ev or "COUNTRY_IE" in ev:
1327                 break
1328         dev[0].dump_monitor()
1329     finally:
1330         clear_regdom_state(dev, hapd, hapd2)
1331 
1332 def start_wnm_tm(ap, country, dev, country3=None):
1333     hapd = start_wnm_ap(ap, country_code=country, country3=country3)
1334     id = dev.connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1335     wait_regdom_changes(dev)
1336     dev.dump_monitor()
1337     dev.set_network(id, "scan_freq", "")
1338     return hapd, id
1339 
1340 def stop_wnm_tm(hapd, dev):
1341     if hapd:
1342         hapd.request("DISABLE")
1343         time.sleep(0.1)
1344     dev[0].disconnect_and_stop_scan()
1345     subprocess.call(['iw', 'reg', 'set', '00'])
1346     wait_regdom_changes(dev[0])
1347     country = dev[0].get_driver_status_field("country")
1348     logger.info("Country code at the end: " + country)
1349     if country != "00":
1350         clear_country(dev)
1351 
1352     dev[0].flush_scan_cache()
1353 
1354 def wnm_bss_tm_check(hapd, dev, data):
1355     addr = dev.p2p_interface_addr()
1356     if "OK" not in hapd.request("BSS_TM_REQ " + addr + " " + data):
1357         raise Exception("BSS_TM_REQ command failed")
1358     ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=5)
1359     if ev is None:
1360         raise Exception("No scan started")
1361     ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15)
1362     if ev is None:
1363         raise Exception("Scan did not complete")
1364 
1365     ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1366     if ev is None:
1367         raise Exception("No BSS Transition Management Response")
1368     if "status_code=7" not in ev:
1369         raise Exception("Unexpected response: " + ev)
1370 
1371 def test_wnm_bss_tm_country_us(dev, apdev):
1372     """WNM BSS Transition Management (US)"""
1373     try:
1374         hapd = None
1375         hapd, id = start_wnm_tm(apdev[0], "US", dev[0])
1376 
1377         logger.info("Preferred Candidate List (no matching neighbor, known channels)")
1378         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1379 
1380         # Make the test take less time by limiting full scans
1381         dev[0].set_network(id, "scan_freq", "2412")
1382         logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1383         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1384 
1385         logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1386         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1387     finally:
1388         stop_wnm_tm(hapd, dev)
1389 
1390 def test_wnm_bss_tm_country_fi(dev, apdev):
1391     """WNM BSS Transition Management (FI)"""
1392     addr = dev[0].p2p_interface_addr()
1393     try:
1394         hapd = None
1395         hapd, id = start_wnm_tm(apdev[0], "FI", dev[0])
1396 
1397         logger.info("Preferred Candidate List (no matching neighbor, known channels)")
1398         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1399 
1400         # Make the test take less time by limiting full scans
1401         dev[0].set_network(id, "scan_freq", "2412")
1402         logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1403         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1404 
1405         logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1406         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=00:11:22:33:44:00,0x0000,0,0,7")
1407     finally:
1408         stop_wnm_tm(hapd, dev)
1409 
1410 def test_wnm_bss_tm_country_jp(dev, apdev):
1411     """WNM BSS Transition Management (JP)"""
1412     addr = dev[0].p2p_interface_addr()
1413     try:
1414         hapd = None
1415         hapd, id = start_wnm_tm(apdev[0], "JP", dev[0])
1416 
1417         logger.info("Preferred Candidate List (no matching neighbor, known channels)")
1418         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1419 
1420         # Make the test take less time by limiting full scans
1421         dev[0].set_network(id, "scan_freq", "2412")
1422         logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1423         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1424     finally:
1425         stop_wnm_tm(hapd, dev)
1426 
1427 def test_wnm_bss_tm_country_cn(dev, apdev):
1428     """WNM BSS Transition Management (CN)"""
1429     addr = dev[0].p2p_interface_addr()
1430     try:
1431         hapd = None
1432         hapd, id = start_wnm_tm(apdev[0], "CN", dev[0])
1433 
1434         logger.info("Preferred Candidate List (no matching neighbor, known channels)")
1435         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1436 
1437         # Make the test take less time by limiting full scans
1438         dev[0].set_network(id, "scan_freq", "2412")
1439         logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1440         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1441     finally:
1442         stop_wnm_tm(hapd, dev)
1443 
1444 def test_wnm_bss_tm_global(dev, apdev):
1445     """WNM BSS Transition Management (global)"""
1446     run_wnm_bss_tm_global(dev, apdev, "XX", None)
1447 
1448 def test_wnm_bss_tm_global4(dev, apdev):
1449     """WNM BSS Transition Management (global; indicate table E-4)"""
1450     run_wnm_bss_tm_global(dev, apdev, "FI", "0x04")
1451 
1452 def run_wnm_bss_tm_global(dev, apdev, country, country3):
1453     addr = dev[0].p2p_interface_addr()
1454     try:
1455         hapd = None
1456         hapd, id = start_wnm_tm(apdev[0], country, dev[0], country3=country3)
1457 
1458         logger.info("Preferred Candidate List (no matching neighbor, known channels)")
1459         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1460 
1461         # Make the test take less time by limiting full scans
1462         dev[0].set_network(id, "scan_freq", "2412")
1463         logger.info("Preferred Candidate List (no matching neighbor, unknown channels)")
1464         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1465 
1466         logger.info("Preferred Candidate List (no matching neighbor, unknown channels 2)")
1467         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=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")
1468     finally:
1469         stop_wnm_tm(hapd, dev)
1470 
1471 def test_wnm_bss_tm_op_class_0(dev, apdev):
1472     """WNM BSS Transition Management with invalid operating class"""
1473     try:
1474         hapd = None
1475         hapd, id = start_wnm_tm(apdev[0], "US", dev[0])
1476 
1477         logger.info("Preferred Candidate List (no matching neighbor, invalid op class specified for channels)")
1478         wnm_bss_tm_check(hapd, dev[0], "pref=1 abridged=1 neighbor=00:11:22:33:44:59,0x0000,0,149,7 neighbor=00:11:22:33:44:5b,0x0000,0,1,7")
1479     finally:
1480         stop_wnm_tm(hapd, dev)
1481 
1482 def test_wnm_bss_tm_rsn(dev, apdev):
1483     """WNM BSS Transition Management with RSN"""
1484     passphrase = "zxcvbnm,.-"
1485     try:
1486         hapd = None
1487         hapd2 = None
1488         hapd = start_wnm_ap(apdev[0], country_code="FI", hw_mode="g",
1489                             channel="1",
1490                             rsn=True, pmf=False, passphrase=passphrase)
1491         hapd2 = start_wnm_ap(apdev[1], country_code="FI", hw_mode="a",
1492                              channel="36",
1493                              rsn=True, pmf=False, passphrase=passphrase)
1494         dev[0].scan_for_bss(apdev[1]['bssid'], 5180)
1495 
1496         id = dev[0].connect("test-wnm-rsn", psk=passphrase,
1497                             bssid=apdev[0]['bssid'], scan_freq="2412")
1498         dev[0].set_network(id, "scan_freq", "")
1499         dev[0].set_network(id, "bssid", "")
1500 
1501         addr = dev[0].own_addr()
1502         dev[0].dump_monitor()
1503 
1504         time.sleep(0.5)
1505         logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1506         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"):
1507             raise Exception("BSS_TM_REQ command failed")
1508         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1509         if ev is None:
1510             raise Exception("No BSS Transition Management Response")
1511         if "status_code=0" not in ev:
1512             raise Exception("BSS transition request was not accepted: " + ev)
1513         if "target_bssid=" + apdev[1]['bssid'] not in ev:
1514             raise Exception("Unexpected target BSS: " + ev)
1515         dev[0].wait_connected(timeout=15, error="No reassociation seen")
1516         if apdev[1]['bssid'] not in ev:
1517             raise Exception("Unexpected reassociation target: " + ev)
1518     finally:
1519         clear_regdom_state(dev, hapd, hapd2)
1520 
1521 def test_wnm_action_proto(dev, apdev):
1522     """WNM Action protocol testing"""
1523     hapd = start_wnm_ap(apdev[0], bss_transition=False, wnm_sleep_mode=True)
1524     bssid = apdev[0]['bssid']
1525     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1526     dev[0].request("WNM_SLEEP enter")
1527     time.sleep(0.1)
1528     hapd.set("ext_mgmt_frame_handling", "1")
1529 
1530     msg = {}
1531     msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1532     msg['da'] = dev[0].own_addr()
1533     msg['sa'] = bssid
1534     msg['bssid'] = bssid
1535 
1536     dialog_token = 1
1537 
1538     logger.debug("Unexpected WNM-Notification Response")
1539     # Note: This is actually not registered for user space processing in
1540     # driver_nl80211.c nl80211_mgmt_subscribe_non_ap() and as such, won't make
1541     # it to wpa_supplicant.
1542     msg['payload'] = struct.pack("<BBBB",
1543                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_RESP,
1544                                  dialog_token, 0)
1545     hapd.mgmt_tx(msg)
1546     expect_ack(hapd)
1547 
1548     logger.debug("Truncated WNM-Notification Request (no Type field)")
1549     msg['payload'] = struct.pack("<BBB",
1550                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1551                                  dialog_token)
1552     hapd.mgmt_tx(msg)
1553     expect_ack(hapd)
1554 
1555     logger.debug("WFA WNM-Notification Request with truncated IE (min)")
1556     msg['payload'] = struct.pack("<BBBBBB",
1557                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1558                                  dialog_token, WNM_NOTIF_TYPE_WFA, 0, 1)
1559     hapd.mgmt_tx(msg)
1560     expect_ack(hapd)
1561 
1562     logger.debug("WFA WNM-Notification Request with truncated IE (max)")
1563     msg['payload'] = struct.pack("<BBBBBB",
1564                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1565                                  dialog_token, WNM_NOTIF_TYPE_WFA, 0, 255)
1566     hapd.mgmt_tx(msg)
1567     expect_ack(hapd)
1568 
1569     logger.debug("WFA WNM-Notification Request with too short IE")
1570     msg['payload'] = struct.pack("<BBBBBB",
1571                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1572                                  dialog_token, WNM_NOTIF_TYPE_WFA, 0, 0)
1573     hapd.mgmt_tx(msg)
1574     expect_ack(hapd)
1575 
1576     logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL")
1577     msg['payload'] = struct.pack(">BBBBBBLB",
1578                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1579                                  dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 5,
1580                                  0x506f9a00, 1)
1581     hapd.mgmt_tx(msg)
1582     expect_ack(hapd)
1583 
1584     logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL(2)")
1585     msg['payload'] = struct.pack(">BBBBBBLBB",
1586                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1587                                  dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 6,
1588                                  0x506f9a00, 1, 0)
1589     hapd.mgmt_tx(msg)
1590     expect_ack(hapd)
1591 
1592     logger.debug("WFA WNM-Notification Request with truncated Sub Rem URL(3)")
1593     msg['payload'] = struct.pack(">BBBBBBLB",
1594                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1595                                  dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 5,
1596                                  0x506f9a00, 0xff)
1597     hapd.mgmt_tx(msg)
1598     expect_ack(hapd)
1599 
1600     logger.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(min)")
1601     msg['payload'] = struct.pack(">BBBBBBLBHB",
1602                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1603                                  dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 8,
1604                                  0x506f9a01, 0, 0, 1)
1605     hapd.mgmt_tx(msg)
1606     expect_ack(hapd)
1607 
1608     logger.debug("WFA WNM-Notification Request with truncated Deauth Imminent URL(max)")
1609     msg['payload'] = struct.pack(">BBBBBBLBHB",
1610                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1611                                  dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 8,
1612                                  0x506f9a01, 0, 0, 0xff)
1613     hapd.mgmt_tx(msg)
1614     expect_ack(hapd)
1615 
1616     logger.debug("WFA WNM-Notification Request with unsupported IE")
1617     msg['payload'] = struct.pack("<BBBBBBL",
1618                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1619                                  dialog_token, WNM_NOTIF_TYPE_WFA, 0xdd, 4, 0)
1620     hapd.mgmt_tx(msg)
1621     expect_ack(hapd)
1622 
1623     logger.debug("WNM-Notification Request with unknown WNM-Notification type 0")
1624     msg['payload'] = struct.pack("<BBBB",
1625                                  ACTION_CATEG_WNM, WNM_ACT_NOTIFICATION_REQ,
1626                                  dialog_token, WNM_NOTIF_TYPE_FW_UPGRADE)
1627     hapd.mgmt_tx(msg)
1628     expect_ack(hapd)
1629 
1630     logger.debug("Truncated WNM Sleep Mode Response - no Dialog Token")
1631     msg['payload'] = struct.pack("<BB",
1632                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP)
1633     hapd.mgmt_tx(msg)
1634     expect_ack(hapd)
1635 
1636     logger.debug("Truncated WNM Sleep Mode Response - no Key Data Length")
1637     msg['payload'] = struct.pack("<BBB",
1638                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0)
1639     hapd.mgmt_tx(msg)
1640     expect_ack(hapd)
1641 
1642     logger.debug("Truncated WNM Sleep Mode Response - truncated Key Data (min)")
1643     msg['payload'] = struct.pack("<BBBH",
1644                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1645                                  1)
1646     hapd.mgmt_tx(msg)
1647     expect_ack(hapd)
1648 
1649     logger.debug("Truncated WNM Sleep Mode Response - truncated Key Data (max)")
1650     msg['payload'] = struct.pack("<BBBH",
1651                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1652                                  0xffff)
1653     hapd.mgmt_tx(msg)
1654     expect_ack(hapd)
1655 
1656     logger.debug("WNM Sleep Mode Response - truncated IE header")
1657     msg['payload'] = struct.pack("<BBBHB",
1658                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1659                                  0, 0)
1660     hapd.mgmt_tx(msg)
1661     expect_ack(hapd)
1662 
1663     logger.debug("WNM Sleep Mode Response - truncated IE")
1664     msg['payload'] = struct.pack("<BBBHBB",
1665                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1666                                  0, 0, 1)
1667     hapd.mgmt_tx(msg)
1668     expect_ack(hapd)
1669 
1670     logger.debug("WNM Sleep Mode Response - Empty TFS Response")
1671     msg['payload'] = struct.pack("<BBBHBB",
1672                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1673                                  0, WLAN_EID_TFS_RESP, 0)
1674     hapd.mgmt_tx(msg)
1675     expect_ack(hapd)
1676 
1677     logger.debug("WNM Sleep Mode Response - EID 0 not recognized")
1678     msg['payload'] = struct.pack("<BBBHBB",
1679                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1680                                  0, 0, 0)
1681     hapd.mgmt_tx(msg)
1682     expect_ack(hapd)
1683 
1684     logger.debug("WNM Sleep Mode Response - Empty WNM Sleep Mode element and TFS Response element")
1685     msg['payload'] = struct.pack("<BBBHBBBB",
1686                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1687                                  0, WLAN_EID_WNMSLEEP, 0, WLAN_EID_TFS_RESP, 0)
1688     hapd.mgmt_tx(msg)
1689     expect_ack(hapd)
1690 
1691     logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element and empty TFS Response element")
1692     msg['payload'] = struct.pack("<BBBHBBBBHBB",
1693                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1694                                  0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_ENTER,
1695                                  WNM_STATUS_SLEEP_ACCEPT, 0,
1696                                  WLAN_EID_TFS_RESP, 0)
1697     hapd.mgmt_tx(msg)
1698     expect_ack(hapd)
1699 
1700     logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element(exit, deny key) and empty TFS Response element")
1701     msg['payload'] = struct.pack("<BBBHBBBBHBB",
1702                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1703                                  0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1704                                  WNM_STATUS_DENIED_KEY, 0,
1705                                  WLAN_EID_TFS_RESP, 0)
1706     hapd.mgmt_tx(msg)
1707     expect_ack(hapd)
1708 
1709     logger.debug("WNM Sleep Mode Response - WNM Sleep Mode element(enter, deny key) and empty TFS Response element")
1710     msg['payload'] = struct.pack("<BBBHBBBBHBB",
1711                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1712                                  0, WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_ENTER,
1713                                  WNM_STATUS_DENIED_KEY, 0,
1714                                  WLAN_EID_TFS_RESP, 0)
1715     hapd.mgmt_tx(msg)
1716     expect_ack(hapd)
1717 
1718 @remote_compatible
1719 def test_wnm_action_proto_pmf(dev, apdev):
1720     """WNM Action protocol testing (PMF enabled)"""
1721     ssid = "test-wnm-pmf"
1722     hapd = start_wnm_ap(apdev[0], rsn=True, wnm_sleep_mode=True, ssid=ssid)
1723     bssid = apdev[0]['bssid']
1724     dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256",
1725                    proto="WPA2", ieee80211w="2", scan_freq="2412")
1726     dev[0].request("WNM_SLEEP enter")
1727     time.sleep(0.1)
1728     hapd.set("ext_mgmt_frame_handling", "1")
1729 
1730     msg = {}
1731     msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1732     msg['da'] = dev[0].own_addr()
1733     msg['sa'] = bssid
1734     msg['bssid'] = bssid
1735 
1736     logger.debug("WNM Sleep Mode Response - Invalid Key Data element length")
1737     keydata = struct.pack("<BB", 0, 1)
1738     msg['payload'] = struct.pack("<BBBH",
1739                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1740                                  len(keydata))
1741     msg['payload'] += keydata
1742     msg['payload'] += struct.pack("<BBBBHBB",
1743                                   WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1744                                   WNM_STATUS_SLEEP_ACCEPT, 0,
1745                                   WLAN_EID_TFS_RESP, 0)
1746     hapd.mgmt_tx(msg)
1747     expect_ack(hapd)
1748 
1749     logger.debug("WNM Sleep Mode Response - Too short GTK subelem")
1750     keydata = struct.pack("<BB", WNM_SLEEP_SUBELEM_GTK, 0)
1751     msg['payload'] = struct.pack("<BBBH",
1752                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1753                                  len(keydata))
1754     msg['payload'] += keydata
1755     msg['payload'] += struct.pack("<BBBBHBB",
1756                                   WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1757                                   WNM_STATUS_SLEEP_ACCEPT, 0,
1758                                   WLAN_EID_TFS_RESP, 0)
1759     hapd.mgmt_tx(msg)
1760     expect_ack(hapd)
1761 
1762     logger.debug("WNM Sleep Mode Response - Invalid GTK subelem")
1763     keydata = struct.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK, 11 + 16,
1764                           0, 17, 0, 0, 0, 0, 0, 0)
1765     msg['payload'] = struct.pack("<BBBH",
1766                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1767                                  len(keydata))
1768     msg['payload'] += keydata
1769     msg['payload'] += struct.pack("<BBBBHBB",
1770                                   WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1771                                   WNM_STATUS_SLEEP_ACCEPT, 0,
1772                                   WLAN_EID_TFS_RESP, 0)
1773     hapd.mgmt_tx(msg)
1774     expect_ack(hapd)
1775 
1776     logger.debug("WNM Sleep Mode Response - Invalid GTK subelem (2)")
1777     keydata = struct.pack("<BBHB2L4L", WNM_SLEEP_SUBELEM_GTK, 11 + 16,
1778                           0, 0, 0, 0, 0, 0, 0, 0)
1779     msg['payload'] = struct.pack("<BBBH",
1780                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1781                                  len(keydata))
1782     msg['payload'] += keydata
1783     msg['payload'] += struct.pack("<BBBBHBB",
1784                                   WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1785                                   WNM_STATUS_SLEEP_ACCEPT, 0,
1786                                   WLAN_EID_TFS_RESP, 0)
1787     hapd.mgmt_tx(msg)
1788     expect_ack(hapd)
1789 
1790     logger.debug("WNM Sleep Mode Response - GTK subelem and too short IGTK subelem")
1791     keydata = struct.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 0, 16)
1792     keydata += struct.pack(">2L4L", 0x01020304, 0x05060708,
1793                            0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1794     keydata += struct.pack("<BB", WNM_SLEEP_SUBELEM_IGTK, 0)
1795     msg['payload'] = struct.pack("<BBBH",
1796                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1797                                  len(keydata))
1798     msg['payload'] += keydata
1799     msg['payload'] += struct.pack("<BBBBHBB",
1800                                   WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1801                                   WNM_STATUS_SLEEP_ACCEPT, 0,
1802                                   WLAN_EID_TFS_RESP, 0)
1803     hapd.mgmt_tx(msg)
1804     expect_ack(hapd)
1805 
1806     logger.debug("WNM Sleep Mode Response - Unknown subelem")
1807     keydata = struct.pack("<BB", 255, 0)
1808     msg['payload'] = struct.pack("<BBBH",
1809                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1810                                  len(keydata))
1811     msg['payload'] += keydata
1812     msg['payload'] += struct.pack("<BBBBHBB",
1813                                   WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1814                                   WNM_STATUS_SLEEP_ACCEPT, 0,
1815                                   WLAN_EID_TFS_RESP, 0)
1816     hapd.mgmt_tx(msg)
1817     expect_ack(hapd)
1818 
1819 @remote_compatible
1820 def test_wnm_action_proto_no_pmf(dev, apdev):
1821     """WNM Action protocol testing (PMF disabled)"""
1822     ssid = "test-wnm-no-pmf"
1823     hapd = start_wnm_ap(apdev[0], rsn=True, pmf=False, bss_transition=False,
1824                         wnm_sleep_mode=True, ssid=ssid)
1825     bssid = apdev[0]['bssid']
1826     dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
1827                    proto="WPA2", ieee80211w="0", scan_freq="2412")
1828     dev[0].request("WNM_SLEEP enter")
1829     time.sleep(0.1)
1830     hapd.set("ext_mgmt_frame_handling", "1")
1831     hapd.dump_monitor()
1832     dev[0].request("WNM_SLEEP exit")
1833     ev = hapd.wait_event(['MGMT-RX'], timeout=5)
1834     if ev is None:
1835         raise Exception("WNM-Sleep Mode Request not seen")
1836 
1837     msg = {}
1838     msg['fc'] = MGMT_SUBTYPE_ACTION << 4
1839     msg['da'] = dev[0].own_addr()
1840     msg['sa'] = bssid
1841     msg['bssid'] = bssid
1842 
1843     logger.debug("WNM Sleep Mode Response - GTK subelem and IGTK subelem")
1844     keydata = struct.pack("<BBHB", WNM_SLEEP_SUBELEM_GTK, 11 + 16, 0, 16)
1845     keydata += struct.pack(">2L4L", 0x01020304, 0x05060708,
1846                            0x11223344, 0x55667788, 0x9900aabb, 0xccddeeff)
1847     keydata += struct.pack("<BBHLH4L", WNM_SLEEP_SUBELEM_IGTK, 2 + 6 + 16, 0,
1848                            0x10203040, 0x5060,
1849                            0xf1f2f3f4, 0xf5f6f7f8, 0xf9f0fafb, 0xfcfdfeff)
1850     msg['payload'] = struct.pack("<BBBH",
1851                                  ACTION_CATEG_WNM, WNM_ACT_SLEEP_MODE_RESP, 0,
1852                                  len(keydata))
1853     msg['payload'] += keydata
1854     msg['payload'] += struct.pack("<BBBBHBB",
1855                                   WLAN_EID_WNMSLEEP, 4, WNM_SLEEP_MODE_EXIT,
1856                                   WNM_STATUS_SLEEP_ACCEPT, 0,
1857                                   WLAN_EID_TFS_RESP, 0)
1858     hapd.mgmt_tx(msg)
1859     expect_ack(hapd)
1860 
1861     ev = dev[0].wait_event(["WNM: Ignore Key Data"], timeout=5)
1862     if ev is None:
1863         raise Exception("Key Data not ignored")
1864 
1865 def test_wnm_bss_tm_req_with_mbo_ie(dev, apdev):
1866     """WNM BSS transition request with MBO IE and reassociation delay attribute"""
1867     ssid = "test-wnm-mbo"
1868     hapd = start_wnm_ap(apdev[0], rsn=True, pmf=False, ssid=ssid)
1869     bssid = apdev[0]['bssid']
1870     if "OK" not in dev[0].request("SET mbo_cell_capa 1"):
1871         raise Exception("Failed to set STA as cellular data capable")
1872 
1873     dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK",
1874                    proto="WPA2", ieee80211w="0", scan_freq="2412")
1875 
1876     logger.debug("BTM request with MBO reassociation delay when disassoc imminent is not set")
1877     if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=3:2:1"):
1878         raise Exception("BSS transition management succeeded unexpectedly")
1879 
1880     logger.debug("BTM request with invalid MBO transition reason code")
1881     if 'FAIL' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " mbo=10:2:1"):
1882         raise Exception("BSS transition management succeeded unexpectedly")
1883 
1884     logger.debug("BTM request with MBO reassociation retry delay of 5 seconds")
1885     if 'OK' not in hapd.request("BSS_TM_REQ " + dev[0].own_addr() + " disassoc_imminent=1 disassoc_timer=3 mbo=3:5:1"):
1886         raise Exception("BSS transition management command failed")
1887 
1888     ev = dev[0].wait_event(['MBO-CELL-PREFERENCE'], 1)
1889     if ev is None or "preference=1" not in ev:
1890         raise Exception("Timeout waiting for MBO-CELL-PREFERENCE event")
1891 
1892     ev = dev[0].wait_event(['MBO-TRANSITION-REASON'], 1)
1893     if ev is None or "reason=3" not in ev:
1894         raise Exception("Timeout waiting for MBO-TRANSITION-REASON event")
1895 
1896     t0 = datetime.now()
1897 
1898     ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1899     if ev is None:
1900         raise Exception("No BSS Transition Management Response")
1901     if dev[0].own_addr() not in ev:
1902         raise Exception("Unexpected BSS Transition Management Response address")
1903 
1904     ev = dev[0].wait_event(['CTRL-EVENT-DISCONNECTED'], 5)
1905     if ev is None:
1906         raise Exception("Station did not disconnect although disassoc imminent was set")
1907 
1908     # Set the scan interval to make dev[0] look for connections
1909     if 'OK' not in dev[0].request("SCAN_INTERVAL 1"):
1910         raise Exception("Failed to set scan interval")
1911 
1912     # Wait until connected
1913     ev = dev[0].wait_event(['CTRL-EVENT-CONNECTED'], 10)
1914     if ev is None:
1915         raise Exception("Station did not connect")
1916 
1917     # Make sure no connection is made during the retry delay
1918     time_diff = datetime.now() - t0
1919     if time_diff.total_seconds() < 5:
1920         raise Exception("Station connected before assoc retry delay was over")
1921 
1922     if "OK" not in dev[0].request("SET mbo_cell_capa 3"):
1923         raise Exception("Failed to set STA as cellular data not-capable")
1924 
1925 @remote_compatible
1926 def test_wnm_bss_transition_mgmt_query(dev, apdev):
1927     """WNM BSS Transition Management query"""
1928     hapd = start_wnm_ap(apdev[0])
1929     params = {"ssid": "another"}
1930     hapd2 = hostapd.add_ap(apdev[1], params)
1931 
1932     dev[0].scan_for_bss(apdev[1]['bssid'], 2412)
1933     dev[0].scan_for_bss(apdev[0]['bssid'], 2412)
1934 
1935     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1936     dev[0].request("WNM_BSS_QUERY 0 list")
1937 
1938     ev = dev[0].wait_event(["WNM: BSS Transition Management Request"],
1939                            timeout=5)
1940     if ev is None:
1941         raise Exception("No BSS Transition Management Request frame seen")
1942 
1943     ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5)
1944     if ev is None:
1945         raise Exception("No BSS Transition Management Response frame seen")
1946 
1947 def test_wnm_bss_transition_mgmt_query_disabled_on_ap(dev, apdev):
1948     """WNM BSS Transition Management query - TM disabled on AP"""
1949     hapd = start_wnm_ap(apdev[0], bss_transition=False)
1950     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1951     # Ignore BSS Transition Management Query from 02:00:00:00:00:00 since BSS Transition Management is disabled
1952     dev[0].request("WNM_BSS_QUERY 0 list")
1953     ev = hapd.wait_event(["BSS-TM-RESP"], timeout=0.1)
1954     if ev is not None:
1955         raise Exception("Unexpected BSS TM Response reported")
1956 
1957 def test_wnm_bss_transition_mgmt_query_mbo(dev, apdev):
1958     """WNM BSS Transition Management query - TM only due to MBO on AP"""
1959     hapd = start_wnm_ap(apdev[0], bss_transition=False, mbo=True)
1960     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
1961     dev[0].request("WNM_BSS_QUERY 0 list")
1962     ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5)
1963     if ev is None:
1964         raise Exception("No BSS TM Response reported")
1965 
1966 @remote_compatible
1967 def test_wnm_bss_tm_security_mismatch(dev, apdev):
1968     """WNM BSS Transition Management and security mismatch"""
1969     hapd = start_wnm_ap(apdev[0], hw_mode="g", channel="1", ssid="test-wnm",
1970                         rsn=True, pmf=False)
1971     hapd2 = start_wnm_ap(apdev[1], hw_mode="g", channel="11")
1972     dev[0].scan_for_bss(apdev[1]['bssid'], 2462)
1973 
1974     id = dev[0].connect("test-wnm", psk="12345678",
1975                         bssid=apdev[0]['bssid'], scan_freq="2412")
1976     dev[0].set_network(id, "scan_freq", "")
1977     dev[0].set_network(id, "bssid", "")
1978 
1979     addr = dev[0].own_addr()
1980     dev[0].dump_monitor()
1981 
1982     logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
1983     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"):
1984         raise Exception("BSS_TM_REQ command failed")
1985     ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
1986     if ev is None:
1987         raise Exception("No BSS Transition Management Response")
1988     if "status_code=7" not in ev:
1989         raise Exception("Unexpected BSS transition request response: " + ev)
1990 
1991 def test_wnm_bss_tm_connect_cmd(dev, apdev):
1992     """WNM BSS Transition Management and cfg80211 connect command"""
1993     hapd = start_wnm_ap(apdev[0], hw_mode="g", channel="1")
1994     hapd2 = start_wnm_ap(apdev[1], hw_mode="g", channel="11")
1995 
1996     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1997     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
1998 
1999     wpas.scan_for_bss(apdev[1]['bssid'], 2462)
2000 
2001     id = wpas.connect("test-wnm", key_mgmt="NONE",
2002                       bssid=apdev[0]['bssid'], scan_freq="2412")
2003     wpas.set_network(id, "scan_freq", "")
2004     wpas.set_network(id, "bssid", "")
2005 
2006     addr = wpas.own_addr()
2007     wpas.dump_monitor()
2008 
2009     logger.info("Preferred Candidate List (matching neighbor for another BSS) without Disassociation Imminent")
2010     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"):
2011         raise Exception("BSS_TM_REQ command failed")
2012     ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
2013     if ev is None:
2014         raise Exception("No BSS Transition Management Response")
2015     if "status_code=0" not in ev:
2016         raise Exception("BSS transition request was not accepted: " + ev)
2017     if "target_bssid=" + apdev[1]['bssid'] not in ev:
2018         raise Exception("Unexpected target BSS: " + ev)
2019     ev = wpas.wait_event(["CTRL-EVENT-CONNECTED",
2020                           "CTRL-EVENT-DISCONNECTED"], timeout=10)
2021     if ev is None:
2022         raise Exception("No reassociation seen")
2023     if "CTRL-EVENT-DISCONNECTED" in ev:
2024         raise Exception("Unexpected disconnection reported")
2025     if apdev[1]['bssid'] not in ev:
2026         raise Exception("Unexpected reassociation target: " + ev)
2027 
2028 def test_wnm_bss_tm_reject(dev, apdev):
2029     """WNM BSS Transition Management request getting rejected"""
2030     try:
2031         hapd = None
2032         hapd = start_wnm_ap(apdev[0], country_code="FI", hw_mode="g",
2033                             channel="1")
2034         id = dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
2035         addr = dev[0].own_addr()
2036         dev[0].dump_monitor()
2037 
2038         if "OK" not in dev[0].request("SET reject_btm_req_reason 123"):
2039             raise Exception("Failed to set reject_btm_req_reason")
2040 
2041         if "OK" not in hapd.request("BSS_TM_REQ " + addr + " disassoc_timer=1"):
2042             raise Exception("BSS_TM_REQ command failed")
2043         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=10)
2044         if ev is None:
2045             raise Exception("No BSS Transition Management Response")
2046         if addr not in ev:
2047             raise Exception("Unexpected BSS Transition Management Response address")
2048         if "status_code=123" not in ev:
2049             raise Exception("Unexpected BSS Transition Management Response status: " + ev)
2050         dev[0].wait_disconnected()
2051         dev[0].wait_connected()
2052     finally:
2053         if hapd:
2054             hapd.request("DISABLE")
2055         dev[0].disconnect_and_stop_scan()
2056         subprocess.call(['iw', 'reg', 'set', '00'])
2057         dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=0.5)
2058         dev[0].flush_scan_cache()
2059 
2060 def test_wnm_bss_tm_ap_proto(dev, apdev):
2061     """WNM BSS TM - protocol testing for AP message parsing"""
2062     hapd = start_wnm_ap(apdev[0])
2063     bssid = hapd.own_addr()
2064     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
2065     addr = dev[0].own_addr()
2066 
2067     hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000"
2068     hapd.set("ext_mgmt_frame_handling", "1")
2069     tests = ["0a",
2070              "0a06",
2071              "0a0601",
2072              "0a060100",
2073              "0a080000",
2074              "0a08000000",
2075              "0a080000001122334455",
2076              "0a08000000112233445566",
2077              "0a08000000112233445566112233445566778899",
2078              "0a08ffffff",
2079              "0a08ffffff112233445566778899",
2080              "0a1a",
2081              "0a1a00",
2082              "0a1a0000",
2083              "0a0c016015007f0f000000000000000000000000000000000000",
2084              "0a0700",
2085              "0aff00",
2086              "0aff"]
2087     for t in tests:
2088         if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
2089             raise Exception("MGMT_RX_PROCESS failed")
2090 
2091     hapd.set("ext_mgmt_frame_handling", "0")
2092 
2093 def test_wnm_bss_transition_mgmt_query_with_unknown_candidates(dev, apdev):
2094     """WNM BSS Transition Management query with unknown candidates"""
2095     hapd = start_wnm_ap(apdev[0])
2096     dev[0].scan_for_bss(apdev[0]['bssid'], 2412)
2097 
2098     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
2099     dev[0].request("WNM_BSS_QUERY 0 neighbor=00:11:22:33:44:55,0,81,1,4")
2100 
2101     ev = dev[0].wait_event(["WNM: BSS Transition Management Request"],
2102                            timeout=5)
2103     if ev is None:
2104         raise Exception("No BSS Transition Management Request frame seen")
2105 
2106     ev = hapd.wait_event(["BSS-TM-RESP"], timeout=5)
2107     if ev is None:
2108         raise Exception("No BSS Transition Management Response frame seen")
2109 
2110 def test_wnm_time_adv_without_time_zone(dev, apdev):
2111     """WNM Time Advertisement without time zone configuration"""
2112     params = {"ssid": "test-wnm",
2113               "time_advertisement": "2"}
2114     hostapd.add_ap(apdev[0], params)
2115 
2116     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
2117 
2118 def test_wnm_coloc_intf_reporting(dev, apdev):
2119     """WNM Collocated Interference Reporting"""
2120     hapd = start_wnm_ap(apdev[0], bss_transition=False,
2121                         coloc_intf_reporting=True)
2122 
2123     no_intf = struct.pack("<BBBBBLLLLH", 96, 21, 0, 127, 0x0f, 0, 0, 0, 0, 0)
2124 
2125     try:
2126         dev[0].set("coloc_intf_reporting", "1")
2127         dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
2128         addr = dev[0].own_addr()
2129         if "OK" not in hapd.request("COLOC_INTF_REQ %s 1 5" % addr):
2130             raise Exception("Could not send Collocated Interference Request")
2131         ev = dev[0].wait_event(["COLOC-INTF-REQ"], timeout=2)
2132         if ev is None:
2133             raise Exception("No Collocated Interference Request frame seen")
2134         vals = ev.split(' ')
2135         if vals[2] != '1' or vals[3] != '5':
2136             raise Exception("Unexpected request values: " + ev)
2137         dev[0].set("coloc_intf_elems", binascii.hexlify(no_intf).decode())
2138         ev = hapd.wait_event(["COLOC-INTF-REPORT"], timeout=1)
2139         if ev is None:
2140             raise Exception("No Collocated Interference Report frame seen")
2141         if addr + " 1 " + binascii.hexlify(no_intf).decode() not in ev:
2142             raise Exception("Unexpected report values: " + ev)
2143 
2144         if "OK" not in hapd.request("COLOC_INTF_REQ %s 0 0" % addr):
2145             raise Exception("Could not send Collocated Interference Request")
2146         ev = dev[0].wait_event(["COLOC-INTF-REQ"], timeout=2)
2147         if ev is None:
2148             raise Exception("No Collocated Interference Request frame seen")
2149         vals = ev.split(' ')
2150         if vals[2] != '0' or vals[3] != '0':
2151             raise Exception("Unexpected request values: " + ev)
2152 
2153         res = dev[0].request("COLOC_INTF_REPORT " + binascii.hexlify(no_intf).decode())
2154         if "OK" not in res:
2155             raise Exception("Could not send unsolicited report")
2156         ev = hapd.wait_event(["COLOC-INTF-REPORT"], timeout=1)
2157         if ev is None:
2158             raise Exception("No Collocated Interference Report frame seen")
2159         if addr + " 0 " + binascii.hexlify(no_intf).decode() not in ev:
2160             raise Exception("Unexpected report values: " + ev)
2161 
2162         if "FAIL" not in hapd.request("COLOC_INTF_REQ foo 1 5"):
2163             raise Exception("Invalid COLOC_INTF_REQ accepted")
2164         if "FAIL" not in hapd.request("COLOC_INTF_REQ 02:ff:ff:ff:ff:ff 1 5"):
2165             raise Exception("COLOC_INTF_REQ for unknown STA accepted")
2166         if "FAIL" not in hapd.request("COLOC_INTF_REQ %s 1" % addr):
2167             raise Exception("Invalid COLOC_INTF_REQ accepted")
2168         if "FAIL" not in hapd.request("COLOC_INTF_REQ %s" % addr):
2169             raise Exception("Invalid COLOC_INTF_REQ accepted")
2170     finally:
2171         dev[0].set("coloc_intf_reporting", "0")
2172         dev[0].set("coloc_intf_elems", "")
2173 
2174 def test_wnm_coloc_intf_reporting_errors(dev, apdev):
2175     """WNM Collocated Interference Reporting errors"""
2176     hapd = start_wnm_ap(apdev[0], bss_transition=False,
2177                         coloc_intf_reporting=True)
2178     bssid = hapd.own_addr()
2179     dev[0].set("coloc_intf_reporting", "1")
2180     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
2181     addr = dev[0].own_addr()
2182     if "FAIL" not in hapd.request("COLOC_INTF_REQ %s 4 5" % addr):
2183         raise Exception("Invalid Collocated Interference Request accepted")
2184     hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000"
2185     hapd.set("ext_mgmt_frame_handling", "1")
2186     tests = ["0a0c016015007f0f000000000000000000000000000000000000",
2187              "0a0c"]
2188     with alloc_fail(hapd, 1, "ieee802_11_rx_wnm_coloc_intf_report"):
2189         for t in tests:
2190             if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
2191                 raise Exception("MGMT_RX_PROCESS failed")
2192 
2193     hapd.set("ext_mgmt_frame_handling", "0")
2194 
2195 def test_wnm_bss_transition_mgmt_disabled(dev, apdev):
2196     """WNM BSS Transition Management disabled"""
2197     hapd = start_wnm_ap(apdev[0])
2198     try:
2199         dev[0].set("disable_btm", "1")
2200         dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
2201         addr = dev[0].own_addr()
2202         hapd.request("BSS_TM_REQ " + addr)
2203         ev = hapd.wait_event(['BSS-TM-RESP'], timeout=0.5)
2204         if ev is not None:
2205             raise Exception("Unexpected BSS Transition Management Response")
2206     finally:
2207         dev[0].set("disable_btm", "0")
2208 
2209 def test_wnm_time_adv_restart(dev, apdev):
2210     """WNM time advertisement and interface restart"""
2211     hapd = start_wnm_ap(apdev[0], time_adv=True)
2212     hapd.disable()
2213     hapd.enable()
2214     dev[0].connect("test-wnm", key_mgmt="NONE", scan_freq="2412")
2215 
2216 def test_wnm_event_report(dev, apdev):
2217     """WNM event report"""
2218     ssid = "test-wnm-rsn"
2219     hapd = start_wnm_ap(apdev[0], rsn=True, he=True)
2220     bssid = apdev[0]['bssid']
2221     dev[0].connect(ssid, psk="12345678", key_mgmt="WPA-PSK-SHA256",
2222                    proto="WPA2", ieee80211w="2", scan_freq="2412")
2223     hapd.wait_sta()
2224 
2225     msg = {'fc': MGMT_SUBTYPE_ACTION << 4,
2226            'da': bssid,
2227            'sa': dev[0].own_addr(),
2228            'bssid': bssid}
2229     cmd = "MGMT_TX {} {} freq=2412 wait_time=200 no_cck=1=".format(bssid, bssid)
2230     cmd += " action="
2231 
2232     for i in range(10):
2233         hapd.note("Event Type %d" % i)
2234         payload = struct.pack("<3B5B",
2235                               ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2236                               WLAN_EID_EVENT_REPORT, 3, 0, i, 0)
2237         mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2238 
2239     hapd.note("Too short Event Report element")
2240     payload = struct.pack("<3B4B",
2241                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2242                           WLAN_EID_EVENT_REPORT, 2, 0, 0)
2243     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2244 
2245     hapd.note("Truncated Event Report element")
2246     payload = struct.pack("<3B4B",
2247                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2248                           WLAN_EID_EVENT_REPORT, 3, 0, 0)
2249     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2250 
2251     hapd.note("Request failed")
2252     payload = struct.pack("<3B5B",
2253                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2254                           WLAN_EID_EVENT_REPORT, 3, 0, 0, 1)
2255     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2256 
2257     hapd.note("Unexpected element ID")
2258     payload = struct.pack("<3B5B",
2259                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2260                           WLAN_EID_EVENT_REPORT + 1, 3, 0, 0, 0)
2261     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2262 
2263     hapd.note("Too short BSS color collision report")
2264     payload = struct.pack("<3B5B",
2265                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2266                           WLAN_EID_EVENT_REPORT, 3, 0, 4, 0)
2267     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2268 
2269     hapd.note("Too short BSS color collision report")
2270     payload = struct.pack("<3B5BQ7B",
2271                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2272                           WLAN_EID_EVENT_REPORT, 3 + 8 + 7, 0, 4, 0, 0,
2273                           0, 0, 0, 0, 0, 0, 0)
2274     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2275 
2276     hapd.note("BSS color collision report")
2277     payload = struct.pack("<3B5BQQ",
2278                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2279                           WLAN_EID_EVENT_REPORT, 3 + 8 + 8, 0, 4, 0,
2280                           0x1122334455667788, 0x123456789)
2281     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2282 
2283     hapd.note("Too short BSS color in use report")
2284     payload = struct.pack("<3B5B",
2285                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2286                           WLAN_EID_EVENT_REPORT, 3, 0, 5, 0)
2287     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2288 
2289     hapd.note("Too short BSS color in use report")
2290     payload = struct.pack("<3B5BQ",
2291                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2292                           WLAN_EID_EVENT_REPORT, 3 + 8, 0, 5, 0, 0)
2293     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2294 
2295     hapd.note("BSS color in use report for color 1")
2296     payload = struct.pack("<3B5BQB",
2297                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2298                           WLAN_EID_EVENT_REPORT, 3 + 8 + 1, 0, 5, 0, 0, 1)
2299     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2300 
2301     hapd.note("BSS color in use report for canceling")
2302     payload = struct.pack("<3B5BQB",
2303                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2304                           WLAN_EID_EVENT_REPORT, 3 + 8 + 1, 0, 5, 0, 0, 0)
2305     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2306 
2307     hapd.note("BSS color in use report for invalid color")
2308     payload = struct.pack("<3B5BQB",
2309                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2310                           WLAN_EID_EVENT_REPORT, 3 + 8 + 1, 0, 5, 0, 0, 64)
2311     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2312 
2313     time.sleep(51)
2314     hapd.note("BSS color collision report for more colors")
2315     payload = struct.pack("<3B5BQQ",
2316                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2317                           WLAN_EID_EVENT_REPORT, 3 + 8 + 8, 0, 4, 0,
2318                           0x1122334455667788, 0xfffffffffffffff0)
2319     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2320 
2321     time.sleep(11)
2322     hapd.note("BSS color collision report")
2323     payload = struct.pack("<3B5BQQ",
2324                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2325                           WLAN_EID_EVENT_REPORT, 3 + 8 + 8, 0, 4, 0,
2326                           0x1122334455667788, 0xf)
2327     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2328 
2329     time.sleep(51)
2330     hapd.note("BSS color collision report for all colors")
2331     payload = struct.pack("<3B5BQQ",
2332                           ACTION_CATEG_WNM, WNM_ACT_EVENT_REPORT, 0,
2333                           WLAN_EID_EVENT_REPORT, 3 + 8 + 8, 0, 4, 0,
2334                           0x1122334455667788, 0xffffffffffffffff)
2335     mgmt_tx(dev[0], cmd + binascii.hexlify(payload).decode())
2336 
2337     time.sleep(11)
2338