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