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