1# P2P device discovery test cases 2# Copyright (c) 2013, Jouni Malinen <j@w1.fi> 3# 4# This software may be distributed under the terms of the BSD license. 5# See README for more details. 6 7from remotehost import remote_compatible 8import logging 9logger = logging.getLogger() 10import binascii 11import os 12import struct 13import time 14 15import hostapd 16import hwsim_utils 17from wpasupplicant import WpaSupplicant 18from p2p_utils import * 19from hwsim import HWSimRadio 20from tshark import run_tshark 21from test_gas import start_ap 22from test_cfg80211 import nl80211_remain_on_channel 23from test_p2p_channel import set_country 24 25@remote_compatible 26def test_discovery(dev): 27 """P2P device discovery and provision discovery""" 28 addr0 = dev[0].p2p_dev_addr() 29 addr1 = dev[1].p2p_dev_addr() 30 logger.info("Start device discovery") 31 dev[0].p2p_find(social=True, delay=1) 32 if not dev[1].discover_peer(addr0): 33 raise Exception("Device discovery timed out") 34 if not dev[0].discover_peer(addr1): 35 raise Exception("Device discovery timed out") 36 37 logger.info("Test provision discovery for display") 38 dev[0].global_request("P2P_PROV_DISC " + addr1 + " display") 39 ev1 = dev[1].wait_global_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=15) 40 if ev1 is None: 41 raise Exception("Provision discovery timed out (display/dev1)") 42 if addr0 not in ev1: 43 raise Exception("Dev0 not in provision discovery event") 44 ev0 = dev[0].wait_global_event(["P2P-PROV-DISC-ENTER-PIN", 45 "P2P-PROV-DISC-FAILURE"], timeout=15) 46 if ev0 is None: 47 raise Exception("Provision discovery timed out (display/dev0)") 48 if "P2P-PROV-DISC-FAILURE" in ev0: 49 raise Exception("Provision discovery failed (display/dev0)") 50 if addr1 not in ev0: 51 raise Exception("Dev1 not in provision discovery event") 52 53 logger.info("Test provision discovery for keypad") 54 dev[0].global_request("P2P_PROV_DISC " + addr1 + " keypad") 55 ev1 = dev[1].wait_global_event(["P2P-PROV-DISC-ENTER-PIN"], timeout=15) 56 if ev1 is None: 57 raise Exception("Provision discovery timed out (keypad/dev1)") 58 if addr0 not in ev1: 59 raise Exception("Dev0 not in provision discovery event") 60 ev0 = dev[0].wait_global_event(["P2P-PROV-DISC-SHOW-PIN", 61 "P2P-PROV-DISC-FAILURE"], 62 timeout=15) 63 if ev0 is None: 64 raise Exception("Provision discovery timed out (keypad/dev0)") 65 if "P2P-PROV-DISC-FAILURE" in ev0: 66 raise Exception("Provision discovery failed (keypad/dev0)") 67 if addr1 not in ev0: 68 raise Exception("Dev1 not in provision discovery event") 69 70 logger.info("Test provision discovery for push button") 71 dev[0].global_request("P2P_PROV_DISC " + addr1 + " pbc") 72 ev1 = dev[1].wait_global_event(["P2P-PROV-DISC-PBC-REQ"], timeout=15) 73 if ev1 is None: 74 raise Exception("Provision discovery timed out (pbc/dev1)") 75 if addr0 not in ev1: 76 raise Exception("Dev0 not in provision discovery event") 77 ev0 = dev[0].wait_global_event(["P2P-PROV-DISC-PBC-RESP", 78 "P2P-PROV-DISC-FAILURE"], 79 timeout=15) 80 if ev0 is None: 81 raise Exception("Provision discovery timed out (pbc/dev0)") 82 if "P2P-PROV-DISC-FAILURE" in ev0: 83 raise Exception("Provision discovery failed (pbc/dev0)") 84 if addr1 not in ev0: 85 raise Exception("Dev1 not in provision discovery event") 86 87 dev[0].p2p_stop_find() 88 dev[1].p2p_stop_find() 89 90 if "FAIL" not in dev[0].p2p_find(dev_id="foo"): 91 raise Exception("P2P_FIND with invalid dev_id accepted") 92 if "FAIL" not in dev[0].p2p_find(dev_type="foo"): 93 raise Exception("P2P_FIND with invalid dev_type accepted") 94 if "FAIL" not in dev[0].p2p_find(dev_type="1-foo-2"): 95 raise Exception("P2P_FIND with invalid dev_type accepted") 96 if "FAIL" not in dev[0].p2p_find(dev_type="1-11223344"): 97 raise Exception("P2P_FIND with invalid dev_type accepted") 98 99 if "FAIL" not in dev[0].global_request("P2P_PROV_DISC foo pbc"): 100 raise Exception("Invalid P2P_PROV_DISC accepted") 101 if "FAIL" not in dev[0].global_request("P2P_PROV_DISC 00:11:22:33:44:55"): 102 raise Exception("Invalid P2P_PROV_DISC accepted") 103 if "FAIL" not in dev[0].global_request("P2P_PROV_DISC 00:11:22:33:44:55 pbc join"): 104 raise Exception("Invalid P2P_PROV_DISC accepted") 105 if "FAIL" not in dev[0].global_request("P2P_PROV_DISC 00:11:22:33:44:55 foo"): 106 raise Exception("Invalid P2P_PROV_DISC accepted") 107 108@remote_compatible 109def test_discovery_pd_retries(dev): 110 """P2P device discovery and provision discovery retries""" 111 addr0 = dev[0].p2p_dev_addr() 112 addr1 = dev[1].p2p_dev_addr() 113 dev[1].p2p_listen() 114 if not dev[0].discover_peer(addr1): 115 raise Exception("Device discovery timed out") 116 dev[1].p2p_stop_find() 117 dev[0].p2p_stop_find() 118 dev[0].global_request("P2P_PROV_DISC " + addr1 + " display") 119 ev = dev[0].wait_global_event(["P2P-PROV-DISC-FAILURE"], timeout=60) 120 if ev is None: 121 raise Exception("No PD failure reported") 122 123def test_discovery_group_client(dev): 124 """P2P device discovery for a client in a group""" 125 logger.info("Start autonomous GO " + dev[0].ifname) 126 res = dev[0].p2p_start_go(freq="2422") 127 logger.debug("res: " + str(res)) 128 logger.info("Connect a client to the GO") 129 pin = dev[1].wps_read_pin() 130 dev[0].p2p_go_authorize_client(pin) 131 dev[1].p2p_connect_group(dev[0].p2p_dev_addr(), pin, freq=int(res['freq']), 132 timeout=60) 133 logger.info("Client connected") 134 hwsim_utils.test_connectivity_p2p(dev[0], dev[1]) 135 logger.info("Try to discover a P2P client in a group") 136 if not dev[2].discover_peer(dev[1].p2p_dev_addr(), social=False, timeout=10): 137 stop_p2p_find_and_wait(dev[2]) 138 if not dev[2].discover_peer(dev[1].p2p_dev_addr(), social=False, timeout=10): 139 stop_p2p_find_and_wait(dev[2]) 140 if not dev[2].discover_peer(dev[1].p2p_dev_addr(), social=False, timeout=10): 141 raise Exception("Could not discover group client") 142 143 # This is not really perfect, but something to get a bit more testing 144 # coverage.. For proper discoverability mechanism validation, the P2P 145 # client would need to go to sleep to avoid acknowledging the GO Negotiation 146 # Request frame. Offchannel Listen mode operation on the P2P Client with 147 # mac80211_hwsim is apparently not enough to avoid the acknowledgement on 148 # the operating channel, so need to disconnect from the group which removes 149 # the GO-to-P2P Client part of the discoverability exchange in practice. 150 151 pin = dev[2].wps_read_pin() 152 # make group client non-responsive on operating channel 153 dev[1].dump_monitor() 154 dev[1].group_request("DISCONNECT") 155 ev = dev[1].wait_group_event(["CTRL-EVENT-DISCONNECTED"], timeout=10) 156 if ev is None: 157 raise Exception("Timeout on waiting disconnection") 158 dev[2].request("P2P_CONNECT {} {} display".format(dev[1].p2p_dev_addr(), 159 pin)) 160 ev = dev[1].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=2) 161 if ev: 162 raise Exception("Unexpected frame RX on P2P client") 163 # make group client available on operating channe 164 dev[1].group_request("REASSOCIATE") 165 ev = dev[1].wait_global_event(["CTRL-EVENT-CONNECTED", 166 "P2P-GO-NEG-REQUEST"], timeout=15) 167 if ev is None: 168 raise Exception("Timeout on reconnection to group") 169 if "P2P-GO-NEG-REQUEST" not in ev: 170 ev = dev[1].wait_global_event(["P2P-GO-NEG-REQUEST"], timeout=10) 171 if ev is None: 172 raise Exception("Timeout on waiting for GO Negotiation Request") 173 174def stop_p2p_find_and_wait(dev): 175 dev.request("P2P_STOP_FIND") 176 for i in range(10): 177 res = dev.get_driver_status_field("scan_state") 178 if "SCAN_STARTED" not in res and "SCAN_REQUESTED" not in res: 179 break 180 logger.debug("Waiting for final P2P_FIND scan to complete") 181 time.sleep(0.02) 182 183def test_discovery_ctrl_char_in_devname(dev): 184 """P2P device discovery and control character in Device Name""" 185 try: 186 _test_discovery_ctrl_char_in_devname(dev) 187 finally: 188 dev[1].global_request("SET device_name Device B") 189 190def _test_discovery_ctrl_char_in_devname(dev): 191 dev[1].global_request("SET device_name Device\tB") 192 addr0 = dev[0].p2p_dev_addr() 193 addr1 = dev[1].p2p_dev_addr() 194 res = dev[0].p2p_start_go(freq=2422) 195 bssid = dev[0].p2p_interface_addr() 196 pin = dev[1].wps_read_pin() 197 dev[0].p2p_go_authorize_client(pin) 198 dev[1].scan_for_bss(bssid, freq=2422) 199 dev[1].p2p_connect_group(addr0, pin, timeout=60, freq=2422) 200 if not dev[2].discover_peer(addr1, social=False, freq=2422, timeout=5): 201 stop_p2p_find_and_wait(dev[2]) 202 if not dev[2].discover_peer(addr1, social=False, freq=2422, timeout=5): 203 stop_p2p_find_and_wait(dev[2]) 204 if not dev[2].discover_peer(addr1, social=False, freq=2422, 205 timeout=5): 206 raise Exception("Could not discover group client") 207 devname = dev[2].get_peer(addr1)['device_name'] 208 dev[2].p2p_stop_find() 209 if devname != "Device_B": 210 raise Exception("Unexpected device_name from group client: " + devname) 211 212 terminate_group(dev[0], dev[1]) 213 dev[2].request("P2P_FLUSH") 214 215 dev[1].p2p_listen() 216 if not dev[2].discover_peer(addr1, social=True, timeout=10): 217 raise Exception("Could not discover peer") 218 devname = dev[2].get_peer(addr1)['device_name'] 219 dev[2].p2p_stop_find() 220 if devname != "Device_B": 221 raise Exception("Unexpected device_name from peer: " + devname) 222 223@remote_compatible 224def test_discovery_dev_type(dev): 225 """P2P device discovery with Device Type filter""" 226 dev[1].request("SET sec_device_type 1-0050F204-2") 227 dev[1].p2p_listen() 228 dev[0].p2p_find(social=True, dev_type="5-0050F204-1") 229 ev = dev[0].wait_global_event(['P2P-DEVICE-FOUND'], timeout=1) 230 if ev: 231 raise Exception("Unexpected P2P device found") 232 dev[0].p2p_find(social=True, dev_type="1-0050F204-2") 233 ev = dev[0].wait_global_event(['P2P-DEVICE-FOUND'], timeout=2) 234 if ev is None: 235 raise Exception("P2P device not found") 236 peer = dev[0].get_peer(dev[1].p2p_dev_addr()) 237 if "1-0050F204-2" not in peer['sec_dev_type']: 238 raise Exception("sec_device_type not reported properly") 239 240def test_discovery_dev_type_go(dev): 241 """P2P device discovery with Device Type filter on GO""" 242 addr1 = dev[1].p2p_dev_addr() 243 dev[1].request("SET sec_device_type 1-0050F204-2") 244 res = dev[0].p2p_start_go(freq="2412") 245 pin = dev[1].wps_read_pin() 246 dev[0].p2p_go_authorize_client(pin) 247 dev[1].p2p_connect_group(dev[0].p2p_dev_addr(), pin, timeout=60) 248 249 dev[2].p2p_find(social=True, dev_type="5-0050F204-1") 250 ev = dev[2].wait_global_event(['P2P-DEVICE-FOUND'], timeout=1) 251 if ev: 252 raise Exception("Unexpected P2P device found") 253 dev[2].p2p_find(social=True, dev_type="1-0050F204-2") 254 ev = dev[2].wait_global_event(['P2P-DEVICE-FOUND ' + addr1], timeout=2) 255 if ev is None: 256 raise Exception("P2P device not found") 257 258def test_discovery_dev_id(dev): 259 """P2P device discovery with Device ID filter""" 260 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 261 wpas.interface_add("wlan5") 262 wpas.request("P2P_LISTEN 1") 263 status = wpas.global_request("STATUS") 264 if "p2p_state=LISTEN_ONLY" not in status: 265 raise Exception("Unexpected status: " + status) 266 addr1 = dev[1].p2p_dev_addr() 267 dev[1].p2p_listen() 268 dev[0].p2p_find(social=True, dev_id="02:03:04:05:06:07") 269 ev = dev[0].wait_global_event(['P2P-DEVICE-FOUND'], timeout=1) 270 if ev: 271 raise Exception("Unexpected P2P device found") 272 dev[0].p2p_find(social=True, dev_id=addr1) 273 ev = dev[0].wait_global_event(['P2P-DEVICE-FOUND'], timeout=5) 274 if ev is None: 275 raise Exception("P2P device not found") 276 if addr1 not in ev: 277 raise Exception("Unexpected P2P peer found") 278 status = wpas.global_request("STATUS") 279 for i in range(0, 2): 280 if "p2p_state=IDLE" in status: 281 break 282 time.sleep(0.5) 283 status = wpas.global_request("STATUS") 284 if "p2p_state=IDLE" not in status: 285 raise Exception("Unexpected status: " + status) 286 287def test_discovery_dev_id_go(dev): 288 """P2P device discovery with Device ID filter on GO""" 289 addr1 = dev[1].p2p_dev_addr() 290 res = dev[0].p2p_start_go(freq="2412") 291 pin = dev[1].wps_read_pin() 292 dev[0].p2p_go_authorize_client(pin) 293 dev[1].p2p_connect_group(dev[0].p2p_dev_addr(), pin, timeout=60) 294 295 dev[2].p2p_find(social=True, dev_id="02:03:04:05:06:07") 296 ev = dev[2].wait_global_event(['P2P-DEVICE-FOUND'], timeout=1) 297 if ev: 298 raise Exception("Unexpected P2P device found") 299 dev[2].p2p_find(social=True, dev_id=addr1) 300 ev = dev[2].wait_global_event(['P2P-DEVICE-FOUND ' + addr1], timeout=2) 301 if ev is None: 302 raise Exception("P2P device not found") 303 304def test_discovery_social_plus_one(dev): 305 """P2P device discovery with social-plus-one""" 306 logger.info("Start autonomous GO " + dev[0].ifname) 307 dev[1].p2p_find(social=True) 308 dev[0].p2p_find(progressive=True) 309 logger.info("Wait for initial progressive find phases") 310 dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"]) 311 dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"]) 312 go = dev[2].p2p_dev_addr() 313 dev[2].p2p_start_go(freq="2422") 314 logger.info("Verify whether the GO on non-social channel can be found") 315 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15) 316 if ev is None: 317 raise Exception("Peer not found") 318 if go not in ev: 319 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15) 320 if ev is None: 321 raise Exception("Peer not found") 322 ev = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15) 323 if ev is None: 324 raise Exception("Peer not found") 325 dev[0].p2p_stop_find() 326 dev[1].p2p_stop_find() 327 if not dev[0].peer_known(go): 328 raise Exception("GO not found in progressive scan") 329 if dev[1].peer_known(go): 330 raise Exception("GO found in social-only scan") 331 332def _test_discovery_and_interface_disabled(dev, delay=1): 333 try: 334 if "OK" not in dev[0].p2p_find(): 335 raise Exception("Failed to start P2P find") 336 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"]) 337 if ev is None: 338 raise Exception("Scan did not start") 339 dev[0].request("DRIVER_EVENT INTERFACE_DISABLED") 340 time.sleep(delay) 341 342 # verify that P2P_FIND is rejected 343 if "FAIL" not in dev[0].p2p_find(): 344 raise Exception("New P2P_FIND request was accepted unexpectedly") 345 346 dev[0].request("DRIVER_EVENT INTERFACE_ENABLED") 347 time.sleep(3) 348 dev[0].scan(freq="2412") 349 if "OK" not in dev[0].p2p_find(): 350 raise Exception("Failed to start P2P find") 351 dev[0].dump_monitor() 352 dev[1].p2p_listen() 353 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15) 354 if ev is None: 355 raise Exception("Peer not found") 356 finally: 357 dev[0].request("DRIVER_EVENT INTERFACE_ENABLED") 358 359def test_discovery_and_interface_disabled(dev): 360 """P2P device discovery with interface getting disabled""" 361 _test_discovery_and_interface_disabled(dev, delay=1) 362 _test_discovery_and_interface_disabled(dev, delay=5) 363 364def test_discovery_auto(dev): 365 """P2P device discovery and provision discovery with auto GO/dev selection""" 366 dev[0].flush_scan_cache() 367 addr0 = dev[0].p2p_dev_addr() 368 addr1 = dev[1].p2p_dev_addr() 369 addr2 = dev[2].p2p_dev_addr() 370 dev[2].p2p_start_go(freq="2412") 371 logger.info("Start device discovery") 372 dev[0].p2p_listen() 373 if not dev[1].discover_peer(addr0): 374 raise Exception("Device discovery timed out") 375 dev[1].p2p_listen() 376 if not dev[0].discover_peer(addr1): 377 raise Exception("Device discovery timed out") 378 if not dev[0].discover_peer(addr2): 379 raise Exception("Device discovery timed out") 380 381 logger.info("Test provision discovery for display (device)") 382 dev[0].global_request("P2P_PROV_DISC " + addr1 + " display auto") 383 ev1 = dev[1].wait_global_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=15) 384 if ev1 is None: 385 raise Exception("Provision discovery timed out (display/dev1)") 386 if addr0 not in ev1: 387 raise Exception("Dev0 not in provision discovery event") 388 if " group=" in ev1: 389 raise Exception("Unexpected group parameter from non-GO") 390 ev0 = dev[0].wait_global_event(["P2P-PROV-DISC-ENTER-PIN", 391 "P2P-PROV-DISC-FAILURE"], timeout=15) 392 if ev0 is None: 393 raise Exception("Provision discovery timed out (display/dev0)") 394 if "P2P-PROV-DISC-FAILURE" in ev0: 395 raise Exception("Provision discovery failed (display/dev0)") 396 if addr1 not in ev0: 397 raise Exception("Dev1 not in provision discovery event") 398 if "peer_go=0" not in ev0: 399 raise Exception("peer_go incorrect in PD response from non-GO") 400 401 logger.info("Test provision discovery for display (GO)") 402 dev[0].global_request("P2P_PROV_DISC " + addr2 + " display auto") 403 ev2 = dev[2].wait_global_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=15) 404 if ev2 is None: 405 raise Exception("Provision discovery timed out (display/dev2)") 406 if addr0 not in ev2: 407 raise Exception("Dev0 not in provision discovery event") 408 if " group=" not in ev2: 409 raise Exception("Group parameter missing from GO") 410 ev0 = dev[0].wait_global_event(["P2P-PROV-DISC-ENTER-PIN", 411 "P2P-PROV-DISC-FAILURE"], timeout=15) 412 if ev0 is None: 413 raise Exception("Provision discovery timed out (display/dev0)") 414 if "P2P-PROV-DISC-FAILURE" in ev0: 415 raise Exception("Provision discovery failed (display/dev0)") 416 if addr2 not in ev0: 417 raise Exception("Dev1 not in provision discovery event") 418 if "peer_go=1" not in ev0: 419 raise Exception("peer_go incorrect in PD response from GO") 420 421def test_discovery_stop(dev): 422 """P2P device discovery and p2p_stop_find""" 423 addr0 = dev[0].p2p_dev_addr() 424 addr1 = dev[1].p2p_dev_addr() 425 dev[1].p2p_listen() 426 dev[2].p2p_listen() 427 428 dev[0].p2p_find(social=False) 429 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.5) 430 if ev is None: 431 logger.info("No CTRL-EVENT-SCAN-STARTED event") 432 dev[0].p2p_stop_find() 433 ev = dev[0].wait_global_event(["P2P-FIND-STOPPED"], timeout=1) 434 if ev is None: 435 raise Exception("P2P_STOP not reported") 436 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5) 437 if ev is not None: 438 raise Exception("Peer found unexpectedly: " + ev) 439 440 dev[0].p2p_find(social=False) 441 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-STARTED"], timeout=0.5) 442 if ev is None: 443 logger.info("No CTRL-EVENT-SCAN-STARTED event") 444 dev[0].global_request("P2P_FLUSH") 445 ev = dev[0].wait_global_event(["P2P-FIND-STOPPED"], timeout=1) 446 if ev is None: 447 raise Exception("P2P_STOP not reported") 448 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5) 449 if ev is not None: 450 raise Exception("Peer found unexpectedly: " + ev) 451 452def test_discovery_restart(dev): 453 """P2P device discovery and p2p_find restart""" 454 autogo(dev[1], freq=2457) 455 dev[0].p2p_find(social=True) 456 dev[0].p2p_stop_find() 457 dev[0].p2p_find(social=False) 458 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=7) 459 if ev is None: 460 dev[0].p2p_find(social=False) 461 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=7) 462 if ev is None: 463 raise Exception("Peer not found") 464 465def test_discovery_restart_progressive(dev): 466 """P2P device discovery and p2p_find type=progressive restart""" 467 try: 468 set_country("US", dev[1]) 469 autogo(dev[1], freq=5805) 470 dev[0].p2p_find(social=True) 471 dev[0].p2p_stop_find() 472 dev[0].p2p_find(progressive=True) 473 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=20) 474 dev[1].remove_group() 475 if ev is None: 476 raise Exception("Peer not found") 477 finally: 478 set_country("00") 479 dev[1].flush_scan_cache() 480 481def test_p2p_peer_command(dev): 482 """P2P_PEER command""" 483 addr0 = dev[0].p2p_dev_addr() 484 addr1 = dev[1].p2p_dev_addr() 485 addr2 = dev[2].p2p_dev_addr() 486 dev[1].p2p_listen() 487 dev[2].p2p_listen() 488 if not dev[0].discover_peer(addr1): 489 raise Exception("Device discovery timed out") 490 if not dev[0].discover_peer(addr2): 491 raise Exception("Device discovery timed out") 492 dev[0].p2p_stop_find() 493 dev[1].p2p_stop_find() 494 dev[2].p2p_stop_find() 495 496 res0 = dev[0].request("P2P_PEER FIRST") 497 peer = res0.splitlines()[0] 498 if peer not in [addr1, addr2]: 499 raise Exception("Unexpected P2P_PEER FIRST address") 500 res1 = dev[0].request("P2P_PEER NEXT-" + peer) 501 peer2 = res1.splitlines()[0] 502 if peer2 not in [addr1, addr2] or peer == peer2: 503 raise Exception("Unexpected P2P_PEER NEXT address") 504 505 if "FAIL" not in dev[0].request("P2P_PEER NEXT-foo"): 506 raise Exception("Invalid P2P_PEER command accepted") 507 if "FAIL" not in dev[0].request("P2P_PEER foo"): 508 raise Exception("Invalid P2P_PEER command accepted") 509 if "FAIL" not in dev[0].request("P2P_PEER 00:11:22:33:44:55"): 510 raise Exception("P2P_PEER command for unknown peer accepted") 511 512def test_p2p_listen_and_offchannel_tx(dev): 513 """P2P_LISTEN behavior with offchannel TX""" 514 addr0 = dev[0].p2p_dev_addr() 515 addr1 = dev[1].p2p_dev_addr() 516 addr2 = dev[2].p2p_dev_addr() 517 518 dev[1].p2p_listen() 519 if not dev[0].discover_peer(addr1): 520 raise Exception("Device discovery timed out") 521 522 dev[0].p2p_listen() 523 dev[0].global_request("P2P_PROV_DISC " + addr1 + " display") 524 ev = dev[0].wait_global_event(["P2P-PROV-DISC-ENTER-PIN"], timeout=15) 525 if ev is None: 526 raise Exception("No PD result reported") 527 dev[1].p2p_stop_find() 528 529 if not dev[2].discover_peer(addr0): 530 raise Exception("Device discovery timed out after PD exchange") 531 dev[2].p2p_stop_find() 532 dev[0].p2p_stop_find() 533 534@remote_compatible 535def test_p2p_listen_and_scan(dev): 536 """P2P_LISTEN and scan""" 537 dev[0].p2p_listen() 538 if "OK" not in dev[0].request("SCAN freq=2412"): 539 raise Exception("Failed to request a scan") 540 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 3) 541 if ev is not None: 542 raise Exception("Unexpected scan results") 543 dev[0].p2p_stop_find() 544 ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 15) 545 if ev is None: 546 raise Exception("Scan timed out") 547 548def test_p2p_config_methods(dev): 549 """P2P and WPS config method update""" 550 addr0 = dev[0].p2p_dev_addr() 551 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 552 wpas.interface_add("wlan5") 553 addr1 = wpas.p2p_dev_addr() 554 555 if "OK" not in wpas.request("SET config_methods keypad virtual_push_button"): 556 raise Exception("Failed to set config_methods") 557 558 wpas.p2p_listen() 559 if not dev[0].discover_peer(addr1): 560 raise Exception("Device discovery timed out") 561 dev[0].p2p_stop_find() 562 peer = dev[0].get_peer(addr1) 563 if peer['config_methods'] != '0x180': 564 raise Exception("Unexpected peer config methods(1): " + peer['config_methods']) 565 dev[0].global_request("P2P_FLUSH") 566 567 if "OK" not in wpas.request("SET config_methods virtual_display"): 568 raise Exception("Failed to set config_methods") 569 570 if not dev[0].discover_peer(addr1): 571 raise Exception("Device discovery timed out") 572 dev[0].p2p_stop_find() 573 peer = dev[0].get_peer(addr1) 574 if peer['config_methods'] != '0x8': 575 raise Exception("Unexpected peer config methods(2): " + peer['config_methods']) 576 577 wpas.p2p_stop_find() 578 579@remote_compatible 580def test_discovery_after_gas(dev, apdev): 581 """P2P device discovery after GAS/ANQP exchange""" 582 hapd = start_ap(apdev[0]) 583 hapd.set("gas_frag_limit", "50") 584 dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True) 585 dev[0].request("FETCH_ANQP") 586 ev = dev[0].wait_event(["ANQP-QUERY-DONE"], timeout=10) 587 if ev is None: 588 raise Exception("No ANQP-QUERY-DONE event") 589 dev[0].dump_monitor() 590 591 start = os.times()[4] 592 dev[0].p2p_listen() 593 dev[1].p2p_find(social=True) 594 ev = dev[1].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5) 595 if ev is None: 596 raise Exception("Peer not discovered") 597 end = os.times()[4] 598 dev[0].dump_monitor() 599 dev[0].p2p_stop_find() 600 dev[1].p2p_stop_find() 601 logger.info("Device discovery after fragmented GAS took %f seconds" % (end - start)) 602 if end - start > 1.3: 603 raise Exception("Device discovery took unexpectedly long time") 604 605@remote_compatible 606def test_discovery_listen_find(dev): 607 """P2P_LISTEN immediately followed by P2P_FIND""" 608 # Request an external remain-on-channel operation to delay start of the ROC 609 # for the following p2p_listen() enough to get p2p_find() processed before 610 # the ROC started event shows up. This is done to test a code path where the 611 # p2p_find() needs to clear the wait for the pending listen operation 612 # (p2p->pending_listen_freq). 613 ifindex = int(dev[0].get_driver_status_field("ifindex")) 614 nl80211_remain_on_channel(dev[0], ifindex, 2417, 200) 615 616 addr0 = dev[0].p2p_dev_addr() 617 dev[0].p2p_listen() 618 dev[0].p2p_find(social=True) 619 time.sleep(0.4) 620 dev[1].p2p_listen() 621 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=1.2) 622 if not dev[1].discover_peer(addr0): 623 raise Exception("Device discovery timed out") 624 if ev is None: 625 raise Exception("Did not find peer quickly enough after stopped P2P_LISTEN") 626 627def test_discovery_long_listen(dev): 628 """Long P2P_LISTEN and offchannel TX""" 629 addr0 = dev[0].p2p_dev_addr() 630 dev[0].p2p_listen() 631 632 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 633 wpas.interface_add("wlan5") 634 addr = wpas.p2p_dev_addr() 635 if not wpas.discover_peer(addr0): 636 raise Exception("Device discovery timed out") 637 peer = wpas.get_peer(addr0) 638 chan = '1' if peer['listen_freq'] == '2462' else '11' 639 640 wpas.request("P2P_SET listen_channel " + chan) 641 wpas.request("P2P_LISTEN 10") 642 if not dev[0].discover_peer(addr): 643 raise Exception("Device discovery timed out (2)") 644 645 time.sleep(0.1) 646 wpas.global_request("P2P_PROV_DISC " + addr0 + " display") 647 ev = dev[0].wait_global_event(["P2P-PROV-DISC-SHOW-PIN"], timeout=15) 648 if ev is None: 649 raise Exception("Provision discovery timed out") 650 dev[0].p2p_stop_find() 651 652 # Verify that the long listen period is still continuing after off-channel 653 # TX of Provision Discovery frames. 654 if not dev[1].discover_peer(addr): 655 raise Exception("Device discovery timed out (3)") 656 657 dev[1].p2p_stop_find() 658 wpas.p2p_stop_find() 659 660def test_discovery_long_listen2(dev): 661 """Long P2P_LISTEN longer than remain-on-channel time""" 662 with HWSimRadio(use_p2p_device=True) as (radio, iface): 663 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 664 wpas.interface_add(iface) 665 addr = wpas.p2p_dev_addr() 666 wpas.request("P2P_LISTEN 15") 667 668 # Wait for remain maximum remain-on-channel time to pass 669 time.sleep(7) 670 671 if not dev[0].discover_peer(addr): 672 raise Exception("Device discovery timed out") 673 dev[0].p2p_stop_find() 674 wpas.p2p_stop_find() 675 676def pd_test(dev, addr): 677 if not dev.discover_peer(addr, freq=2412): 678 raise Exception("Device discovery timed out") 679 dev.global_request("P2P_PROV_DISC " + addr + " display") 680 ev0 = dev.wait_global_event(["P2P-PROV-DISC-ENTER-PIN"], timeout=15) 681 if ev0 is None: 682 raise Exception("Provision discovery timed out (display)") 683 dev.p2p_stop_find() 684 685def run_discovery_while_go(wpas, dev, params): 686 wpas.request("P2P_SET listen_channel 1") 687 wpas.p2p_start_go(freq="2412") 688 addr = wpas.p2p_dev_addr() 689 pin = dev[0].wps_read_pin() 690 wpas.p2p_go_authorize_client(pin) 691 dev[1].p2p_connect_group(addr, pin, freq=2412, timeout=30) 692 693 pd_test(dev[0], addr) 694 wpas.p2p_listen() 695 pd_test(dev[2], addr) 696 697 wpas.p2p_stop_find() 698 terminate_group(wpas, dev[1]) 699 700 out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"), 701 "wifi_p2p.public_action.subtype == 8", ["wlan.da"]) 702 da = out.splitlines() 703 logger.info("PD Response DAs: " + str(da)) 704 if len(da) != 3: 705 raise Exception("Unexpected DA count for PD Response") 706 707def test_discovery_while_go(dev, apdev, params): 708 """P2P provision discovery from GO""" 709 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 710 wpas.interface_add("wlan5") 711 run_discovery_while_go(wpas, dev, params) 712 713def test_discovery_while_go_p2p_dev(dev, apdev, params): 714 """P2P provision discovery from GO (using P2P Device interface)""" 715 with HWSimRadio(use_p2p_device=True) as (radio, iface): 716 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 717 wpas.interface_add(iface) 718 run_discovery_while_go(wpas, dev, params) 719 720def run_discovery_while_cli(wpas, dev, params): 721 wpas.request("P2P_SET listen_channel 1") 722 dev[1].p2p_start_go(freq="2412") 723 addr = wpas.p2p_dev_addr() 724 pin = wpas.wps_read_pin() 725 dev[1].p2p_go_authorize_client(pin) 726 wpas.p2p_connect_group(dev[1].p2p_dev_addr(), pin, freq=2412, timeout=30) 727 728 pd_test(dev[0], addr) 729 wpas.p2p_listen() 730 pd_test(dev[2], addr) 731 732 wpas.p2p_stop_find() 733 terminate_group(dev[1], wpas) 734 735 out = run_tshark(os.path.join(params['logdir'], "hwsim0.pcapng"), 736 "wifi_p2p.public_action.subtype == 8", ["wlan.da"]) 737 da = out.splitlines() 738 logger.info("PD Response DAs: " + str(da)) 739 if len(da) != 3: 740 raise Exception("Unexpected DA count for PD Response") 741 742def test_discovery_while_cli(dev, apdev, params): 743 """P2P provision discovery from CLI""" 744 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 745 wpas.interface_add("wlan5") 746 run_discovery_while_cli(wpas, dev, params) 747 748def test_discovery_while_cli_p2p_dev(dev, apdev, params): 749 """P2P provision discovery from CLI (using P2P Device interface)""" 750 with HWSimRadio(use_p2p_device=True) as (radio, iface): 751 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 752 wpas.interface_add(iface) 753 run_discovery_while_cli(wpas, dev, params) 754 755def test_discovery_device_name_change(dev): 756 """P2P device discovery and peer changing device name""" 757 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') 758 wpas.interface_add("wlan5") 759 wpas.set("device_name", "test-a") 760 wpas.p2p_listen() 761 dev[0].p2p_find(social=True) 762 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15) 763 if ev is None: 764 raise Exception("Peer not found") 765 if "new=1" not in ev: 766 raise Exception("Incorrect new event: " + ev) 767 if "name='test-a'" not in ev: 768 raise Exception("Unexpected device name(1): " + ev) 769 770 # Verify that new P2P-DEVICE-FOUND event is indicated when the peer changes 771 # its device name. 772 wpas.set("device_name", "test-b") 773 ev = dev[0].wait_global_event(["P2P-DEVICE-FOUND"], timeout=15) 774 if ev is None: 775 raise Exception("Peer update not seen") 776 if "new=0" not in ev: 777 raise Exception("Incorrect update event: " + ev) 778 if "name='test-b'" not in ev: 779 raise Exception("Unexpected device name(2): " + ev) 780 wpas.p2p_stop_find() 781 dev[0].p2p_stop_find() 782 783def test_p2p_group_cli_invalid(dev, apdev): 784 """P2P device discovery with invalid group client info""" 785 attr = struct.pack('<BHBB', 2, 2, 0x25, 0x09) 786 787 attr += struct.pack('<BH', 3, 6) + "\x02\x02\x02\x02\x02\x00".encode() 788 789 cli = bytes() 790 cli += "\x02\x02\x02\x02\x02\x03".encode() 791 cli += "\x02\x02\x02\x02\x02\x04".encode() 792 cli += struct.pack('>BH', 0, 0x3148) 793 dev_type = "\x00\x00\x00\x00\x00\x00\x00\x01".encode() 794 cli += dev_type 795 num_sec = 25 796 cli += struct.pack('B', num_sec) 797 cli += num_sec * dev_type 798 name = "TEST".encode() 799 cli += struct.pack('>HH', 0x1011, len(name)) + name 800 desc = struct.pack('B', len(cli)) + cli 801 attr += struct.pack('<BH', 14, len(desc)) + desc 802 803 p2p_ie = struct.pack('>BBL', 0xdd, 4 + len(attr), 0x506f9a09) + attr 804 ie = binascii.hexlify(p2p_ie).decode() 805 806 params = {"ssid": "DIRECT-test", 807 "eap_server": "1", 808 "wps_state": "2", 809 "wpa_passphrase": "12345678", 810 "wpa": "2", 811 "wpa_key_mgmt": "WPA-PSK", 812 "rsn_pairwise": "CCMP", 813 "vendor_elements": ie} 814 hapd = hostapd.add_ap(apdev[0], params) 815 816 for i in range(2): 817 dev[i].p2p_find(social=True) 818 ev = dev[i].wait_global_event(["P2P-DEVICE-FOUND"], timeout=5) 819 if not ev: 820 raise Exception("P2P device not found") 821 822def test_discovery_max_peers(dev): 823 """P2P device discovery and maximum peer limit exceeded""" 824 dev[0].p2p_listen() 825 dev[0].request("SET ext_mgmt_frame_handling 1") 826 probereq1 = "40000000ffffffffffff" 827 probereq2 = "ffffffffffff000000074449524543542d01080c1218243048606c0301012d1afe131bffff000000000000000000000100000000000000000000ff16230178c812400000bfce0000000000000000fafffaffdd730050f204104a000110103a00010110080002314810470010572cf82fc95756539b16b5cfb298abf1105400080000000000000000103c0001031002000200001009000200001012000200001021000120102300012010240001201011000844657669636520421049000900372a000120030101dd11506f9a0902020025000605005858045106" 828 829 # Fill the P2P peer table with max+1 entries based on Probe Request frames 830 # to verify correct behavior on# removing the oldest entry when running out 831 # of room. 832 for i in range(101): 833 addr = "0202020202%02x" % i 834 probereq = probereq1 + addr + probereq2 835 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=60 ssi_signal=-30 frame=" + probereq): 836 raise Exception("MGMT_RX_PROCESS failed") 837 838 res = dev[0].global_request("P2P_PEER FIRST") 839 addr = res.splitlines()[0] 840 peers = [addr] 841 limit = 200 842 while limit > 0: 843 res = dev[0].global_request("P2P_PEER NEXT-" + addr) 844 addr = res.splitlines()[0] 845 if addr == "FAIL": 846 break 847 peers.append(addr) 848 limit -= 1 849 logger.info("Peers: " + str(peers)) 850 851 if len(peers) != 100: 852 raise Exception("Unexpected number of peer entries") 853 oldest = "02:02:02:02:02:00" 854 if oldest in peers: 855 raise Exception("Oldest entry is still present") 856 for i in range(101): 857 addr = "02:02:02:02:02:%02x" % i 858 if addr == oldest: 859 continue 860 if addr not in peers: 861 raise Exception("Peer missing from table: " + addr) 862 863 # Provision Discovery Request from the oldest peer (SA) using internally 864 # different P2P Device Address as a regression test for incorrect processing 865 # for this corner case. 866 dst = dev[0].own_addr().replace(':', '') 867 src = peers[99].replace(':', '') 868 devaddr = "0202020202ff" 869 pdreq = "d0004000" + dst + src + dst + "d0000409506f9a090701dd29506f9a0902020025000d1d00" + devaddr + "1108000000000000000000101100084465766963652041dd0a0050f204100800020008" 870 if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=60 ssi_signal=-30 frame=" + pdreq): 871 raise Exception("MGMT_RX_PROCESS failed") 872