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