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