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