blob: be453136a9cb780d7022f88bfe369f4e3c839044 [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;
819 else
820 freq = 5000 + chan * 5;
821
822 if (ssid_param)
823 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix %s",
824 ssid_param);
825 else
826 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix ");
827 if (wpa_command(intf, buf) < 0)
828 return -2;
829
830 /* Stop Listen/Discovery state to avoid issues with GO operations */
831 if (wpa_command(intf, "P2P_STOP_FIND") < 0)
832 return -2;
833
834 ctrl = open_wpa_mon(intf);
835 if (ctrl == NULL) {
836 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
837 "wpa_supplicant monitor connection");
838 return -2;
839 }
840
841 snprintf(buf, sizeof(buf), "P2P_GROUP_ADD %sfreq=%d",
842 dut->persistent ? "persistent " : "", freq);
843 if (wpa_command(intf, buf) < 0) {
844 wpa_ctrl_detach(ctrl);
845 wpa_ctrl_close(ctrl);
846 return -2;
847 }
848
849 res = get_wpa_cli_event(dut, ctrl, "P2P-GROUP-STARTED",
850 buf, sizeof(buf));
851
852 wpa_ctrl_detach(ctrl);
853 wpa_ctrl_close(ctrl);
854
855 if (res < 0) {
856 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,GO starting "
857 "did not complete");
858 return 0;
859 }
860
861 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group started event '%s'", buf);
862 ifname = strchr(buf, ' ');
863 if (ifname == NULL)
864 return -2;
865 ifname++;
866 pos = strchr(ifname, ' ');
867 if (pos == NULL)
868 return -2;
869 *pos++ = '\0';
870 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group interface %s", ifname);
871
872 gtype = pos;
873 pos = strchr(gtype, ' ');
874 if (pos == NULL)
875 return -2;
876 *pos++ = '\0';
877 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group type %s", gtype);
878
879 ssid = strstr(pos, "ssid=\"");
880 if (ssid == NULL)
881 return -2;
882 ssid += 6;
883 pos = strchr(ssid, '"');
884 if (pos == NULL)
885 return -2;
886 *pos++ = '\0';
887 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group SSID %s", ssid);
888
889 go_dev_addr = strstr(pos, "go_dev_addr=");
890 if (go_dev_addr == NULL) {
891 sigma_dut_print(dut, DUT_MSG_ERROR, "No GO P2P Device Address "
892 "found");
893 return -2;
894 }
895 go_dev_addr += 12;
896 if (strlen(go_dev_addr) < 17) {
897 sigma_dut_print(dut, DUT_MSG_ERROR, "Too short GO P2P Device "
898 "Address '%s'", go_dev_addr);
899 return -2;
900 }
901 go_dev_addr[17] = '\0';
902 *pos = '\0';
903 sigma_dut_print(dut, DUT_MSG_DEBUG, "GO P2P Device Address %s",
904 go_dev_addr);
905
906 if (get_wpa_status(ifname, "bssid", bssid, sizeof(bssid)) < 0)
907 return -2;
908 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group BSSID %s", bssid);
909
910 snprintf(grpid, sizeof(grpid), "%s %s", go_dev_addr, ssid);
911 p2p_group_add(dut, ifname, strcmp(gtype, "GO") == 0, grpid, ssid);
912
913 snprintf(resp, sizeof(resp), "GroupID,%s", grpid);
914 send_resp(dut, conn, SIGMA_COMPLETE, resp);
915 return 0;
916}
917
918
919static int cmd_sta_p2p_connect(struct sigma_dut *dut, struct sigma_conn *conn,
920 struct sigma_cmd *cmd)
921{
Danny Segalf2af39b2016-04-10 16:23:11 +0300922 const char *intf = get_p2p_ifname(get_param(cmd, "Interface"));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200923 const char *devid = get_param(cmd, "P2PDevID");
924 /* const char *grpid_param = get_param(cmd, "GroupID"); */
925 int res;
926 char buf[256];
927 struct wpa_ctrl *ctrl;
928 char *ifname, *gtype, *pos, *ssid, bssid[20];
929 char grpid[100];
930
931 /* TODO: handle the new grpid argument */
932
933 if (devid == NULL)
934 return -1;
935
936 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
937 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS parameters "
938 "not yet set");
939 return 0;
940 }
941
942 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover GO %s", devid);
943 if (p2p_discover_peer(dut, intf, devid, 1) < 0) {
944 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
945 "discover the requested peer");
946 return 0;
947 }
948
949 ctrl = open_wpa_mon(intf);
950 if (ctrl == NULL) {
951 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
952 "wpa_supplicant monitor connection");
953 return -2;
954 }
955
956 switch (dut->wps_method) {
957 case WFA_CS_WPS_PBC:
958 snprintf(buf, sizeof(buf), "P2P_CONNECT %s pbc join",
959 devid);
960 break;
961 case WFA_CS_WPS_PIN_DISPLAY:
962 snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s display join",
963 devid, dut->wps_pin);
964 break;
965 case WFA_CS_WPS_PIN_KEYPAD:
966 snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s keypad join",
967 devid, dut->wps_pin);
968 break;
969 default:
970 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unknown WPS "
971 "method for sta_p2p_connect");
972 wpa_ctrl_detach(ctrl);
973 wpa_ctrl_close(ctrl);
974 return 0;
975 }
976
977 if (wpa_command(intf, buf) < 0) {
978 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to join "
979 "the group");
980 wpa_ctrl_detach(ctrl);
981 wpa_ctrl_close(ctrl);
982 return 0;
983 }
984
985 res = get_wpa_cli_event(dut, ctrl, "P2P-GROUP-STARTED",
986 buf, sizeof(buf));
987
988 wpa_ctrl_detach(ctrl);
989 wpa_ctrl_close(ctrl);
990
991 if (res < 0) {
992 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Group joining "
993 "did not complete");
994 return 0;
995 }
996
997 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group started event '%s'", buf);
998 ifname = strchr(buf, ' ');
999 if (ifname == NULL)
1000 return -2;
1001 ifname++;
1002 pos = strchr(ifname, ' ');
1003 if (pos == NULL)
1004 return -2;
1005 *pos++ = '\0';
1006 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group interface %s", ifname);
1007
1008 gtype = pos;
1009 pos = strchr(gtype, ' ');
1010 if (pos == NULL)
1011 return -2;
1012 *pos++ = '\0';
1013 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group type %s", gtype);
1014
1015 ssid = strstr(pos, "ssid=\"");
1016 if (ssid == NULL)
1017 return -2;
1018 ssid += 6;
1019 pos = strchr(ssid, '"');
1020 if (pos == NULL)
1021 return -2;
1022 *pos = '\0';
1023 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group SSID %s", ssid);
1024
1025 if (get_wpa_status(ifname, "bssid", bssid, sizeof(bssid)) < 0)
1026 return -2;
1027 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group BSSID %s", bssid);
1028
1029 snprintf(grpid, sizeof(grpid), "%s %s", bssid, ssid);
1030 p2p_group_add(dut, ifname, strcmp(gtype, "GO") == 0, grpid, ssid);
1031
1032 return 1;
1033}
1034
1035
1036static int p2p_group_formation_event(struct sigma_dut *dut,
1037 struct sigma_conn *conn,
1038 struct wpa_ctrl *ctrl,
1039 const char *intf, const char *peer_role,
1040 int nfc);
1041
1042static int cmd_sta_p2p_start_group_formation(struct sigma_dut *dut,
1043 struct sigma_conn *conn,
1044 struct sigma_cmd *cmd)
1045{
Danny Segalf2af39b2016-04-10 16:23:11 +03001046 const char *intf = get_p2p_ifname(get_param(cmd, "Interface"));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001047 const char *devid = get_param(cmd, "P2PDevID");
1048 const char *intent_val = get_param(cmd, "INTENT_VAL");
1049 const char *init_go_neg = get_param(cmd, "INIT_GO_NEG");
1050 const char *oper_chn = get_param(cmd, "OPER_CHN");
1051 const char *ssid_param = get_param(cmd, "SSID");
Danny Segal9e390a52016-04-10 17:29:09 +03001052 int freq = 0, chan = 0, init;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001053 char buf[256];
1054 struct wpa_ctrl *ctrl;
1055
1056 if (devid == NULL || intent_val == NULL)
1057 return -1;
1058
1059 if (init_go_neg)
1060 init = atoi(init_go_neg);
1061 else
1062 init = 0;
1063
Danny Segal9e390a52016-04-10 17:29:09 +03001064 if (dut->program == PROGRAM_60GHZ) {
1065 if (!oper_chn)
1066 return -1;
1067 chan = atoi(oper_chn);
1068 freq = get_60g_freq(chan);
1069 if (freq == 0) {
1070 sigma_dut_print(dut, DUT_MSG_ERROR,
1071 "Invalid channel: %d", chan);
1072 return -1;
1073 }
1074 } else if (oper_chn) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001075 chan = atoi(oper_chn);
1076 if (chan >= 1 && chan <= 13)
1077 freq = 2407 + chan * 5;
1078 else if (chan == 14)
1079 freq = 2484;
1080 else
1081 freq = 5000 + chan * 5;
1082 }
1083
1084 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
1085 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS parameters "
1086 "not yet set");
1087 return 0;
1088 }
1089
Danny Segal9e390a52016-04-10 17:29:09 +03001090 sigma_dut_print(dut, DUT_MSG_DEBUG,
1091 "Trying to discover peer %s for group formation chan %d (freq %d)",
1092 devid, chan, freq);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001093 if (p2p_discover_peer(dut, intf, devid, init) < 0) {
1094 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
1095 "discover the requested peer");
1096 return 0;
1097 }
1098
1099 if (ssid_param)
1100 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix %s",
1101 ssid_param);
1102 else
1103 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix ");
1104 if (wpa_command(intf, buf) < 0)
1105 return -2;
1106
1107 if (init) {
1108 ctrl = open_wpa_mon(intf);
1109 if (ctrl == NULL) {
1110 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
1111 "wpa_supplicant monitor connection");
1112 return -2;
1113 }
1114 } else
1115 ctrl = NULL;
1116
1117 snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s%s%s%s go_intent=%d",
1118 devid,
1119 dut->wps_method == WFA_CS_WPS_PBC ?
1120 "pbc" : dut->wps_pin,
1121 dut->wps_method == WFA_CS_WPS_PBC ? "" :
1122 (dut->wps_method == WFA_CS_WPS_PIN_DISPLAY ? " display" :
1123 (dut->wps_method == WFA_CS_WPS_PIN_LABEL ? " label" :
1124 " keypad" )),
1125 dut->persistent ? " persistent" : "",
1126 init ? "" : " auth",
1127 atoi(intent_val));
1128 if (freq > 0) {
1129 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
1130 " freq=%d", freq);
1131 }
1132 if (wpa_command(intf, buf) < 0) {
1133 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to start "
1134 "group formation");
1135 if (ctrl) {
1136 wpa_ctrl_detach(ctrl);
1137 wpa_ctrl_close(ctrl);
1138 }
1139 return 0;
1140 }
1141
1142 if (!init)
1143 return 1;
1144
1145 return p2p_group_formation_event(dut, conn, ctrl, intf, NULL, 0);
1146}
1147
1148
1149static int p2p_group_formation_event(struct sigma_dut *dut,
1150 struct sigma_conn *conn,
1151 struct wpa_ctrl *ctrl,
1152 const char *intf, const char *peer_role,
1153 int nfc)
1154{
1155 int res;
1156 char buf[256], grpid[50], resp[256];
1157 char *ifname, *gtype, *pos, *ssid, bssid[20];
1158 char *go_dev_addr;
1159 char role[30];
1160 const char *events[] = {
1161 "P2P-GROUP-STARTED",
1162 "P2P-GO-NEG-FAILURE",
1163 "P2P-NFC-PEER-CLIENT",
1164 "P2P-GROUP-FORMATION-FAILURE",
1165 NULL
1166 };
1167
1168 role[0] = '\0';
1169 if (peer_role)
1170 snprintf(role, sizeof(role), ",PeerRole,%s", peer_role);
1171
1172 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
1173
1174 wpa_ctrl_detach(ctrl);
1175 wpa_ctrl_close(ctrl);
1176
1177 if (res < 0) {
1178 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Group formation "
1179 "did not complete");
1180 return 0;
1181 }
1182
1183 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group started event '%s'", buf);
1184
1185 if (strstr(buf, "P2P-NFC-PEER-CLIENT")) {
1186 snprintf(resp, sizeof(resp),
1187 "Result,,GroupID,,PeerRole,1,PauseFlag,0");
1188 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1189 return 0;
1190 }
1191
1192 if (strstr(buf, "P2P-GROUP-FORMATION-FAILURE")) {
1193 snprintf(buf, sizeof(buf), "ErrorCode,Group formation failed");
1194 send_resp(dut, conn, SIGMA_ERROR, buf);
1195 return 0;
1196 }
1197
1198 if (strstr(buf, "P2P-GO-NEG-FAILURE")) {
1199 int status = -1;
1200 pos = strstr(buf, " status=");
1201 if (pos)
1202 status = atoi(pos + 8);
1203 sigma_dut_print(dut, DUT_MSG_INFO, "GO Negotiation failed "
1204 "(status=%d)", status);
1205 if (status == 9) {
1206 sigma_dut_print(dut, DUT_MSG_INFO, "Both devices "
1207 "tried to use GO Intent 15");
1208 send_resp(dut, conn, SIGMA_COMPLETE, "result,FAIL");
1209 return 0;
1210 }
1211 snprintf(buf, sizeof(buf), "ErrorCode,GO Negotiation failed "
1212 "(status=%d)", status);
1213 send_resp(dut, conn, SIGMA_ERROR, buf);
1214 return 0;
1215 }
1216
1217 ifname = strchr(buf, ' ');
1218 if (ifname == NULL)
1219 return -2;
1220 ifname++;
1221 pos = strchr(ifname, ' ');
1222 if (pos == NULL)
1223 return -2;
1224 *pos++ = '\0';
1225 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group interface %s", ifname);
1226
1227 gtype = pos;
1228 pos = strchr(gtype, ' ');
1229 if (pos == NULL)
1230 return -2;
1231 *pos++ = '\0';
1232 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group type %s", gtype);
1233
1234 ssid = strstr(pos, "ssid=\"");
1235 if (ssid == NULL)
1236 return -2;
1237 ssid += 6;
1238 pos = strchr(ssid, '"');
1239 if (pos == NULL)
1240 return -2;
1241 *pos++ = '\0';
1242 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group SSID %s", ssid);
1243
1244 go_dev_addr = strstr(pos, "go_dev_addr=");
1245 if (go_dev_addr == NULL) {
1246 sigma_dut_print(dut, DUT_MSG_ERROR, "No GO P2P Device Address "
1247 "found\n");
1248 return -2;
1249 }
1250 go_dev_addr += 12;
1251 if (strlen(go_dev_addr) < 17) {
1252 sigma_dut_print(dut, DUT_MSG_ERROR, "Too short GO P2P Device "
1253 "Address '%s'", go_dev_addr);
1254 return -2;
1255 }
1256 go_dev_addr[17] = '\0';
1257 *pos = '\0';
1258 sigma_dut_print(dut, DUT_MSG_ERROR, "GO P2P Device Address %s",
1259 go_dev_addr);
1260
1261 if (get_wpa_status(ifname, "bssid", bssid, sizeof(bssid)) < 0)
1262 return -2;
1263 sigma_dut_print(dut, DUT_MSG_DEBUG, "Group BSSID %s", bssid);
1264
1265 snprintf(grpid, sizeof(grpid), "%s %s", go_dev_addr, ssid);
1266 p2p_group_add(dut, ifname, strcmp(gtype, "GO") == 0, grpid, ssid);
1267 snprintf(resp, sizeof(resp), "Result,%s,GroupID,%s%s%s",
1268 strcmp(gtype, "GO") == 0 ? "GO" : "CLIENT", grpid, role,
1269 nfc ? ",PauseFlag,0" : "");
1270 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1271
1272#ifdef __QNXNTO__
1273 /* Start DHCP server if we became the GO */
1274 if (strcmp(gtype, "GO") == 0 &&
1275 system("dhcpd -cf /etc/dhcpd.conf -pf /var/run/dhcpd qca1 &") == 0)
1276 sigma_dut_print(dut, DUT_MSG_ERROR,
1277 "Failed to start DHCPD server");
1278#endif /* __QNXNTO__ */
1279
1280 return 0;
1281}
1282
1283
1284int wps_connection_event(struct sigma_dut *dut, struct sigma_conn *conn,
1285 struct wpa_ctrl *ctrl, const char *intf, int p2p_resp)
1286{
1287 int res;
1288 char buf[256];
1289 const char *events[] = {
1290 "CTRL-EVENT-CONNECTED",
1291 "WPS-FAIL",
1292 "WPS-TIMEOUT",
1293 NULL
1294 };
1295
1296 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
1297
1298 wpa_ctrl_detach(ctrl);
1299 wpa_ctrl_close(ctrl);
1300
1301 if (res < 0) {
1302#ifdef USE_ERROR_RETURNS
1303 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS connection "
1304 "did not complete");
1305#else
1306 send_resp(dut, conn, SIGMA_COMPLETE, "ErrorCode,WPS connection "
1307 "did not complete");
1308#endif
1309 return 0;
1310 }
1311
1312 if (strstr(buf, "WPS-FAIL") || strstr(buf, "WPS-TIMEOUT")) {
1313#ifdef USE_ERROR_RETURNS
1314 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS operation "
1315 "failed");
1316#else
1317 send_resp(dut, conn, SIGMA_COMPLETE, "ErrorCode,WPS operation "
1318 "failed");
1319#endif
1320 return 0;
1321 }
1322
1323 if (!p2p_resp)
1324 return 1;
1325 send_resp(dut, conn, SIGMA_COMPLETE, "Result,,GroupID,,PeerRole,");
1326 return 0;
1327}
1328
1329
1330static int cmd_sta_p2p_dissolve(struct sigma_dut *dut, struct sigma_conn *conn,
1331 struct sigma_cmd *cmd)
1332{
1333 const char *intf = get_param(cmd, "interface");
1334 const char *grpid = get_param(cmd, "GroupID");
1335 struct wfa_cs_p2p_group *grp;
1336 char buf[128];
1337
1338 if (grpid == NULL)
1339 return -1;
1340
1341 grp = p2p_group_get(dut, grpid);
1342 if (grp == NULL) {
1343 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Requested group "
1344 "not found");
1345 return 0;
1346 }
1347
1348 snprintf(buf, sizeof(buf), "P2P_GROUP_REMOVE %s", grp->ifname);
1349 if (wpa_command(intf, buf) < 0) {
1350 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to remove the "
1351 "specified group from wpa_supplicant - assume "
1352 "group has already been removed");
1353 }
1354 sigma_dut_print(dut, DUT_MSG_DEBUG, "Removed group %s", grpid);
1355 if (grp->go)
1356 dut->go = 0;
1357 else
1358 dut->p2p_client = 0;
1359 p2p_group_remove(dut, grpid);
1360 return 1;
1361}
1362
1363
1364static int cmd_sta_send_p2p_invitation_req(struct sigma_dut *dut,
1365 struct sigma_conn *conn,
1366 struct sigma_cmd *cmd)
1367{
1368 const char *intf = get_param(cmd, "interface");
1369 const char *devid = get_param(cmd, "P2PDevID");
1370 const char *grpid = get_param(cmd, "GroupID");
1371 const char *reinvoke = get_param(cmd, "Reinvoke");
1372 char c[256];
1373 char buf[4096];
1374 struct wpa_ctrl *ctrl;
1375 int res;
1376
1377 if (devid == NULL || grpid == NULL)
1378 return -1;
1379
1380 if (reinvoke && atoi(reinvoke)) {
1381 int id = -1;
1382 char *ssid, *pos;
1383
1384 ssid = strchr(grpid, ' ');
1385 if (ssid == NULL) {
1386 sigma_dut_print(dut, DUT_MSG_INFO, "Invalid grpid");
1387 return -1;
1388 }
1389 ssid++;
1390 sigma_dut_print(dut, DUT_MSG_DEBUG, "Search for persistent "
1391 "group credentials based on SSID: '%s'", ssid);
1392 if (wpa_command_resp(intf, "LIST_NETWORKS",
1393 buf, sizeof(buf)) < 0)
1394 return -2;
1395 pos = strstr(buf, ssid);
1396 if (pos == NULL || pos == buf || pos[-1] != '\t' ||
1397 pos[strlen(ssid)] != '\t') {
1398 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
1399 "Persistent group credentials not found");
1400 return 0;
1401 }
1402 while (pos > buf && pos[-1] != '\n')
1403 pos--;
1404 id = atoi(pos);
1405 snprintf(c, sizeof(c), "P2P_INVITE persistent=%d peer=%s",
1406 id, devid);
1407 } else {
1408 struct wfa_cs_p2p_group *grp;
1409 grp = p2p_group_get(dut, grpid);
1410 if (grp == NULL) {
1411 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
1412 "No active P2P group found for invitation");
1413 return 0;
1414 }
1415 snprintf(c, sizeof(c), "P2P_INVITE group=%s peer=%s",
1416 grp->ifname, devid);
1417 }
1418
1419 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover peer %s for "
1420 "invitation", devid);
1421 if (p2p_discover_peer(dut, intf, devid, 0) < 0) {
1422 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
1423 "discover the requested peer");
1424 return 0;
1425 }
1426
1427 ctrl = open_wpa_mon(intf);
1428 if (ctrl == NULL) {
1429 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
1430 "wpa_supplicant monitor connection");
1431 return -2;
1432 }
1433
1434 if (wpa_command(intf, c) < 0) {
1435 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to send invitation "
1436 "request");
1437 wpa_ctrl_detach(ctrl);
1438 wpa_ctrl_close(ctrl);
1439 return -2;
1440 }
1441
1442 res = get_wpa_cli_event(dut, ctrl, "P2P-INVITATION-RESULT",
1443 buf, sizeof(buf));
1444
1445 wpa_ctrl_detach(ctrl);
1446 wpa_ctrl_close(ctrl);
1447
1448 if (res < 0)
1449 return -2;
1450
1451 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invitation event: '%s'", buf);
1452 return 1;
1453}
1454
1455
1456static int cmd_sta_accept_p2p_invitation_req(struct sigma_dut *dut,
1457 struct sigma_conn *conn,
1458 struct sigma_cmd *cmd)
1459{
1460 const char *intf = get_param(cmd, "Interface");
1461 const char *devid = get_param(cmd, "P2PDevID");
1462 const char *grpid = get_param(cmd, "GroupID");
1463 const char *reinvoke = get_param(cmd, "Reinvoke");
1464 char buf[100];
1465
1466 if (devid == NULL || grpid == NULL)
1467 return -1;
1468
1469 if (reinvoke && atoi(reinvoke)) {
1470 /*
1471 * Assume persistent reconnect is enabled and there is no need
1472 * to do anything here.
1473 */
1474 return 1;
1475 }
1476
1477 /*
1478 * In a client-joining-a-running-group case, we need to separately
1479 * authorize the invitation.
1480 */
1481
1482 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover GO %s", devid);
1483 if (p2p_discover_peer(dut, intf, devid, 1) < 0) {
1484 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
1485 "discover the requested peer");
1486 return 0;
1487 }
1488
1489 snprintf(buf, sizeof(buf), "P2P_CONNECT %s %s join auth",
1490 devid,
1491 dut->wps_method == WFA_CS_WPS_PBC ?
1492 "pbc" : dut->wps_pin);
1493 if (wpa_command(intf, buf) < 0)
1494 return -2;
1495
1496 return 1;
1497}
1498
1499
1500static int cmd_sta_send_p2p_provision_dis_req(struct sigma_dut *dut,
1501 struct sigma_conn *conn,
1502 struct sigma_cmd *cmd)
1503{
1504 const char *intf = get_param(cmd, "interface");
1505 const char *conf_method = get_param(cmd, "ConfigMethod");
1506 const char *devid = get_param(cmd, "P2PDevID");
1507 char buf[256];
1508 char *method;
1509
1510 if (conf_method == NULL || devid == NULL)
1511 return -1;
1512
1513 if (strcasecmp(conf_method, "Display") == 0)
1514 method = "display";
1515 else if (strcasecmp(conf_method, "Keyboard") == 0 ||
1516 strcasecmp(conf_method, "keypad") == 0)
1517 method = "keypad";
1518 else if (strcasecmp(conf_method, "Label") == 0)
1519 method = "label";
1520 else if (strcasecmp(conf_method, "pbc") == 0 ||
1521 strcasecmp(conf_method, "pushbutton") == 0)
1522 method = "pbc";
1523 else
1524 return -1;
1525
1526 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trying to discover peer %s for "
1527 "provision discovery", devid);
1528 if (p2p_discover_peer(dut, intf, devid, 0) < 0) {
1529 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
1530 "discover the requested peer");
1531 return 0;
1532 }
1533
1534 snprintf(buf, sizeof(buf), "P2P_PROV_DISC %s %s", devid, method);
1535 if (wpa_command(intf, buf) < 0) {
1536 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to send provision "
1537 "discovery request");
1538 return -2;
1539 }
1540
1541 return 1;
1542}
1543
1544
1545static int cmd_sta_set_wps_pbc(struct sigma_dut *dut, struct sigma_conn *conn,
1546 struct sigma_cmd *cmd)
1547{
1548 /* const char *intf = get_param(cmd, "Interface"); */
1549 const char *grpid = get_param(cmd, "GroupID");
1550
1551 if (grpid) {
1552 struct wfa_cs_p2p_group *grp;
1553 grp = p2p_group_get(dut, grpid);
1554 if (grp && grp->go) {
1555 sigma_dut_print(dut, DUT_MSG_DEBUG, "Authorize a "
1556 "client to join with WPS");
1557 wpa_command(grp->ifname, "WPS_PBC");
1558 return 1;
1559 }
1560 }
1561
1562 dut->wps_method = WFA_CS_WPS_PBC;
1563 return 1;
1564}
1565
1566
1567static int cmd_sta_wps_read_pin(struct sigma_dut *dut, struct sigma_conn *conn,
1568 struct sigma_cmd *cmd)
1569{
1570 /* const char *intf = get_param(cmd, "Interface"); */
1571 const char *grpid = get_param(cmd, "GroupID");
1572 char *pin = "12345670"; /* TODO: use random PIN */
1573 char resp[100];
1574
1575 if (grpid) {
1576 char buf[100];
1577 struct wfa_cs_p2p_group *grp;
1578 grp = p2p_group_get(dut, grpid);
1579 if (grp && grp->go) {
1580 sigma_dut_print(dut, DUT_MSG_DEBUG, "Authorize a "
1581 "client to join with WPS");
1582 snprintf(buf, sizeof(buf), "WPS_PIN any %s", pin);
1583 if (wpa_command(grp->ifname, buf) < 0)
1584 return -1;
1585 goto done;
1586 }
1587 }
1588
1589 strncpy(dut->wps_pin, pin, sizeof(dut->wps_pin));
1590 dut->wps_method = WFA_CS_WPS_PIN_DISPLAY;
1591done:
1592 snprintf(resp, sizeof(resp), "PIN,%s", pin);
1593 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1594
1595 return 0;
1596}
1597
1598
1599static int cmd_sta_wps_read_label(struct sigma_dut *dut,
1600 struct sigma_conn *conn,
1601 struct sigma_cmd *cmd)
1602{
1603 /* const char *intf = get_param(cmd, "Interface"); */
1604 const char *grpid = get_param(cmd, "GroupID");
1605 char *pin = "12345670";
1606 char resp[100];
1607
1608 if (grpid) {
1609 char buf[100];
1610 struct wfa_cs_p2p_group *grp;
1611 grp = p2p_group_get(dut, grpid);
1612 if (grp && grp->go) {
1613 sigma_dut_print(dut, DUT_MSG_DEBUG, "Authorize a "
1614 "client to join with WPS");
1615 snprintf(buf, sizeof(buf), "WPS_PIN any %s", pin);
1616 wpa_command(grp->ifname, buf);
1617 return 1;
1618 }
1619 }
1620
1621 strncpy(dut->wps_pin, pin, sizeof(dut->wps_pin));
1622 dut->wps_method = WFA_CS_WPS_PIN_LABEL;
1623 snprintf(resp, sizeof(resp), "LABEL,%s", pin);
1624 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1625
1626 return 0;
1627}
1628
1629
1630static int cmd_sta_wps_enter_pin(struct sigma_dut *dut,
1631 struct sigma_conn *conn,
1632 struct sigma_cmd *cmd)
1633{
1634 /* const char *intf = get_param(cmd, "Interface"); */
1635 const char *grpid = get_param(cmd, "GroupID");
1636 const char *pin = get_param(cmd, "PIN");
1637
1638 if (pin == NULL)
1639 return -1;
1640
1641 if (grpid) {
1642 char buf[100];
1643 struct wfa_cs_p2p_group *grp;
1644 grp = p2p_group_get(dut, grpid);
1645 if (grp && grp->go) {
1646 sigma_dut_print(dut, DUT_MSG_DEBUG, "Authorize a "
1647 "client to join with WPS");
1648 snprintf(buf, sizeof(buf), "WPS_PIN any %s", pin);
1649 wpa_command(grp->ifname, buf);
1650 return 1;
1651 }
1652 }
1653
1654 strncpy(dut->wps_pin, pin, sizeof(dut->wps_pin));
1655 dut->wps_pin[sizeof(dut->wps_pin) - 1] = '\0';
1656 dut->wps_method = WFA_CS_WPS_PIN_KEYPAD;
1657
1658 return 1;
1659}
1660
1661
1662static int cmd_sta_get_psk(struct sigma_dut *dut, struct sigma_conn *conn,
1663 struct sigma_cmd *cmd)
1664{
1665 /* const char *intf = get_param(cmd, "interface"); */
1666 const char *grpid = get_param(cmd, "GroupID");
1667 struct wfa_cs_p2p_group *grp;
1668 char passphrase[64], resp[200];
1669
1670 if (grpid == NULL)
1671 return -1;
1672
1673 grp = p2p_group_get(dut, grpid);
1674 if (grp == NULL) {
1675 send_resp(dut, conn, SIGMA_ERROR,
1676 "errorCode,Requested group not found");
1677 return 0;
1678 }
1679 if (!grp->go) {
1680 send_resp(dut, conn, SIGMA_ERROR,
1681 "errorCode,Local role is not GO in the specified "
1682 "group");
1683 return 0;
1684 }
1685
1686 if (wpa_command_resp(grp->ifname, "P2P_GET_PASSPHRASE",
1687 passphrase, sizeof(passphrase)) < 0)
1688 return -2;
1689
1690 snprintf(resp, sizeof(resp), "passPhrase,%s,ssid,%s",
1691 passphrase, grp->ssid);
1692 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1693
1694 return 0;
1695}
1696
1697
1698int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
1699 struct sigma_cmd *cmd)
1700{
1701 const char *intf = get_param(cmd, "interface");
1702 struct wfa_cs_p2p_group *grp, *prev;
1703 char buf[256];
1704
1705 dut->go = 0;
1706 dut->p2p_client = 0;
1707 dut->wps_method = WFA_CS_WPS_NOT_READY;
1708
1709 grp = dut->groups;
1710 while (grp) {
1711 prev = grp;
1712 grp = grp->next;
1713
1714 snprintf(buf, sizeof(buf), "P2P_GROUP_REMOVE %s",
1715 prev->ifname);
1716 wpa_command(intf, buf);
1717 p2p_group_remove(dut, prev->grpid);
1718 }
1719
1720 wpa_command(intf, "P2P_GROUP_REMOVE *");
1721 wpa_command(intf, "P2P_STOP_FIND");
1722 wpa_command(intf, "P2P_FLUSH");
1723 wpa_command(intf, "P2P_SERVICE_FLUSH");
1724 wpa_command(intf, "P2P_SET disabled 0");
1725 wpa_command(intf, "P2P_SET ssid_postfix ");
Danny Segal842a4e02016-04-10 17:55:42 +03001726
1727 if (dut->program == PROGRAM_60GHZ) {
1728 wpa_command(intf, "SET p2p_oper_reg_class 180");
1729 wpa_command(intf, "P2P_SET listen_channel 2 180");
1730 dut->listen_chn = 2;
1731 } else {
1732 wpa_command(intf, "P2P_SET listen_channel 6");
1733 dut->listen_chn = 6;
1734 }
1735
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001736 wpa_command(intf, "P2P_EXT_LISTEN");
1737 wpa_command(intf, "SET p2p_go_intent 7");
1738 wpa_command(intf, "P2P_SET client_apsd disable");
1739 wpa_command(intf, "P2P_SET go_apsd disable");
1740 wpa_command(get_station_ifname(), "P2P_SET ps 98");
1741 wpa_command(get_station_ifname(), "P2P_SET ps 96");
1742 wpa_command(get_station_ifname(), "P2P_SET ps 0");
1743 wpa_command(intf, "SET persistent_reconnect 1");
1744 wpa_command(intf, "SET ampdu 1");
1745 run_system(dut, "iptables -F INPUT");
1746 if (dut->arp_ipaddr[0]) {
1747 snprintf(buf, sizeof(buf), "ip nei del %s dev %s",
1748 dut->arp_ipaddr, dut->arp_ifname);
1749 run_system(dut, buf);
1750 dut->arp_ipaddr[0] = '\0';
1751 }
1752 snprintf(buf, sizeof(buf), "ip nei flush dev %s",
1753 get_station_ifname());
1754 run_system(dut, buf);
1755 dut->p2p_mode = P2P_IDLE;
1756 dut->client_uapsd = 0;
1757 ath6kl_client_uapsd(dut, intf, 0);
1758
1759 remove_wpa_networks(intf);
1760
1761 disconnect_station(dut);
1762
1763 if (dut->iface_down_on_reset)
1764 dut_ifc_reset(dut);
1765
1766 return 1;
1767}
1768
1769
1770static int cmd_sta_get_p2p_ip_config(struct sigma_dut *dut,
1771 struct sigma_conn *conn,
1772 struct sigma_cmd *cmd)
1773{
1774 /* const char *intf = get_param(cmd, "Interface"); */
1775 const char *grpid = get_param(cmd, "GroupID");
1776 struct wfa_cs_p2p_group *grp = NULL;
1777 int count;
1778 char macaddr[20];
1779 char resp[200], info[150];
1780
1781 if (grpid == NULL)
1782 return -1;
1783
1784 if (strcmp(grpid, "$P2P_GROUP_ID") == 0)
1785 return -1;
1786
1787 /*
1788 * If we did not initiate the operation that created the group, we may
1789 * not have the group information available in the DUT code yet and it
1790 * may take some time to get this from wpa_supplicant in case we are
1791 * the P2P client. As such, we better try this multiple times to allow
1792 * some time to complete the operation.
1793 */
1794
1795 sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting to find the requested "
1796 "group");
1797 count = dut->default_timeout;
1798 while (count > 0) {
1799 grp = p2p_group_get(dut, grpid);
1800 if (grp == NULL) {
1801 sigma_dut_print(dut, DUT_MSG_DEBUG, "Requested group "
1802 "not yet found (count=%d)", count);
1803 sleep(1);
1804 } else
1805 break;
1806 count--;
1807 }
1808 if (grp == NULL) {
1809 send_resp(dut, conn, SIGMA_ERROR,
1810 "errorCode,Requested group not found");
1811 return 0;
1812 }
1813
1814 sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting for IP address on group "
1815 "interface %s", grp->ifname);
1816 if (wait_ip_addr(dut, grp->ifname, dut->default_timeout) < 0) {
1817 send_resp(dut, conn, SIGMA_ERROR,
1818 "errorCode,No IP address received");
1819 return 0;
1820 }
1821
1822 if (get_ip_config(dut, grp->ifname, info, sizeof(info)) < 0) {
1823 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get IP address "
1824 "for group interface %s",
1825 grp->ifname);
1826 send_resp(dut, conn, SIGMA_ERROR,
1827 "errorCode,Failed to get IP address");
1828 return 0;
1829 }
1830
1831 if (get_wpa_status(grp->ifname, "address",
1832 macaddr, sizeof(macaddr)) < 0) {
1833 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to get interface "
1834 "address for group interface %s",
1835 grp->ifname);
1836 return -2;
1837 }
1838
1839 sigma_dut_print(dut, DUT_MSG_DEBUG, "IP address for group interface "
1840 "%s found", grp->ifname);
1841
1842 snprintf(resp, sizeof(resp), "%s,P2PInterfaceAddress,%s",
1843 info, macaddr);
1844
1845 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1846 return 0;
1847}
1848
1849
1850static int cmd_sta_send_p2p_presence_req(struct sigma_dut *dut,
1851 struct sigma_conn *conn,
1852 struct sigma_cmd *cmd)
1853{
1854 const char *intf = get_param(cmd, "Interface");
1855 const char *dur = get_param(cmd, "Duration");
1856 const char *interv = get_param(cmd, "Interval");
1857 /* const char *grpid = get_param(cmd, "GroupID"); */
1858 const char *ifname;
1859 char buf[100];
1860
1861 if (dur == NULL || interv == NULL)
1862 return -1;
1863
1864 /* TODO: need to add groupid into parameters in CAPI spec; for now,
1865 * pick the first active group */
1866 ifname = get_group_ifname(dut, intf);
1867 snprintf(buf, sizeof(buf), "P2P_PRESENCE_REQ %s %s", dur, interv);
1868 if (wpa_command(ifname, buf) < 0)
1869 return -2;
1870
1871 return 1;
1872}
1873
1874
1875static int cmd_sta_set_sleep(struct sigma_dut *dut, struct sigma_conn *conn,
1876 struct sigma_cmd *cmd)
1877{
1878 /* const char *intf = get_param(cmd, "Interface"); */
1879 struct wfa_cs_p2p_group *grp;
1880 char *ifname;
1881 const char *grpid = get_param(cmd, "GroupID");
1882
Danny Segal0c0b2612016-04-10 17:58:29 +03001883 if (dut->program == PROGRAM_60GHZ) {
1884 send_resp(dut, conn, SIGMA_ERROR,
1885 "errorCode,UAPSD Sleep is not applicable for 60 GHz");
1886 return 0;
1887 }
1888
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001889 if (grpid == NULL)
1890 ifname = get_station_ifname();
1891 else {
1892 grp = p2p_group_get(dut, grpid);
1893 if (grp == NULL) {
1894 send_resp(dut, conn, SIGMA_ERROR,
1895 "errorCode,Requested group not found");
1896 return 0;
1897 }
1898 ifname = grp->ifname;
1899 }
1900
1901 if (dut->client_uapsd) {
1902#ifdef __linux__
1903 /* no special handling for nl80211 yet */
1904 char path[128];
1905 struct stat s;
1906 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211",
1907 ifname);
1908 if (stat(path, &s) == 0) {
1909 if (wpa_command(ifname, "P2P_SET ps 1") < 0) {
1910 send_resp(dut, conn, SIGMA_ERROR,
1911 "errorCode,Going to sleep not supported");
1912 return 0;
1913 }
1914 return 1;
1915 }
1916#endif /* __linux__ */
1917 if (wpa_command(ifname, "P2P_SET ps 99") < 0)
1918 return -2;
1919 } else {
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 }
1926
1927 return 1;
1928}
1929
1930
1931static int cmd_sta_set_opportunistic_ps(struct sigma_dut *dut,
1932 struct sigma_conn *conn,
1933 struct sigma_cmd *cmd)
1934{
1935 /* const char *intf = get_param(cmd, "Interface"); */
1936 struct wfa_cs_p2p_group *grp;
1937 char buf[100];
1938 const char *grpid = get_param(cmd, "GroupID");
1939 const char *ctwindow = get_param(cmd, "CTWindow");
1940
1941 if (grpid == NULL || ctwindow == NULL)
1942 return -1;
1943
1944 grp = p2p_group_get(dut, grpid);
1945 if (grp == NULL) {
1946 send_resp(dut, conn, SIGMA_ERROR,
1947 "errorCode,Requested group not found");
1948 return 0;
1949 }
1950
1951 if (wpa_command(grp->ifname, "P2P_SET oppps 1") < 0) {
1952 send_resp(dut, conn, SIGMA_ERROR,
1953 "errorCode,Use of OppPS as GO not supported");
1954 return 0;
1955 }
1956 snprintf(buf, sizeof(buf), "P2P_SET ctwindow %d", atoi(ctwindow));
1957 if (wpa_command(grp->ifname, buf) < 0) {
1958 send_resp(dut, conn, SIGMA_ERROR,
1959 "errorCode,Use of CTWindow as GO not supported");
1960 return 0;
1961 }
1962
1963 return 1;
1964}
1965
1966
1967static int cmd_sta_send_service_discovery_req(struct sigma_dut *dut,
1968 struct sigma_conn *conn,
1969 struct sigma_cmd *cmd)
1970{
1971 const char *intf = get_param(cmd, "Interface");
1972 const char *devid = get_param(cmd, "P2PDevID");
1973 char buf[128];
1974
1975 if (devid == NULL)
1976 return -1;
1977
1978 snprintf(buf, sizeof(buf), "P2P_SERV_DISC_REQ %s 02000001",
1979 devid);
1980 if (wpa_command(intf, buf) < 0) {
1981 send_resp(dut, conn, SIGMA_ERROR, NULL);
1982 return 0;
1983 }
1984
1985 return 1;
1986}
1987
1988
1989static int cmd_sta_add_arp_table_entry(struct sigma_dut *dut,
1990 struct sigma_conn *conn,
1991 struct sigma_cmd *cmd)
1992{
1993 char buf[256];
1994 char *ifname;
1995 const char *grpid, *ipaddr, *macaddr;
1996
1997 grpid = get_param(cmd, "GroupID");
1998 ipaddr = get_param(cmd, "IPAddress");
1999 macaddr = get_param(cmd, "MACAddress");
2000 if (ipaddr == NULL || macaddr == NULL)
2001 return -1;
2002
2003 if (grpid == NULL)
2004 ifname = get_station_ifname();
2005 else {
2006 struct wfa_cs_p2p_group *grp;
2007 grp = p2p_group_get(dut, grpid);
2008 if (grp == NULL) {
2009 send_resp(dut, conn, SIGMA_ERROR,
2010 "errorCode,Requested group not found");
2011 return 0;
2012 }
2013 ifname = grp->ifname;
2014 }
2015
2016 snprintf(dut->arp_ipaddr, sizeof(dut->arp_ipaddr), "%s",
2017 ipaddr);
2018 snprintf(dut->arp_ifname, sizeof(dut->arp_ifname), "%s",
2019 ifname);
2020
2021 snprintf(buf, sizeof(buf), "ip nei add %s lladdr %s dev %s",
2022 ipaddr, macaddr, ifname);
2023 run_system(dut, buf);
2024
2025 return 1;
2026}
2027
2028
2029static int cmd_sta_block_icmp_response(struct sigma_dut *dut,
2030 struct sigma_conn *conn,
2031 struct sigma_cmd *cmd)
2032{
2033 char buf[256];
2034 struct wfa_cs_p2p_group *grp;
2035 char *ifname;
2036 const char *grpid, *ipaddr;
2037
2038 grpid = get_param(cmd, "GroupID");
2039 ipaddr = get_param(cmd, "IPAddress");
2040 if (ipaddr == NULL)
2041 return -1;
2042
2043 if (grpid == NULL)
2044 ifname = get_station_ifname();
2045 else {
2046 grp = p2p_group_get(dut, grpid);
2047 if (grp == NULL) {
2048 send_resp(dut, conn, SIGMA_ERROR,
2049 "errorCode,Requested group not found");
2050 return 0;
2051 }
2052 ifname = grp->ifname;
2053 }
2054
2055 snprintf(buf, sizeof(buf),
2056 "iptables -I INPUT -s %s -p icmp -i %s -j DROP",
2057 ipaddr, ifname);
2058 run_system(dut, buf);
2059
2060 return 1;
2061}
2062
2063
2064static int run_nfc_command(struct sigma_dut *dut, const char *cmd,
2065 const char *info)
2066{
2067 int res;
2068
2069 sigma_dut_summary(dut, "NFC operation: %s", info);
2070 printf("\n\n\n=====[ NFC operation ]=========================\n\n");
2071 printf("%s\n\n", info);
2072
2073 nfc_status(dut, "START", info);
2074 res = run_system(dut, cmd);
2075 nfc_status(dut, res ? "FAIL" : "SUCCESS", info);
2076 if (res) {
2077 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s': %d",
2078 cmd, res);
2079 return res;
2080 }
2081
2082 return 0;
2083}
2084
2085
2086static int nfc_write_p2p_select(struct sigma_dut *dut, struct sigma_conn *conn,
2087 struct sigma_cmd *cmd)
2088{
2089 int res;
2090 const char *ifname = get_param(cmd, "Interface");
2091 char buf[300];
2092
2093 run_system(dut, "killall wps-nfc.py");
2094 run_system(dut, "killall p2p-nfc.py");
2095
2096 if (wpa_command(ifname, "WPS_NFC_TOKEN NDEF") < 0) {
2097 send_resp(dut, conn, SIGMA_ERROR,
2098 "ErrorCode,Failed to generate NFC password token");
2099 return 0;
2100 }
2101
2102 unlink("nfc-success");
2103 snprintf(buf, sizeof(buf),
2104 "./p2p-nfc.py -1 --no-wait %s%s --success nfc-success write-p2p-sel",
2105 dut->summary_log ? "--summary " : "",
2106 dut->summary_log ? dut->summary_log : "");
2107 res = run_nfc_command(dut, buf,
2108 "Touch NFC Tag to write P2P connection handover select");
2109 if (res || !file_exists("nfc-success")) {
2110 send_resp(dut, conn, SIGMA_ERROR,
2111 "ErrorCode,Failed to write tag");
2112 return 0;
2113 }
2114
2115 if (wpa_command(ifname, "P2P_SET nfc_tag 1") < 0) {
2116 send_resp(dut, conn, SIGMA_ERROR,
2117 "ErrorCode,Failed to enable NFC password token");
2118 return 0;
2119 }
2120
2121 if (!dut->go && wpa_command(ifname, "P2P_LISTEN") < 0) {
2122 send_resp(dut, conn, SIGMA_ERROR,
2123 "ErrorCode,Failed to start listen mode");
2124 return 0;
2125 }
2126
2127 send_resp(dut, conn, SIGMA_COMPLETE,
2128 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2129 return 0;
2130}
2131
2132
2133static int nfc_write_config_token(struct sigma_dut *dut,
2134 struct sigma_conn *conn,
2135 struct sigma_cmd *cmd)
2136{
2137 int res;
2138 const char *bssid = get_param(cmd, "Bssid");
2139 const char *intf = get_param(cmd, "Interface");
2140 char buf[200];
2141
2142 run_system(dut, "killall wps-nfc.py");
2143 run_system(dut, "killall p2p-nfc.py");
2144 unlink("nfc-success");
2145 if (dut->er_oper_performed && bssid) {
2146 char current_bssid[30], id[10];
2147 if (get_wpa_status(intf, "id", id, sizeof(id)) < 0 ||
2148 get_wpa_status(intf, "bssid", current_bssid,
2149 sizeof(current_bssid)) < 0 ||
2150 strncasecmp(bssid, current_bssid, strlen(current_bssid)) !=
2151 0) {
2152 send_resp(dut, conn, SIGMA_ERROR,
2153 "ErrorCode,No configuration known for BSSID");
2154 return 0;
2155 }
2156 snprintf(buf, sizeof(buf),
2157 "./wps-nfc.py --id %s --no-wait %s%s --success nfc-success write-config",
2158 id,
2159 dut->summary_log ? "--summary " : "",
2160 dut->summary_log ? dut->summary_log : "");
2161 res = run_nfc_command(dut, buf,
2162 "Touch NFC Tag to write WPS configuration token");
2163 } else {
2164 snprintf(buf, sizeof(buf),
2165 "./wps-nfc.py --no-wait %s%s --success nfc-success write-config",
2166 dut->summary_log ? "--summary " : "",
2167 dut->summary_log ? dut->summary_log : "");
2168 res = run_nfc_command(dut, buf,
2169 "Touch NFC Tag to write WPS configuration token");
2170 }
2171 if (res || !file_exists("nfc-success")) {
2172 send_resp(dut, conn, SIGMA_ERROR,
2173 "ErrorCode,Failed to write tag");
2174 return 0;
2175 }
2176
2177 send_resp(dut, conn, SIGMA_COMPLETE,
2178 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2179 return 0;
2180}
2181
2182
2183static int nfc_write_password_token(struct sigma_dut *dut,
2184 struct sigma_conn *conn,
2185 struct sigma_cmd *cmd)
2186{
2187 int res;
2188 char buf[300];
2189
2190 run_system(dut, "killall wps-nfc.py");
2191 run_system(dut, "killall p2p-nfc.py");
2192 unlink("nfc-success");
2193 snprintf(buf, sizeof(buf),
2194 "./wps-nfc.py --no-wait %s%s --success nfc-success write-password",
2195 dut->summary_log ? "--summary " : "",
2196 dut->summary_log ? dut->summary_log : "");
2197 res = run_nfc_command(dut, buf,
2198 "Touch NFC Tag to write WPS password token");
2199 if (res || !file_exists("nfc-success")) {
2200 send_resp(dut, conn, SIGMA_ERROR,
2201 "ErrorCode,Failed to write tag");
2202 return 0;
2203 }
2204
2205 send_resp(dut, conn, SIGMA_COMPLETE,
2206 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2207 return 0;
2208}
2209
2210
2211static int nfc_read_tag(struct sigma_dut *dut,
2212 struct sigma_conn *conn,
2213 struct sigma_cmd *cmd)
2214{
2215 int res;
2216 struct wpa_ctrl *ctrl;
2217 const char *intf = get_param(cmd, "Interface");
2218 const char *oper_chn = get_param(cmd, "OPER_CHN");
2219 char buf[1000], freq_str[20];
2220
2221 run_system(dut, "killall wps-nfc.py");
2222 run_system(dut, "killall p2p-nfc.py");
2223
2224 ctrl = open_wpa_mon(intf);
2225 if (ctrl == NULL) {
2226 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2227 "wpa_supplicant monitor connection");
2228 return -2;
2229 }
2230
2231 freq_str[0] = '\0';
2232 if (oper_chn) {
2233 int chan = atoi(oper_chn);
2234 if (chan >= 1 && chan <= 11)
2235 snprintf(freq_str, sizeof(freq_str), " --freq %d",
2236 2407 + chan * 5);
2237 }
2238
2239 unlink("nfc-success");
2240 snprintf(buf, sizeof(buf),
2241 "./p2p-nfc.py -1 -t %s%s --success nfc-success --no-wait%s",
2242 dut->summary_log ? "--summary " : "",
2243 dut->summary_log ? dut->summary_log : "",
2244 freq_str);
2245 res = run_nfc_command(dut, buf,
2246 "Touch NFC Tag to read it");
2247 if (res || !file_exists("nfc-success")) {
2248 send_resp(dut, conn, SIGMA_ERROR,
2249 "ErrorCode,Failed to read tag");
2250 wpa_ctrl_detach(ctrl);
2251 wpa_ctrl_close(ctrl);
2252 return 0;
2253 }
2254
2255 if (dut->p2p_mode == P2P_DISABLE)
2256 return wps_connection_event(dut, conn, ctrl, intf, 1);
2257
2258 if (dut->go || dut->p2p_client) {
2259 wpa_ctrl_detach(ctrl);
2260 wpa_ctrl_close(ctrl);
2261 send_resp(dut, conn, SIGMA_COMPLETE,
2262 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2263 return 0;
2264 }
2265
2266 /* FIX: PeerRole */
2267 return p2p_group_formation_event(dut, conn, ctrl, intf, "0", 1);
2268}
2269
2270
2271static int nfc_wps_read_tag(struct sigma_dut *dut,
2272 struct sigma_conn *conn,
2273 struct sigma_cmd *cmd)
2274{
2275 int res;
2276 struct wpa_ctrl *ctrl;
2277 const char *intf = get_param(cmd, "Interface");
2278 char buf[300];
2279
2280 run_system(dut, "killall wps-nfc.py");
2281 run_system(dut, "killall p2p-nfc.py");
2282
2283 ctrl = open_wpa_mon(intf);
2284 if (ctrl == NULL) {
2285 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2286 "wpa_supplicant monitor connection");
2287 return -2;
2288 }
2289
2290 unlink("nfc-success");
2291 snprintf(buf, sizeof(buf),
2292 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success",
2293 dut->summary_log ? "--summary " : "",
2294 dut->summary_log ? dut->summary_log : "");
2295 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
2296 if (res || !file_exists("nfc-success")) {
2297 send_resp(dut, conn, SIGMA_ERROR,
2298 "ErrorCode,Failed to read tag");
2299 wpa_ctrl_detach(ctrl);
2300 wpa_ctrl_close(ctrl);
2301 return 0;
2302 }
2303
2304 return wps_connection_event(dut, conn, ctrl, intf, 1);
2305}
2306
2307
2308static int er_ap_add_match(const char *event, const char *bssid,
2309 const char *req_uuid,
2310 char *ret_uuid, size_t max_uuid_len)
2311{
2312 const char *pos, *uuid;
2313
2314 pos = strchr(event, ' ');
2315 if (pos == NULL)
2316 return 0;
2317 pos++;
2318 uuid = pos;
2319
2320 pos = strchr(pos, ' ');
2321 if (pos == NULL)
2322 return 0;
2323 if (ret_uuid) {
2324 if ((size_t) (pos - uuid + 1) < max_uuid_len) {
2325 memcpy(ret_uuid, uuid, pos - uuid);
2326 ret_uuid[pos - uuid] = '\0';
2327 } else
2328 ret_uuid[0] = '\0';
2329 }
2330
2331 if (req_uuid && strncasecmp(req_uuid, uuid, pos - uuid) == 0)
2332 return 1;
2333
2334 pos++;
2335 /* at BSSID */
2336
2337 return strncasecmp(pos, bssid, strlen(bssid)) == 0;
2338}
2339
2340
2341static int er_start(struct sigma_dut *dut, struct sigma_conn *conn,
2342 struct wpa_ctrl *ctrl, const char *intf, const char *bssid,
2343 const char *uuid, char *ret_uuid, size_t max_uuid_len)
2344{
2345 char id[10];
2346 int res;
2347 char buf[1000];
2348
2349 sigma_dut_print(dut, DUT_MSG_INFO, "Trying to find WPS AP %s over UPnP",
2350 bssid);
2351
2352 if (wpa_command(intf, "WPS_ER_START") < 0) {
2353 send_resp(dut, conn, SIGMA_ERROR,
2354 "ErrorCode,Failed to start ER");
2355 return 0;
2356 }
2357
2358 for (;;) {
2359 res = get_wpa_cli_event(dut, ctrl, "WPS-ER-AP-ADD",
2360 buf, sizeof(buf));
2361 if (res < 0) {
2362#ifdef USE_ERROR_RETURNS
2363 send_resp(dut, conn, SIGMA_ERROR,
2364 "ErrorCode,Could not find the AP over UPnP");
2365#else
2366 send_resp(dut, conn, SIGMA_COMPLETE,
2367 "ErrorCode,Could not find the AP over UPnP");
2368#endif
2369 return 0;
2370 }
2371
2372 if (er_ap_add_match(buf, bssid, uuid, ret_uuid, max_uuid_len)) {
2373 sigma_dut_print(dut, DUT_MSG_INFO,
2374 "Found WPS AP over UPnP: %s", buf);
2375 break;
2376 }
2377 }
2378
2379 if (get_wpa_status(intf, "id", id, sizeof(id)) < 0) {
2380 send_resp(dut, conn, SIGMA_ERROR,
2381 "ErrorCode,Could not find AP configuration");
2382 return 0;
2383 }
2384
2385 if (ret_uuid) {
2386 snprintf(buf, sizeof(buf), "WPS_ER_SET_CONFIG %s %s",
2387 ret_uuid, id);
2388 } else if (uuid) {
2389 snprintf(buf, sizeof(buf), "WPS_ER_SET_CONFIG %s %s",
2390 uuid, id);
2391 } else {
2392 snprintf(buf, sizeof(buf), "WPS_ER_SET_CONFIG %s %s",
2393 bssid, id);
2394 }
2395 if (wpa_command(intf, buf) < 0) {
2396 send_resp(dut, conn, SIGMA_ERROR,
2397 "ErrorCode,Failed to select network configuration for ER");
2398 return 0;
2399 }
2400
2401 return 1;
2402}
2403
2404
2405static int nfc_wps_read_passwd(struct sigma_dut *dut,
2406 struct sigma_conn *conn,
2407 struct sigma_cmd *cmd)
2408{
2409 int res;
2410 struct wpa_ctrl *ctrl;
2411 const char *intf = get_param(cmd, "Interface");
2412 const char *bssid = get_param(cmd, "Bssid");
2413 const char *ssid = get_param(cmd, "SSID");
2414 const char *security = get_param(cmd, "Security");
2415 const char *passphrase = get_param(cmd, "Passphrase");
2416 char ssid_hex[200], passphrase_hex[200];
2417 const char *val;
2418 int sta_action;
2419 char buf[1000];
2420 const char *keymgmt, *cipher;
2421
2422 run_system(dut, "killall wps-nfc.py");
2423 run_system(dut, "killall p2p-nfc.py");
2424
2425 if ((ssid && strlen(ssid) >= 2 * sizeof(ssid_hex)) ||
2426 (passphrase && strlen(passphrase) >= 2 * sizeof(passphrase_hex))) {
2427 send_resp(dut, conn, SIGMA_ERROR,
2428 "ErrorCode,Too long SSID/passphrase");
2429 return 0;
2430 }
2431
2432 val = get_param(cmd, "WpsStaAction");
2433 if (!val) {
2434 send_resp(dut, conn, SIGMA_ERROR,
2435 "ErrorCode,Missing WpsStaAction argument");
2436 return 0;
2437 }
2438
2439 sta_action = atoi(val);
2440 if (sta_action != 1 && sta_action != 2) {
2441 send_resp(dut, conn, SIGMA_ERROR,
2442 "ErrorCode,Unsupported WpsStaAction value");
2443 return 0;
2444 }
2445
2446 if (!bssid) {
2447 send_resp(dut, conn, SIGMA_ERROR,
2448 "ErrorCode,Missing Bssid argument");
2449 return 0;
2450 }
2451
2452 if (sta_action == 2) {
2453 if (!ssid) {
2454 send_resp(dut, conn, SIGMA_ERROR,
2455 "ErrorCode,Missing SSID argument");
2456 return 0;
2457 }
2458
2459 if (!security) {
2460 send_resp(dut, conn, SIGMA_ERROR,
2461 "ErrorCode,Missing Security argument");
2462 return 0;
2463 }
2464
2465 if (!passphrase) {
2466 send_resp(dut, conn, SIGMA_ERROR,
2467 "ErrorCode,Missing Passphrase argument");
2468 return 0;
2469 }
2470 }
2471
2472 ctrl = open_wpa_mon(intf);
2473 if (ctrl == NULL) {
2474 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2475 "wpa_supplicant monitor connection");
2476 return -2;
2477 }
2478
2479 if (sta_action == 1) {
2480 const char *uuid = get_param(cmd, "UUID");
2481 res = er_start(dut, conn, ctrl, intf, bssid, uuid, NULL, 0);
2482 if (res != 1) {
2483 wpa_ctrl_detach(ctrl);
2484 wpa_ctrl_close(ctrl);
2485 return res;
2486 }
2487 }
2488
2489 unlink("nfc-success");
2490 snprintf(buf, sizeof(buf),
2491 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success",
2492 dut->summary_log ? "--summary " : "",
2493 dut->summary_log ? dut->summary_log : "");
2494 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
2495 if (res || !file_exists("nfc-success")) {
2496 wpa_ctrl_detach(ctrl);
2497 wpa_ctrl_close(ctrl);
2498 send_resp(dut, conn, SIGMA_ERROR,
2499 "ErrorCode,Failed to read tag");
2500 return 0;
2501 }
2502
2503 if (sta_action == 1) {
2504 sigma_dut_print(dut, DUT_MSG_INFO, "Prepared device password for ER to enroll a new station");
2505 wpa_ctrl_detach(ctrl);
2506 wpa_ctrl_close(ctrl);
2507 send_resp(dut, conn, SIGMA_COMPLETE,
2508 "Result,,GroupID,,PeerRole,");
2509 return 0;
2510 }
2511 if (strcasecmp(security, "wpa2-psk") == 0) {
2512 keymgmt = "WPA2PSK";
2513 cipher = "CCMP";
2514 } else {
2515 wpa_ctrl_detach(ctrl);
2516 wpa_ctrl_close(ctrl);
2517 send_resp(dut, conn, SIGMA_ERROR,
2518 "ErrorCode,Unsupported Security value");
2519 return 0;
2520 }
2521
2522 ascii2hexstr(ssid, ssid_hex);
2523 ascii2hexstr(passphrase, passphrase_hex);
2524 snprintf(buf, sizeof(buf), "WPS_REG %s nfc-pw %s %s %s %s",
2525 bssid, ssid_hex, keymgmt, cipher, passphrase_hex);
2526
2527 if (wpa_command(intf, buf) < 0) {
2528 wpa_ctrl_detach(ctrl);
2529 wpa_ctrl_close(ctrl);
2530 send_resp(dut, conn, SIGMA_ERROR,
2531 "ErrorCode,Failed to start registrar");
2532 return 0;
2533 }
2534
2535 return wps_connection_event(dut, conn, ctrl, intf, 1);
2536}
2537
2538
2539static int nfc_wps_read_config(struct sigma_dut *dut,
2540 struct sigma_conn *conn,
2541 struct sigma_cmd *cmd)
2542{
2543 int res;
2544 struct wpa_ctrl *ctrl;
2545 const char *intf = get_param(cmd, "Interface");
2546 char buf[300];
2547
2548 run_system(dut, "killall wps-nfc.py");
2549 run_system(dut, "killall p2p-nfc.py");
2550
2551 ctrl = open_wpa_mon(intf);
2552 if (ctrl == NULL) {
2553 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2554 "wpa_supplicant monitor connection");
2555 return -2;
2556 }
2557
2558 unlink("nfc-success");
2559 snprintf(buf, sizeof(buf),
2560 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success",
2561 dut->summary_log ? "--summary " : "",
2562 dut->summary_log ? dut->summary_log : "");
2563 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
2564 if (res || !file_exists("nfc-success")) {
2565 send_resp(dut, conn, SIGMA_ERROR,
2566 "ErrorCode,Failed to read tag");
2567 wpa_ctrl_detach(ctrl);
2568 wpa_ctrl_close(ctrl);
2569 return 0;
2570 }
2571
2572 return wps_connection_event(dut, conn, ctrl, intf, 1);
2573}
2574
2575
2576static int nfc_wps_connection_handover(struct sigma_dut *dut,
2577 struct sigma_conn *conn,
2578 struct sigma_cmd *cmd)
2579{
2580 const char *intf = get_param(cmd, "Interface");
2581 int res;
2582 const char *init = get_param(cmd, "Init");
2583 struct wpa_ctrl *ctrl = NULL;
2584 char buf[300];
2585
2586 run_system(dut, "killall wps-nfc.py");
2587 run_system(dut, "killall p2p-nfc.py");
2588
2589 ctrl = open_wpa_mon(intf);
2590 if (ctrl == NULL) {
2591 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2592 "wpa_supplicant monitor connection");
2593 return -2;
2594 }
2595
2596 unlink("nfc-success");
2597 if ((!init || atoi(init) == 0) && dut->er_oper_performed) {
2598 const char *bssid = get_param(cmd, "Bssid");
2599 const char *req_uuid = get_param(cmd, "UUID");
2600 char uuid[100];
2601
2602 if (bssid == NULL)
2603 bssid = dut->er_oper_bssid;
2604
2605 res = er_start(dut, conn, ctrl, intf, bssid, req_uuid, uuid,
2606 sizeof(uuid));
2607 if (res != 1) {
2608 wpa_ctrl_detach(ctrl);
2609 wpa_ctrl_close(ctrl);
2610 return res;
2611 }
2612
2613 snprintf(buf, sizeof(buf),
2614 "./wps-nfc.py -1 --uuid %s %s%s --success nfc-success",
2615 uuid,
2616 dut->summary_log ? "--summary " : "",
2617 dut->summary_log ? dut->summary_log : "");
2618 res = run_nfc_command(dut, buf,
2619 "Touch NFC Device to respond to WPS connection handover");
2620 } else if (!init || atoi(init)) {
2621 snprintf(buf, sizeof(buf),
2622 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success",
2623 dut->summary_log ? "--summary " : "",
2624 dut->summary_log ? dut->summary_log : "");
2625 res = run_nfc_command(dut, buf,
2626 "Touch NFC Device to initiate WPS connection handover");
2627 } else {
2628 snprintf(buf, sizeof(buf),
2629 "./p2p-nfc.py -1 --no-wait --no-input %s%s --success nfc-success --handover-only",
2630 dut->summary_log ? "--summary " : "",
2631 dut->summary_log ? dut->summary_log : "");
2632 res = run_nfc_command(dut, buf,
2633 "Touch NFC Device to respond to WPS connection handover");
2634 }
2635 if (res) {
2636 wpa_ctrl_detach(ctrl);
2637 wpa_ctrl_close(ctrl);
2638 send_resp(dut, conn, SIGMA_ERROR,
2639 "ErrorCode,Failed to enable NFC for connection "
2640 "handover");
2641 return 0;
2642 }
2643 if (!file_exists("nfc-success")) {
2644 wpa_ctrl_detach(ctrl);
2645 wpa_ctrl_close(ctrl);
2646 send_resp(dut, conn, SIGMA_ERROR,
2647 "ErrorCode,Failed to complete NFC connection handover");
2648 return 0;
2649 }
2650
2651 if (init && atoi(init))
2652 return wps_connection_event(dut, conn, ctrl, intf, 1);
2653
2654 wpa_ctrl_detach(ctrl);
2655 wpa_ctrl_close(ctrl);
2656
2657 send_resp(dut, conn, SIGMA_COMPLETE,
2658 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2659 return 0;
2660}
2661
2662
2663static int nfc_p2p_connection_handover(struct sigma_dut *dut,
2664 struct sigma_conn *conn,
2665 struct sigma_cmd *cmd)
2666{
2667 const char *intf = get_param(cmd, "Interface");
2668 int res;
2669 const char *init = get_param(cmd, "Init");
2670 const char *oper_chn = get_param(cmd, "OPER_CHN");
2671 struct wpa_ctrl *ctrl;
2672 char buf[1000], freq_str[20];
2673
2674 run_system(dut, "killall wps-nfc.py");
2675 run_system(dut, "killall p2p-nfc.py");
2676
2677 ctrl = open_wpa_mon(intf);
2678 if (ctrl == NULL) {
2679 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2680 "wpa_supplicant monitor connection");
2681 return -2;
2682 }
2683
2684 freq_str[0] = '\0';
2685 if (oper_chn) {
2686 int chan = atoi(oper_chn);
2687 if (chan >= 1 && chan <= 11)
2688 snprintf(freq_str, sizeof(freq_str), " --freq %d",
2689 2407 + chan * 5);
2690 }
2691
2692 unlink("nfc-success");
2693 if (init && atoi(init)) {
2694 snprintf(buf, sizeof(buf),
2695 "./p2p-nfc.py -1 -I -N --no-wait %s%s --success nfc-success --no-input%s --handover-only",
2696 dut->summary_log ? "--summary " : "",
2697 dut->summary_log ? dut->summary_log : "",
2698 freq_str);
2699 res = run_nfc_command(dut, buf,
2700 "Touch NFC Device to initiate P2P connection handover");
2701 } else {
2702 snprintf(buf, sizeof(buf),
2703 "./p2p-nfc.py -1 --no-wait %s%s --success nfc-success --no-input%s --handover-only",
2704 dut->summary_log ? "--summary " : "",
2705 dut->summary_log ? dut->summary_log : "",
2706 freq_str);
2707 res = run_nfc_command(dut, buf,
2708 "Touch NFC Device to respond to P2P connection handover");
2709 }
2710 if (res) {
2711 wpa_ctrl_detach(ctrl);
2712 wpa_ctrl_close(ctrl);
2713 send_resp(dut, conn, SIGMA_ERROR,
2714 "ErrorCode,Failed to enable NFC for connection "
2715 "handover");
2716 return 0;
2717 }
2718 if (!file_exists("nfc-success")) {
2719 wpa_ctrl_detach(ctrl);
2720 wpa_ctrl_close(ctrl);
2721 send_resp(dut, conn, SIGMA_ERROR,
2722 "ErrorCode,Failed to complete NFC connection handover");
2723 return 0;
2724 }
2725
2726 if (dut->go || dut->p2p_client) {
2727 wpa_ctrl_detach(ctrl);
2728 wpa_ctrl_close(ctrl);
2729 send_resp(dut, conn, SIGMA_COMPLETE,
2730 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2731 return 0;
2732 }
2733
2734 /* FIX: peer role from handover message */
2735 return p2p_group_formation_event(dut, conn, ctrl, intf, "0", 1);
2736}
2737
2738
2739static int cmd_sta_nfc_action(struct sigma_dut *dut, struct sigma_conn *conn,
2740 struct sigma_cmd *cmd)
2741{
2742 const char *intf = get_param(cmd, "Interface");
2743 const char *oper = get_param(cmd, "Operation");
2744 const char *ssid_param = get_param(cmd, "SSID");
2745 const char *intent_val = get_param(cmd, "INTENT_VAL");
2746 const char *oper_chn = get_param(cmd, "OPER_CHN");
2747 char buf[256];
2748
2749 if (oper == NULL)
2750 return -1;
2751
2752 if (ssid_param)
2753 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix %s",
2754 ssid_param);
2755 else
2756 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix ");
2757 if (wpa_command(intf, buf) < 0)
2758 sigma_dut_print(dut, DUT_MSG_INFO, "Failed P2P ssid_postfix - ignore and assume this is for non-P2P case");
2759
2760 if (intent_val) {
2761 snprintf(buf, sizeof(buf), "SET p2p_go_intent %s", intent_val);
2762 if (wpa_command(intf, buf) < 0)
2763 return -2;
2764 }
2765
2766 if (oper_chn) {
2767 int chan = atoi(oper_chn);
2768 if (chan < 1 || chan > 11) {
2769 send_resp(dut, conn, SIGMA_ERROR,
2770 "ErrorCode,Unsupported operating channel");
2771 return 0;
2772 }
2773 snprintf(buf, sizeof(buf), "SET p2p_oper_channel %d", chan);
2774 if (wpa_command(intf, "SET p2p_oper_reg_class 81") < 0 ||
2775 wpa_command(intf, buf) < 0) {
2776 send_resp(dut, conn, SIGMA_ERROR,
2777 "ErrorCode,Failed to set operating channel");
2778 return 0;
2779 }
2780 }
2781
2782 if (strcasecmp(oper, "WRITE_SELECT") == 0)
2783 return nfc_write_p2p_select(dut, conn, cmd);
2784 if (strcasecmp(oper, "WRITE_CONFIG") == 0)
2785 return nfc_write_config_token(dut, conn, cmd);
2786 if (strcasecmp(oper, "WRITE_PASSWD") == 0)
2787 return nfc_write_password_token(dut, conn, cmd);
2788 if (strcasecmp(oper, "READ_TAG") == 0)
2789 return nfc_read_tag(dut, conn, cmd);
2790 if (strcasecmp(oper, "WPS_READ_TAG") == 0)
2791 return nfc_wps_read_tag(dut, conn, cmd);
2792 if (strcasecmp(oper, "WPS_READ_PASSWD") == 0)
2793 return nfc_wps_read_passwd(dut, conn, cmd);
2794 if (strcasecmp(oper, "WPS_READ_CONFIG") == 0)
2795 return nfc_wps_read_config(dut, conn, cmd);
2796 if (strcasecmp(oper, "CONN_HNDOVR") == 0)
2797 return nfc_p2p_connection_handover(dut, conn, cmd);
2798 if (strcasecmp(oper, "WPS_CONN_HNDOVR") == 0)
2799 return nfc_wps_connection_handover(dut, conn, cmd);
2800
2801 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported operation");
2802 return 0;
2803}
2804
2805
2806int p2p_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2807 struct sigma_cmd *cmd)
2808{
2809 const char *parameter = get_param(cmd, "Parameter");
2810 char buf[100];
2811
2812 if (parameter == NULL)
2813 return -1;
2814 if (strcasecmp(parameter, "ListenChannel") == 0) {
2815 snprintf(buf, sizeof(buf), "ListenChnl,%u", dut->listen_chn);
2816 send_resp(dut, conn, SIGMA_COMPLETE, buf);
2817 return 0;
2818 }
2819
2820 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
2821 return 0;
2822}
2823
2824
2825static int req_intf(struct sigma_cmd *cmd)
2826{
2827 return get_param(cmd, "interface") == NULL ? -1 : 0;
2828}
2829
2830
2831void p2p_register_cmds(void)
2832{
2833 sigma_dut_reg_cmd("sta_get_p2p_dev_address", req_intf,
2834 cmd_sta_get_p2p_dev_address);
2835 sigma_dut_reg_cmd("sta_set_p2p", req_intf, cmd_sta_set_p2p);
2836 sigma_dut_reg_cmd("sta_start_autonomous_go", req_intf,
2837 cmd_sta_start_autonomous_go);
2838 sigma_dut_reg_cmd("sta_p2p_connect", req_intf, cmd_sta_p2p_connect);
2839 sigma_dut_reg_cmd("sta_p2p_start_group_formation", req_intf,
2840 cmd_sta_p2p_start_group_formation);
2841 sigma_dut_reg_cmd("sta_p2p_dissolve", req_intf, cmd_sta_p2p_dissolve);
2842 sigma_dut_reg_cmd("sta_send_p2p_invitation_req", req_intf,
2843 cmd_sta_send_p2p_invitation_req);
2844 sigma_dut_reg_cmd("sta_accept_p2p_invitation_req", req_intf,
2845 cmd_sta_accept_p2p_invitation_req);
2846 sigma_dut_reg_cmd("sta_send_p2p_provision_dis_req", req_intf,
2847 cmd_sta_send_p2p_provision_dis_req);
2848 sigma_dut_reg_cmd("sta_set_wps_pbc", req_intf, cmd_sta_set_wps_pbc);
2849 sigma_dut_reg_cmd("sta_wps_read_pin", req_intf, cmd_sta_wps_read_pin);
2850 sigma_dut_reg_cmd("sta_wps_read_label", req_intf,
2851 cmd_sta_wps_read_label);
2852 sigma_dut_reg_cmd("sta_wps_enter_pin", req_intf,
2853 cmd_sta_wps_enter_pin);
2854 sigma_dut_reg_cmd("sta_get_psk", req_intf, cmd_sta_get_psk);
2855 sigma_dut_reg_cmd("sta_p2p_reset", req_intf, cmd_sta_p2p_reset);
2856 sigma_dut_reg_cmd("sta_get_p2p_ip_config", req_intf,
2857 cmd_sta_get_p2p_ip_config);
2858 sigma_dut_reg_cmd("sta_send_p2p_presence_req", req_intf,
2859 cmd_sta_send_p2p_presence_req);
2860 sigma_dut_reg_cmd("sta_set_sleep", req_intf, cmd_sta_set_sleep);
2861 sigma_dut_reg_cmd("sta_set_opportunistic_ps", req_intf,
2862 cmd_sta_set_opportunistic_ps);
2863 sigma_dut_reg_cmd("sta_send_service_discovery_req", req_intf,
2864 cmd_sta_send_service_discovery_req);
2865 sigma_dut_reg_cmd("sta_add_arp_table_entry", req_intf,
2866 cmd_sta_add_arp_table_entry);
2867 sigma_dut_reg_cmd("sta_block_icmp_response", req_intf,
2868 cmd_sta_block_icmp_response);
2869 sigma_dut_reg_cmd("sta_nfc_action", req_intf, cmd_sta_nfc_action);
2870}