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