]> git.ipfire.org Git - thirdparty/hostap.git/blob - tests/hwsim/test_rrm.py
tests: Fix ap_ft_reassoc_replay for case where wlantest has the PSK
[thirdparty/hostap.git] / tests / hwsim / test_rrm.py
1 # Radio measurement
2 # Copyright(c) 2013 - 2016 Intel Mobile Communications GmbH.
3 # Copyright(c) 2011 - 2016 Intel Corporation. All rights reserved.
4 # Copyright (c) 2017, Jouni Malinen <j@w1.fi>
5 #
6 # This software may be distributed under the terms of the BSD license.
7 # See README for more details.
8
9 import binascii
10 import re
11 import logging
12 logger = logging.getLogger()
13 import struct
14 import subprocess
15 import time
16
17 import hostapd
18 from wpasupplicant import WpaSupplicant
19 from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger
20 from utils import disable_hapd, clear_regdom_dev, clear_regdom
21 from test_ap_ht import clear_scan_cache
22 from remotehost import remote_compatible
23 from test_ap_vht import vht_supported
24
25 def check_rrm_support(dev):
26 rrm = int(dev.get_driver_status_field("capa.rrm_flags"), 16)
27 if rrm & 0x5 != 0x5 and rrm & 0x10 != 0x10:
28 raise HwsimSkip("Required RRM capabilities are not supported")
29
30 def check_tx_power_support(dev):
31 rrm = int(dev.get_driver_status_field("capa.rrm_flags"), 16)
32 if rrm & 0x8 != 0x8:
33 raise HwsimSkip("Required RRM capabilities are not supported")
34
35 nr = "00112233445500000000510107"
36 lci = "01000800101298c0b512926666f6c2f1001c00004104050000c00012"
37 civic = "01000b0011223344556677889900998877665544332211aabbccddeeff"
38
39 def check_nr_results(dev, bssids=None, lci=False, civic=False):
40 if bssids is None:
41 ev = dev.wait_event(["RRM-NEIGHBOR-REP-REQUEST-FAILED"], timeout=10)
42 if ev is None:
43 raise Exception("RRM neighbor report failure not received")
44 return
45
46 received = []
47 for bssid in bssids:
48 ev = dev.wait_event(["RRM-NEIGHBOR-REP-RECEIVED"], timeout=10)
49 if ev is None:
50 raise Exception("RRM report result not indicated")
51 received.append(ev)
52
53 for bssid in bssids:
54 found = False
55 for r in received:
56 if "RRM-NEIGHBOR-REP-RECEIVED bssid=" + bssid in r:
57 if lci and "lci=" not in r:
58 raise Exception("LCI data not reported for %s" % bssid)
59 if civic and "civic=" not in r:
60 raise Exception("civic data not reported for %s" % bssid)
61 received.remove(r)
62 found = True
63 break
64 if not found:
65 raise Exception("RRM report result for %s not indicated" % bssid)
66
67 def test_rrm_neighbor_db(dev, apdev):
68 """hostapd ctrl_iface SET_NEIGHBOR"""
69 params = {"ssid": "test", "rrm_neighbor_report": "1"}
70 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
71
72 # Bad BSSID
73 if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:gg ssid=\"test1\" nr=" + nr):
74 raise Exception("Set neighbor succeeded unexpectedly")
75
76 # Bad SSID
77 if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=test1 nr=" + nr):
78 raise Exception("Set neighbor succeeded unexpectedly")
79
80 # No SSID
81 if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 nr=" + nr):
82 raise Exception("Set neighbor succeeded unexpectedly")
83
84 # No NR
85 if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\""):
86 raise Exception("Set neighbor succeeded unexpectedly")
87
88 # Odd length of NR
89 if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr[:-1]):
90 raise Exception("Set neighbor succeeded unexpectedly")
91
92 # Invalid lci
93 if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " lci=1"):
94 raise Exception("Set neighbor succeeded unexpectedly")
95
96 # Invalid civic
97 if "FAIL" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " civic=1"):
98 raise Exception("Set neighbor succeeded unexpectedly")
99
100 # No entry yet in database
101 if "FAIL" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\""):
102 raise Exception("Remove neighbor succeeded unexpectedly")
103
104 # Add a neighbor entry
105 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic):
106 raise Exception("Set neighbor failed")
107
108 # Another BSSID with the same SSID
109 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:56 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic):
110 raise Exception("Set neighbor failed")
111
112 # Fewer parameters
113 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr):
114 raise Exception("Set neighbor failed")
115
116 # SSID in hex format
117 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=7465737431 nr=" + nr):
118 raise Exception("Set neighbor failed")
119
120 # With more parameters
121 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " civic=" + civic):
122 raise Exception("Set neighbor failed")
123
124 # With all parameters
125 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\" nr=" + nr + " lci=" + lci + " civic=" + civic):
126 raise Exception("Set neighbor failed")
127
128 # Another SSID on the same BSSID
129 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test2\" nr=" + nr + " lci=" + lci):
130 raise Exception("Set neighbor failed")
131
132 if "OK" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\""):
133 raise Exception("Remove neighbor failed")
134
135 if "OK" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:56 ssid=\"test1\""):
136 raise Exception("Remove neighbor failed")
137
138 if "OK" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test2\""):
139 raise Exception("Remove neighbor failed")
140
141 # Double remove
142 if "FAIL" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1\""):
143 raise Exception("Remove neighbor succeeded unexpectedly")
144
145 # Stationary AP
146 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test3\" nr=" + nr + " lci=" + lci + " civic=" + civic + " stat"):
147 raise Exception("Set neighbor failed")
148
149 if "OK" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test3\""):
150 raise Exception("Remove neighbor failed")
151
152 # Invalid remove - bad BSSID
153 if "FAIL" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:5 ssid=\"test1\""):
154 raise Exception("Remove neighbor succeeded unexpectedly")
155
156 # Invalid remove - bad SSID
157 if "FAIL" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55 ssid=\"test1"):
158 raise Exception("Remove neighbor succeeded unexpectedly")
159
160 # Invalid remove - missing SSID
161 if "FAIL" not in hapd.request("REMOVE_NEIGHBOR 00:11:22:33:44:55"):
162 raise Exception("Remove neighbor succeeded unexpectedly")
163
164 def test_rrm_neighbor_rep_req(dev, apdev):
165 """wpa_supplicant ctrl_iface NEIGHBOR_REP_REQUEST"""
166 check_rrm_support(dev[0])
167
168 nr1 = "00112233445500000000510107"
169 nr2 = "00112233445600000000510107"
170 nr3 = "dd112233445500000000510107"
171
172 params = {"ssid": "test"}
173 hostapd.add_ap(apdev[0]['ifname'], params)
174 params = {"ssid": "test2", "rrm_neighbor_report": "1"}
175 hapd = hostapd.add_ap(apdev[1]['ifname'], params)
176
177 bssid1 = apdev[1]['bssid']
178
179 dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
180 if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
181 raise Exception("Request succeeded unexpectedly (AP without RRM)")
182 if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"abcdef\""):
183 raise Exception("Request succeeded unexpectedly (AP without RRM 2)")
184 dev[0].request("DISCONNECT")
185
186 dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
187
188 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
189 raise Exception("Request failed")
190 check_nr_results(dev[0], [bssid1])
191
192 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST lci"):
193 raise Exception("Request failed")
194 check_nr_results(dev[0], [bssid1])
195
196 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST lci civic"):
197 raise Exception("Request failed")
198 check_nr_results(dev[0], [bssid1])
199
200 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\""):
201 raise Exception("Request failed")
202 check_nr_results(dev[0])
203
204 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\" lci civic"):
205 raise Exception("Request failed")
206 check_nr_results(dev[0])
207
208 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"test3\" nr=" + nr1 + " lci=" + lci + " civic=" + civic):
209 raise Exception("Set neighbor failed")
210 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:56 ssid=\"test3\" nr=" + nr2 + " lci=" + lci + " civic=" + civic):
211 raise Exception("Set neighbor failed")
212 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:56 ssid=\"test4\" nr=" + nr2 + " lci=" + lci + " civic=" + civic):
213 raise Exception("Set neighbor failed")
214 if "OK" not in hapd.request("SET_NEIGHBOR dd:11:22:33:44:55 ssid=\"test5\" nr=" + nr3 + " lci=" + lci):
215 raise Exception("Set neighbor failed")
216
217 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\""):
218 raise Exception("Request failed")
219 check_nr_results(dev[0], ["00:11:22:33:44:55", "00:11:22:33:44:56"])
220
221 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\" lci"):
222 raise Exception("Request failed")
223 check_nr_results(dev[0], ["00:11:22:33:44:55", "00:11:22:33:44:56"],
224 lci=True)
225
226 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\" civic"):
227 raise Exception("Request failed")
228 check_nr_results(dev[0], ["00:11:22:33:44:55", "00:11:22:33:44:56"],
229 civic=True)
230
231 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test3\" lci civic"):
232 raise Exception("Request failed")
233 check_nr_results(dev[0], ["00:11:22:33:44:55", "00:11:22:33:44:56"],
234 lci=True, civic=True)
235
236 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test4\""):
237 raise Exception("Request failed")
238 check_nr_results(dev[0], ["00:11:22:33:44:56"])
239
240 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test4\" lci"):
241 raise Exception("Request failed")
242 check_nr_results(dev[0], ["00:11:22:33:44:56"], lci=True)
243
244 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test4\" civic"):
245 raise Exception("Request failed")
246 check_nr_results(dev[0], ["00:11:22:33:44:56"], civic=True)
247
248 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test4\" lci civic"):
249 raise Exception("Request failed")
250 check_nr_results(dev[0], ["00:11:22:33:44:56"], lci=True, civic=True)
251
252 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test5\""):
253 raise Exception("Request failed")
254 check_nr_results(dev[0], ["dd:11:22:33:44:55"])
255
256 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test5\" lci"):
257 raise Exception("Request failed")
258 check_nr_results(dev[0], ["dd:11:22:33:44:55"], lci=True)
259
260 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test5\" civic"):
261 raise Exception("Request failed")
262 check_nr_results(dev[0], ["dd:11:22:33:44:55"])
263
264 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST ssid=\"test5\" lci civic"):
265 raise Exception("Request failed")
266 check_nr_results(dev[0], ["dd:11:22:33:44:55"], lci=True)
267
268 def test_rrm_neighbor_rep_oom(dev, apdev):
269 """hostapd neighbor report OOM"""
270 check_rrm_support(dev[0])
271
272 nr1 = "00112233445500000000510107"
273 nr2 = "00112233445600000000510107"
274 nr3 = "dd112233445500000000510107"
275
276 params = {"ssid": "test", "rrm_neighbor_report": "1"}
277 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
278
279 dev[0].connect("test", key_mgmt="NONE", scan_freq="2412")
280
281 with alloc_fail(hapd, 1, "hostapd_send_nei_report_resp"):
282 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
283 raise Exception("Request failed")
284 ev = dev[0].wait_event(["RRM-NEIGHBOR-REP-REQUEST-FAILED"], timeout=5)
285 if ev is None:
286 raise Exception("Neighbor report failure not reported")
287
288 def test_rrm_lci_req(dev, apdev):
289 """hostapd lci request"""
290 check_rrm_support(dev[0])
291
292 params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
293 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
294
295 # station not specified
296 if "FAIL" not in hapd.request("REQ_LCI "):
297 raise Exception("REQ_LCI with no station succeeded unexpectedly")
298
299 # station that is not connected specified
300 if "FAIL" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
301 raise Exception("REQ_LCI succeeded unexpectedly (station not connected)")
302
303 dev[0].request("SET LCI ")
304 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
305
306 # station connected without LCI
307 if "FAIL" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
308 raise Exception("REQ_LCI succeeded unexpectedly (station without lci)")
309
310 dev[0].request("DISCONNECT")
311 dev[0].wait_disconnected(timeout=2)
312
313 dev[0].request("SET LCI " + lci)
314
315 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
316
317 # station connected with LCI
318 if "OK" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
319 raise Exception("REQ_LCI failed unexpectedly")
320
321 def test_rrm_lci_req_timeout(dev, apdev):
322 """hostapd lci request timeout"""
323 check_rrm_support(dev[0])
324
325 params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
326 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
327
328 dev[0].request("SET LCI " + lci)
329 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
330 addr = dev[0].own_addr()
331
332 hapd.set("ext_mgmt_frame_handling", "1")
333 if "OK" not in hapd.request("REQ_LCI " + addr):
334 raise Exception("REQ_LCI failed unexpectedly")
335 ev = hapd.wait_event(["MGMT-RX"], timeout=5)
336 if ev is None:
337 raise Exception("No response seen at the AP")
338 # Ignore response and wait for HOSTAPD_RRM_REQUEST_TIMEOUT
339 time.sleep(5.1)
340 # Process response after timeout
341 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % ev.split(' ')[1]):
342 raise Exception("MGMT_RX_PROCESS failed")
343 for i in range(257):
344 if "OK" not in hapd.request("REQ_LCI " + addr):
345 raise Exception("REQ_LCI failed unexpectedly")
346 dev[0].dump_monitor()
347 hapd.dump_monitor()
348 hapd.set("ext_mgmt_frame_handling", "0")
349 dev[0].request("DISCONNECT")
350 dev[0].wait_disconnected()
351
352 def test_rrm_lci_req_oom(dev, apdev):
353 """LCI report generation OOM"""
354 check_rrm_support(dev[0])
355
356 params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
357 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
358
359 dev[0].request("SET LCI " + lci)
360 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
361
362 with alloc_fail(dev[0], 1, "wpabuf_resize;wpas_rrm_build_lci_report"):
363 if "OK" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
364 raise Exception("REQ_LCI failed unexpectedly")
365 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
366
367 dev[0].request("SET LCI ")
368 # This in in wpas_rrm_build_lci_report(), but backtrace may not always work
369 # for the "reject" label there.
370 with alloc_fail(dev[0], 1, "wpabuf_resize;wpas_rrm_handle_msr_req_element"):
371 if "OK" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
372 raise Exception("REQ_LCI failed unexpectedly")
373 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
374
375 def test_rrm_lci_req_ap_oom(dev, apdev):
376 """LCI report generation AP OOM and failure"""
377 check_rrm_support(dev[0])
378
379 params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
380 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
381
382 dev[0].request("SET LCI " + lci)
383 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
384
385 with alloc_fail(hapd, 1, "wpabuf_alloc;hostapd_send_lci_req"):
386 if "FAIL" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
387 raise Exception("REQ_LCI succeeded during OOM")
388
389 with fail_test(hapd, 1, "nl80211_send_frame_cmd;hostapd_send_lci_req"):
390 if "FAIL" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
391 raise Exception("REQ_LCI succeeded during failure testing")
392
393 def test_rrm_lci_req_get_reltime_failure(dev, apdev):
394 """LCI report generation and os_get_reltime() failure"""
395 check_rrm_support(dev[0])
396
397 params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
398 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
399
400 dev[0].request("SET LCI " + lci)
401 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
402
403 with fail_test(dev[0], 1, "os_get_reltime;wpas_rrm_build_lci_report"):
404 if "OK" not in hapd.request("REQ_LCI " + dev[0].own_addr()):
405 raise Exception("REQ_LCI failed unexpectedly")
406 wait_fail_trigger(dev[0], "GET_FAIL")
407
408 def test_rrm_neighbor_rep_req_from_conf(dev, apdev):
409 """wpa_supplicant ctrl_iface NEIGHBOR_REP_REQUEST and hostapd config"""
410 check_rrm_support(dev[0])
411
412 params = {"ssid": "test2", "rrm_neighbor_report": "1",
413 "stationary_ap": "1", "lci": lci, "civic": civic}
414 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
415
416 bssid = apdev[0]['bssid']
417
418 dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
419
420 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
421 raise Exception("Request failed")
422 check_nr_results(dev[0], [bssid])
423
424 def test_rrm_neighbor_rep_req_timeout(dev, apdev):
425 """wpa_supplicant behavior on NEIGHBOR_REP_REQUEST response timeout"""
426 check_rrm_support(dev[0])
427
428 params = {"ssid": "test2", "rrm_neighbor_report": "1",
429 "stationary_ap": "1", "lci": lci, "civic": civic}
430 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
431
432 dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
433
434 hapd.set("ext_mgmt_frame_handling", "1")
435
436 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
437 raise Exception("Request failed")
438 msg = hapd.mgmt_rx()
439 if msg is None:
440 raise Exception("Neighbor report request not seen")
441 check_nr_results(dev[0])
442
443 def test_rrm_neighbor_rep_req_oom(dev, apdev):
444 """wpa_supplicant ctrl_iface NEIGHBOR_REP_REQUEST OOM"""
445 check_rrm_support(dev[0])
446
447 params = {"ssid": "test2", "rrm_neighbor_report": "1",
448 "stationary_ap": "1", "lci": lci, "civic": civic}
449 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
450
451 dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
452
453 with alloc_fail(dev[0], 1, "wpabuf_alloc;wpas_rrm_process_neighbor_rep"):
454 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
455 raise Exception("Request failed")
456 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
457
458 with fail_test(dev[0], 1,
459 "wpa_driver_nl80211_send_action;wpas_rrm_send_neighbor_rep_request"):
460 if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
461 raise Exception("Request succeeded unexpectedly")
462
463 with alloc_fail(dev[0], 1,
464 "wpabuf_alloc;wpas_rrm_send_neighbor_rep_request"):
465 if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
466 raise Exception("Request succeeded unexpectedly")
467
468 def test_rrm_neighbor_rep_req_disconnect(dev, apdev):
469 """wpa_supplicant behavior on disconnection during NEIGHBOR_REP_REQUEST"""
470 check_rrm_support(dev[0])
471
472 params = {"ssid": "test2", "rrm_neighbor_report": "1",
473 "stationary_ap": "1", "lci": lci, "civic": civic}
474 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
475
476 if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
477 raise Exception("Request accepted while disconnected")
478
479 dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
480
481 hapd.set("ext_mgmt_frame_handling", "1")
482
483 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
484 raise Exception("Request failed")
485 msg = hapd.mgmt_rx()
486 if msg is None:
487 raise Exception("Neighbor report request not seen")
488 dev[0].request("DISCONNECT")
489 check_nr_results(dev[0])
490
491 def test_rrm_neighbor_rep_req_not_supported(dev, apdev):
492 """NEIGHBOR_REP_REQUEST for AP not supporting neighbor report"""
493 check_rrm_support(dev[0])
494
495 params = {"ssid": "test2", "rrm_beacon_report": "1"}
496 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
497
498 dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
499
500 if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
501 raise Exception("Request accepted unexpectedly")
502
503 def test_rrm_neighbor_rep_req_busy(dev, apdev):
504 """wpa_supplicant and concurrent NEIGHBOR_REP_REQUEST commands"""
505 check_rrm_support(dev[0])
506
507 params = {"ssid": "test2", "rrm_neighbor_report": "1",
508 "stationary_ap": "1", "lci": lci, "civic": civic}
509 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
510
511 dev[0].connect("test2", key_mgmt="NONE", scan_freq="2412")
512
513 hapd.set("ext_mgmt_frame_handling", "1")
514
515 if "OK" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
516 raise Exception("Request failed")
517 msg = hapd.mgmt_rx()
518 if msg is None:
519 raise Exception("Neighbor report request not seen")
520
521 if "FAIL" not in dev[0].request("NEIGHBOR_REP_REQUEST"):
522 raise Exception("Request accepted while disconnected")
523
524 def test_rrm_ftm_range_req(dev, apdev):
525 """hostapd FTM range request command"""
526 check_rrm_support(dev[0])
527 try:
528 run_rrm_ftm_range_req(dev, apdev)
529 finally:
530 dev[1].request("VENDOR_ELEM_REMOVE 13 *")
531
532 def run_rrm_ftm_range_req(dev, apdev):
533 params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
534 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
535 bssid = hapd.own_addr()
536
537 # station not specified
538 if "FAIL" not in hapd.request("REQ_RANGE "):
539 raise Exception("REQ_RANGE with no station succeeded unexpectedly")
540
541 # station that is not connected specified
542 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr()):
543 raise Exception("REQ_RANGE succeeded unexpectedly (station not connected)")
544
545 # No responders specified
546 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 10"):
547 raise Exception("REQ_RANGE succeeded unexpectedly (no responder)")
548
549 # Bad responder address
550 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 10 00:11:22:33:44:"):
551 raise Exception("REQ_RANGE succeeded unexpectedly (bad responder address)")
552
553 # Bad responder address
554 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 10 00:11:22:33:44:55 00:11:22:33:44"):
555 raise Exception("REQ_RANGE succeeded unexpectedly (bad responder address 2)")
556
557 # Bad min_ap value
558 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 300 00:11:22:33:44:55"):
559 raise Exception("REQ_RANGE succeeded unexpectedly (invalid min_ap value)")
560
561 # Bad rand value
562 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " -1 10 00:11:22:33:44:55"):
563 raise Exception("REQ_RANGE succeeded unexpectedly (invalid rand value)")
564 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 65536 10 00:11:22:33:44:55"):
565 raise Exception("REQ_RANGE succeeded unexpectedly (invalid rand value)")
566
567 # Missing min_ap value
568 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10"):
569 raise Exception("REQ_RANGE succeeded unexpectedly (missing min_ap value)")
570
571 # Too many responders
572 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 10" + 20*" 00:11:22:33:44:55"):
573 raise Exception("REQ_RANGE succeeded unexpectedly (too many responders)")
574 # Wrong min AP count
575 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 10 00:11:22:33:44:55"):
576 raise Exception("REQ_RANGE succeeded unexpectedly (responder not in database)")
577
578 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
579 # Override RM capabilities to include FTM range report
580 dev[1].request("VENDOR_ELEM_ADD 13 46057100000004")
581 dev[1].connect("rrm", key_mgmt="NONE", scan_freq="2412")
582
583 # Request range: Destination address is not connected
584 if "FAIL" not in hapd.request("REQ_RANGE 11:22:33:44:55:66 10 1 00:11:22:33:44:55"):
585 raise Exception("REQ_RANGE succeeded unexpectedly (responder not in database)")
586
587 # Responder not in database
588 # Note: this check would pass since the station does not support FTM range
589 # request and not because the responder is not in the database.
590 if "FAIL" not in hapd.request("REQ_RANGE " + dev[0].own_addr() + " 10 1 00:11:22:33:44:55"):
591 raise Exception("REQ_RANGE succeeded unexpectedly (responder not in database)")
592
593 # Missing neighbor report for 00:11:22:33:44:55
594 if "FAIL" not in hapd.request("REQ_RANGE " + dev[1].own_addr() + " 10 1 00:11:22:33:44:55"):
595 raise Exception("REQ_RANGE succeeded unexpectedly (responder not in database)")
596
597 # Send request
598 if "OK" not in hapd.request("REQ_RANGE " + dev[1].own_addr() + " 10 1 " + bssid):
599 raise Exception("REQ_RANGE failed unexpectedly")
600
601 # Too long range request
602 if "FAIL" not in hapd.request("REQ_RANGE " + dev[1].own_addr() + " 10 1" + 16*(" " + bssid)):
603 raise Exception("REQ_RANGE accepted for too long range request")
604
605 time.sleep(0.1)
606 dev[0].request("DISCONNECT")
607 dev[1].request("DISCONNECT")
608 dev[1].wait_disconnected()
609
610 def test_rrm_ftm_range_req_timeout(dev, apdev):
611 """hostapd FTM range request timeout"""
612 check_rrm_support(dev[0])
613 try:
614 run_rrm_ftm_range_req_timeout(dev, apdev)
615 finally:
616 dev[1].request("VENDOR_ELEM_REMOVE 13 *")
617
618 def run_rrm_ftm_range_req_timeout(dev, apdev):
619 params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
620 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
621 bssid = hapd.own_addr()
622
623 # Override RM capabilities to include FTM range report
624 dev[1].request("VENDOR_ELEM_ADD 13 46057100000004")
625 dev[1].connect("rrm", key_mgmt="NONE", scan_freq="2412")
626 addr = dev[1].own_addr()
627
628 hapd.set("ext_mgmt_frame_handling", "1")
629 if "OK" not in hapd.request("REQ_RANGE " + addr + " 10 1 " + bssid):
630 raise Exception("REQ_RANGE failed")
631 ev = hapd.wait_event(["MGMT-RX"], timeout=5)
632 if ev is None:
633 raise Exception("No response seen at the AP")
634 # Ignore response and wait for HOSTAPD_RRM_REQUEST_TIMEOUT
635 time.sleep(5.1)
636 # Process response after timeout
637 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % ev.split(' ')[1]):
638 raise Exception("MGMT_RX_PROCESS failed")
639
640 for i in range(257):
641 if "OK" not in hapd.request("REQ_RANGE " + addr + " 10 1 " + bssid):
642 raise Exception("REQ_RANGE failed")
643 dev[1].dump_monitor()
644 hapd.dump_monitor()
645
646 hapd.set("ext_mgmt_frame_handling", "0")
647 dev[1].request("DISCONNECT")
648 dev[1].wait_disconnected()
649
650 def test_rrm_ftm_range_req_failure(dev, apdev):
651 """hostapd FTM range request failure"""
652 check_rrm_support(dev[0])
653 try:
654 run_rrm_ftm_range_req_failure(dev, apdev)
655 finally:
656 dev[1].request("VENDOR_ELEM_REMOVE 13 *")
657
658 def run_rrm_ftm_range_req_failure(dev, apdev):
659 params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
660 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
661 bssid = hapd.own_addr()
662
663 # Override RM capabilities to include FTM range report
664 dev[1].request("VENDOR_ELEM_ADD 13 46057100000004")
665 dev[1].connect("rrm", key_mgmt="NONE", scan_freq="2412")
666
667 with alloc_fail(hapd, 1, "wpabuf_alloc;hostapd_send_range_req"):
668 if "FAIL" not in hapd.request("REQ_RANGE " + dev[1].own_addr() + " 10 1 " + bssid):
669 raise Exception("REQ_RANGE succeeded during OOM")
670
671 with fail_test(hapd, 1, "nl80211_send_frame_cmd;hostapd_send_range_req"):
672 if "FAIL" not in hapd.request("REQ_RANGE " + dev[1].own_addr() + " 10 1 " + bssid):
673 raise Exception("REQ_RANGE succeeded during failure testing")
674
675 dev[1].request("DISCONNECT")
676 dev[1].wait_disconnected()
677
678 def test_rrm_ftm_capa_indication(dev, apdev):
679 """FTM capability indication"""
680 try:
681 _test_rrm_ftm_capa_indication(dev, apdev)
682 finally:
683 dev[0].request("SET ftm_initiator 0")
684 dev[0].request("SET ftm_responder 0")
685
686 def _test_rrm_ftm_capa_indication(dev, apdev):
687 params = {"ssid": "ftm",
688 "ftm_responder": "1",
689 "ftm_initiator": "1",}
690 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
691
692 if "OK" not in dev[0].request("SET ftm_initiator 1"):
693 raise Exception("could not set ftm_initiator")
694 if "OK" not in dev[0].request("SET ftm_responder 1"):
695 raise Exception("could not set ftm_responder")
696 dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True)
697
698 class BeaconReport:
699 def __init__(self, report):
700 self.opclass, self.channel, self.start, self.duration, self.frame_info, self.rcpi, self.rsni = struct.unpack("<BBQHBBB", report[0:15])
701 report = report[15:]
702 self.bssid = report[0:6]
703 self.bssid_str = "%02x:%02x:%02x:%02x:%02x:%02x" % (struct.unpack('6B', self.bssid))
704 report = report[6:]
705 self.antenna_id, self.parent_tsf = struct.unpack("<BI", report[0:5])
706 report = report[5:]
707 self.subelems = report
708 self.frame_body = None
709 self.frame_body_fragment_id = None
710 self.last_indication = None
711 while len(report) >= 2:
712 eid, elen = struct.unpack('BB', report[0:2])
713 report = report[2:]
714 if len(report) < elen:
715 raise Exception("Invalid subelement in beacon report")
716 if eid == 1:
717 # Reported Frame Body
718 # Contents depends on the reporting detail request:
719 # 0 = no Reported Frame Body subelement
720 # 1 = all fixed fields and any elements identified in Request
721 # element
722 # 2 = all fixed fields and all elements
723 # Fixed fields: Timestamp[8] BeaconInt[2] CapabInfo[2]
724 self.frame_body = report[0:elen]
725 if eid == 2:
726 self.frame_body_fragment_id = report[0:elen]
727 if eid == 164:
728 self.last_indication = report[0:elen]
729 report = report[elen:]
730 def __str__(self):
731 txt = "opclass={} channel={} start={} duration={} frame_info={} rcpi={} rsni={} bssid={} antenna_id={} parent_tsf={}".format(self.opclass, self.channel, self.start, self.duration, self.frame_info, self.rcpi, self.rsni, self.bssid_str, self.antenna_id, self.parent_tsf)
732 if self.frame_body:
733 txt += " frame_body=" + binascii.hexlify(self.frame_body).decode()
734 if self.frame_body_fragment_id:
735 txt += " fragment_id=" + binascii.hexlify(self.frame_body_fragment_id).decode()
736 if self.last_indication:
737 txt += " last_indication=" + binascii.hexlify(self.last_indication).decode()
738
739 return txt
740
741 def run_req_beacon(hapd, addr, request):
742 token = hapd.request("REQ_BEACON " + addr + " " + request)
743 if "FAIL" in token:
744 raise Exception("REQ_BEACON failed")
745
746 ev = hapd.wait_event(["BEACON-REQ-TX-STATUS"], timeout=5)
747 if ev is None:
748 raise Exception("No TX status event for beacon request received")
749 fields = ev.split(' ')
750 if fields[1] != addr:
751 raise Exception("Unexpected STA address in TX status: " + fields[1])
752 if fields[2] != token:
753 raise Exception("Unexpected dialog token in TX status: " + fields[2] + " (expected " + token + ")")
754 if fields[3] != "ack=1":
755 raise Exception("Unexected ACK status in TX status: " + fields[3])
756 return token
757
758 @remote_compatible
759 def test_rrm_beacon_req_table(dev, apdev):
760 """Beacon request - beacon table mode"""
761 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
762 hapd = hostapd.add_ap(apdev[0], params)
763 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another"})
764
765 tests = ["REQ_BEACON ",
766 "REQ_BEACON q",
767 "REQ_BEACON 11:22:33:44:55:66 1",
768 "REQ_BEACON 11:22:33:44:55:66 1q",
769 "REQ_BEACON 11:22:33:44:55:66 11223344556677889900aabbccddeeff"]
770 for t in tests:
771 if "FAIL" not in hapd.request(t):
772 raise Exception("Invalid command accepted: " + t)
773
774 dev[0].scan_for_bss(apdev[1]['bssid'], freq=2412)
775 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
776 addr = dev[0].own_addr()
777
778 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff")
779
780 for i in range(1, 3):
781 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
782 if ev is None:
783 raise Exception("Beacon report %d response not received" % i)
784 fields = ev.split(' ')
785 if fields[1] != addr:
786 raise Exception("Unexpected STA address in beacon report response: " + fields[1])
787 if fields[2] != token:
788 raise Exception("Unexpected dialog token in beacon report response: " + fields[2] + " (expected " + token + ")")
789 if fields[3] != "00":
790 raise Exception("Unexpected measurement report mode")
791
792 report = BeaconReport(binascii.unhexlify(fields[4]))
793 logger.info("Received beacon report: " + str(report))
794
795 # Default reporting detail is 2, i.e., all fixed fields and elements.
796 if not report.frame_body:
797 raise Exception("Reported Frame Body subelement missing")
798 if len(report.frame_body) <= 12:
799 raise Exception("Too short Reported Frame Body subelement")
800
801 def test_rrm_beacon_req_frame_body_fragmentation(dev, apdev):
802 """Beacon request - beacon table mode - frame body fragmentation"""
803 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
804
805 hapd = hostapd.add_ap(apdev[0], params)
806 hapd.set('vendor_elements', ("dd051122330203dd0400137400dd04001374ffdd0511"
807 "22330203dd0400137400dd04001374ffdd051122330203dd0400137400dd04001"
808 "374ffdd051122330203dd0400137400dd04001374ffdd051122330203dd040013"
809 "7400dd04001374ffdd051122330203dd0400137400dd04001374ffdd051122330"
810 "203dd0400137400dd04001374ffdd051122330203dd0400137400dd04001374ff"
811 "dd051122330203dd0400137400dd04001374ff"))
812
813 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
814 addr = dev[0].own_addr()
815
816 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff")
817
818 # 2 beacon reports elements are expected because of fragmentation
819 for i in range(0, 2):
820 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
821 if ev is None:
822 raise Exception("Beacon report %d response not received" % i)
823 fields = ev.split(' ')
824 if fields[1] != addr:
825 raise Exception("Unexpected STA address in beacon report response: " + fields[1])
826 if fields[2] != token:
827 raise Exception("Unexpected dialog token in beacon report response: " + fields[2] + " (expected " + token + ")")
828 if fields[3] != "00":
829 raise Exception("Unexpected measurement report mode")
830
831 report = BeaconReport(binascii.unhexlify(fields[4]))
832 logger.info("Received beacon report: " + str(report))
833
834 # Default reporting detail is 2, i.e., all fixed fields and elements.
835 if not report.frame_body_fragment_id:
836 raise Exception("Reported Frame Body Fragment ID subelement missing")
837 fragment_id = binascii.hexlify(report.frame_body_fragment_id)
838 frag_number = int(fragment_id[2:], 16) & int(0x7f)
839 if frag_number != i:
840 raise Exception("Incorrect fragment number: %d" % frag_number)
841 more_frags = int(fragment_id[2:], 16) >> 7
842 if i == 0 and more_frags != 1:
843 raise Exception("more fragments bit is not set on first fragment")
844 if i == 1 and more_frags != 0:
845 raise Exception("more fragments bit is set on last fragment")
846
847 def test_rrm_beacon_req_last_frame_indication(dev, apdev):
848 """Beacon request - beacon table mode - last frame indication"""
849 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
850
851 hapd = hostapd.add_ap(apdev[0], params)
852 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another"})
853
854 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
855 addr = dev[0].own_addr()
856
857 # The request contains the last beacon report indication subelement
858 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffffa40101")
859
860 for i in range(1, 3):
861 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
862 if ev is None:
863 raise Exception("Beacon report %d response not received" % i)
864 fields = ev.split(' ')
865 if fields[1] != addr:
866 raise Exception("Unexpected STA address in beacon report response: " + fields[1])
867 if fields[2] != token:
868 raise Exception("Unexpected dialog token in beacon report response: " + fields[2] + " (expected " + token + ")")
869 if fields[3] != "00":
870 raise Exception("Unexpected measurement report mode")
871
872 report = BeaconReport(binascii.unhexlify(fields[4]))
873 logger.info("Received beacon report: " + str(report))
874
875 if not report.last_indication:
876 raise Exception("Last Beacon Report Indication subelement missing")
877
878 last = binascii.hexlify(report.last_indication).decode()
879 if (i == 2 and last != '01') or (i != 2 and last != '00'):
880 raise Exception("last beacon report indication is not set on last frame")
881
882 # The request does not contain the last beacon report indication subelement
883 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff")
884
885 for i in range(1, 3):
886 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
887 if ev is None:
888 raise Exception("Beacon report %d response not received" % i)
889 fields = ev.split(' ')
890 if fields[1] != addr:
891 raise Exception("Unexpected STA address in beacon report response: " + fields[1])
892 if fields[2] != token:
893 raise Exception("Unexpected dialog token in beacon report response: " + fields[2] + " (expected " + token + ")")
894 if fields[3] != "00":
895 raise Exception("Unexpected measurement report mode")
896
897 report = BeaconReport(binascii.unhexlify(fields[4]))
898 logger.info("Received beacon report: " + str(report))
899
900 if report.last_indication:
901 raise Exception("Last Beacon Report Indication subelement present but not requested")
902
903 @remote_compatible
904 def test_rrm_beacon_req_table_detail(dev, apdev):
905 """Beacon request - beacon table mode - reporting detail"""
906 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
907 hapd = hostapd.add_ap(apdev[0], params)
908
909 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
910 addr = dev[0].own_addr()
911
912 logger.info("Reporting Detail 0")
913 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020100")
914 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
915 if ev is None:
916 raise Exception("Beacon report response not received")
917 fields = ev.split(' ')
918 report = BeaconReport(binascii.unhexlify(fields[4]))
919 logger.info("Received beacon report: " + str(report))
920 if report.frame_body:
921 raise Exception("Reported Frame Body subelement included with Reporting Detail 0")
922 hapd.dump_monitor()
923
924 logger.info("Reporting Detail 1")
925 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020101")
926 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
927 if ev is None:
928 raise Exception("Beacon report response not received")
929 fields = ev.split(' ')
930 report = BeaconReport(binascii.unhexlify(fields[4]))
931 logger.info("Received beacon report: " + str(report))
932 if not report.frame_body:
933 raise Exception("Reported Frame Body subelement missing")
934 if len(report.frame_body) != 12:
935 raise Exception("Unexpected Reported Frame Body subelement length with Reporting Detail 1")
936 hapd.dump_monitor()
937
938 logger.info("Reporting Detail 2")
939 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020102")
940 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
941 if ev is None:
942 raise Exception("Beacon report response not received")
943 fields = ev.split(' ')
944 report = BeaconReport(binascii.unhexlify(fields[4]))
945 logger.info("Received beacon report: " + str(report))
946 if not report.frame_body:
947 raise Exception("Reported Frame Body subelement missing")
948 if len(report.frame_body) <= 12:
949 raise Exception("Unexpected Reported Frame Body subelement length with Reporting Detail 2")
950 hapd.dump_monitor()
951
952 logger.info("Reporting Detail 3 (invalid)")
953 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020103")
954 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
955 if ev is not None:
956 raise Exception("Unexpected beacon report response to invalid reporting detail 3")
957 hapd.dump_monitor()
958
959 logger.info("Reporting Detail (too short)")
960 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "0200")
961 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
962 if ev is not None:
963 raise Exception("Unexpected beacon report response to invalid reporting detail")
964 hapd.dump_monitor()
965
966 @remote_compatible
967 def test_rrm_beacon_req_table_request(dev, apdev):
968 """Beacon request - beacon table mode - request element"""
969 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
970 hapd = hostapd.add_ap(apdev[0], params)
971
972 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
973 addr = dev[0].own_addr()
974
975 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020101" + "0a03000106")
976 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
977 if ev is None:
978 raise Exception("Beacon report response not received")
979 fields = ev.split(' ')
980 report = BeaconReport(binascii.unhexlify(fields[4]))
981 logger.info("Received beacon report: " + str(report))
982 if not report.frame_body:
983 raise Exception("Reported Frame Body subelement missing")
984 if len(report.frame_body) != 12 + 5 + 10:
985 raise Exception("Unexpected Reported Frame Body subelement length with Reporting Detail 1 and requested elements SSID + SuppRates")
986 hapd.dump_monitor()
987
988 logger.info("Incorrect reporting detail with request subelement")
989 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020102" + "0a03000106")
990 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
991 if ev is not None:
992 raise Exception("Unexpected beacon report response (invalid reporting detail)")
993 hapd.dump_monitor()
994
995 logger.info("Invalid request subelement length")
996 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020101" + "0a00")
997 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
998 if ev is not None:
999 raise Exception("Unexpected beacon report response (invalid request subelement length)")
1000 hapd.dump_monitor()
1001
1002 logger.info("Multiple request subelements")
1003 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020101" + "0a0100" + "0a0101")
1004 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
1005 if ev is not None:
1006 raise Exception("Unexpected beacon report response (multiple request subelements)")
1007 hapd.dump_monitor()
1008
1009 @remote_compatible
1010 def test_rrm_beacon_req_table_request_oom(dev, apdev):
1011 """Beacon request - beacon table mode - request element OOM"""
1012 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1013 hapd = hostapd.add_ap(apdev[0], params)
1014
1015 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1016 addr = dev[0].own_addr()
1017
1018 with alloc_fail(dev[0], 1,
1019 "bitfield_alloc;wpas_rm_handle_beacon_req_subelem"):
1020 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020101" + "0a03000106")
1021 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1022 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.1)
1023 if ev is not None:
1024 raise Exception("Unexpected beacon report response received (OOM)")
1025
1026 with alloc_fail(dev[0], 1,
1027 "wpabuf_alloc;wpas_rrm_send_msr_report_mpdu"):
1028 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020101" + "0a03000106")
1029 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1030 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.1)
1031 if ev is not None:
1032 raise Exception("Unexpected beacon report response received (OOM)")
1033
1034 with fail_test(dev[0], 1,
1035 "wpa_driver_nl80211_send_action;wpas_rrm_send_msr_report_mpdu"):
1036 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020101" + "0a03000106")
1037 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1038 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.1)
1039 if ev is not None:
1040 raise Exception("Unexpected beacon report response received (OOM)")
1041
1042 with alloc_fail(dev[0], 1,
1043 "wpabuf_resize;wpas_add_beacon_rep"):
1044 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020101" + "0a03000106")
1045 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1046 if ev is None:
1047 raise Exception("Beacon report response not received (OOM -> empty report)")
1048 fields = ev.split(' ')
1049 if len(fields[4]) > 0:
1050 raise Exception("Unexpected beacon report received")
1051
1052 @remote_compatible
1053 def test_rrm_beacon_req_table_bssid(dev, apdev):
1054 """Beacon request - beacon table mode - specific BSSID"""
1055 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1056 hapd = hostapd.add_ap(apdev[0], params)
1057 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another"})
1058
1059 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1060 addr = dev[0].own_addr()
1061
1062 bssid2 = hapd2.own_addr()
1063 token = run_req_beacon(hapd, addr, "51000000000002" + bssid2.replace(':', ''))
1064 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1065 if ev is None:
1066 raise Exception("Beacon report response not received")
1067 fields = ev.split(' ')
1068 report = BeaconReport(binascii.unhexlify(fields[4]))
1069 logger.info("Received beacon report: " + str(report))
1070 if "bssid=" + bssid2 not in str(report):
1071 raise Exception("Report for unexpect BSS")
1072 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.1)
1073 if ev is not None:
1074 raise Exception("Unexpected beacon report response")
1075
1076 @remote_compatible
1077 def test_rrm_beacon_req_table_ssid(dev, apdev):
1078 """Beacon request - beacon table mode - specific SSID"""
1079 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1080 hapd = hostapd.add_ap(apdev[0], params)
1081 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another"})
1082
1083 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1084 addr = dev[0].own_addr()
1085
1086 bssid2 = hapd2.own_addr()
1087 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "0007" + binascii.hexlify(b"another").decode())
1088 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1089 if ev is None:
1090 raise Exception("Beacon report response not received")
1091 fields = ev.split(' ')
1092 report = BeaconReport(binascii.unhexlify(fields[4]))
1093 logger.info("Received beacon report: " + str(report))
1094 if "bssid=" + bssid2 not in str(report):
1095 raise Exception("Report for unexpect BSS")
1096 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.1)
1097 if ev is not None:
1098 raise Exception("Unexpected beacon report response")
1099 hapd.dump_monitor()
1100
1101 logger.info("Wildcard SSID")
1102 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "0000")
1103 for i in range(2):
1104 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1105 if ev is None:
1106 raise Exception("Beacon report response not received")
1107 fields = ev.split(' ')
1108 report = BeaconReport(binascii.unhexlify(fields[4]))
1109 logger.info("Received beacon report: " + str(report))
1110 hapd.dump_monitor()
1111
1112 logger.info("Too long SSID")
1113 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "0021" + 33*"00")
1114 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
1115 if ev is not None:
1116 raise Exception("Unexpected beacon report response (invalid SSID subelement in request)")
1117 hapd.dump_monitor()
1118
1119 @remote_compatible
1120 def test_rrm_beacon_req_table_info(dev, apdev):
1121 """Beacon request - beacon table mode - Reporting Information subelement"""
1122 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1123 hapd = hostapd.add_ap(apdev[0], params)
1124
1125 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1126 addr = dev[0].own_addr()
1127
1128 logger.info("Unsupported reporting information 1")
1129 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "01020100")
1130 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1131 if ev is None:
1132 raise Exception("Beacon report response (incapable) is not received")
1133
1134 fields = ev.split(' ')
1135 if fields[3] != "02":
1136 raise Exception("Beacon report response - unexpected mode (" + fields[3] + ")")
1137 hapd.dump_monitor()
1138
1139 logger.info("Invalid reporting information length")
1140 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "010100")
1141 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
1142 if ev is not None:
1143 raise Exception("Unexpected beacon report response (invalid reporting information length)")
1144 hapd.dump_monitor()
1145
1146 @remote_compatible
1147 def test_rrm_beacon_req_table_unknown_subelem(dev, apdev):
1148 """Beacon request - beacon table mode - unknown subelement"""
1149 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1150 hapd = hostapd.add_ap(apdev[0], params)
1151
1152 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1153 addr = dev[0].own_addr()
1154
1155 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "330101" + "fe00")
1156 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1157 if ev is None:
1158 raise Exception("Beacon report response not received")
1159 fields = ev.split(' ')
1160 report = BeaconReport(binascii.unhexlify(fields[4]))
1161 logger.info("Received beacon report: " + str(report))
1162
1163 @remote_compatible
1164 def test_rrm_beacon_req_table_truncated_subelem(dev, apdev):
1165 """Beacon request - beacon table mode - Truncated subelement"""
1166 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1167 hapd = hostapd.add_ap(apdev[0], params)
1168
1169 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1170 addr = dev[0].own_addr()
1171
1172 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "0001")
1173 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
1174 if ev is not None:
1175 raise Exception("Unexpected beacon report response (truncated subelement)")
1176 hapd.dump_monitor()
1177
1178 @remote_compatible
1179 def test_rrm_beacon_req_table_rsne(dev, apdev):
1180 """Beacon request - beacon table mode - RSNE reporting"""
1181 params = hostapd.wpa2_params(ssid="rrm-rsn", passphrase="12345678")
1182 params["rrm_beacon_report"] = "1"
1183 hapd = hostapd.add_ap(apdev[0], params)
1184
1185 dev[0].connect("rrm-rsn", psk="12345678", scan_freq="2412")
1186 addr = dev[0].own_addr()
1187
1188 token = run_req_beacon(hapd, addr, "51000000000002ffffffffffff" + "020101" + "0a0130")
1189 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1190 if ev is None:
1191 raise Exception("Beacon report response not received")
1192 fields = ev.split(' ')
1193 report = BeaconReport(binascii.unhexlify(fields[4]))
1194 logger.info("Received beacon report: " + str(report))
1195 if not report.frame_body:
1196 raise Exception("Reported Frame Body subelement missing")
1197 if len(report.frame_body) != 12 + 22:
1198 raise Exception("Unexpected Reported Frame Body subelement length with Reporting Detail 1 and requested element RSNE")
1199 if binascii.unhexlify("30140100000fac040100000fac040100000fac020c00") not in report.frame_body:
1200 raise Exception("Full RSNE not found")
1201
1202 def test_rrm_beacon_req_table_vht(dev, apdev):
1203 """Beacon request - beacon table mode - VHT"""
1204 clear_scan_cache(apdev[0])
1205 try:
1206 hapd = None
1207 params = {"ssid": "rrm-vht",
1208 "country_code": "FI",
1209 "hw_mode": "a",
1210 "channel": "36",
1211 "ht_capab": "[HT40+]",
1212 "ieee80211n": "1",
1213 "ieee80211ac": "1",
1214 "vht_oper_chwidth": "1",
1215 "vht_oper_centr_freq_seg0_idx": "42",
1216 "rrm_beacon_report": "1"}
1217 hapd = hostapd.add_ap(apdev[0], params)
1218
1219 params = {"ssid": "test-vht40",
1220 "country_code": "FI",
1221 "hw_mode": "a",
1222 "channel": "48",
1223 "ieee80211n": "1",
1224 "ieee80211ac": "1",
1225 "ht_capab": "[HT40-]",
1226 "vht_capab": "",
1227 "vht_oper_chwidth": "0",
1228 "vht_oper_centr_freq_seg0_idx": "0",
1229 }
1230 hapd2 = hostapd.add_ap(apdev[1], params)
1231
1232 dev[0].scan_for_bss(apdev[1]['bssid'], freq=5240)
1233 dev[0].connect("rrm-vht", key_mgmt="NONE", scan_freq="5180")
1234
1235 addr = dev[0].own_addr()
1236
1237 token = run_req_beacon(hapd, addr, "f0000000000002ffffffffffff")
1238 for i in range(2):
1239 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1240 if ev is None:
1241 raise Exception("Beacon report %d response not received" % i)
1242 fields = ev.split(' ')
1243 report = BeaconReport(binascii.unhexlify(fields[4]))
1244 logger.info("Received beacon report: " + str(report))
1245 if report.bssid_str == apdev[0]['bssid']:
1246 if report.opclass != 128 or report.channel != 36:
1247 raise Exception("Incorrect opclass/channel for AP0")
1248 elif report.bssid_str == apdev[1]['bssid']:
1249 if report.opclass != 117 or report.channel != 48:
1250 raise Exception("Incorrect opclass/channel for AP1")
1251 except Exception as e:
1252 if isinstance(e, Exception) and str(e) == "AP startup failed":
1253 if not vht_supported():
1254 raise HwsimSkip("80 MHz channel not supported in regulatory information")
1255 raise
1256 finally:
1257 dev[0].request("DISCONNECT")
1258 disable_hapd(hapd)
1259 disable_hapd(hapd2)
1260 clear_regdom_dev(dev)
1261
1262 @remote_compatible
1263 def test_rrm_beacon_req_active(dev, apdev):
1264 """Beacon request - active scan mode"""
1265 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1266 hapd = hostapd.add_ap(apdev[0], params)
1267 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another", "channel": "11"})
1268
1269 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1270 addr = dev[0].own_addr()
1271
1272 token = run_req_beacon(hapd, addr, "51000000640001ffffffffffff")
1273
1274 for i in range(1, 3):
1275 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1276 if ev is None:
1277 raise Exception("Beacon report %d response not received" % i)
1278 fields = ev.split(' ')
1279 report = BeaconReport(binascii.unhexlify(fields[4]))
1280 logger.info("Received beacon report: " + str(report))
1281 if report.bssid_str == apdev[0]['bssid']:
1282 if report.opclass != 81 or report.channel != 1:
1283 raise Exception("Incorrect opclass/channel for AP0")
1284 elif report.bssid_str == apdev[1]['bssid']:
1285 if report.opclass != 81 or report.channel != 11:
1286 raise Exception("Incorrect opclass/channel for AP1")
1287
1288 @remote_compatible
1289 def test_rrm_beacon_req_active_ignore_old_result(dev, apdev):
1290 """Beacon request - active scan mode and old scan result"""
1291 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another"})
1292 dev[0].scan_for_bss(apdev[1]['bssid'], freq=2412)
1293 hapd2.disable()
1294
1295 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1296 hapd = hostapd.add_ap(apdev[0], params)
1297
1298 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1299 addr = dev[0].own_addr()
1300
1301 token = run_req_beacon(hapd, addr, "51010000640001ffffffffffff")
1302
1303 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1304 if ev is None:
1305 raise Exception("Beacon report response not received")
1306 fields = ev.split(' ')
1307 report = BeaconReport(binascii.unhexlify(fields[4]))
1308 logger.info("Received beacon report: " + str(report))
1309 if report.bssid_str == apdev[1]['bssid']:
1310 raise Exception("Old BSS reported")
1311
1312 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
1313 if ev is not None:
1314 raise Exception("Unexpected beacon report response")
1315
1316 def start_ap(dev):
1317 id = dev.add_network()
1318 dev.set_network(id, "mode", "2")
1319 dev.set_network_quoted(id, "ssid", 32*'A')
1320 dev.set_network_quoted(id, "psk", "1234567890")
1321 dev.set_network(id, "frequency", "2412")
1322 dev.set_network(id, "scan_freq", "2412")
1323 dev.select_network(id)
1324 dev.wait_connected()
1325
1326 def test_rrm_beacon_req_active_many(dev, apdev):
1327 """Beacon request - active scan mode and many BSSs"""
1328 for i in range(1, 7):
1329 ifname = apdev[0]['ifname'] if i == 1 else apdev[0]['ifname'] + "-%d" % i
1330 hapd1 = hostapd.add_bss(apdev[0], ifname, 'bss-%i.conf' % i)
1331 hapd1.set('vendor_elements', "dd50" + 80*'bb')
1332 hapd1.request("UPDATE_BEACON")
1333
1334 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
1335 wpas.interface_add("wlan5")
1336 wpas.request("SET device_name " + 20*'a')
1337 start_ap(wpas)
1338 start_ap(dev[1])
1339 start_ap(dev[2])
1340
1341 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1342 params['vendor_elements'] = "dd50" + 80*'aa'
1343 hapd = hostapd.add_ap(apdev[1]['ifname'], params)
1344
1345 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1346 addr = dev[0].own_addr()
1347
1348 ok = False
1349 for j in range(3):
1350 token = run_req_beacon(hapd, addr, "51010000640001ffffffffffff")
1351
1352 for i in range(10):
1353 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1354 if ev is None:
1355 raise Exception("Beacon report %d response not received" % i)
1356 fields = ev.split(' ')
1357 if len(fields[4]) == 0:
1358 break
1359 report = BeaconReport(binascii.unhexlify(fields[4]))
1360 logger.info("Received beacon report: " + str(report))
1361 if i == 9:
1362 ok = True
1363 if ok:
1364 break
1365
1366 @remote_compatible
1367 def test_rrm_beacon_req_active_ap_channels(dev, apdev):
1368 """Beacon request - active scan mode with AP Channel Report subelement"""
1369 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1370 hapd = hostapd.add_ap(apdev[0], params)
1371 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another", "channel": "11"})
1372
1373 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1374 addr = dev[0].own_addr()
1375
1376 token = run_req_beacon(hapd, addr, "51ff0000640001ffffffffffff" + "dd0111" + "330351010b" + "dd0111")
1377
1378 for i in range(1, 3):
1379 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1380 if ev is None:
1381 raise Exception("Beacon report %d response not received" % i)
1382 fields = ev.split(' ')
1383 report = BeaconReport(binascii.unhexlify(fields[4]))
1384 logger.info("Received beacon report: " + str(report))
1385 if report.bssid_str == apdev[0]['bssid']:
1386 if report.opclass != 81 or report.channel != 1:
1387 raise Exception("Incorrect opclass/channel for AP0")
1388 elif report.bssid_str == apdev[1]['bssid']:
1389 if report.opclass != 81 or report.channel != 11:
1390 raise Exception("Incorrect opclass/channel for AP1")
1391
1392 @remote_compatible
1393 def test_rrm_beacon_req_passive_ap_channels(dev, apdev):
1394 """Beacon request - passive scan mode with AP Channel Report subelement"""
1395 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1396 hapd = hostapd.add_ap(apdev[0], params)
1397 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another", "channel": "11"})
1398
1399 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1400 addr = dev[0].own_addr()
1401
1402 token = run_req_beacon(hapd, addr, "51ff0000640000ffffffffffff" + "330351010b" + "3300" + "dd00")
1403
1404 for i in range(1, 3):
1405 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1406 if ev is None:
1407 raise Exception("Beacon report %d response not received" % i)
1408 fields = ev.split(' ')
1409 report = BeaconReport(binascii.unhexlify(fields[4]))
1410 logger.info("Received beacon report: " + str(report))
1411 if report.bssid_str == apdev[0]['bssid']:
1412 if report.opclass != 81 or report.channel != 1:
1413 raise Exception("Incorrect opclass/channel for AP0")
1414 elif report.bssid_str == apdev[1]['bssid']:
1415 if report.opclass != 81 or report.channel != 11:
1416 raise Exception("Incorrect opclass/channel for AP1")
1417
1418 @remote_compatible
1419 def test_rrm_beacon_req_active_single_channel(dev, apdev):
1420 """Beacon request - active scan mode with single channel"""
1421 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1422 hapd = hostapd.add_ap(apdev[0], params)
1423 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another", "channel": "11"})
1424
1425 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1426 addr = dev[0].own_addr()
1427
1428 token = run_req_beacon(hapd, addr, "510b0000640001ffffffffffff")
1429
1430 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1431 if ev is None:
1432 raise Exception("Beacon report response not received")
1433 fields = ev.split(' ')
1434 report = BeaconReport(binascii.unhexlify(fields[4]))
1435 logger.info("Received beacon report: " + str(report))
1436
1437 @remote_compatible
1438 def test_rrm_beacon_req_active_ap_channels_unknown_opclass(dev, apdev):
1439 """Beacon request - active scan mode with AP Channel Report subelement and unknown opclass"""
1440 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1441 hapd = hostapd.add_ap(apdev[0], params)
1442 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another", "channel": "11"})
1443
1444 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1445 addr = dev[0].own_addr()
1446
1447 token = run_req_beacon(hapd, addr, "51ff0000640001ffffffffffff" + "3303ff010b")
1448
1449 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1450 if ev is None:
1451 raise Exception("Beacon report response (refused) not received")
1452
1453 fields = ev.split(' ')
1454 if fields[3] != "04":
1455 raise Exception("Unexpected beacon report mode: " + fields[3])
1456
1457 @remote_compatible
1458 def test_rrm_beacon_req_active_ap_channel_oom(dev, apdev):
1459 """Beacon request - AP Channel Report subelement and OOM"""
1460 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1461 hapd = hostapd.add_ap(apdev[0], params)
1462 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another", "channel": "11"})
1463
1464 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1465 addr = dev[0].own_addr()
1466
1467 with alloc_fail(dev[0], 1, "wpas_add_channels"):
1468 token = run_req_beacon(hapd, addr, "51ff0000640001ffffffffffff" + "330351010b")
1469 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1470 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1471 # allow either not to respond or send refused response
1472 if ev is not None:
1473 fields = ev.split(' ')
1474 if fields[3] != "04":
1475 raise Exception("Unexpected Beacon report during OOM with mode: " + fields[3])
1476
1477 @remote_compatible
1478 def test_rrm_beacon_req_active_scan_fail(dev, apdev):
1479 """Beacon request - Active scan failure"""
1480 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1481 hapd = hostapd.add_ap(apdev[0], params)
1482
1483 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1484 addr = dev[0].own_addr()
1485
1486 with alloc_fail(dev[0], 1, "wpa_supplicant_trigger_scan"):
1487 token = run_req_beacon(hapd, addr, "51ff0000640001ffffffffffff" + "330351010b")
1488 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1489 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1490 if ev is None:
1491 raise Exception("No Beacon report")
1492 fields = ev.split(' ')
1493 if fields[3] != "04":
1494 raise Exception("Unexpected Beacon report contents: " + ev)
1495
1496 @remote_compatible
1497 def test_rrm_beacon_req_active_zero_duration(dev, apdev):
1498 """Beacon request - Action scan and zero duration"""
1499 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1500 hapd = hostapd.add_ap(apdev[0], params)
1501 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another", "channel": "11"})
1502
1503 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1504 addr = dev[0].own_addr()
1505
1506 token = run_req_beacon(hapd, addr, "51000000000001ffffffffffff")
1507 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
1508 if ev is not None:
1509 raise Exception("Unexpected Beacon report")
1510
1511 @remote_compatible
1512 def test_rrm_beacon_req_active_fail_random(dev, apdev):
1513 """Beacon request - active scan mode os_get_random failure"""
1514 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1515 hapd = hostapd.add_ap(apdev[0], params)
1516 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1517 addr = dev[0].own_addr()
1518
1519 with fail_test(dev[0], 1, "os_get_random;wpas_rm_handle_beacon_req"):
1520 token = run_req_beacon(hapd, addr, "51000000640001ffffffffffff")
1521 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1522 if ev is None:
1523 raise Exception("Beacon report response not received")
1524 fields = ev.split(' ')
1525 report = BeaconReport(binascii.unhexlify(fields[4]))
1526 logger.info("Received beacon report: " + str(report))
1527
1528 @remote_compatible
1529 def test_rrm_beacon_req_passive(dev, apdev):
1530 """Beacon request - passive scan mode"""
1531 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1532 hapd = hostapd.add_ap(apdev[0], params)
1533 hapd2 = hostapd.add_ap(apdev[1], {"ssid": "another", "channel": "11"})
1534
1535 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1536 addr = dev[0].own_addr()
1537
1538 token = run_req_beacon(hapd, addr, "51000000640000ffffffffffff")
1539
1540 for i in range(1, 3):
1541 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1542 if ev is None:
1543 raise Exception("Beacon report %d response not received" % i)
1544 fields = ev.split(' ')
1545 report = BeaconReport(binascii.unhexlify(fields[4]))
1546 logger.info("Received beacon report: " + str(report))
1547 if report.bssid_str == apdev[0]['bssid']:
1548 if report.opclass != 81 or report.channel != 1:
1549 raise Exception("Incorrect opclass/channel for AP0")
1550 elif report.bssid_str == apdev[1]['bssid']:
1551 if report.opclass != 81 or report.channel != 11:
1552 raise Exception("Incorrect opclass/channel for AP1")
1553
1554 @remote_compatible
1555 def test_rrm_beacon_req_passive_no_match(dev, apdev):
1556 """Beacon request - passive scan mode and no matching BSS"""
1557 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1558 hapd = hostapd.add_ap(apdev[0], params)
1559
1560 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1561 addr = dev[0].own_addr()
1562
1563 token = run_req_beacon(hapd, addr, "51010000640000021122334455")
1564 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1565 if ev is None:
1566 raise Exception("Beacon report %d response not received" % i)
1567 fields = ev.split(' ')
1568 if len(fields[4]) > 0:
1569 raise Exception("Unexpected beacon report BSS")
1570
1571 @remote_compatible
1572 def test_rrm_beacon_req_passive_no_match_oom(dev, apdev):
1573 """Beacon request - passive scan mode and no matching BSS (OOM)"""
1574 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1575 hapd = hostapd.add_ap(apdev[0], params)
1576
1577 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1578 addr = dev[0].own_addr()
1579
1580 with alloc_fail(dev[0], 1, "wpabuf_resize;wpas_beacon_rep_scan_process"):
1581 token = run_req_beacon(hapd, addr, "51010000640000021122334455")
1582 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1583 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=0.2)
1584 if ev is not None:
1585 raise Exception("Unexpected Beacon report response during OOM")
1586
1587 # verify reporting is still functional
1588 token = run_req_beacon(hapd, addr, "51010000640000021122334455")
1589 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1590 if ev is None:
1591 raise Exception("Beacon report %d response not received" % i)
1592 fields = ev.split(' ')
1593 if len(fields[4]) > 0:
1594 raise Exception("Unexpected beacon report BSS")
1595
1596 @remote_compatible
1597 def test_rrm_beacon_req_active_duration_mandatory(dev, apdev):
1598 """Beacon request - Action scan and duration mandatory"""
1599 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1600 hapd = hostapd.add_ap(apdev[0], params)
1601
1602 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1603 addr = dev[0].own_addr()
1604
1605 token = run_req_beacon(hapd, addr, "req_mode=10 51000000640001ffffffffffff")
1606 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1607 if ev is None:
1608 raise Exception("No Beacon report response")
1609 fields = ev.split(' ')
1610 rrm = int(dev[0].get_driver_status_field("capa.rrm_flags"), 16)
1611 if rrm & 0x20 == 0x20:
1612 report = BeaconReport(binascii.unhexlify(fields[4]))
1613 logger.info("Received beacon report: " + str(report))
1614 else:
1615 # Driver does not support scan dwell time setting, so wpa_supplicant
1616 # rejects the measurement request due to the mandatory duration using
1617 # Measurement Report Mode field Incapable=1.
1618 if fields[3] != '02':
1619 raise Exception("Unexpected Measurement Report Mode: " + fields[3])
1620 if len(fields[4]) > 0:
1621 raise Exception("Unexpected beacon report received")
1622
1623 def test_rrm_beacon_req_passive_scan_vht(dev, apdev):
1624 """Beacon request - passive scan mode - VHT"""
1625 clear_scan_cache(apdev[0])
1626 try:
1627 hapd = None
1628 params = {"ssid": "rrm-vht",
1629 "country_code": "FI",
1630 'ieee80211d': '1',
1631 "hw_mode": "a",
1632 "channel": "36",
1633 "ht_capab": "[HT40+]",
1634 "ieee80211n": "1",
1635 "ieee80211ac": "1",
1636 "vht_oper_chwidth": "1",
1637 "vht_oper_centr_freq_seg0_idx": "42",
1638 "rrm_beacon_report": "1"}
1639 hapd = hostapd.add_ap(apdev[0], params)
1640
1641 dev[0].scan_for_bss(apdev[0]['bssid'], freq=5180)
1642 dev[0].connect("rrm-vht", key_mgmt="NONE", scan_freq="5180")
1643
1644 addr = dev[0].own_addr()
1645
1646 token = run_req_beacon(hapd, addr, "80000000640000ffffffffffff")
1647 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1648 if ev is None:
1649 raise Exception("Beacon report response not received")
1650 fields = ev.split(' ')
1651 report = BeaconReport(binascii.unhexlify(fields[4]))
1652 logger.info("Received beacon report: " + str(report))
1653 if report.opclass != 128 or report.channel != 36:
1654 raise Exception("Incorrect opclass/channel for AP")
1655
1656 token = run_req_beacon(hapd, addr, "82000000640000ffffffffffff")
1657 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1658 if ev is None:
1659 raise Exception("Beacon report response not received")
1660 fields = ev.split(' ')
1661 report = BeaconReport(binascii.unhexlify(fields[4]))
1662 logger.info("Received beacon report: " + str(report))
1663 if report.opclass != 128 or report.channel != 36:
1664 raise Exception("Incorrect opclass/channel for AP")
1665 except Exception as e:
1666 if isinstance(e, Exception) and str(e) == "AP startup failed":
1667 if not vht_supported():
1668 raise HwsimSkip("80 MHz channel not supported in regulatory information")
1669 raise
1670 finally:
1671 clear_regdom(hapd, dev)
1672
1673 def test_rrm_beacon_req_passive_scan_vht160(dev, apdev):
1674 """Beacon request - passive scan mode - VHT160"""
1675 clear_scan_cache(apdev[0])
1676 try:
1677 hapd = None
1678 params = {"ssid": "rrm-vht",
1679 "country_code": "ZA",
1680 'ieee80211d': '1',
1681 "hw_mode": "a",
1682 "channel": "104",
1683 "ht_capab": "[HT40-]",
1684 "ieee80211n": "1",
1685 "ieee80211ac": "1",
1686 "vht_oper_chwidth": "2",
1687 "vht_oper_centr_freq_seg0_idx": "114",
1688 "rrm_beacon_report": "1"}
1689 hapd = hostapd.add_ap(apdev[0], params)
1690
1691 dev[0].scan_for_bss(apdev[0]['bssid'], freq=5520)
1692 dev[0].connect("rrm-vht", key_mgmt="NONE", scan_freq="5520")
1693 sig = dev[0].request("SIGNAL_POLL").splitlines()
1694 if "WIDTH=160 MHz" not in sig:
1695 raise Exception("Unexpected SIGNAL_POLL value: " + str(sig))
1696
1697 addr = dev[0].own_addr()
1698
1699 token = run_req_beacon(hapd, addr, "81000000640000ffffffffffff")
1700 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
1701 if ev is None:
1702 raise Exception("Beacon report response not received")
1703 fields = ev.split(' ')
1704 report = BeaconReport(binascii.unhexlify(fields[4]))
1705 logger.info("Received beacon report: " + str(report))
1706 if report.opclass != 129 or report.channel != 104:
1707 raise Exception("Incorrect opclass/channel for AP")
1708 except Exception as e:
1709 if isinstance(e, Exception) and str(e) == "AP startup failed":
1710 raise HwsimSkip("ZA regulatory rule likely did not have DFS requirement removed")
1711 raise
1712 finally:
1713 clear_regdom(hapd, dev)
1714
1715 def test_rrm_beacon_req_ap_errors(dev, apdev):
1716 """Beacon request - AP error cases"""
1717 try:
1718 run_rrm_beacon_req_ap_errors(dev, apdev)
1719 finally:
1720 dev[1].request("VENDOR_ELEM_REMOVE 13 *")
1721
1722 def run_rrm_beacon_req_ap_errors(dev, apdev):
1723 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1724 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1725 bssid = hapd.own_addr()
1726 dev[0].scan_for_bss(bssid, freq=2412)
1727 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1728 addr = dev[0].own_addr()
1729 # Override RM capabilities (remove all)
1730 dev[1].request("VENDOR_ELEM_ADD 13 46050000000000")
1731 dev[1].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1732 addr1 = dev[1].own_addr()
1733
1734 # Beacon request: Too short request data
1735 if "FAIL" not in hapd.request("REQ_BEACON " + addr + " 11"):
1736 raise Exception("Invalid REQ_BEACON accepted")
1737
1738 # Beacon request: 02:00:00:00:01:00 does not support table beacon report
1739 if "FAIL" not in hapd.request("REQ_BEACON " + addr1 + " 51000000000002ffffffffffff"):
1740 raise Exception("Invalid REQ_BEACON accepted")
1741
1742 # Beacon request: 02:00:00:00:01:00 does not support active beacon report
1743 if "FAIL" not in hapd.request("REQ_BEACON " + addr1 + " 51000000640001ffffffffffff"):
1744 raise Exception("Invalid REQ_BEACON accepted")
1745
1746 # Beacon request: 02:00:00:00:01:00 does not support passive beacon report
1747 if "FAIL" not in hapd.request("REQ_BEACON " + addr1 + " 510b0000640000ffffffffffff"):
1748 raise Exception("Invalid REQ_BEACON accepted")
1749
1750 # Beacon request: Unknown measurement mode 3
1751 if "FAIL" not in hapd.request("REQ_BEACON " + addr1 + " 510b0000640003ffffffffffff"):
1752 raise Exception("Invalid REQ_BEACON accepted")
1753
1754 for i in range(257):
1755 if "FAIL" in hapd.request("REQ_BEACON " + addr + " 510b0000640000ffffffffffff"):
1756 raise Exception("REQ_BEACON failed")
1757 dev[0].dump_monitor()
1758 hapd.dump_monitor()
1759
1760 with alloc_fail(hapd, 1, "wpabuf_alloc;hostapd_send_beacon_req"):
1761 if "FAIL" not in hapd.request("REQ_BEACON " + addr + " 510b0000640000ffffffffffff"):
1762 raise Exception("REQ_BEACON accepted during OOM")
1763
1764 with fail_test(hapd, 1, "nl80211_send_frame_cmd;hostapd_send_beacon_req"):
1765 if "FAIL" not in hapd.request("REQ_BEACON " + addr + " 510b0000640000ffffffffffff"):
1766 raise Exception("REQ_BEACON accepted during failure testing")
1767
1768 def test_rrm_req_reject_oom(dev, apdev):
1769 """Radio measurement request - OOM while rejecting a request"""
1770 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1771 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1772 bssid = hapd.own_addr()
1773
1774 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1775 addr = dev[0].own_addr()
1776
1777 hdr = "d0003a01" + addr.replace(':', '') + 2*bssid.replace(':', '') + "1000"
1778
1779 hapd.set("ext_mgmt_frame_handling", "1")
1780 dev[0].request("SET ext_mgmt_frame_handling 1")
1781
1782 with alloc_fail(dev[0], 1, "wpabuf_resize;wpas_rrm_handle_msr_req_element"):
1783 # "RRM: Parallel measurements are not supported, reject"
1784 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "05000100002603010105"):
1785 raise Exception("MGMT_RX_PROCESS failed")
1786 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1787 ev = hapd.wait_event(["MGMT-RX"], timeout=0.2)
1788 if ev is not None:
1789 raise Exception("Unexpected beacon report response during OOM")
1790
1791 def test_rrm_req_when_rrm_not_used(dev, apdev):
1792 """Radio/link measurement request for non-RRM association"""
1793 params = {"ssid": "rrm"}
1794 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1795 bssid = hapd.own_addr()
1796
1797 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1798 addr = dev[0].own_addr()
1799
1800 hdr = "d0003a01" + addr.replace(':', '') + 2*bssid.replace(':', '') + "1000"
1801
1802 hapd.set("ext_mgmt_frame_handling", "1")
1803 dev[0].request("SET ext_mgmt_frame_handling 1")
1804
1805 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "050001000026030100fe"):
1806 raise Exception("MGMT_RX_PROCESS failed")
1807 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "0502000000"):
1808 raise Exception("MGMT_RX_PROCESS failed")
1809 ev = hapd.wait_event(["MGMT-RX"], timeout=0.2)
1810 if ev is not None:
1811 raise Exception("Unexpected beacon report response when RRM is disabled")
1812
1813 dev[0].request("REMOVE_NETWORK all")
1814 dev[0].wait_disconnected()
1815 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "050001000026030100fe"):
1816 raise Exception("MGMT_RX_PROCESS failed")
1817 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "0502000000"):
1818 raise Exception("MGMT_RX_PROCESS failed")
1819
1820 @remote_compatible
1821 def test_rrm_req_proto(dev, apdev):
1822 """Radio measurement request - protocol testing"""
1823 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1824 hapd = hostapd.add_ap(apdev[0], params)
1825 bssid = hapd.own_addr()
1826
1827 dev[0].request("SET LCI ")
1828 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1829 addr = dev[0].own_addr()
1830
1831 hdr = "d0003a01" + addr.replace(':', '') + 2*bssid.replace(':', '') + "1000"
1832
1833 hapd.set("ext_mgmt_frame_handling", "1")
1834 dev[0].request("SET ext_mgmt_frame_handling 1")
1835
1836 tests = []
1837 # "RRM: Ignoring too short radio measurement request"
1838 tests += ["0500", "050001", "05000100"]
1839 # No measurement request element at all
1840 tests += ["0500010000"]
1841 # "RRM: Truncated element"
1842 tests += ["050001000026"]
1843 # "RRM: Element length too short"
1844 tests += ["05000100002600", "0500010000260111", "050001000026021122"]
1845 # "RRM: Element length too long"
1846 tests += ["05000100002603", "0500010000260311", "050001000026031122"]
1847 # "RRM: Enable bit not supported, ignore"
1848 tests += ["05000100002603010200"]
1849 # "RRM: Measurement report failed. TX power insertion not supported"
1850 # OR
1851 # "RRM: Link measurement report failed. Request too short"
1852 tests += ["0502"]
1853 # Too short LCI request
1854 tests += ["05000100002603010008"]
1855 # Too short neighbor report response
1856 tests += ["0505"]
1857 # Unexpected neighbor report response
1858 tests += ["050500", "050501", "050502", "050503", "050504", "050505"]
1859 # Too short beacon request
1860 tests += ["05000100002603010005",
1861 "0500010000260f010005112233445566778899aabbcc"]
1862 # Unknown beacon report mode
1863 tests += ["05000100002610010005112233445566778899aabbccdd"]
1864 # "RRM: Expected Measurement Request element, but EID is 0"
1865 tests += ["05000100000000"]
1866 for t in tests:
1867 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
1868 raise Exception("MGMT_RX_PROCESS failed")
1869 ev = hapd.wait_event(["MGMT-RX"], timeout=0.2)
1870 if ev is not None:
1871 raise Exception("Unexpected response seen at the AP: " + ev)
1872
1873 tests = []
1874 # "RRM: Parallel measurements are not supported, reject"
1875 tests += ["05000100002603010105"]
1876 # "RRM: Unsupported radio measurement type 254"
1877 tests += ["050001000026030100fe"]
1878 # Reject LCI request
1879 tests += ["0500010000260701000811223344"]
1880 # Beacon report info subelement; no valid channels
1881 tests += ["05000100002614010005112233445566008899aabbccdd01020000"]
1882 for t in tests:
1883 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
1884 raise Exception("MGMT_RX_PROCESS failed")
1885 ev = hapd.wait_event(["MGMT-RX"], timeout=5)
1886 if ev is None:
1887 raise Exception("No response seen at the AP")
1888 hapd.dump_monitor()
1889
1890 dev[0].request("SET LCI " + lci)
1891 tests = []
1892 # "Not building LCI report - bad location subject"
1893 tests += ["0500010000260701000811223344"]
1894 for t in tests:
1895 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
1896 raise Exception("MGMT_RX_PROCESS failed")
1897 ev = hapd.wait_event(["MGMT-RX"], timeout=0.2)
1898 if ev is not None:
1899 raise Exception("Unexpected response seen at the AP: " + ev)
1900
1901 tests = []
1902 # LCI report or reject
1903 tests += ["0500010000260701000801223344",
1904 "05000100002607010008010402ff",
1905 "05000100002608010008010402ffff"]
1906 for t in tests:
1907 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
1908 raise Exception("MGMT_RX_PROCESS failed")
1909 ev = hapd.wait_event(["MGMT-RX"], timeout=5)
1910 if ev is None:
1911 raise Exception("No response seen at the AP")
1912 hapd.dump_monitor()
1913
1914 # Verify rejection of a group-addressed request frame
1915 hdr = "d0003a01" + "ffffffffffff" + 2*bssid.replace(':', '') + "1000"
1916 # "RRM: Parallel measurements are not supported, reject"
1917 t = "05000100002603010105"
1918 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
1919 raise Exception("MGMT_RX_PROCESS failed")
1920 ev = hapd.wait_event(["MGMT-RX"], timeout=0.1)
1921 if ev is not None:
1922 raise Exception("Unexpected response seen at the AP (broadcast request rejected)")
1923 hapd.dump_monitor()
1924
1925 hapd.set("ext_mgmt_frame_handling", "0")
1926 dev[0].request("SET ext_mgmt_frame_handling 0")
1927 dev[0].request("SET LCI ")
1928
1929 def test_rrm_link_measurement(dev, apdev):
1930 """Radio measurement request - link measurement"""
1931 check_tx_power_support(dev[0])
1932 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1933 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1934 bssid = hapd.own_addr()
1935
1936 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1937 addr = dev[0].own_addr()
1938
1939 hdr = "d0003a01" + addr.replace(':', '') + 2*bssid.replace(':', '') + "1000"
1940
1941 hapd.set("ext_mgmt_frame_handling", "1")
1942 dev[0].request("SET ext_mgmt_frame_handling 1")
1943
1944 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "0502000000"):
1945 raise Exception("MGMT_RX_PROCESS failed")
1946 ev = hapd.wait_event(["MGMT-RX"], timeout=5)
1947 if ev is None:
1948 raise Exception("No link measurement report seen")
1949
1950 def test_rrm_link_measurement_oom(dev, apdev):
1951 """Radio measurement request - link measurement OOM"""
1952 check_tx_power_support(dev[0])
1953 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
1954 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1955 bssid = hapd.own_addr()
1956
1957 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1958 addr = dev[0].own_addr()
1959
1960 hdr = "d0003a01" + addr.replace(':', '') + 2*bssid.replace(':', '') + "1000"
1961
1962 hapd.set("ext_mgmt_frame_handling", "1")
1963 dev[0].request("SET ext_mgmt_frame_handling 1")
1964
1965 with alloc_fail(dev[0], 1, "wpabuf_alloc;wpas_rrm_handle_link_measurement_request"):
1966 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "0502000000"):
1967 raise Exception("MGMT_RX_PROCESS failed")
1968 wait_fail_trigger(dev[0], "GET_ALLOC_FAIL")
1969
1970 with fail_test(dev[0], 1, "wpas_rrm_handle_link_measurement_request"):
1971 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "0502000000"):
1972 raise Exception("MGMT_RX_PROCESS failed")
1973 wait_fail_trigger(dev[0], "GET_FAIL")
1974
1975 ev = hapd.wait_event(["MGMT-RX"], timeout=0.1)
1976 if ev is not None:
1977 raise Exception("Unexpected beacon report response during OOM")
1978
1979 def test_rrm_rep_parse_proto(dev, apdev):
1980 """hostapd rrm report parsing protocol testing"""
1981 check_rrm_support(dev[0])
1982
1983 params = {"ssid": "rrm", "rrm_neighbor_report": "1"}
1984 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1985 bssid = hapd.own_addr()
1986
1987 dev[0].request("SET LCI " + lci)
1988 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
1989 addr = dev[0].own_addr()
1990
1991 hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000"
1992 hapd.set("ext_mgmt_frame_handling", "1")
1993
1994 tests = ["0501",
1995 "05ff01",
1996 "0501012703fffffe2700",
1997 "0501012703ffff05",
1998 "05010127ffffff05" + 252*"00",
1999 "0504012603ffffff2600",
2000 "0504012603ffff08",
2001 "0504012608ffff08ffffffffff",
2002 "0504012608ffff08ff04021234",
2003 "0504012608ffff08ff04020100",
2004 "0504012608ffff08ff0402ffff"]
2005 for t in tests:
2006 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
2007 raise Exception("MGMT_RX_PROCESS failed for " + t)
2008
2009 if "OK" not in hapd.request("SET_NEIGHBOR 00:11:22:33:44:55 ssid=\"rrm\" nr=" + nr + " lci=" + lci):
2010 raise Exception("Set neighbor failed")
2011 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + "0504012608ffff08ff04021000"):
2012 raise Exception("MGMT_RX_PROCESS failed")
2013
2014 def test_rrm_unexpected(dev, apdev):
2015 """hostapd unexpected rrm"""
2016 check_rrm_support(dev[0])
2017
2018 params = {"ssid": "rrm", "rrm_neighbor_report": "0"}
2019 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2020 bssid = hapd.own_addr()
2021
2022 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
2023 addr = dev[0].own_addr()
2024
2025 hdr = "d0003a01" + bssid.replace(':', '') + addr.replace(':', '') + bssid.replace(':', '') + "1000"
2026 hapd.set("ext_mgmt_frame_handling", "1")
2027
2028 tests = ["050401"]
2029 for t in tests:
2030 if "OK" not in hapd.request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + hdr + t):
2031 raise Exception("MGMT_RX_PROCESS failed for " + t)
2032
2033 def check_beacon_req(hapd, addr, idx):
2034 request = "51000000000002ffffffffffff" + "020100"
2035 token = hapd.request("REQ_BEACON " + addr + " " + request)
2036 if "FAIL" in token:
2037 raise Exception("REQ_BEACON failed (%d)" % idx)
2038 ev = hapd.wait_event(["BEACON-RESP-RX"], timeout=10)
2039 if ev is None:
2040 raise Exception("Beacon report response not received (%d)" % idx)
2041
2042 def test_rrm_reassociation(dev, apdev):
2043 """Radio measurement request - reassociation"""
2044 params = {"ssid": "rrm", "rrm_beacon_report": "1"}
2045 hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2046 bssid = hapd.own_addr()
2047
2048 addr = dev[0].own_addr()
2049 dev[0].connect("rrm", key_mgmt="NONE", scan_freq="2412")
2050 check_beacon_req(hapd, addr, 1)
2051
2052 dev[0].request("REASSOCIATE")
2053 dev[0].wait_connected()
2054 check_beacon_req(hapd, addr, 1)
2055
2056 hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
2057 bssid2 = hapd2.own_addr()
2058 dev[0].scan_for_bss(bssid2, freq=2412)
2059 dev[0].roam(bssid2)
2060 check_beacon_req(hapd2, addr, 2)
2061
2062 dev[0].scan_for_bss(bssid, freq=2412)
2063 dev[0].roam(bssid)
2064 check_beacon_req(hapd, addr, 3)