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