1 /* 2 * Sigma Control API DUT (station/AP) 3 * Copyright (c) 2010-2011, Atheros Communications, Inc. 4 * Copyright (c) 2011-2014, Qualcomm Atheros, Inc. 5 * All Rights Reserved. 6 * Licensed under the Clear BSD license. See README for more details. 7 */ 8 9 #include "sigma_dut.h" 10 #include <sys/stat.h> 11 #include "wpa_ctrl.h" 12 #include "wpa_helpers.h" 13 14 15 int run_system(struct sigma_dut *dut, const char *cmd) 16 { 17 int res; 18 19 sigma_dut_print(dut, DUT_MSG_DEBUG, "Running '%s'", cmd); 20 res = system(cmd); 21 if (res < 0) { 22 sigma_dut_print(dut, DUT_MSG_DEBUG, "Failed to execute " 23 "command '%s'", cmd); 24 } 25 return res; 26 } 27 28 29 static int get_60g_freq(int chan) 30 { 31 int freq = 0; 32 33 switch(chan) { 34 case 1: 35 freq = 58320; 36 break; 37 case 2: 38 freq = 60480; 39 break; 40 case 3: 41 freq = 62640; 42 break; 43 case 4: 44 /* freq = 64800; Not supported in Sparrow 2.0 */ 45 break; 46 default: 47 break; 48 } 49 50 return freq; 51 } 52 53 54 #define GO_IP_ADDR "192.168.43.1" 55 #define START_IP_RANGE "192.168.43.10" 56 #define END_IP_RANGE "192.168.43.100" 57 #define FLUSH_IP_ADDR "0.0.0.0" 58 59 static void start_dhcp(struct sigma_dut *dut, const char *group_ifname, int go) 60 { 61 #ifdef __linux__ 62 char buf[200]; 63 64 if (go) { 65 snprintf(buf, sizeof(buf), "ifconfig %s %s", group_ifname, 66 GO_IP_ADDR); 67 run_system(dut, buf); 68 snprintf(buf, sizeof(buf), 69 "/system/bin/dnsmasq -x /data/dnsmasq.pid --no-resolv --no-poll --dhcp-range=%s,%s,1h", 70 START_IP_RANGE, END_IP_RANGE); 71 } else { 72 #ifdef ANDROID 73 if (access("/system/bin/dhcpcd", F_OK) != -1) { 74 snprintf(buf, sizeof(buf), "/system/bin/dhcpcd -KL %s", 75 group_ifname); 76 } else { 77 sigma_dut_print(dut, DUT_MSG_ERROR, 78 "DHCP client program missing"); 79 return; 80 } 81 #else /* ANDROID */ 82 snprintf(buf, sizeof(buf), 83 "dhclient -nw -pf /var/run/dhclient-%s.pid %s", 84 group_ifname, group_ifname); 85 #endif /* ANDROID */ 86 } 87 88 run_system(dut, buf); 89 #endif /* __linux__ */ 90 } 91 92 93 static void stop_dhcp(struct sigma_dut *dut, const char *group_ifname, int go) 94 { 95 #ifdef __linux__ 96 char path[128]; 97 char buf[200]; 98 struct stat s; 99 100 if (go) { 101 snprintf(path, sizeof(path), "/data/dnsmasq.pid"); 102 sigma_dut_print(dut, DUT_MSG_DEBUG, 103 "Kill previous DHCP server: %s", buf); 104 } else { 105 #ifdef ANDROID 106 if (access("/system/bin/dhcpcd", F_OK) != -1) { 107 snprintf(path, sizeof(path), 108 "/data/misc/dhcp/dhcpcd-%s.pid", group_ifname); 109 } else { 110 sigma_dut_print(dut, DUT_MSG_ERROR, 111 "No active DHCP client program"); 112 return; 113 } 114 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", 115 group_ifname); 116 #else /* ANDROID */ 117 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", 118 group_ifname); 119 #endif /* ANDROID */ 120 sigma_dut_print(dut, DUT_MSG_DEBUG, 121 "Kill previous DHCP client: %s", buf); 122 } 123 if (stat(path, &s) == 0) { 124 snprintf(buf, sizeof(buf), "kill `cat %s`", path); 125 run_system(dut, buf); 126 unlink(path); 127 sleep(1); 128 } 129 130 snprintf(buf, sizeof(buf), "ip address flush dev %s", group_ifname); 131 run_system(dut, buf); 132 snprintf(buf, sizeof(buf), "ifconfig %s %s", 133 group_ifname, FLUSH_IP_ADDR); 134 sigma_dut_print(dut, DUT_MSG_DEBUG, "Clear IP address: %s", buf); 135 run_system(dut, buf); 136 #endif /* __linux__ */ 137 } 138 139 140 static int stop_event_rx = 0; 141 142 #ifdef __linux__ 143 void stop_event_thread() 144 { 145 stop_event_rx = 1; 146 printf("sigma_dut dhcp terminating\n"); 147 } 148 #endif /* __linux__ */ 149 150 151 static void * wpa_event_recv(void *ptr) 152 { 153 struct sigma_dut *dut = ptr; 154 struct wpa_ctrl *ctrl; 155 char buf[4096]; 156 char *pos, *gtype, *p2p_group_ifname = NULL; 157 int fd, ret, i; 158 int go = 0; 159 fd_set rfd; 160 struct timeval tv; 161 size_t len; 162 163 const char *events[] = { 164 "P2P-GROUP-STARTED", 165 "P2P-GROUP-REMOVED", 166 NULL 167 }; 168 169 ctrl = open_wpa_mon(dut->p2p_ifname); 170 if (!ctrl) { 171 sigma_dut_print(dut, DUT_MSG_ERROR, 172 "Failed to open wpa_supplicant monitor connection"); 173 return NULL; 174 } 175 176 for (i = 0; events[i]; i++) { 177 sigma_dut_print(dut, DUT_MSG_DEBUG, 178 "Waiting for wpa_cli event: %s", events[i]); 179 } 180 181 fd = wpa_ctrl_get_fd(ctrl); 182 if (fd < 0) { 183 wpa_ctrl_detach(ctrl); 184 wpa_ctrl_close(ctrl); 185 return NULL; 186 } 187 188 while (!stop_event_rx) { 189 FD_ZERO(&rfd); 190 FD_SET(fd, &rfd); 191 tv.tv_sec = 1; 192 tv.tv_usec = 0; 193 194 ret = select(fd + 1, &rfd, NULL, NULL, &tv); 195 if (ret == 0) 196 continue; 197 if (ret < 0) { 198 sigma_dut_print(dut, DUT_MSG_INFO, "select: %s", 199 strerror(errno)); 200 usleep(100000); 201 continue; 202 } 203 204 len = sizeof(buf); 205 if (wpa_ctrl_recv(ctrl, buf, &len) < 0) { 206 sigma_dut_print(dut, DUT_MSG_ERROR, 207 "Failure while waiting for events"); 208 continue; 209 } 210 211 ret = 0; 212 pos = strchr(buf, '>'); 213 if (pos) { 214 for (i = 0; events[i]; i++) { 215 if (strncmp(pos + 1, events[i], 216 strlen(events[i])) == 0) { 217 ret = 1; 218 break; /* Event found */ 219 } 220 } 221 } 222 if (!ret) 223 continue; 224 225 if (strstr(buf, "P2P-GROUP-")) { 226 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group event '%s'", 227 buf); 228 p2p_group_ifname = strchr(buf, ' '); 229 if (!p2p_group_ifname) 230 continue; 231 p2p_group_ifname++; 232 pos = strchr(p2p_group_ifname, ' '); 233 if (!pos) 234 continue; 235 *pos++ = '\0'; 236 gtype = pos; 237 pos = strchr(gtype, ' '); 238 if (!pos) 239 continue; 240 *pos++ = '\0'; 241 242 go = strcmp(gtype, "GO") == 0; 243 } 244 245 if (strstr(buf, "P2P-GROUP-STARTED")) { 246 start_dhcp(dut, p2p_group_ifname, go); 247 } else if (strstr(buf, "P2P-GROUP-REMOVED")) { 248 stop_dhcp(dut, p2p_group_ifname, go); 249 go = 0; 250 } 251 } 252 253 /* terminate DHCP server, if runnin! */ 254 if (go) 255 stop_dhcp(dut, p2p_group_ifname, go); 256 257 wpa_ctrl_detach(ctrl); 258 wpa_ctrl_close(ctrl); 259 260 pthread_exit(0); 261 return NULL; 262 } 263 264 265 void p2p_create_event_thread(struct sigma_dut *dut) 266 { 267 static pthread_t event_thread; 268 269 /* create event thread */ 270 pthread_create(&event_thread, NULL, &wpa_event_recv, (void *) dut); 271 } 272 273 274 static int p2p_group_add(struct sigma_dut *dut, const char *ifname, 275 int go, const char *grpid, const char *ssid) 276 { 277 struct wfa_cs_p2p_group *grp; 278 279 if (go) 280 dut->go = 1; 281 else 282 dut->p2p_client = 1; 283 grp = malloc(sizeof(*grp)); 284 if (grp == NULL) 285 return -1; 286 memset(grp, 0, sizeof(*grp)); 287 strncpy(grp->ifname, ifname, IFNAMSIZ); 288 grp->go = go; 289 strncpy(grp->grpid, grpid, P2P_GRP_ID_LEN); 290 strncpy(grp->ssid, ssid, sizeof(grp->ssid)); 291 292 grp->next = dut->groups; 293 dut->groups = grp; 294 295 return 0; 296 } 297 298 299 static int p2p_group_remove(struct sigma_dut *dut, const char *grpid) 300 { 301 struct wfa_cs_p2p_group *grp, *prev; 302 303 prev = NULL; 304 grp = dut->groups; 305 while (grp) { 306 if (strcmp(grpid, grp->grpid) == 0) { 307 if (prev) 308 prev->next = grp->next; 309 else 310 dut->groups = grp->next; 311 free(grp); 312 return 0; 313 } 314 prev = grp; 315 grp = grp->next; 316 } 317 return -1; 318 } 319 320 321 static struct wfa_cs_p2p_group * p2p_group_get(struct sigma_dut *dut, 322 const char *grpid) 323 { 324 struct wfa_cs_p2p_group *grp; 325 char buf[1000], buf2[4096], *ifname, *pos; 326 char go_dev_addr[50]; 327 char ssid[33]; 328 329 for (grp = dut->groups; grp; grp = grp->next) { 330 if (strcmp(grpid, grp->grpid) == 0) 331 return grp; 332 } 333 334 /* 335 * No group found based on group id. As a workaround for GO Negotiation 336 * responder case where we do not store group id, try to find an active 337 * group that matches with the requested group id. 338 */ 339 340 pos = strchr(grpid, ' '); 341 if (pos == NULL) 342 return NULL; 343 if (pos - grpid > (int) sizeof(go_dev_addr)) 344 return NULL; 345 memcpy(go_dev_addr, grpid, pos - grpid); 346 go_dev_addr[pos - grpid] = '\0'; 347 strncpy(ssid, pos + 1, sizeof(ssid)); 348 ssid[sizeof(ssid) - 1] = '\0'; 349 printf("Trying to find suitable interface for group: go_dev_addr='%s' " 350 "grpid='%s'\n", go_dev_addr, grpid); 351 352 if (wpa_command_resp(get_main_ifname(), "INTERFACES", buf, sizeof(buf)) 353 < 0) 354 return NULL; 355 ifname = buf; 356 while (ifname && *ifname) { 357 int add = 0; 358 int go = 0; 359 pos = strchr(ifname, '\n'); 360 if (pos) 361 *pos++ = '\0'; 362 printf("Considering interface '%s' for group\n", ifname); 363 364 if (wpa_command_resp(ifname, "STATUS", buf2, sizeof(buf2)) == 365 0) { 366 if (strstr(buf2, ssid)) { 367 printf("Selected interface '%s' based on " 368 "STATUS\n", ifname); 369 add = 1; 370 } 371 if (strstr(buf2, "P2P GO")) 372 go = 1; 373 } 374 375 if (wpa_command_resp(ifname, "LIST_NETWORKS", buf2, 376 sizeof(buf2)) == 0) { 377 char *line, *end; 378 line = buf2; 379 while (line && *line) { 380 end = strchr(line, ' '); 381 if (end) 382 *end++ = '\0'; 383 if (strstr(line, ssid) && 384 strstr(line, "[CURRENT]")) { 385 printf("Selected interface '%s' " 386 "based on LIST_NETWORKS\n", 387 ifname); 388 add = 1; 389 break; 390 } 391 line = end; 392 } 393 } 394 395 if (add) { 396 p2p_group_add(dut, ifname, go, grpid, ssid); 397 return dut->groups; 398 } 399 400 ifname = pos; 401 } 402 403 return NULL; 404 } 405 406 407 static const char * get_group_ifname(struct sigma_dut *dut, const char *ifname) 408 { 409 char buf[1000], *iface, *pos; 410 char state[100]; 411 412 if (dut->groups) { 413 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Use group interface " 414 "%s instead of main interface %s", 415 __func__, dut->groups->ifname, ifname); 416 return dut->groups->ifname; 417 } 418 419 /* Try to find a suitable group interface */ 420 if (wpa_command_resp(get_main_ifname(), "INTERFACES", 421 buf, sizeof(buf)) < 0) 422 return ifname; 423 424 iface = buf; 425 while (iface && *iface) { 426 pos = strchr(iface, '\n'); 427 if (pos) 428 *pos++ = '\0'; 429 sigma_dut_print(dut, DUT_MSG_DEBUG, "Considering interface " 430 "'%s' for IP address", iface); 431 if (get_wpa_status(iface, "wpa_state", state, sizeof(state)) == 432 0 && strcmp(state, "COMPLETED") == 0) 433 return iface; 434 iface = pos; 435 } 436 437 return ifname; 438 } 439 440 441 static int p2p_peer_known(const char *ifname, const char *peer, int full) 442 { 443 char buf[4096]; 444 445 snprintf(buf, sizeof(buf), "P2P_PEER %s", peer); 446 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0) 447 return 0; 448 if (strncasecmp(buf, peer, strlen(peer)) != 0) 449 return 0; 450 if (!full) 451 return 1; 452 return strstr(buf, "[PROBE_REQ_ONLY]") == NULL ? 1 : 0; 453 } 454 455 456 static int p2p_discover_peer(struct sigma_dut *dut, const char *ifname, 457 const char *peer, int full) 458 { 459 unsigned int count; 460 461 if (p2p_peer_known(ifname, peer, full)) 462 return 0; 463 printf("Peer not yet discovered - start discovery\n"); 464 if (wpa_command(ifname, "P2P_FIND") < 0) { 465 printf("Failed to start discovery\n"); 466 return -1; 467 } 468 469 count = 0; 470 while (count < dut->default_timeout) { 471 count++; 472 sleep(1); 473 if (p2p_peer_known(ifname, peer, full)) { 474 printf("Peer discovered - return to previous state\n"); 475 switch (dut->p2p_mode) { 476 case P2P_IDLE: 477 wpa_command(ifname, "P2P_STOP_FIND"); 478 break; 479 case P2P_DISCOVER: 480 /* Already running discovery */ 481 break; 482 case P2P_LISTEN: 483 wpa_command(ifname, "P2P_LISTEN"); 484 break; 485 case P2P_DISABLE: 486 printf("Invalid state - P2P was disabled?!\n"); 487 break; 488 } 489 return 0; 490 } 491 } 492 493 printf("Peer discovery timed out - peer not discovered\n"); 494 wpa_command(ifname, "P2P_STOP_FIND"); 495 496 return -1; 497 } 498 499 500 static void add_dummy_services(const char *intf) 501 { 502 wpa_command(intf, "P2P_SERVICE_ADD bonjour 0b5f6166706f766572746370c00c000c01 074578616d706c65c027"); 503 wpa_command(intf, "P2P_SERVICE_ADD bonjour 076578616d706c650b5f6166706f766572746370c00c001001 00"); 504 wpa_command(intf, "P2P_SERVICE_ADD bonjour 045f697070c00c000c01 094d795072696e746572c027"); 505 wpa_command(intf, "P2P_SERVICE_ADD bonjour 096d797072696e746572045f697070c00c001001 09747874766572733d311a70646c3d6170706c69636174696f6e2f706f7374736372797074"); 506 507 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::upnp:rootdevice"); 508 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:5566d33e-9774-09ab-4822-333456785632::upnp:rootdevice"); 509 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:1122de4e-8574-59ab-9322-333456789044::urn:schemas-upnp-org:service:ContentDirectory:2"); 510 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:5566d33e-9774-09ab-4822-333456785632::urn:schemas-upnp-org:service:ContentDirectory:2"); 511 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:6859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:InternetGatewayDevice:1"); 512 513 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:1859dede-8574-59ab-9332-123456789012::upnp:rootdevice"); 514 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:1566d33e-9774-09ab-4822-333456785632::upnp:rootdevice"); 515 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:2122de4e-8574-59ab-9322-333456789044::urn:schemas-upnp-org:service:ContentDirectory:2"); 516 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:1566d33e-9774-09ab-4822-333456785632::urn:schemas-upnp-org:service:ContentDirectory:2"); 517 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:1859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:InternetGatewayDevice:1"); 518 519 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:2859dede-8574-59ab-9332-123456789012::upnp:rootdevice"); 520 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:2566d33e-9774-09ab-4822-333456785632::upnp:rootdevice"); 521 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:3122de4e-8574-59ab-9322-333456789044::urn:schemas-upnp-org:service:ContentDirectory:2"); 522 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:2566d33e-9774-09ab-4822-333456785632::urn:schemas-upnp-org:service:ContentDirectory:2"); 523 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:2859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:InternetGatewayDevice:1"); 524 525 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:3859dede-8574-59ab-9332-123456789012::upnp:rootdevice"); 526 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:3566d33e-9774-09ab-4822-333456785632::upnp:rootdevice"); 527 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:4122de4e-8574-59ab-9322-333456789044::urn:schemas-upnp-org:service:ContentDirectory:2"); 528 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:3566d33e-9774-09ab-4822-333456785632::urn:schemas-upnp-org:service:ContentDirectory:2"); 529 wpa_command(intf, "P2P_SERVICE_ADD upnp 10 uuid:3859dede-8574-59ab-9332-123456789012::urn:schemas-upnp-org:device:InternetGatewayDevice:1"); 530 } 531 532 533 void disconnect_station(struct sigma_dut *dut) 534 { 535 wpa_command(get_station_ifname(), "DISCONNECT"); 536 remove_wpa_networks(get_station_ifname()); 537 dut->infra_ssid[0] = '\0'; 538 #ifdef __linux__ 539 { 540 char path[128]; 541 char buf[200]; 542 struct stat s; 543 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", 544 get_station_ifname()); 545 if (stat(path, &s) == 0) { 546 snprintf(buf, sizeof(buf), 547 "kill `cat %s`", path); 548 sigma_dut_print(dut, DUT_MSG_DEBUG, 549 "Kill previous DHCP client: %s", buf); 550 run_system(dut, buf); 551 unlink(path); 552 } 553 snprintf(buf, sizeof(buf), 554 "ifconfig %s 0.0.0.0", get_station_ifname()); 555 sigma_dut_print(dut, DUT_MSG_DEBUG, 556 "Clear infrastructure station IP address: %s", 557 buf); 558 run_system(dut, buf); 559 } 560 #endif /* __linux__ */ 561 } 562 563 564 static int cmd_sta_get_p2p_dev_address(struct sigma_dut *dut, 565 struct sigma_conn *conn, 566 struct sigma_cmd *cmd) 567 { 568 const char *intf = get_param(cmd, "interface"); 569 char buf[100], resp[200]; 570 571 start_sta_mode(dut); 572 if (get_wpa_status(intf, "p2p_device_address", buf, sizeof(buf)) < 0) { 573 send_resp(dut, conn, SIGMA_ERROR, NULL); 574 return 0; 575 } 576 577 snprintf(resp, sizeof(resp), "DevID,%s", buf); 578 send_resp(dut, conn, SIGMA_COMPLETE, resp); 579 return 0; 580 } 581 582 583 static int cmd_sta_set_p2p(struct sigma_dut *dut, struct sigma_conn *conn, 584 struct sigma_cmd *cmd) 585 { 586 const char *intf = get_p2p_ifname(get_param(cmd, "Interface")); 587 char buf[256]; 588 const char *val; 589 const char *noa_dur, *noa_int, *noa_count; 590 const char *ext_listen_int, *ext_listen_period; 591 592 val = get_param(cmd, "LISTEN_CHN"); 593 if (val) { 594 dut->listen_chn = atoi(val); 595 if (dut->listen_chn == 2) { 596 /* social channel 2 on 60 GHz band */ 597 snprintf(buf, sizeof(buf), 598 "P2P_SET listen_channel 2 180"); 599 } else { 600 /* social channels 1/6/11 on 2.4 GHz band */ 601 snprintf(buf, sizeof(buf), "P2P_SET listen_channel %d", 602 dut->listen_chn); 603 } 604 if (wpa_command(intf, buf) < 0) 605 return -2; 606 } 607 608 ext_listen_int = get_param(cmd, "Ext_Listen_Time_Interval"); 609 ext_listen_period = get_param(cmd, "Ext_Listen_Time_Period"); 610 611 if (ext_listen_int || ext_listen_period) { 612 if (!ext_listen_int || !ext_listen_period) { 613 sigma_dut_print(dut, DUT_MSG_INFO, "Only one " 614 "ext_listen_time parameter included; " 615 "both are needed"); 616 return -1; 617 } 618 snprintf(buf, sizeof(buf), "P2P_EXT_LISTEN %d %d", 619 atoi(ext_listen_period), 620 atoi(ext_listen_int)); 621 if (wpa_command(intf, buf) < 0) 622 return -2; 623 } 624 625 val = get_param(cmd, "P2P_MODE"); 626 if (val) { 627 if (strcasecmp(val, "Listen") == 0) { 628 wpa_command(intf, "P2P_SET disabled 0"); 629 if (wpa_command(intf, "P2P_LISTEN") < 0) 630 return -2; 631 dut->p2p_mode = P2P_LISTEN; 632 } else if (strcasecmp(val, "Discover") == 0) { 633 wpa_command(intf, "P2P_SET disabled 0"); 634 if (wpa_command(intf, "P2P_FIND") < 0) 635 return -2; 636 dut->p2p_mode = P2P_DISCOVER; 637 } else if (strcasecmp(val, "Idle") == 0) { 638 wpa_command(intf, "P2P_SET disabled 0"); 639 if (wpa_command(intf, "P2P_STOP_FIND") < 0) 640 return -2; 641 dut->p2p_mode = P2P_IDLE; 642 } else if (strcasecmp(val, "Disable") == 0) { 643 if (wpa_command(intf, "P2P_SET disabled 1") < 0) 644 return -2; 645 dut->p2p_mode = P2P_DISABLE; 646 } else 647 return -1; 648 } 649 650 val = get_param(cmd, "PERSISTENT"); 651 if (val) { 652 dut->persistent = atoi(val); 653 } 654 655 val = get_param(cmd, "INTRA_BSS"); 656 if (val) { 657 int intra_bss = atoi(val); 658 /* TODO: add support for this */ 659 if (!intra_bss) { 660 sigma_dut_print(dut, DUT_MSG_INFO, "Disabling of " 661 "intra-BSS bridging not supported"); 662 return -1; 663 } 664 dut->intra_bss = intra_bss; 665 } 666 667 /* NoA is not applicable for 60 GHz */ 668 if (dut->program != PROGRAM_60GHZ) { 669 noa_dur = get_param(cmd, "NoA_duration"); 670 noa_int = get_param(cmd, "NoA_Interval"); 671 noa_count = get_param(cmd, "NoA_Count"); 672 if (noa_dur) 673 dut->noa_duration = atoi(noa_dur); 674 675 if (noa_int) 676 dut->noa_interval = atoi(noa_int); 677 678 if (noa_count) 679 dut->noa_count = atoi(noa_count); 680 681 if (noa_dur || noa_int || noa_count) { 682 int start; 683 const char *ifname; 684 if (dut->noa_count == 0 && dut->noa_duration == 0) 685 start = 0; 686 else if (dut->noa_duration > 102) /* likely non-periodic 687 * NoA */ 688 start = 50; 689 else 690 start = 102 - dut->noa_duration; 691 snprintf(buf, sizeof(buf), "P2P_SET noa %d,%d,%d", 692 dut->noa_count, start, 693 dut->noa_duration); 694 ifname = get_group_ifname(dut, intf); 695 sigma_dut_print(dut, DUT_MSG_INFO, 696 "Set GO NoA for interface %s", ifname); 697 if (wpa_command(ifname, buf) < 0) { 698 send_resp(dut, conn, SIGMA_ERROR, 699 "errorCode,Use of NoA as GO not supported"); 700 return 0; 701 } 702 } 703 } 704 705 val = get_param(cmd, "Concurrency"); 706 if (val) { 707 /* TODO */ 708 } 709 710 val = get_param(cmd, "P2PInvitation"); 711 if (val) { 712 /* TODO */ 713 } 714 715 val = get_param(cmd, "BCN_INT"); 716 if (val) { 717 /* TODO */ 718 } 719 720 val = get_param(cmd, "Discoverability"); 721 if (val) { 722 snprintf(buf, sizeof(buf), "P2P_SET discoverability %d", 723 atoi(val)); 724 if (wpa_command(intf, buf) < 0) 725 return -2; 726 } 727 728 val = get_param(cmd, "Service_Discovery"); 729 if (val) { 730 int sd = atoi(val); 731 if (sd) { 732 wpa_command(intf, "P2P_SERVICE_FLUSH"); 733 734 if (sd == 2) 735 wpa_command(intf, "P2P_SET force_long_sd 1"); 736 737 /* 738 * Set up some dummy service to create a large SD 739 * response that requires fragmentation. 740 */ 741 add_dummy_services(intf); 742 } else { 743 wpa_command(intf, "P2P_SERVICE_FLUSH"); 744 } 745 } 746 747 val = get_param(cmd, "CrossConnection"); 748 if (val) { 749 if (atoi(val)) { 750 if (wpa_command(intf, "P2P_SET cross_connect 1") < 0) 751 return -2; 752 } else { 753 if (wpa_command(intf, "P2P_SET cross_connect 0") < 0) 754 return -2; 755 } 756 } 757 758 val = get_param(cmd, "P2PManaged"); 759 if (val) { 760 if (atoi(val)) { 761 send_resp(dut, conn, SIGMA_INVALID, "ErrorCode," 762 "P2P Managed functionality not supported"); 763 return 0; 764 } 765 } 766 767 val = get_param(cmd, "GO_APSD"); 768 if (val) { 769 if (atoi(val)) { 770 if (wpa_command(intf, "P2P_SET go_apsd 1") < 0) 771 return -2; 772 } else { 773 if (wpa_command(intf, "P2P_SET go_apsd 0") < 0) 774 return -2; 775 } 776 } 777 778 return 1; 779 } 780 781 782 static int cmd_sta_start_autonomous_go(struct sigma_dut *dut, 783 struct sigma_conn *conn, 784 struct sigma_cmd *cmd) 785 { 786 const char *intf = get_param(cmd, "Interface"); 787 const char *oper_chn = get_param(cmd, "OPER_CHN"); 788 const char *ssid_param = get_param(cmd, "SSID"); 789 int freq, chan, res; 790 char buf[256], grpid[100], resp[200]; 791 struct wpa_ctrl *ctrl; 792 char *ifname, *gtype, *pos, *ssid, bssid[20]; 793 char *go_dev_addr; 794 795 if (oper_chn == NULL) 796 return -1; 797 798 chan = atoi(oper_chn); 799 if (dut->program == PROGRAM_60GHZ) { 800 freq = get_60g_freq(chan); 801 if (freq == 0) { 802 sigma_dut_print(dut, DUT_MSG_ERROR, 803 "Invalid channel: %d", chan); 804 return -1; 805 } 806 } else if (chan >= 1 && chan <= 13) 807 freq = 2407 + chan * 5; 808 else if (chan == 14) 809 freq = 2484; 810 else 811 freq = 5000 + chan * 5; 812 813 if (ssid_param) 814 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix %s", 815 ssid_param); 816 else 817 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix "); 818 if (wpa_command(intf, buf) < 0) 819 return -2; 820 821 /* Stop Listen/Discovery state to avoid issues with GO operations */ 822 if (wpa_command(intf, "P2P_STOP_FIND") < 0) 823 return -2; 824 825 ctrl = open_wpa_mon(intf); 826 if (ctrl == NULL) { 827 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open " 828 "wpa_supplicant monitor connection"); 829 return -2; 830 } 831 832 snprintf(buf, sizeof(buf), "P2P_GROUP_ADD %sfreq=%d", 833 dut->persistent ? "persistent " : "", freq); 834 if (wpa_command(intf, buf) < 0) { 835 wpa_ctrl_detach(ctrl); 836 wpa_ctrl_close(ctrl); 837 return -2; 838 } 839 840 res = get_wpa_cli_event(dut, ctrl, "P2P-GROUP-STARTED", 841 buf, sizeof(buf)); 842 843 wpa_ctrl_detach(ctrl); 844 wpa_ctrl_close(ctrl); 845 846 if (res < 0) { 847 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,GO starting " 848 "did not complete"); 849 return 0; 850 } 851 852 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group started event '%s'", buf); 853 ifname = strchr(buf, ' '); 854 if (ifname == NULL) 855 return -2; 856 ifname++; 857 pos = strchr(ifname, ' '); 858 if (pos == NULL) 859 return -2; 860 *pos++ = '\0'; 861 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group interface %s", ifname); 862 863 gtype = pos; 864 pos = strchr(gtype, ' '); 865 if (pos == NULL) 866 return -2; 867 *pos++ = '\0'; 868 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group type %s", gtype); 869 870 ssid = strstr(pos, "ssid=\""); 871 if (ssid == NULL) 872 return -2; 873 ssid += 6; 874 pos = strchr(ssid, '"'); 875 if (pos == NULL) 876 return -2; 877 *pos++ = '\0'; 878 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group SSID %s", ssid); 879 880 go_dev_addr = strstr(pos, "go_dev_addr="); 881 if (go_dev_addr == NULL) { 882 sigma_dut_print(dut, DUT_MSG_ERROR, "No GO P2P Device Address " 883 "found"); 884 return -2; 885 } 886 go_dev_addr += 12; 887 if (strlen(go_dev_addr) < 17) { 888 sigma_dut_print(dut, DUT_MSG_ERROR, "Too short GO P2P Device " 889 "Address '%s'", go_dev_addr); 890 return -2; 891 } 892 go_dev_addr[17] = '\0'; 893 *pos = '\0'; 894 sigma_dut_print(dut, DUT_MSG_DEBUG, "GO P2P Device Address %s", 895 go_dev_addr); 896 897 if (get_wpa_status(ifname, "bssid", bssid, sizeof(bssid)) < 0) 898 return -2; 899 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group BSSID %s", bssid); 900 901 snprintf(grpid, sizeof(grpid), "%s %s", go_dev_addr, ssid); 902 p2p_group_add(dut, ifname, strcmp(gtype, "GO") == 0, grpid, ssid); 903 904 snprintf(resp, sizeof(resp), "GroupID,%s", grpid); 905 send_resp(dut, conn, SIGMA_COMPLETE, resp); 906 return 0; 907 } 908 909 910 static int cmd_sta_p2p_connect(struct sigma_dut *dut, struct sigma_conn *conn, 911 struct sigma_cmd *cmd) 912 { 913 const char *intf = get_p2p_ifname(get_param(cmd, "Interface")); 914 const char *devid = get_param(cmd, "P2PDevID"); 915 /* const char *grpid_param = get_param(cmd, "GroupID"); */ 916 int res; 917 char buf[256]; 918 struct wpa_ctrl *ctrl; 919 char *ifname, *gtype, *pos, *ssid, bssid[20]; 920 char grpid[100]; 921 922 /* TODO: handle the new grpid argument */ 923 924 if (devid == NULL) 925 return -1; 926 927 if (dut->wps_method == WFA_CS_WPS_NOT_READY) { 928 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS parameters " 929 "not yet set"); 930 return 0; 931 } 932 933 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover GO %s", devid); 934 if (p2p_discover_peer(dut, intf, devid, 1) < 0) { 935 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not " 936 "discover the requested peer"); 937 return 0; 938 } 939 940 ctrl = open_wpa_mon(intf); 941 if (ctrl == NULL) { 942 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open " 943 "wpa_supplicant monitor connection"); 944 return -2; 945 } 946 947 switch (dut->wps_method) { 948 case WFA_CS_WPS_PBC: 949 snprintf(buf, sizeof(buf), "P2P_CONNECT %s pbc join", 950 devid); 951 break; 952 case WFA_CS_WPS_PIN_DISPLAY: 953 snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s display join", 954 devid, dut->wps_pin); 955 break; 956 case WFA_CS_WPS_PIN_KEYPAD: 957 snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s keypad join", 958 devid, dut->wps_pin); 959 break; 960 default: 961 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unknown WPS " 962 "method for sta_p2p_connect"); 963 wpa_ctrl_detach(ctrl); 964 wpa_ctrl_close(ctrl); 965 return 0; 966 } 967 968 if (wpa_command(intf, buf) < 0) { 969 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to join " 970 "the group"); 971 wpa_ctrl_detach(ctrl); 972 wpa_ctrl_close(ctrl); 973 return 0; 974 } 975 976 res = get_wpa_cli_event(dut, ctrl, "P2P-GROUP-STARTED", 977 buf, sizeof(buf)); 978 979 wpa_ctrl_detach(ctrl); 980 wpa_ctrl_close(ctrl); 981 982 if (res < 0) { 983 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Group joining " 984 "did not complete"); 985 return 0; 986 } 987 988 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group started event '%s'", buf); 989 ifname = strchr(buf, ' '); 990 if (ifname == NULL) 991 return -2; 992 ifname++; 993 pos = strchr(ifname, ' '); 994 if (pos == NULL) 995 return -2; 996 *pos++ = '\0'; 997 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group interface %s", ifname); 998 999 gtype = pos; 1000 pos = strchr(gtype, ' '); 1001 if (pos == NULL) 1002 return -2; 1003 *pos++ = '\0'; 1004 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group type %s", gtype); 1005 1006 ssid = strstr(pos, "ssid=\""); 1007 if (ssid == NULL) 1008 return -2; 1009 ssid += 6; 1010 pos = strchr(ssid, '"'); 1011 if (pos == NULL) 1012 return -2; 1013 *pos = '\0'; 1014 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group SSID %s", ssid); 1015 1016 if (get_wpa_status(ifname, "bssid", bssid, sizeof(bssid)) < 0) 1017 return -2; 1018 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group BSSID %s", bssid); 1019 1020 snprintf(grpid, sizeof(grpid), "%s %s", bssid, ssid); 1021 p2p_group_add(dut, ifname, strcmp(gtype, "GO") == 0, grpid, ssid); 1022 1023 return 1; 1024 } 1025 1026 1027 static int p2p_group_formation_event(struct sigma_dut *dut, 1028 struct sigma_conn *conn, 1029 struct wpa_ctrl *ctrl, 1030 const char *intf, const char *peer_role, 1031 int nfc); 1032 1033 static int cmd_sta_p2p_start_group_formation(struct sigma_dut *dut, 1034 struct sigma_conn *conn, 1035 struct sigma_cmd *cmd) 1036 { 1037 const char *intf = get_p2p_ifname(get_param(cmd, "Interface")); 1038 const char *devid = get_param(cmd, "P2PDevID"); 1039 const char *intent_val = get_param(cmd, "INTENT_VAL"); 1040 const char *init_go_neg = get_param(cmd, "INIT_GO_NEG"); 1041 const char *oper_chn = get_param(cmd, "OPER_CHN"); 1042 const char *ssid_param = get_param(cmd, "SSID"); 1043 int freq = 0, chan = 0, init; 1044 char buf[256]; 1045 struct wpa_ctrl *ctrl; 1046 1047 if (devid == NULL || intent_val == NULL) 1048 return -1; 1049 1050 if (init_go_neg) 1051 init = atoi(init_go_neg); 1052 else 1053 init = 0; 1054 1055 if (dut->program == PROGRAM_60GHZ) { 1056 if (!oper_chn) 1057 return -1; 1058 chan = atoi(oper_chn); 1059 freq = get_60g_freq(chan); 1060 if (freq == 0) { 1061 sigma_dut_print(dut, DUT_MSG_ERROR, 1062 "Invalid channel: %d", chan); 1063 return -1; 1064 } 1065 } else if (oper_chn) { 1066 chan = atoi(oper_chn); 1067 if (chan >= 1 && chan <= 13) 1068 freq = 2407 + chan * 5; 1069 else if (chan == 14) 1070 freq = 2484; 1071 else 1072 freq = 5000 + chan * 5; 1073 } 1074 1075 if (dut->wps_method == WFA_CS_WPS_NOT_READY) { 1076 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS parameters " 1077 "not yet set"); 1078 return 0; 1079 } 1080 1081 sigma_dut_print(dut, DUT_MSG_DEBUG, 1082 "Trying to discover peer %s for group formation chan %d (freq %d)", 1083 devid, chan, freq); 1084 if (p2p_discover_peer(dut, intf, devid, init) < 0) { 1085 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not " 1086 "discover the requested peer"); 1087 return 0; 1088 } 1089 1090 if (ssid_param) 1091 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix %s", 1092 ssid_param); 1093 else 1094 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix "); 1095 if (wpa_command(intf, buf) < 0) 1096 return -2; 1097 1098 if (init) { 1099 ctrl = open_wpa_mon(intf); 1100 if (ctrl == NULL) { 1101 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open " 1102 "wpa_supplicant monitor connection"); 1103 return -2; 1104 } 1105 } else 1106 ctrl = NULL; 1107 1108 snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s%s%s%s go_intent=%d", 1109 devid, 1110 dut->wps_method == WFA_CS_WPS_PBC ? 1111 "pbc" : dut->wps_pin, 1112 dut->wps_method == WFA_CS_WPS_PBC ? "" : 1113 (dut->wps_method == WFA_CS_WPS_PIN_DISPLAY ? " display" : 1114 (dut->wps_method == WFA_CS_WPS_PIN_LABEL ? " label" : 1115 " keypad" )), 1116 dut->persistent ? " persistent" : "", 1117 init ? "" : " auth", 1118 atoi(intent_val)); 1119 if (freq > 0) { 1120 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), 1121 " freq=%d", freq); 1122 } 1123 if (wpa_command(intf, buf) < 0) { 1124 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to start " 1125 "group formation"); 1126 if (ctrl) { 1127 wpa_ctrl_detach(ctrl); 1128 wpa_ctrl_close(ctrl); 1129 } 1130 return 0; 1131 } 1132 1133 if (!init) 1134 return 1; 1135 1136 return p2p_group_formation_event(dut, conn, ctrl, intf, NULL, 0); 1137 } 1138 1139 1140 static int p2p_group_formation_event(struct sigma_dut *dut, 1141 struct sigma_conn *conn, 1142 struct wpa_ctrl *ctrl, 1143 const char *intf, const char *peer_role, 1144 int nfc) 1145 { 1146 int res; 1147 char buf[256], grpid[50], resp[256]; 1148 char *ifname, *gtype, *pos, *ssid, bssid[20]; 1149 char *go_dev_addr; 1150 char role[30]; 1151 const char *events[] = { 1152 "P2P-GROUP-STARTED", 1153 "P2P-GO-NEG-FAILURE", 1154 "P2P-NFC-PEER-CLIENT", 1155 "P2P-GROUP-FORMATION-FAILURE", 1156 NULL 1157 }; 1158 1159 role[0] = '\0'; 1160 if (peer_role) 1161 snprintf(role, sizeof(role), ",PeerRole,%s", peer_role); 1162 1163 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf)); 1164 1165 wpa_ctrl_detach(ctrl); 1166 wpa_ctrl_close(ctrl); 1167 1168 if (res < 0) { 1169 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Group formation " 1170 "did not complete"); 1171 return 0; 1172 } 1173 1174 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group started event '%s'", buf); 1175 1176 if (strstr(buf, "P2P-NFC-PEER-CLIENT")) { 1177 snprintf(resp, sizeof(resp), 1178 "Result,,GroupID,,PeerRole,1,PauseFlag,0"); 1179 send_resp(dut, conn, SIGMA_COMPLETE, resp); 1180 return 0; 1181 } 1182 1183 if (strstr(buf, "P2P-GROUP-FORMATION-FAILURE")) { 1184 snprintf(buf, sizeof(buf), "ErrorCode,Group formation failed"); 1185 send_resp(dut, conn, SIGMA_ERROR, buf); 1186 return 0; 1187 } 1188 1189 if (strstr(buf, "P2P-GO-NEG-FAILURE")) { 1190 int status = -1; 1191 pos = strstr(buf, " status="); 1192 if (pos) 1193 status = atoi(pos + 8); 1194 sigma_dut_print(dut, DUT_MSG_INFO, "GO Negotiation failed " 1195 "(status=%d)", status); 1196 if (status == 9) { 1197 sigma_dut_print(dut, DUT_MSG_INFO, "Both devices " 1198 "tried to use GO Intent 15"); 1199 send_resp(dut, conn, SIGMA_COMPLETE, "result,FAIL"); 1200 return 0; 1201 } 1202 snprintf(buf, sizeof(buf), "ErrorCode,GO Negotiation failed " 1203 "(status=%d)", status); 1204 send_resp(dut, conn, SIGMA_ERROR, buf); 1205 return 0; 1206 } 1207 1208 ifname = strchr(buf, ' '); 1209 if (ifname == NULL) 1210 return -2; 1211 ifname++; 1212 pos = strchr(ifname, ' '); 1213 if (pos == NULL) 1214 return -2; 1215 *pos++ = '\0'; 1216 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group interface %s", ifname); 1217 1218 gtype = pos; 1219 pos = strchr(gtype, ' '); 1220 if (pos == NULL) 1221 return -2; 1222 *pos++ = '\0'; 1223 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group type %s", gtype); 1224 1225 ssid = strstr(pos, "ssid=\""); 1226 if (ssid == NULL) 1227 return -2; 1228 ssid += 6; 1229 pos = strchr(ssid, '"'); 1230 if (pos == NULL) 1231 return -2; 1232 *pos++ = '\0'; 1233 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group SSID %s", ssid); 1234 1235 go_dev_addr = strstr(pos, "go_dev_addr="); 1236 if (go_dev_addr == NULL) { 1237 sigma_dut_print(dut, DUT_MSG_ERROR, "No GO P2P Device Address " 1238 "found\n"); 1239 return -2; 1240 } 1241 go_dev_addr += 12; 1242 if (strlen(go_dev_addr) < 17) { 1243 sigma_dut_print(dut, DUT_MSG_ERROR, "Too short GO P2P Device " 1244 "Address '%s'", go_dev_addr); 1245 return -2; 1246 } 1247 go_dev_addr[17] = '\0'; 1248 *pos = '\0'; 1249 sigma_dut_print(dut, DUT_MSG_ERROR, "GO P2P Device Address %s", 1250 go_dev_addr); 1251 1252 if (get_wpa_status(ifname, "bssid", bssid, sizeof(bssid)) < 0) 1253 return -2; 1254 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group BSSID %s", bssid); 1255 1256 snprintf(grpid, sizeof(grpid), "%s %s", go_dev_addr, ssid); 1257 p2p_group_add(dut, ifname, strcmp(gtype, "GO") == 0, grpid, ssid); 1258 snprintf(resp, sizeof(resp), "Result,%s,GroupID,%s%s%s", 1259 strcmp(gtype, "GO") == 0 ? "GO" : "CLIENT", grpid, role, 1260 nfc ? ",PauseFlag,0" : ""); 1261 send_resp(dut, conn, SIGMA_COMPLETE, resp); 1262 1263 #ifdef __QNXNTO__ 1264 /* Start DHCP server if we became the GO */ 1265 if (strcmp(gtype, "GO") == 0 && 1266 system("dhcpd -cf /etc/dhcpd.conf -pf /var/run/dhcpd qca1 &") == 0) 1267 sigma_dut_print(dut, DUT_MSG_ERROR, 1268 "Failed to start DHCPD server"); 1269 #endif /* __QNXNTO__ */ 1270 1271 return 0; 1272 } 1273 1274 1275 int wps_connection_event(struct sigma_dut *dut, struct sigma_conn *conn, 1276 struct wpa_ctrl *ctrl, const char *intf, int p2p_resp) 1277 { 1278 int res; 1279 char buf[256]; 1280 const char *events[] = { 1281 "CTRL-EVENT-CONNECTED", 1282 "WPS-FAIL", 1283 "WPS-TIMEOUT", 1284 NULL 1285 }; 1286 1287 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf)); 1288 1289 wpa_ctrl_detach(ctrl); 1290 wpa_ctrl_close(ctrl); 1291 1292 if (res < 0) { 1293 #ifdef USE_ERROR_RETURNS 1294 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS connection " 1295 "did not complete"); 1296 #else 1297 send_resp(dut, conn, SIGMA_COMPLETE, "ErrorCode,WPS connection " 1298 "did not complete"); 1299 #endif 1300 return 0; 1301 } 1302 1303 if (strstr(buf, "WPS-FAIL") || strstr(buf, "WPS-TIMEOUT")) { 1304 #ifdef USE_ERROR_RETURNS 1305 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS operation " 1306 "failed"); 1307 #else 1308 send_resp(dut, conn, SIGMA_COMPLETE, "ErrorCode,WPS operation " 1309 "failed"); 1310 #endif 1311 return 0; 1312 } 1313 1314 if (!p2p_resp) 1315 return 1; 1316 send_resp(dut, conn, SIGMA_COMPLETE, "Result,,GroupID,,PeerRole,"); 1317 return 0; 1318 } 1319 1320 1321 static int cmd_sta_p2p_dissolve(struct sigma_dut *dut, struct sigma_conn *conn, 1322 struct sigma_cmd *cmd) 1323 { 1324 const char *intf = get_param(cmd, "interface"); 1325 const char *grpid = get_param(cmd, "GroupID"); 1326 struct wfa_cs_p2p_group *grp; 1327 char buf[128]; 1328 1329 if (grpid == NULL) 1330 return -1; 1331 1332 grp = p2p_group_get(dut, grpid); 1333 if (grp == NULL) { 1334 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Requested group " 1335 "not found"); 1336 return 0; 1337 } 1338 1339 snprintf(buf, sizeof(buf), "P2P_GROUP_REMOVE %s", grp->ifname); 1340 if (wpa_command(intf, buf) < 0) { 1341 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to remove the " 1342 "specified group from wpa_supplicant - assume " 1343 "group has already been removed"); 1344 } 1345 sigma_dut_print(dut, DUT_MSG_DEBUG, "Removed group %s", grpid); 1346 if (grp->go) 1347 dut->go = 0; 1348 else 1349 dut->p2p_client = 0; 1350 p2p_group_remove(dut, grpid); 1351 return 1; 1352 } 1353 1354 1355 static int cmd_sta_send_p2p_invitation_req(struct sigma_dut *dut, 1356 struct sigma_conn *conn, 1357 struct sigma_cmd *cmd) 1358 { 1359 const char *intf = get_param(cmd, "interface"); 1360 const char *devid = get_param(cmd, "P2PDevID"); 1361 const char *grpid = get_param(cmd, "GroupID"); 1362 const char *reinvoke = get_param(cmd, "Reinvoke"); 1363 char c[256]; 1364 char buf[4096]; 1365 struct wpa_ctrl *ctrl; 1366 int res; 1367 1368 if (devid == NULL || grpid == NULL) 1369 return -1; 1370 1371 if (reinvoke && atoi(reinvoke)) { 1372 int id = -1; 1373 char *ssid, *pos; 1374 1375 ssid = strchr(grpid, ' '); 1376 if (ssid == NULL) { 1377 sigma_dut_print(dut, DUT_MSG_INFO, "Invalid grpid"); 1378 return -1; 1379 } 1380 ssid++; 1381 sigma_dut_print(dut, DUT_MSG_DEBUG, "Search for persistent " 1382 "group credentials based on SSID: '%s'", ssid); 1383 if (wpa_command_resp(intf, "LIST_NETWORKS", 1384 buf, sizeof(buf)) < 0) 1385 return -2; 1386 pos = strstr(buf, ssid); 1387 if (pos == NULL || pos == buf || pos[-1] != '\t' || 1388 pos[strlen(ssid)] != '\t') { 1389 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode," 1390 "Persistent group credentials not found"); 1391 return 0; 1392 } 1393 while (pos > buf && pos[-1] != '\n') 1394 pos--; 1395 id = atoi(pos); 1396 snprintf(c, sizeof(c), "P2P_INVITE persistent=%d peer=%s", 1397 id, devid); 1398 } else { 1399 struct wfa_cs_p2p_group *grp; 1400 grp = p2p_group_get(dut, grpid); 1401 if (grp == NULL) { 1402 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode," 1403 "No active P2P group found for invitation"); 1404 return 0; 1405 } 1406 snprintf(c, sizeof(c), "P2P_INVITE group=%s peer=%s", 1407 grp->ifname, devid); 1408 } 1409 1410 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover peer %s for " 1411 "invitation", devid); 1412 if (p2p_discover_peer(dut, intf, devid, 0) < 0) { 1413 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not " 1414 "discover the requested peer"); 1415 return 0; 1416 } 1417 1418 ctrl = open_wpa_mon(intf); 1419 if (ctrl == NULL) { 1420 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open " 1421 "wpa_supplicant monitor connection"); 1422 return -2; 1423 } 1424 1425 if (wpa_command(intf, c) < 0) { 1426 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to send invitation " 1427 "request"); 1428 wpa_ctrl_detach(ctrl); 1429 wpa_ctrl_close(ctrl); 1430 return -2; 1431 } 1432 1433 res = get_wpa_cli_event(dut, ctrl, "P2P-INVITATION-RESULT", 1434 buf, sizeof(buf)); 1435 1436 wpa_ctrl_detach(ctrl); 1437 wpa_ctrl_close(ctrl); 1438 1439 if (res < 0) 1440 return -2; 1441 1442 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invitation event: '%s'", buf); 1443 return 1; 1444 } 1445 1446 1447 static int cmd_sta_accept_p2p_invitation_req(struct sigma_dut *dut, 1448 struct sigma_conn *conn, 1449 struct sigma_cmd *cmd) 1450 { 1451 const char *intf = get_param(cmd, "Interface"); 1452 const char *devid = get_param(cmd, "P2PDevID"); 1453 const char *grpid = get_param(cmd, "GroupID"); 1454 const char *reinvoke = get_param(cmd, "Reinvoke"); 1455 char buf[100]; 1456 1457 if (devid == NULL || grpid == NULL) 1458 return -1; 1459 1460 if (reinvoke && atoi(reinvoke)) { 1461 /* 1462 * Assume persistent reconnect is enabled and there is no need 1463 * to do anything here. 1464 */ 1465 return 1; 1466 } 1467 1468 /* 1469 * In a client-joining-a-running-group case, we need to separately 1470 * authorize the invitation. 1471 */ 1472 1473 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover GO %s", devid); 1474 if (p2p_discover_peer(dut, intf, devid, 1) < 0) { 1475 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not " 1476 "discover the requested peer"); 1477 return 0; 1478 } 1479 1480 snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s join auth", 1481 devid, 1482 dut->wps_method == WFA_CS_WPS_PBC ? 1483 "pbc" : dut->wps_pin); 1484 if (wpa_command(intf, buf) < 0) 1485 return -2; 1486 1487 return 1; 1488 } 1489 1490 1491 static int cmd_sta_send_p2p_provision_dis_req(struct sigma_dut *dut, 1492 struct sigma_conn *conn, 1493 struct sigma_cmd *cmd) 1494 { 1495 const char *intf = get_param(cmd, "interface"); 1496 const char *conf_method = get_param(cmd, "ConfigMethod"); 1497 const char *devid = get_param(cmd, "P2PDevID"); 1498 char buf[256]; 1499 char *method; 1500 1501 if (conf_method == NULL || devid == NULL) 1502 return -1; 1503 1504 if (strcasecmp(conf_method, "Display") == 0) 1505 method = "display"; 1506 else if (strcasecmp(conf_method, "Keyboard") == 0 || 1507 strcasecmp(conf_method, "keypad") == 0) 1508 method = "keypad"; 1509 else if (strcasecmp(conf_method, "Label") == 0) 1510 method = "label"; 1511 else if (strcasecmp(conf_method, "pbc") == 0 || 1512 strcasecmp(conf_method, "pushbutton") == 0) 1513 method = "pbc"; 1514 else 1515 return -1; 1516 1517 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover peer %s for " 1518 "provision discovery", devid); 1519 if (p2p_discover_peer(dut, intf, devid, 0) < 0) { 1520 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not " 1521 "discover the requested peer"); 1522 return 0; 1523 } 1524 1525 snprintf(buf, sizeof(buf), "P2P_PROV_DISC %s %s", devid, method); 1526 if (wpa_command(intf, buf) < 0) { 1527 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to send provision " 1528 "discovery request"); 1529 return -2; 1530 } 1531 1532 return 1; 1533 } 1534 1535 1536 static int cmd_sta_set_wps_pbc(struct sigma_dut *dut, struct sigma_conn *conn, 1537 struct sigma_cmd *cmd) 1538 { 1539 /* const char *intf = get_param(cmd, "Interface"); */ 1540 const char *grpid = get_param(cmd, "GroupID"); 1541 1542 if (grpid) { 1543 struct wfa_cs_p2p_group *grp; 1544 grp = p2p_group_get(dut, grpid); 1545 if (grp && grp->go) { 1546 sigma_dut_print(dut, DUT_MSG_DEBUG, "Authorize a " 1547 "client to join with WPS"); 1548 wpa_command(grp->ifname, "WPS_PBC"); 1549 return 1; 1550 } 1551 } 1552 1553 dut->wps_method = WFA_CS_WPS_PBC; 1554 return 1; 1555 } 1556 1557 1558 static int cmd_sta_wps_read_pin(struct sigma_dut *dut, struct sigma_conn *conn, 1559 struct sigma_cmd *cmd) 1560 { 1561 /* const char *intf = get_param(cmd, "Interface"); */ 1562 const char *grpid = get_param(cmd, "GroupID"); 1563 char *pin = "12345670"; /* TODO: use random PIN */ 1564 char resp[100]; 1565 1566 if (grpid) { 1567 char buf[100]; 1568 struct wfa_cs_p2p_group *grp; 1569 grp = p2p_group_get(dut, grpid); 1570 if (grp && grp->go) { 1571 sigma_dut_print(dut, DUT_MSG_DEBUG, "Authorize a " 1572 "client to join with WPS"); 1573 snprintf(buf, sizeof(buf), "WPS_PIN any %s", pin); 1574 if (wpa_command(grp->ifname, buf) < 0) 1575 return -1; 1576 goto done; 1577 } 1578 } 1579 1580 strncpy(dut->wps_pin, pin, sizeof(dut->wps_pin)); 1581 dut->wps_method = WFA_CS_WPS_PIN_DISPLAY; 1582 done: 1583 snprintf(resp, sizeof(resp), "PIN,%s", pin); 1584 send_resp(dut, conn, SIGMA_COMPLETE, resp); 1585 1586 return 0; 1587 } 1588 1589 1590 static int cmd_sta_wps_read_label(struct sigma_dut *dut, 1591 struct sigma_conn *conn, 1592 struct sigma_cmd *cmd) 1593 { 1594 /* const char *intf = get_param(cmd, "Interface"); */ 1595 const char *grpid = get_param(cmd, "GroupID"); 1596 char *pin = "12345670"; 1597 char resp[100]; 1598 1599 if (grpid) { 1600 char buf[100]; 1601 struct wfa_cs_p2p_group *grp; 1602 grp = p2p_group_get(dut, grpid); 1603 if (grp && grp->go) { 1604 sigma_dut_print(dut, DUT_MSG_DEBUG, "Authorize a " 1605 "client to join with WPS"); 1606 snprintf(buf, sizeof(buf), "WPS_PIN any %s", pin); 1607 wpa_command(grp->ifname, buf); 1608 return 1; 1609 } 1610 } 1611 1612 strncpy(dut->wps_pin, pin, sizeof(dut->wps_pin)); 1613 dut->wps_method = WFA_CS_WPS_PIN_LABEL; 1614 snprintf(resp, sizeof(resp), "LABEL,%s", pin); 1615 send_resp(dut, conn, SIGMA_COMPLETE, resp); 1616 1617 return 0; 1618 } 1619 1620 1621 static int cmd_sta_wps_enter_pin(struct sigma_dut *dut, 1622 struct sigma_conn *conn, 1623 struct sigma_cmd *cmd) 1624 { 1625 /* const char *intf = get_param(cmd, "Interface"); */ 1626 const char *grpid = get_param(cmd, "GroupID"); 1627 const char *pin = get_param(cmd, "PIN"); 1628 1629 if (pin == NULL) 1630 return -1; 1631 1632 if (grpid) { 1633 char buf[100]; 1634 struct wfa_cs_p2p_group *grp; 1635 grp = p2p_group_get(dut, grpid); 1636 if (grp && grp->go) { 1637 sigma_dut_print(dut, DUT_MSG_DEBUG, "Authorize a " 1638 "client to join with WPS"); 1639 snprintf(buf, sizeof(buf), "WPS_PIN any %s", pin); 1640 wpa_command(grp->ifname, buf); 1641 return 1; 1642 } 1643 } 1644 1645 strncpy(dut->wps_pin, pin, sizeof(dut->wps_pin)); 1646 dut->wps_pin[sizeof(dut->wps_pin) - 1] = '\0'; 1647 dut->wps_method = WFA_CS_WPS_PIN_KEYPAD; 1648 1649 return 1; 1650 } 1651 1652 1653 static int cmd_sta_get_psk(struct sigma_dut *dut, struct sigma_conn *conn, 1654 struct sigma_cmd *cmd) 1655 { 1656 /* const char *intf = get_param(cmd, "interface"); */ 1657 const char *grpid = get_param(cmd, "GroupID"); 1658 struct wfa_cs_p2p_group *grp; 1659 char passphrase[64], resp[200]; 1660 1661 if (grpid == NULL) 1662 return -1; 1663 1664 grp = p2p_group_get(dut, grpid); 1665 if (grp == NULL) { 1666 send_resp(dut, conn, SIGMA_ERROR, 1667 "errorCode,Requested group not found"); 1668 return 0; 1669 } 1670 if (!grp->go) { 1671 send_resp(dut, conn, SIGMA_ERROR, 1672 "errorCode,Local role is not GO in the specified " 1673 "group"); 1674 return 0; 1675 } 1676 1677 if (wpa_command_resp(grp->ifname, "P2P_GET_PASSPHRASE", 1678 passphrase, sizeof(passphrase)) < 0) 1679 return -2; 1680 1681 snprintf(resp, sizeof(resp), "passPhrase,%s,ssid,%s", 1682 passphrase, grp->ssid); 1683 send_resp(dut, conn, SIGMA_COMPLETE, resp); 1684 1685 return 0; 1686 } 1687 1688 1689 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn, 1690 struct sigma_cmd *cmd) 1691 { 1692 const char *intf = get_param(cmd, "interface"); 1693 struct wfa_cs_p2p_group *grp, *prev; 1694 char buf[256]; 1695 1696 dut->go = 0; 1697 dut->p2p_client = 0; 1698 dut->wps_method = WFA_CS_WPS_NOT_READY; 1699 1700 grp = dut->groups; 1701 while (grp) { 1702 prev = grp; 1703 grp = grp->next; 1704 1705 snprintf(buf, sizeof(buf), "P2P_GROUP_REMOVE %s", 1706 prev->ifname); 1707 wpa_command(intf, buf); 1708 p2p_group_remove(dut, prev->grpid); 1709 } 1710 1711 wpa_command(intf, "P2P_GROUP_REMOVE *"); 1712 wpa_command(intf, "P2P_STOP_FIND"); 1713 wpa_command(intf, "P2P_FLUSH"); 1714 wpa_command(intf, "P2P_SERVICE_FLUSH"); 1715 wpa_command(intf, "P2P_SET disabled 0"); 1716 wpa_command(intf, "P2P_SET ssid_postfix "); 1717 1718 if (dut->program == PROGRAM_60GHZ) { 1719 wpa_command(intf, "SET p2p_oper_reg_class 180"); 1720 wpa_command(intf, "P2P_SET listen_channel 2 180"); 1721 dut->listen_chn = 2; 1722 } else { 1723 wpa_command(intf, "P2P_SET listen_channel 6"); 1724 dut->listen_chn = 6; 1725 } 1726 1727 wpa_command(intf, "P2P_EXT_LISTEN"); 1728 wpa_command(intf, "SET p2p_go_intent 7"); 1729 wpa_command(intf, "P2P_SET client_apsd disable"); 1730 wpa_command(intf, "P2P_SET go_apsd disable"); 1731 wpa_command(get_station_ifname(), "P2P_SET ps 98"); 1732 wpa_command(get_station_ifname(), "P2P_SET ps 96"); 1733 wpa_command(get_station_ifname(), "P2P_SET ps 0"); 1734 wpa_command(intf, "SET persistent_reconnect 1"); 1735 wpa_command(intf, "SET ampdu 1"); 1736 run_system(dut, "iptables -F INPUT"); 1737 if (dut->arp_ipaddr[0]) { 1738 snprintf(buf, sizeof(buf), "ip nei del %s dev %s", 1739 dut->arp_ipaddr, dut->arp_ifname); 1740 run_system(dut, buf); 1741 dut->arp_ipaddr[0] = '\0'; 1742 } 1743 snprintf(buf, sizeof(buf), "ip nei flush dev %s", 1744 get_station_ifname()); 1745 run_system(dut, buf); 1746 dut->p2p_mode = P2P_IDLE; 1747 dut->client_uapsd = 0; 1748 ath6kl_client_uapsd(dut, intf, 0); 1749 1750 remove_wpa_networks(intf); 1751 1752 disconnect_station(dut); 1753 1754 if (dut->iface_down_on_reset) 1755 dut_ifc_reset(dut); 1756 1757 return 1; 1758 } 1759 1760 1761 static int cmd_sta_get_p2p_ip_config(struct sigma_dut *dut, 1762 struct sigma_conn *conn, 1763 struct sigma_cmd *cmd) 1764 { 1765 /* const char *intf = get_param(cmd, "Interface"); */ 1766 const char *grpid = get_param(cmd, "GroupID"); 1767 struct wfa_cs_p2p_group *grp = NULL; 1768 int count; 1769 char macaddr[20]; 1770 char resp[200], info[150]; 1771 1772 if (grpid == NULL) 1773 return -1; 1774 1775 if (strcmp(grpid, "$P2P_GROUP_ID") == 0) 1776 return -1; 1777 1778 /* 1779 * If we did not initiate the operation that created the group, we may 1780 * not have the group information available in the DUT code yet and it 1781 * may take some time to get this from wpa_supplicant in case we are 1782 * the P2P client. As such, we better try this multiple times to allow 1783 * some time to complete the operation. 1784 */ 1785 1786 sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting to find the requested " 1787 "group"); 1788 count = dut->default_timeout; 1789 while (count > 0) { 1790 grp = p2p_group_get(dut, grpid); 1791 if (grp == NULL) { 1792 sigma_dut_print(dut, DUT_MSG_DEBUG, "Requested group " 1793 "not yet found (count=%d)", count); 1794 sleep(1); 1795 } else 1796 break; 1797 count--; 1798 } 1799 if (grp == NULL) { 1800 send_resp(dut, conn, SIGMA_ERROR, 1801 "errorCode,Requested group not found"); 1802 return 0; 1803 } 1804 1805 sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting for IP address on group " 1806 "interface %s", grp->ifname); 1807 if (wait_ip_addr(dut, grp->ifname, dut->default_timeout) < 0) { 1808 send_resp(dut, conn, SIGMA_ERROR, 1809 "errorCode,No IP address received"); 1810 return 0; 1811 } 1812 1813 if (get_ip_config(dut, grp->ifname, info, sizeof(info)) < 0) { 1814 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get IP address " 1815 "for group interface %s", 1816 grp->ifname); 1817 send_resp(dut, conn, SIGMA_ERROR, 1818 "errorCode,Failed to get IP address"); 1819 return 0; 1820 } 1821 1822 if (get_wpa_status(grp->ifname, "address", 1823 macaddr, sizeof(macaddr)) < 0) { 1824 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to get interface " 1825 "address for group interface %s", 1826 grp->ifname); 1827 return -2; 1828 } 1829 1830 sigma_dut_print(dut, DUT_MSG_DEBUG, "IP address for group interface " 1831 "%s found", grp->ifname); 1832 1833 snprintf(resp, sizeof(resp), "%s,P2PInterfaceAddress,%s", 1834 info, macaddr); 1835 1836 send_resp(dut, conn, SIGMA_COMPLETE, resp); 1837 return 0; 1838 } 1839 1840 1841 static int cmd_sta_send_p2p_presence_req(struct sigma_dut *dut, 1842 struct sigma_conn *conn, 1843 struct sigma_cmd *cmd) 1844 { 1845 const char *intf = get_param(cmd, "Interface"); 1846 const char *dur = get_param(cmd, "Duration"); 1847 const char *interv = get_param(cmd, "Interval"); 1848 /* const char *grpid = get_param(cmd, "GroupID"); */ 1849 const char *ifname; 1850 char buf[100]; 1851 1852 if (dur == NULL || interv == NULL) 1853 return -1; 1854 1855 /* TODO: need to add groupid into parameters in CAPI spec; for now, 1856 * pick the first active group */ 1857 ifname = get_group_ifname(dut, intf); 1858 snprintf(buf, sizeof(buf), "P2P_PRESENCE_REQ %s %s", dur, interv); 1859 if (wpa_command(ifname, buf) < 0) 1860 return -2; 1861 1862 return 1; 1863 } 1864 1865 1866 static int cmd_sta_set_sleep(struct sigma_dut *dut, struct sigma_conn *conn, 1867 struct sigma_cmd *cmd) 1868 { 1869 /* const char *intf = get_param(cmd, "Interface"); */ 1870 struct wfa_cs_p2p_group *grp; 1871 char *ifname; 1872 const char *grpid = get_param(cmd, "GroupID"); 1873 1874 if (dut->program == PROGRAM_60GHZ) { 1875 send_resp(dut, conn, SIGMA_ERROR, 1876 "errorCode,UAPSD Sleep is not applicable for 60 GHz"); 1877 return 0; 1878 } 1879 1880 if (grpid == NULL) 1881 ifname = get_station_ifname(); 1882 else { 1883 grp = p2p_group_get(dut, grpid); 1884 if (grp == NULL) { 1885 send_resp(dut, conn, SIGMA_ERROR, 1886 "errorCode,Requested group not found"); 1887 return 0; 1888 } 1889 ifname = grp->ifname; 1890 } 1891 1892 if (dut->client_uapsd) { 1893 #ifdef __linux__ 1894 /* no special handling for nl80211 yet */ 1895 char path[128]; 1896 struct stat s; 1897 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", 1898 ifname); 1899 if (stat(path, &s) == 0) { 1900 if (wpa_command(ifname, "P2P_SET ps 1") < 0) { 1901 send_resp(dut, conn, SIGMA_ERROR, 1902 "errorCode,Going to sleep not supported"); 1903 return 0; 1904 } 1905 return 1; 1906 } 1907 #endif /* __linux__ */ 1908 if (wpa_command(ifname, "P2P_SET ps 99") < 0) 1909 return -2; 1910 } else { 1911 if (wpa_command(ifname, "P2P_SET ps 1") < 0) { 1912 send_resp(dut, conn, SIGMA_ERROR, 1913 "errorCode,Going to sleep not supported"); 1914 return 0; 1915 } 1916 } 1917 1918 return 1; 1919 } 1920 1921 1922 static int cmd_sta_set_opportunistic_ps(struct sigma_dut *dut, 1923 struct sigma_conn *conn, 1924 struct sigma_cmd *cmd) 1925 { 1926 /* const char *intf = get_param(cmd, "Interface"); */ 1927 struct wfa_cs_p2p_group *grp; 1928 char buf[100]; 1929 const char *grpid = get_param(cmd, "GroupID"); 1930 const char *ctwindow = get_param(cmd, "CTWindow"); 1931 1932 if (grpid == NULL || ctwindow == NULL) 1933 return -1; 1934 1935 grp = p2p_group_get(dut, grpid); 1936 if (grp == NULL) { 1937 send_resp(dut, conn, SIGMA_ERROR, 1938 "errorCode,Requested group not found"); 1939 return 0; 1940 } 1941 1942 if (wpa_command(grp->ifname, "P2P_SET oppps 1") < 0) { 1943 send_resp(dut, conn, SIGMA_ERROR, 1944 "errorCode,Use of OppPS as GO not supported"); 1945 return 0; 1946 } 1947 snprintf(buf, sizeof(buf), "P2P_SET ctwindow %d", atoi(ctwindow)); 1948 if (wpa_command(grp->ifname, buf) < 0) { 1949 send_resp(dut, conn, SIGMA_ERROR, 1950 "errorCode,Use of CTWindow as GO not supported"); 1951 return 0; 1952 } 1953 1954 return 1; 1955 } 1956 1957 1958 static int cmd_sta_send_service_discovery_req(struct sigma_dut *dut, 1959 struct sigma_conn *conn, 1960 struct sigma_cmd *cmd) 1961 { 1962 const char *intf = get_param(cmd, "Interface"); 1963 const char *devid = get_param(cmd, "P2PDevID"); 1964 char buf[128]; 1965 1966 if (devid == NULL) 1967 return -1; 1968 1969 snprintf(buf, sizeof(buf), "P2P_SERV_DISC_REQ %s 02000001", 1970 devid); 1971 if (wpa_command(intf, buf) < 0) { 1972 send_resp(dut, conn, SIGMA_ERROR, NULL); 1973 return 0; 1974 } 1975 1976 return 1; 1977 } 1978 1979 1980 static int cmd_sta_add_arp_table_entry(struct sigma_dut *dut, 1981 struct sigma_conn *conn, 1982 struct sigma_cmd *cmd) 1983 { 1984 char buf[256]; 1985 char *ifname; 1986 const char *grpid, *ipaddr, *macaddr; 1987 1988 grpid = get_param(cmd, "GroupID"); 1989 ipaddr = get_param(cmd, "IPAddress"); 1990 macaddr = get_param(cmd, "MACAddress"); 1991 if (ipaddr == NULL || macaddr == NULL) 1992 return -1; 1993 1994 if (grpid == NULL) 1995 ifname = get_station_ifname(); 1996 else { 1997 struct wfa_cs_p2p_group *grp; 1998 grp = p2p_group_get(dut, grpid); 1999 if (grp == NULL) { 2000 send_resp(dut, conn, SIGMA_ERROR, 2001 "errorCode,Requested group not found"); 2002 return 0; 2003 } 2004 ifname = grp->ifname; 2005 } 2006 2007 snprintf(dut->arp_ipaddr, sizeof(dut->arp_ipaddr), "%s", 2008 ipaddr); 2009 snprintf(dut->arp_ifname, sizeof(dut->arp_ifname), "%s", 2010 ifname); 2011 2012 snprintf(buf, sizeof(buf), "ip nei add %s lladdr %s dev %s", 2013 ipaddr, macaddr, ifname); 2014 run_system(dut, buf); 2015 2016 return 1; 2017 } 2018 2019 2020 static int cmd_sta_block_icmp_response(struct sigma_dut *dut, 2021 struct sigma_conn *conn, 2022 struct sigma_cmd *cmd) 2023 { 2024 char buf[256]; 2025 struct wfa_cs_p2p_group *grp; 2026 char *ifname; 2027 const char *grpid, *ipaddr; 2028 2029 grpid = get_param(cmd, "GroupID"); 2030 ipaddr = get_param(cmd, "IPAddress"); 2031 if (ipaddr == NULL) 2032 return -1; 2033 2034 if (grpid == NULL) 2035 ifname = get_station_ifname(); 2036 else { 2037 grp = p2p_group_get(dut, grpid); 2038 if (grp == NULL) { 2039 send_resp(dut, conn, SIGMA_ERROR, 2040 "errorCode,Requested group not found"); 2041 return 0; 2042 } 2043 ifname = grp->ifname; 2044 } 2045 2046 snprintf(buf, sizeof(buf), 2047 "iptables -I INPUT -s %s -p icmp -i %s -j DROP", 2048 ipaddr, ifname); 2049 run_system(dut, buf); 2050 2051 return 1; 2052 } 2053 2054 2055 static int run_nfc_command(struct sigma_dut *dut, const char *cmd, 2056 const char *info) 2057 { 2058 int res; 2059 2060 sigma_dut_summary(dut, "NFC operation: %s", info); 2061 printf("\n\n\n=====[ NFC operation ]=========================\n\n"); 2062 printf("%s\n\n", info); 2063 2064 nfc_status(dut, "START", info); 2065 res = run_system(dut, cmd); 2066 nfc_status(dut, res ? "FAIL" : "SUCCESS", info); 2067 if (res) { 2068 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s': %d", 2069 cmd, res); 2070 return res; 2071 } 2072 2073 return 0; 2074 } 2075 2076 2077 static int nfc_write_p2p_select(struct sigma_dut *dut, struct sigma_conn *conn, 2078 struct sigma_cmd *cmd) 2079 { 2080 int res; 2081 const char *ifname = get_param(cmd, "Interface"); 2082 char buf[300]; 2083 2084 run_system(dut, "killall wps-nfc.py"); 2085 run_system(dut, "killall p2p-nfc.py"); 2086 2087 if (wpa_command(ifname, "WPS_NFC_TOKEN NDEF") < 0) { 2088 send_resp(dut, conn, SIGMA_ERROR, 2089 "ErrorCode,Failed to generate NFC password token"); 2090 return 0; 2091 } 2092 2093 unlink("nfc-success"); 2094 snprintf(buf, sizeof(buf), 2095 "./p2p-nfc.py -1 --no-wait %s%s --success nfc-success write-p2p-sel", 2096 dut->summary_log ? "--summary " : "", 2097 dut->summary_log ? dut->summary_log : ""); 2098 res = run_nfc_command(dut, buf, 2099 "Touch NFC Tag to write P2P connection handover select"); 2100 if (res || !file_exists("nfc-success")) { 2101 send_resp(dut, conn, SIGMA_ERROR, 2102 "ErrorCode,Failed to write tag"); 2103 return 0; 2104 } 2105 2106 if (wpa_command(ifname, "P2P_SET nfc_tag 1") < 0) { 2107 send_resp(dut, conn, SIGMA_ERROR, 2108 "ErrorCode,Failed to enable NFC password token"); 2109 return 0; 2110 } 2111 2112 if (!dut->go && wpa_command(ifname, "P2P_LISTEN") < 0) { 2113 send_resp(dut, conn, SIGMA_ERROR, 2114 "ErrorCode,Failed to start listen mode"); 2115 return 0; 2116 } 2117 2118 send_resp(dut, conn, SIGMA_COMPLETE, 2119 "Result,,GroupID,,PeerRole,,PauseFlag,0"); 2120 return 0; 2121 } 2122 2123 2124 static int nfc_write_config_token(struct sigma_dut *dut, 2125 struct sigma_conn *conn, 2126 struct sigma_cmd *cmd) 2127 { 2128 int res; 2129 const char *bssid = get_param(cmd, "Bssid"); 2130 const char *intf = get_param(cmd, "Interface"); 2131 char buf[200]; 2132 2133 run_system(dut, "killall wps-nfc.py"); 2134 run_system(dut, "killall p2p-nfc.py"); 2135 unlink("nfc-success"); 2136 if (dut->er_oper_performed && bssid) { 2137 char current_bssid[30], id[10]; 2138 if (get_wpa_status(intf, "id", id, sizeof(id)) < 0 || 2139 get_wpa_status(intf, "bssid", current_bssid, 2140 sizeof(current_bssid)) < 0 || 2141 strncasecmp(bssid, current_bssid, strlen(current_bssid)) != 2142 0) { 2143 send_resp(dut, conn, SIGMA_ERROR, 2144 "ErrorCode,No configuration known for BSSID"); 2145 return 0; 2146 } 2147 snprintf(buf, sizeof(buf), 2148 "./wps-nfc.py --id %s --no-wait %s%s --success nfc-success write-config", 2149 id, 2150 dut->summary_log ? "--summary " : "", 2151 dut->summary_log ? dut->summary_log : ""); 2152 res = run_nfc_command(dut, buf, 2153 "Touch NFC Tag to write WPS configuration token"); 2154 } else { 2155 snprintf(buf, sizeof(buf), 2156 "./wps-nfc.py --no-wait %s%s --success nfc-success write-config", 2157 dut->summary_log ? "--summary " : "", 2158 dut->summary_log ? dut->summary_log : ""); 2159 res = run_nfc_command(dut, buf, 2160 "Touch NFC Tag to write WPS configuration token"); 2161 } 2162 if (res || !file_exists("nfc-success")) { 2163 send_resp(dut, conn, SIGMA_ERROR, 2164 "ErrorCode,Failed to write tag"); 2165 return 0; 2166 } 2167 2168 send_resp(dut, conn, SIGMA_COMPLETE, 2169 "Result,,GroupID,,PeerRole,,PauseFlag,0"); 2170 return 0; 2171 } 2172 2173 2174 static int nfc_write_password_token(struct sigma_dut *dut, 2175 struct sigma_conn *conn, 2176 struct sigma_cmd *cmd) 2177 { 2178 int res; 2179 char buf[300]; 2180 2181 run_system(dut, "killall wps-nfc.py"); 2182 run_system(dut, "killall p2p-nfc.py"); 2183 unlink("nfc-success"); 2184 snprintf(buf, sizeof(buf), 2185 "./wps-nfc.py --no-wait %s%s --success nfc-success write-password", 2186 dut->summary_log ? "--summary " : "", 2187 dut->summary_log ? dut->summary_log : ""); 2188 res = run_nfc_command(dut, buf, 2189 "Touch NFC Tag to write WPS password token"); 2190 if (res || !file_exists("nfc-success")) { 2191 send_resp(dut, conn, SIGMA_ERROR, 2192 "ErrorCode,Failed to write tag"); 2193 return 0; 2194 } 2195 2196 send_resp(dut, conn, SIGMA_COMPLETE, 2197 "Result,,GroupID,,PeerRole,,PauseFlag,0"); 2198 return 0; 2199 } 2200 2201 2202 static int nfc_read_tag(struct sigma_dut *dut, 2203 struct sigma_conn *conn, 2204 struct sigma_cmd *cmd) 2205 { 2206 int res; 2207 struct wpa_ctrl *ctrl; 2208 const char *intf = get_param(cmd, "Interface"); 2209 const char *oper_chn = get_param(cmd, "OPER_CHN"); 2210 char buf[1000], freq_str[20]; 2211 2212 run_system(dut, "killall wps-nfc.py"); 2213 run_system(dut, "killall p2p-nfc.py"); 2214 2215 ctrl = open_wpa_mon(intf); 2216 if (ctrl == NULL) { 2217 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open " 2218 "wpa_supplicant monitor connection"); 2219 return -2; 2220 } 2221 2222 freq_str[0] = '\0'; 2223 if (oper_chn) { 2224 int chan = atoi(oper_chn); 2225 if (chan >= 1 && chan <= 11) 2226 snprintf(freq_str, sizeof(freq_str), " --freq %d", 2227 2407 + chan * 5); 2228 } 2229 2230 unlink("nfc-success"); 2231 snprintf(buf, sizeof(buf), 2232 "./p2p-nfc.py -1 -t %s%s --success nfc-success --no-wait%s", 2233 dut->summary_log ? "--summary " : "", 2234 dut->summary_log ? dut->summary_log : "", 2235 freq_str); 2236 res = run_nfc_command(dut, buf, 2237 "Touch NFC Tag to read it"); 2238 if (res || !file_exists("nfc-success")) { 2239 send_resp(dut, conn, SIGMA_ERROR, 2240 "ErrorCode,Failed to read tag"); 2241 wpa_ctrl_detach(ctrl); 2242 wpa_ctrl_close(ctrl); 2243 return 0; 2244 } 2245 2246 if (dut->p2p_mode == P2P_DISABLE) 2247 return wps_connection_event(dut, conn, ctrl, intf, 1); 2248 2249 if (dut->go || dut->p2p_client) { 2250 wpa_ctrl_detach(ctrl); 2251 wpa_ctrl_close(ctrl); 2252 send_resp(dut, conn, SIGMA_COMPLETE, 2253 "Result,,GroupID,,PeerRole,,PauseFlag,0"); 2254 return 0; 2255 } 2256 2257 /* FIX: PeerRole */ 2258 return p2p_group_formation_event(dut, conn, ctrl, intf, "0", 1); 2259 } 2260 2261 2262 static int nfc_wps_read_tag(struct sigma_dut *dut, 2263 struct sigma_conn *conn, 2264 struct sigma_cmd *cmd) 2265 { 2266 int res; 2267 struct wpa_ctrl *ctrl; 2268 const char *intf = get_param(cmd, "Interface"); 2269 char buf[300]; 2270 2271 run_system(dut, "killall wps-nfc.py"); 2272 run_system(dut, "killall p2p-nfc.py"); 2273 2274 ctrl = open_wpa_mon(intf); 2275 if (ctrl == NULL) { 2276 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open " 2277 "wpa_supplicant monitor connection"); 2278 return -2; 2279 } 2280 2281 unlink("nfc-success"); 2282 snprintf(buf, sizeof(buf), 2283 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success", 2284 dut->summary_log ? "--summary " : "", 2285 dut->summary_log ? dut->summary_log : ""); 2286 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it"); 2287 if (res || !file_exists("nfc-success")) { 2288 send_resp(dut, conn, SIGMA_ERROR, 2289 "ErrorCode,Failed to read tag"); 2290 wpa_ctrl_detach(ctrl); 2291 wpa_ctrl_close(ctrl); 2292 return 0; 2293 } 2294 2295 return wps_connection_event(dut, conn, ctrl, intf, 1); 2296 } 2297 2298 2299 static int er_ap_add_match(const char *event, const char *bssid, 2300 const char *req_uuid, 2301 char *ret_uuid, size_t max_uuid_len) 2302 { 2303 const char *pos, *uuid; 2304 2305 pos = strchr(event, ' '); 2306 if (pos == NULL) 2307 return 0; 2308 pos++; 2309 uuid = pos; 2310 2311 pos = strchr(pos, ' '); 2312 if (pos == NULL) 2313 return 0; 2314 if (ret_uuid) { 2315 if ((size_t) (pos - uuid + 1) < max_uuid_len) { 2316 memcpy(ret_uuid, uuid, pos - uuid); 2317 ret_uuid[pos - uuid] = '\0'; 2318 } else 2319 ret_uuid[0] = '\0'; 2320 } 2321 2322 if (req_uuid && strncasecmp(req_uuid, uuid, pos - uuid) == 0) 2323 return 1; 2324 2325 pos++; 2326 /* at BSSID */ 2327 2328 return strncasecmp(pos, bssid, strlen(bssid)) == 0; 2329 } 2330 2331 2332 static int er_start(struct sigma_dut *dut, struct sigma_conn *conn, 2333 struct wpa_ctrl *ctrl, const char *intf, const char *bssid, 2334 const char *uuid, char *ret_uuid, size_t max_uuid_len) 2335 { 2336 char id[10]; 2337 int res; 2338 char buf[1000]; 2339 2340 sigma_dut_print(dut, DUT_MSG_INFO, "Trying to find WPS AP %s over UPnP", 2341 bssid); 2342 2343 if (wpa_command(intf, "WPS_ER_START") < 0) { 2344 send_resp(dut, conn, SIGMA_ERROR, 2345 "ErrorCode,Failed to start ER"); 2346 return 0; 2347 } 2348 2349 for (;;) { 2350 res = get_wpa_cli_event(dut, ctrl, "WPS-ER-AP-ADD", 2351 buf, sizeof(buf)); 2352 if (res < 0) { 2353 #ifdef USE_ERROR_RETURNS 2354 send_resp(dut, conn, SIGMA_ERROR, 2355 "ErrorCode,Could not find the AP over UPnP"); 2356 #else 2357 send_resp(dut, conn, SIGMA_COMPLETE, 2358 "ErrorCode,Could not find the AP over UPnP"); 2359 #endif 2360 return 0; 2361 } 2362 2363 if (er_ap_add_match(buf, bssid, uuid, ret_uuid, max_uuid_len)) { 2364 sigma_dut_print(dut, DUT_MSG_INFO, 2365 "Found WPS AP over UPnP: %s", buf); 2366 break; 2367 } 2368 } 2369 2370 if (get_wpa_status(intf, "id", id, sizeof(id)) < 0) { 2371 send_resp(dut, conn, SIGMA_ERROR, 2372 "ErrorCode,Could not find AP configuration"); 2373 return 0; 2374 } 2375 2376 if (ret_uuid) { 2377 snprintf(buf, sizeof(buf), "WPS_ER_SET_CONFIG %s %s", 2378 ret_uuid, id); 2379 } else if (uuid) { 2380 snprintf(buf, sizeof(buf), "WPS_ER_SET_CONFIG %s %s", 2381 uuid, id); 2382 } else { 2383 snprintf(buf, sizeof(buf), "WPS_ER_SET_CONFIG %s %s", 2384 bssid, id); 2385 } 2386 if (wpa_command(intf, buf) < 0) { 2387 send_resp(dut, conn, SIGMA_ERROR, 2388 "ErrorCode,Failed to select network configuration for ER"); 2389 return 0; 2390 } 2391 2392 return 1; 2393 } 2394 2395 2396 static int nfc_wps_read_passwd(struct sigma_dut *dut, 2397 struct sigma_conn *conn, 2398 struct sigma_cmd *cmd) 2399 { 2400 int res; 2401 struct wpa_ctrl *ctrl; 2402 const char *intf = get_param(cmd, "Interface"); 2403 const char *bssid = get_param(cmd, "Bssid"); 2404 const char *ssid = get_param(cmd, "SSID"); 2405 const char *security = get_param(cmd, "Security"); 2406 const char *passphrase = get_param(cmd, "Passphrase"); 2407 char ssid_hex[200], passphrase_hex[200]; 2408 const char *val; 2409 int sta_action; 2410 char buf[1000]; 2411 const char *keymgmt, *cipher; 2412 2413 run_system(dut, "killall wps-nfc.py"); 2414 run_system(dut, "killall p2p-nfc.py"); 2415 2416 if ((ssid && strlen(ssid) >= 2 * sizeof(ssid_hex)) || 2417 (passphrase && strlen(passphrase) >= 2 * sizeof(passphrase_hex))) { 2418 send_resp(dut, conn, SIGMA_ERROR, 2419 "ErrorCode,Too long SSID/passphrase"); 2420 return 0; 2421 } 2422 2423 val = get_param(cmd, "WpsStaAction"); 2424 if (!val) { 2425 send_resp(dut, conn, SIGMA_ERROR, 2426 "ErrorCode,Missing WpsStaAction argument"); 2427 return 0; 2428 } 2429 2430 sta_action = atoi(val); 2431 if (sta_action != 1 && sta_action != 2) { 2432 send_resp(dut, conn, SIGMA_ERROR, 2433 "ErrorCode,Unsupported WpsStaAction value"); 2434 return 0; 2435 } 2436 2437 if (!bssid) { 2438 send_resp(dut, conn, SIGMA_ERROR, 2439 "ErrorCode,Missing Bssid argument"); 2440 return 0; 2441 } 2442 2443 if (sta_action == 2) { 2444 if (!ssid) { 2445 send_resp(dut, conn, SIGMA_ERROR, 2446 "ErrorCode,Missing SSID argument"); 2447 return 0; 2448 } 2449 2450 if (!security) { 2451 send_resp(dut, conn, SIGMA_ERROR, 2452 "ErrorCode,Missing Security argument"); 2453 return 0; 2454 } 2455 2456 if (!passphrase) { 2457 send_resp(dut, conn, SIGMA_ERROR, 2458 "ErrorCode,Missing Passphrase argument"); 2459 return 0; 2460 } 2461 } 2462 2463 ctrl = open_wpa_mon(intf); 2464 if (ctrl == NULL) { 2465 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open " 2466 "wpa_supplicant monitor connection"); 2467 return -2; 2468 } 2469 2470 if (sta_action == 1) { 2471 const char *uuid = get_param(cmd, "UUID"); 2472 res = er_start(dut, conn, ctrl, intf, bssid, uuid, NULL, 0); 2473 if (res != 1) { 2474 wpa_ctrl_detach(ctrl); 2475 wpa_ctrl_close(ctrl); 2476 return res; 2477 } 2478 } 2479 2480 unlink("nfc-success"); 2481 snprintf(buf, sizeof(buf), 2482 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success", 2483 dut->summary_log ? "--summary " : "", 2484 dut->summary_log ? dut->summary_log : ""); 2485 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it"); 2486 if (res || !file_exists("nfc-success")) { 2487 wpa_ctrl_detach(ctrl); 2488 wpa_ctrl_close(ctrl); 2489 send_resp(dut, conn, SIGMA_ERROR, 2490 "ErrorCode,Failed to read tag"); 2491 return 0; 2492 } 2493 2494 if (sta_action == 1) { 2495 sigma_dut_print(dut, DUT_MSG_INFO, "Prepared device password for ER to enroll a new station"); 2496 wpa_ctrl_detach(ctrl); 2497 wpa_ctrl_close(ctrl); 2498 send_resp(dut, conn, SIGMA_COMPLETE, 2499 "Result,,GroupID,,PeerRole,"); 2500 return 0; 2501 } 2502 if (strcasecmp(security, "wpa2-psk") == 0) { 2503 keymgmt = "WPA2PSK"; 2504 cipher = "CCMP"; 2505 } else { 2506 wpa_ctrl_detach(ctrl); 2507 wpa_ctrl_close(ctrl); 2508 send_resp(dut, conn, SIGMA_ERROR, 2509 "ErrorCode,Unsupported Security value"); 2510 return 0; 2511 } 2512 2513 ascii2hexstr(ssid, ssid_hex); 2514 ascii2hexstr(passphrase, passphrase_hex); 2515 snprintf(buf, sizeof(buf), "WPS_REG %s nfc-pw %s %s %s %s", 2516 bssid, ssid_hex, keymgmt, cipher, passphrase_hex); 2517 2518 if (wpa_command(intf, buf) < 0) { 2519 wpa_ctrl_detach(ctrl); 2520 wpa_ctrl_close(ctrl); 2521 send_resp(dut, conn, SIGMA_ERROR, 2522 "ErrorCode,Failed to start registrar"); 2523 return 0; 2524 } 2525 2526 return wps_connection_event(dut, conn, ctrl, intf, 1); 2527 } 2528 2529 2530 static int nfc_wps_read_config(struct sigma_dut *dut, 2531 struct sigma_conn *conn, 2532 struct sigma_cmd *cmd) 2533 { 2534 int res; 2535 struct wpa_ctrl *ctrl; 2536 const char *intf = get_param(cmd, "Interface"); 2537 char buf[300]; 2538 2539 run_system(dut, "killall wps-nfc.py"); 2540 run_system(dut, "killall p2p-nfc.py"); 2541 2542 ctrl = open_wpa_mon(intf); 2543 if (ctrl == NULL) { 2544 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open " 2545 "wpa_supplicant monitor connection"); 2546 return -2; 2547 } 2548 2549 unlink("nfc-success"); 2550 snprintf(buf, sizeof(buf), 2551 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success", 2552 dut->summary_log ? "--summary " : "", 2553 dut->summary_log ? dut->summary_log : ""); 2554 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it"); 2555 if (res || !file_exists("nfc-success")) { 2556 send_resp(dut, conn, SIGMA_ERROR, 2557 "ErrorCode,Failed to read tag"); 2558 wpa_ctrl_detach(ctrl); 2559 wpa_ctrl_close(ctrl); 2560 return 0; 2561 } 2562 2563 return wps_connection_event(dut, conn, ctrl, intf, 1); 2564 } 2565 2566 2567 static int nfc_wps_connection_handover(struct sigma_dut *dut, 2568 struct sigma_conn *conn, 2569 struct sigma_cmd *cmd) 2570 { 2571 const char *intf = get_param(cmd, "Interface"); 2572 int res; 2573 const char *init = get_param(cmd, "Init"); 2574 struct wpa_ctrl *ctrl = NULL; 2575 char buf[300]; 2576 2577 run_system(dut, "killall wps-nfc.py"); 2578 run_system(dut, "killall p2p-nfc.py"); 2579 2580 ctrl = open_wpa_mon(intf); 2581 if (ctrl == NULL) { 2582 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open " 2583 "wpa_supplicant monitor connection"); 2584 return -2; 2585 } 2586 2587 unlink("nfc-success"); 2588 if ((!init || atoi(init) == 0) && dut->er_oper_performed) { 2589 const char *bssid = get_param(cmd, "Bssid"); 2590 const char *req_uuid = get_param(cmd, "UUID"); 2591 char uuid[100]; 2592 2593 if (bssid == NULL) 2594 bssid = dut->er_oper_bssid; 2595 2596 res = er_start(dut, conn, ctrl, intf, bssid, req_uuid, uuid, 2597 sizeof(uuid)); 2598 if (res != 1) { 2599 wpa_ctrl_detach(ctrl); 2600 wpa_ctrl_close(ctrl); 2601 return res; 2602 } 2603 2604 snprintf(buf, sizeof(buf), 2605 "./wps-nfc.py -1 --uuid %s %s%s --success nfc-success", 2606 uuid, 2607 dut->summary_log ? "--summary " : "", 2608 dut->summary_log ? dut->summary_log : ""); 2609 res = run_nfc_command(dut, buf, 2610 "Touch NFC Device to respond to WPS connection handover"); 2611 } else if (!init || atoi(init)) { 2612 snprintf(buf, sizeof(buf), 2613 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success", 2614 dut->summary_log ? "--summary " : "", 2615 dut->summary_log ? dut->summary_log : ""); 2616 res = run_nfc_command(dut, buf, 2617 "Touch NFC Device to initiate WPS connection handover"); 2618 } else { 2619 snprintf(buf, sizeof(buf), 2620 "./p2p-nfc.py -1 --no-wait --no-input %s%s --success nfc-success --handover-only", 2621 dut->summary_log ? "--summary " : "", 2622 dut->summary_log ? dut->summary_log : ""); 2623 res = run_nfc_command(dut, buf, 2624 "Touch NFC Device to respond to WPS connection handover"); 2625 } 2626 if (res) { 2627 wpa_ctrl_detach(ctrl); 2628 wpa_ctrl_close(ctrl); 2629 send_resp(dut, conn, SIGMA_ERROR, 2630 "ErrorCode,Failed to enable NFC for connection " 2631 "handover"); 2632 return 0; 2633 } 2634 if (!file_exists("nfc-success")) { 2635 wpa_ctrl_detach(ctrl); 2636 wpa_ctrl_close(ctrl); 2637 send_resp(dut, conn, SIGMA_ERROR, 2638 "ErrorCode,Failed to complete NFC connection handover"); 2639 return 0; 2640 } 2641 2642 if (init && atoi(init)) 2643 return wps_connection_event(dut, conn, ctrl, intf, 1); 2644 2645 wpa_ctrl_detach(ctrl); 2646 wpa_ctrl_close(ctrl); 2647 2648 send_resp(dut, conn, SIGMA_COMPLETE, 2649 "Result,,GroupID,,PeerRole,,PauseFlag,0"); 2650 return 0; 2651 } 2652 2653 2654 static int nfc_p2p_connection_handover(struct sigma_dut *dut, 2655 struct sigma_conn *conn, 2656 struct sigma_cmd *cmd) 2657 { 2658 const char *intf = get_param(cmd, "Interface"); 2659 int res; 2660 const char *init = get_param(cmd, "Init"); 2661 const char *oper_chn = get_param(cmd, "OPER_CHN"); 2662 struct wpa_ctrl *ctrl; 2663 char buf[1000], freq_str[20]; 2664 2665 run_system(dut, "killall wps-nfc.py"); 2666 run_system(dut, "killall p2p-nfc.py"); 2667 2668 ctrl = open_wpa_mon(intf); 2669 if (ctrl == NULL) { 2670 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open " 2671 "wpa_supplicant monitor connection"); 2672 return -2; 2673 } 2674 2675 freq_str[0] = '\0'; 2676 if (oper_chn) { 2677 int chan = atoi(oper_chn); 2678 if (chan >= 1 && chan <= 11) 2679 snprintf(freq_str, sizeof(freq_str), " --freq %d", 2680 2407 + chan * 5); 2681 } 2682 2683 unlink("nfc-success"); 2684 if (init && atoi(init)) { 2685 snprintf(buf, sizeof(buf), 2686 "./p2p-nfc.py -1 -I -N --no-wait %s%s --success nfc-success --no-input%s --handover-only", 2687 dut->summary_log ? "--summary " : "", 2688 dut->summary_log ? dut->summary_log : "", 2689 freq_str); 2690 res = run_nfc_command(dut, buf, 2691 "Touch NFC Device to initiate P2P connection handover"); 2692 } else { 2693 snprintf(buf, sizeof(buf), 2694 "./p2p-nfc.py -1 --no-wait %s%s --success nfc-success --no-input%s --handover-only", 2695 dut->summary_log ? "--summary " : "", 2696 dut->summary_log ? dut->summary_log : "", 2697 freq_str); 2698 res = run_nfc_command(dut, buf, 2699 "Touch NFC Device to respond to P2P connection handover"); 2700 } 2701 if (res) { 2702 wpa_ctrl_detach(ctrl); 2703 wpa_ctrl_close(ctrl); 2704 send_resp(dut, conn, SIGMA_ERROR, 2705 "ErrorCode,Failed to enable NFC for connection " 2706 "handover"); 2707 return 0; 2708 } 2709 if (!file_exists("nfc-success")) { 2710 wpa_ctrl_detach(ctrl); 2711 wpa_ctrl_close(ctrl); 2712 send_resp(dut, conn, SIGMA_ERROR, 2713 "ErrorCode,Failed to complete NFC connection handover"); 2714 return 0; 2715 } 2716 2717 if (dut->go || dut->p2p_client) { 2718 wpa_ctrl_detach(ctrl); 2719 wpa_ctrl_close(ctrl); 2720 send_resp(dut, conn, SIGMA_COMPLETE, 2721 "Result,,GroupID,,PeerRole,,PauseFlag,0"); 2722 return 0; 2723 } 2724 2725 /* FIX: peer role from handover message */ 2726 return p2p_group_formation_event(dut, conn, ctrl, intf, "0", 1); 2727 } 2728 2729 2730 static int cmd_sta_nfc_action(struct sigma_dut *dut, struct sigma_conn *conn, 2731 struct sigma_cmd *cmd) 2732 { 2733 const char *intf = get_param(cmd, "Interface"); 2734 const char *oper = get_param(cmd, "Operation"); 2735 const char *ssid_param = get_param(cmd, "SSID"); 2736 const char *intent_val = get_param(cmd, "INTENT_VAL"); 2737 const char *oper_chn = get_param(cmd, "OPER_CHN"); 2738 char buf[256]; 2739 2740 if (oper == NULL) 2741 return -1; 2742 2743 if (ssid_param) 2744 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix %s", 2745 ssid_param); 2746 else 2747 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix "); 2748 if (wpa_command(intf, buf) < 0) 2749 sigma_dut_print(dut, DUT_MSG_INFO, "Failed P2P ssid_postfix - ignore and assume this is for non-P2P case"); 2750 2751 if (intent_val) { 2752 snprintf(buf, sizeof(buf), "SET p2p_go_intent %s", intent_val); 2753 if (wpa_command(intf, buf) < 0) 2754 return -2; 2755 } 2756 2757 if (oper_chn) { 2758 int chan = atoi(oper_chn); 2759 if (chan < 1 || chan > 11) { 2760 send_resp(dut, conn, SIGMA_ERROR, 2761 "ErrorCode,Unsupported operating channel"); 2762 return 0; 2763 } 2764 snprintf(buf, sizeof(buf), "SET p2p_oper_channel %d", chan); 2765 if (wpa_command(intf, "SET p2p_oper_reg_class 81") < 0 || 2766 wpa_command(intf, buf) < 0) { 2767 send_resp(dut, conn, SIGMA_ERROR, 2768 "ErrorCode,Failed to set operating channel"); 2769 return 0; 2770 } 2771 } 2772 2773 if (strcasecmp(oper, "WRITE_SELECT") == 0) 2774 return nfc_write_p2p_select(dut, conn, cmd); 2775 if (strcasecmp(oper, "WRITE_CONFIG") == 0) 2776 return nfc_write_config_token(dut, conn, cmd); 2777 if (strcasecmp(oper, "WRITE_PASSWD") == 0) 2778 return nfc_write_password_token(dut, conn, cmd); 2779 if (strcasecmp(oper, "READ_TAG") == 0) 2780 return nfc_read_tag(dut, conn, cmd); 2781 if (strcasecmp(oper, "WPS_READ_TAG") == 0) 2782 return nfc_wps_read_tag(dut, conn, cmd); 2783 if (strcasecmp(oper, "WPS_READ_PASSWD") == 0) 2784 return nfc_wps_read_passwd(dut, conn, cmd); 2785 if (strcasecmp(oper, "WPS_READ_CONFIG") == 0) 2786 return nfc_wps_read_config(dut, conn, cmd); 2787 if (strcasecmp(oper, "CONN_HNDOVR") == 0) 2788 return nfc_p2p_connection_handover(dut, conn, cmd); 2789 if (strcasecmp(oper, "WPS_CONN_HNDOVR") == 0) 2790 return nfc_wps_connection_handover(dut, conn, cmd); 2791 2792 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported operation"); 2793 return 0; 2794 } 2795 2796 2797 int p2p_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn, 2798 struct sigma_cmd *cmd) 2799 { 2800 const char *parameter = get_param(cmd, "Parameter"); 2801 char buf[100]; 2802 2803 if (parameter == NULL) 2804 return -1; 2805 if (strcasecmp(parameter, "ListenChannel") == 0) { 2806 snprintf(buf, sizeof(buf), "ListenChnl,%u", dut->listen_chn); 2807 send_resp(dut, conn, SIGMA_COMPLETE, buf); 2808 return 0; 2809 } 2810 2811 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter"); 2812 return 0; 2813 } 2814 2815 2816 static int req_intf(struct sigma_cmd *cmd) 2817 { 2818 return get_param(cmd, "interface") == NULL ? -1 : 0; 2819 } 2820 2821 2822 void p2p_register_cmds(void) 2823 { 2824 sigma_dut_reg_cmd("sta_get_p2p_dev_address", req_intf, 2825 cmd_sta_get_p2p_dev_address); 2826 sigma_dut_reg_cmd("sta_set_p2p", req_intf, cmd_sta_set_p2p); 2827 sigma_dut_reg_cmd("sta_start_autonomous_go", req_intf, 2828 cmd_sta_start_autonomous_go); 2829 sigma_dut_reg_cmd("sta_p2p_connect", req_intf, cmd_sta_p2p_connect); 2830 sigma_dut_reg_cmd("sta_p2p_start_group_formation", req_intf, 2831 cmd_sta_p2p_start_group_formation); 2832 sigma_dut_reg_cmd("sta_p2p_dissolve", req_intf, cmd_sta_p2p_dissolve); 2833 sigma_dut_reg_cmd("sta_send_p2p_invitation_req", req_intf, 2834 cmd_sta_send_p2p_invitation_req); 2835 sigma_dut_reg_cmd("sta_accept_p2p_invitation_req", req_intf, 2836 cmd_sta_accept_p2p_invitation_req); 2837 sigma_dut_reg_cmd("sta_send_p2p_provision_dis_req", req_intf, 2838 cmd_sta_send_p2p_provision_dis_req); 2839 sigma_dut_reg_cmd("sta_set_wps_pbc", req_intf, cmd_sta_set_wps_pbc); 2840 sigma_dut_reg_cmd("sta_wps_read_pin", req_intf, cmd_sta_wps_read_pin); 2841 sigma_dut_reg_cmd("sta_wps_read_label", req_intf, 2842 cmd_sta_wps_read_label); 2843 sigma_dut_reg_cmd("sta_wps_enter_pin", req_intf, 2844 cmd_sta_wps_enter_pin); 2845 sigma_dut_reg_cmd("sta_get_psk", req_intf, cmd_sta_get_psk); 2846 sigma_dut_reg_cmd("sta_p2p_reset", req_intf, cmd_sta_p2p_reset); 2847 sigma_dut_reg_cmd("sta_get_p2p_ip_config", req_intf, 2848 cmd_sta_get_p2p_ip_config); 2849 sigma_dut_reg_cmd("sta_send_p2p_presence_req", req_intf, 2850 cmd_sta_send_p2p_presence_req); 2851 sigma_dut_reg_cmd("sta_set_sleep", req_intf, cmd_sta_set_sleep); 2852 sigma_dut_reg_cmd("sta_set_opportunistic_ps", req_intf, 2853 cmd_sta_set_opportunistic_ps); 2854 sigma_dut_reg_cmd("sta_send_service_discovery_req", req_intf, 2855 cmd_sta_send_service_discovery_req); 2856 sigma_dut_reg_cmd("sta_add_arp_table_entry", req_intf, 2857 cmd_sta_add_arp_table_entry); 2858 sigma_dut_reg_cmd("sta_block_icmp_response", req_intf, 2859 cmd_sta_block_icmp_response); 2860 sigma_dut_reg_cmd("sta_nfc_action", req_intf, cmd_sta_nfc_action); 2861 } 2862