blob: 2fe4617fb99770e9c1972837f765b6446b214f83 [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");
1753 wpa_command(intf, "SET persistent_reconnect 1");
1754 wpa_command(intf, "SET ampdu 1");
1755 run_system(dut, "iptables -F INPUT");
1756 if (dut->arp_ipaddr[0]) {
1757 snprintf(buf, sizeof(buf), "ip nei del %s dev %s",
1758 dut->arp_ipaddr, dut->arp_ifname);
1759 run_system(dut, buf);
1760 dut->arp_ipaddr[0] = '\0';
1761 }
1762 snprintf(buf, sizeof(buf), "ip nei flush dev %s",
1763 get_station_ifname());
1764 run_system(dut, buf);
1765 dut->p2p_mode = P2P_IDLE;
1766 dut->client_uapsd = 0;
1767 ath6kl_client_uapsd(dut, intf, 0);
1768
1769 remove_wpa_networks(intf);
1770
1771 disconnect_station(dut);
1772
1773 if (dut->iface_down_on_reset)
1774 dut_ifc_reset(dut);
1775
1776 return 1;
1777}
1778
1779
1780static int cmd_sta_get_p2p_ip_config(struct sigma_dut *dut,
1781 struct sigma_conn *conn,
1782 struct sigma_cmd *cmd)
1783{
1784 /* const char *intf = get_param(cmd, "Interface"); */
1785 const char *grpid = get_param(cmd, "GroupID");
1786 struct wfa_cs_p2p_group *grp = NULL;
1787 int count;
1788 char macaddr[20];
1789 char resp[200], info[150];
1790
1791 if (grpid == NULL)
1792 return -1;
1793
1794 if (strcmp(grpid, "$P2P_GROUP_ID") == 0)
1795 return -1;
1796
1797 /*
1798 * If we did not initiate the operation that created the group, we may
1799 * not have the group information available in the DUT code yet and it
1800 * may take some time to get this from wpa_supplicant in case we are
1801 * the P2P client. As such, we better try this multiple times to allow
1802 * some time to complete the operation.
1803 */
1804
1805 sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting to find the requested "
1806 "group");
1807 count = dut->default_timeout;
1808 while (count > 0) {
1809 grp = p2p_group_get(dut, grpid);
1810 if (grp == NULL) {
1811 sigma_dut_print(dut, DUT_MSG_DEBUG, "Requested group "
1812 "not yet found (count=%d)", count);
1813 sleep(1);
1814 } else
1815 break;
1816 count--;
1817 }
1818 if (grp == NULL) {
1819 send_resp(dut, conn, SIGMA_ERROR,
1820 "errorCode,Requested group not found");
1821 return 0;
1822 }
1823
1824 sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting for IP address on group "
1825 "interface %s", grp->ifname);
1826 if (wait_ip_addr(dut, grp->ifname, dut->default_timeout) < 0) {
1827 send_resp(dut, conn, SIGMA_ERROR,
1828 "errorCode,No IP address received");
1829 return 0;
1830 }
1831
1832 if (get_ip_config(dut, grp->ifname, info, sizeof(info)) < 0) {
1833 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get IP address "
1834 "for group interface %s",
1835 grp->ifname);
1836 send_resp(dut, conn, SIGMA_ERROR,
1837 "errorCode,Failed to get IP address");
1838 return 0;
1839 }
1840
1841 if (get_wpa_status(grp->ifname, "address",
1842 macaddr, sizeof(macaddr)) < 0) {
1843 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to get interface "
1844 "address for group interface %s",
1845 grp->ifname);
1846 return -2;
1847 }
1848
1849 sigma_dut_print(dut, DUT_MSG_DEBUG, "IP address for group interface "
1850 "%s found", grp->ifname);
1851
1852 snprintf(resp, sizeof(resp), "%s,P2PInterfaceAddress,%s",
1853 info, macaddr);
1854
1855 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1856 return 0;
1857}
1858
1859
1860static int cmd_sta_send_p2p_presence_req(struct sigma_dut *dut,
1861 struct sigma_conn *conn,
1862 struct sigma_cmd *cmd)
1863{
1864 const char *intf = get_param(cmd, "Interface");
1865 const char *dur = get_param(cmd, "Duration");
1866 const char *interv = get_param(cmd, "Interval");
1867 /* const char *grpid = get_param(cmd, "GroupID"); */
1868 const char *ifname;
1869 char buf[100];
1870
1871 if (dur == NULL || interv == NULL)
1872 return -1;
1873
1874 /* TODO: need to add groupid into parameters in CAPI spec; for now,
1875 * pick the first active group */
1876 ifname = get_group_ifname(dut, intf);
1877 snprintf(buf, sizeof(buf), "P2P_PRESENCE_REQ %s %s", dur, interv);
1878 if (wpa_command(ifname, buf) < 0)
1879 return -2;
1880
1881 return 1;
1882}
1883
1884
1885static int cmd_sta_set_sleep(struct sigma_dut *dut, struct sigma_conn *conn,
1886 struct sigma_cmd *cmd)
1887{
1888 /* const char *intf = get_param(cmd, "Interface"); */
1889 struct wfa_cs_p2p_group *grp;
1890 char *ifname;
1891 const char *grpid = get_param(cmd, "GroupID");
1892
Danny Segal0c0b2612016-04-10 17:58:29 +03001893 if (dut->program == PROGRAM_60GHZ) {
1894 send_resp(dut, conn, SIGMA_ERROR,
1895 "errorCode,UAPSD Sleep is not applicable for 60 GHz");
1896 return 0;
1897 }
1898
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001899 if (grpid == NULL)
1900 ifname = get_station_ifname();
1901 else {
1902 grp = p2p_group_get(dut, grpid);
1903 if (grp == NULL) {
1904 send_resp(dut, conn, SIGMA_ERROR,
1905 "errorCode,Requested group not found");
1906 return 0;
1907 }
1908 ifname = grp->ifname;
1909 }
1910
1911 if (dut->client_uapsd) {
1912#ifdef __linux__
1913 /* no special handling for nl80211 yet */
1914 char path[128];
1915 struct stat s;
1916 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211",
1917 ifname);
1918 if (stat(path, &s) == 0) {
1919 if (wpa_command(ifname, "P2P_SET ps 1") < 0) {
1920 send_resp(dut, conn, SIGMA_ERROR,
1921 "errorCode,Going to sleep not supported");
1922 return 0;
1923 }
1924 return 1;
1925 }
1926#endif /* __linux__ */
1927 if (wpa_command(ifname, "P2P_SET ps 99") < 0)
1928 return -2;
1929 } else {
1930 if (wpa_command(ifname, "P2P_SET ps 1") < 0) {
1931 send_resp(dut, conn, SIGMA_ERROR,
1932 "errorCode,Going to sleep not supported");
1933 return 0;
1934 }
1935 }
1936
1937 return 1;
1938}
1939
1940
1941static int cmd_sta_set_opportunistic_ps(struct sigma_dut *dut,
1942 struct sigma_conn *conn,
1943 struct sigma_cmd *cmd)
1944{
1945 /* const char *intf = get_param(cmd, "Interface"); */
1946 struct wfa_cs_p2p_group *grp;
1947 char buf[100];
1948 const char *grpid = get_param(cmd, "GroupID");
1949 const char *ctwindow = get_param(cmd, "CTWindow");
1950
1951 if (grpid == NULL || ctwindow == NULL)
1952 return -1;
1953
1954 grp = p2p_group_get(dut, grpid);
1955 if (grp == NULL) {
1956 send_resp(dut, conn, SIGMA_ERROR,
1957 "errorCode,Requested group not found");
1958 return 0;
1959 }
1960
1961 if (wpa_command(grp->ifname, "P2P_SET oppps 1") < 0) {
1962 send_resp(dut, conn, SIGMA_ERROR,
1963 "errorCode,Use of OppPS as GO not supported");
1964 return 0;
1965 }
1966 snprintf(buf, sizeof(buf), "P2P_SET ctwindow %d", atoi(ctwindow));
1967 if (wpa_command(grp->ifname, buf) < 0) {
1968 send_resp(dut, conn, SIGMA_ERROR,
1969 "errorCode,Use of CTWindow as GO not supported");
1970 return 0;
1971 }
1972
1973 return 1;
1974}
1975
1976
1977static int cmd_sta_send_service_discovery_req(struct sigma_dut *dut,
1978 struct sigma_conn *conn,
1979 struct sigma_cmd *cmd)
1980{
1981 const char *intf = get_param(cmd, "Interface");
1982 const char *devid = get_param(cmd, "P2PDevID");
1983 char buf[128];
1984
1985 if (devid == NULL)
1986 return -1;
1987
1988 snprintf(buf, sizeof(buf), "P2P_SERV_DISC_REQ %s 02000001",
1989 devid);
1990 if (wpa_command(intf, buf) < 0) {
1991 send_resp(dut, conn, SIGMA_ERROR, NULL);
1992 return 0;
1993 }
1994
1995 return 1;
1996}
1997
1998
1999static int cmd_sta_add_arp_table_entry(struct sigma_dut *dut,
2000 struct sigma_conn *conn,
2001 struct sigma_cmd *cmd)
2002{
2003 char buf[256];
2004 char *ifname;
2005 const char *grpid, *ipaddr, *macaddr;
2006
2007 grpid = get_param(cmd, "GroupID");
2008 ipaddr = get_param(cmd, "IPAddress");
2009 macaddr = get_param(cmd, "MACAddress");
2010 if (ipaddr == NULL || macaddr == NULL)
2011 return -1;
2012
2013 if (grpid == NULL)
2014 ifname = get_station_ifname();
2015 else {
2016 struct wfa_cs_p2p_group *grp;
2017 grp = p2p_group_get(dut, grpid);
2018 if (grp == NULL) {
2019 send_resp(dut, conn, SIGMA_ERROR,
2020 "errorCode,Requested group not found");
2021 return 0;
2022 }
2023 ifname = grp->ifname;
2024 }
2025
2026 snprintf(dut->arp_ipaddr, sizeof(dut->arp_ipaddr), "%s",
2027 ipaddr);
2028 snprintf(dut->arp_ifname, sizeof(dut->arp_ifname), "%s",
2029 ifname);
2030
2031 snprintf(buf, sizeof(buf), "ip nei add %s lladdr %s dev %s",
2032 ipaddr, macaddr, ifname);
2033 run_system(dut, buf);
2034
2035 return 1;
2036}
2037
2038
2039static int cmd_sta_block_icmp_response(struct sigma_dut *dut,
2040 struct sigma_conn *conn,
2041 struct sigma_cmd *cmd)
2042{
2043 char buf[256];
2044 struct wfa_cs_p2p_group *grp;
2045 char *ifname;
2046 const char *grpid, *ipaddr;
2047
2048 grpid = get_param(cmd, "GroupID");
2049 ipaddr = get_param(cmd, "IPAddress");
2050 if (ipaddr == NULL)
2051 return -1;
2052
2053 if (grpid == NULL)
2054 ifname = get_station_ifname();
2055 else {
2056 grp = p2p_group_get(dut, grpid);
2057 if (grp == NULL) {
2058 send_resp(dut, conn, SIGMA_ERROR,
2059 "errorCode,Requested group not found");
2060 return 0;
2061 }
2062 ifname = grp->ifname;
2063 }
2064
2065 snprintf(buf, sizeof(buf),
2066 "iptables -I INPUT -s %s -p icmp -i %s -j DROP",
2067 ipaddr, ifname);
2068 run_system(dut, buf);
2069
2070 return 1;
2071}
2072
2073
2074static int run_nfc_command(struct sigma_dut *dut, const char *cmd,
2075 const char *info)
2076{
2077 int res;
2078
2079 sigma_dut_summary(dut, "NFC operation: %s", info);
2080 printf("\n\n\n=====[ NFC operation ]=========================\n\n");
2081 printf("%s\n\n", info);
2082
2083 nfc_status(dut, "START", info);
2084 res = run_system(dut, cmd);
2085 nfc_status(dut, res ? "FAIL" : "SUCCESS", info);
2086 if (res) {
2087 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s': %d",
2088 cmd, res);
2089 return res;
2090 }
2091
2092 return 0;
2093}
2094
2095
2096static int nfc_write_p2p_select(struct sigma_dut *dut, struct sigma_conn *conn,
2097 struct sigma_cmd *cmd)
2098{
2099 int res;
2100 const char *ifname = get_param(cmd, "Interface");
2101 char buf[300];
2102
2103 run_system(dut, "killall wps-nfc.py");
2104 run_system(dut, "killall p2p-nfc.py");
2105
2106 if (wpa_command(ifname, "WPS_NFC_TOKEN NDEF") < 0) {
2107 send_resp(dut, conn, SIGMA_ERROR,
2108 "ErrorCode,Failed to generate NFC password token");
2109 return 0;
2110 }
2111
2112 unlink("nfc-success");
2113 snprintf(buf, sizeof(buf),
2114 "./p2p-nfc.py -1 --no-wait %s%s --success nfc-success write-p2p-sel",
2115 dut->summary_log ? "--summary " : "",
2116 dut->summary_log ? dut->summary_log : "");
2117 res = run_nfc_command(dut, buf,
2118 "Touch NFC Tag to write P2P connection handover select");
2119 if (res || !file_exists("nfc-success")) {
2120 send_resp(dut, conn, SIGMA_ERROR,
2121 "ErrorCode,Failed to write tag");
2122 return 0;
2123 }
2124
2125 if (wpa_command(ifname, "P2P_SET nfc_tag 1") < 0) {
2126 send_resp(dut, conn, SIGMA_ERROR,
2127 "ErrorCode,Failed to enable NFC password token");
2128 return 0;
2129 }
2130
2131 if (!dut->go && wpa_command(ifname, "P2P_LISTEN") < 0) {
2132 send_resp(dut, conn, SIGMA_ERROR,
2133 "ErrorCode,Failed to start listen mode");
2134 return 0;
2135 }
2136
2137 send_resp(dut, conn, SIGMA_COMPLETE,
2138 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2139 return 0;
2140}
2141
2142
2143static int nfc_write_config_token(struct sigma_dut *dut,
2144 struct sigma_conn *conn,
2145 struct sigma_cmd *cmd)
2146{
2147 int res;
2148 const char *bssid = get_param(cmd, "Bssid");
2149 const char *intf = get_param(cmd, "Interface");
2150 char buf[200];
2151
2152 run_system(dut, "killall wps-nfc.py");
2153 run_system(dut, "killall p2p-nfc.py");
2154 unlink("nfc-success");
2155 if (dut->er_oper_performed && bssid) {
2156 char current_bssid[30], id[10];
2157 if (get_wpa_status(intf, "id", id, sizeof(id)) < 0 ||
2158 get_wpa_status(intf, "bssid", current_bssid,
2159 sizeof(current_bssid)) < 0 ||
2160 strncasecmp(bssid, current_bssid, strlen(current_bssid)) !=
2161 0) {
2162 send_resp(dut, conn, SIGMA_ERROR,
2163 "ErrorCode,No configuration known for BSSID");
2164 return 0;
2165 }
2166 snprintf(buf, sizeof(buf),
2167 "./wps-nfc.py --id %s --no-wait %s%s --success nfc-success write-config",
2168 id,
2169 dut->summary_log ? "--summary " : "",
2170 dut->summary_log ? dut->summary_log : "");
2171 res = run_nfc_command(dut, buf,
2172 "Touch NFC Tag to write WPS configuration token");
2173 } else {
2174 snprintf(buf, sizeof(buf),
2175 "./wps-nfc.py --no-wait %s%s --success nfc-success write-config",
2176 dut->summary_log ? "--summary " : "",
2177 dut->summary_log ? dut->summary_log : "");
2178 res = run_nfc_command(dut, buf,
2179 "Touch NFC Tag to write WPS configuration token");
2180 }
2181 if (res || !file_exists("nfc-success")) {
2182 send_resp(dut, conn, SIGMA_ERROR,
2183 "ErrorCode,Failed to write tag");
2184 return 0;
2185 }
2186
2187 send_resp(dut, conn, SIGMA_COMPLETE,
2188 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2189 return 0;
2190}
2191
2192
2193static int nfc_write_password_token(struct sigma_dut *dut,
2194 struct sigma_conn *conn,
2195 struct sigma_cmd *cmd)
2196{
2197 int res;
2198 char buf[300];
2199
2200 run_system(dut, "killall wps-nfc.py");
2201 run_system(dut, "killall p2p-nfc.py");
2202 unlink("nfc-success");
2203 snprintf(buf, sizeof(buf),
2204 "./wps-nfc.py --no-wait %s%s --success nfc-success write-password",
2205 dut->summary_log ? "--summary " : "",
2206 dut->summary_log ? dut->summary_log : "");
2207 res = run_nfc_command(dut, buf,
2208 "Touch NFC Tag to write WPS password token");
2209 if (res || !file_exists("nfc-success")) {
2210 send_resp(dut, conn, SIGMA_ERROR,
2211 "ErrorCode,Failed to write tag");
2212 return 0;
2213 }
2214
2215 send_resp(dut, conn, SIGMA_COMPLETE,
2216 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2217 return 0;
2218}
2219
2220
2221static int nfc_read_tag(struct sigma_dut *dut,
2222 struct sigma_conn *conn,
2223 struct sigma_cmd *cmd)
2224{
2225 int res;
2226 struct wpa_ctrl *ctrl;
2227 const char *intf = get_param(cmd, "Interface");
2228 const char *oper_chn = get_param(cmd, "OPER_CHN");
2229 char buf[1000], freq_str[20];
2230
2231 run_system(dut, "killall wps-nfc.py");
2232 run_system(dut, "killall p2p-nfc.py");
2233
2234 ctrl = open_wpa_mon(intf);
2235 if (ctrl == NULL) {
2236 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2237 "wpa_supplicant monitor connection");
2238 return -2;
2239 }
2240
2241 freq_str[0] = '\0';
2242 if (oper_chn) {
2243 int chan = atoi(oper_chn);
2244 if (chan >= 1 && chan <= 11)
2245 snprintf(freq_str, sizeof(freq_str), " --freq %d",
2246 2407 + chan * 5);
2247 }
2248
2249 unlink("nfc-success");
2250 snprintf(buf, sizeof(buf),
2251 "./p2p-nfc.py -1 -t %s%s --success nfc-success --no-wait%s",
2252 dut->summary_log ? "--summary " : "",
2253 dut->summary_log ? dut->summary_log : "",
2254 freq_str);
2255 res = run_nfc_command(dut, buf,
2256 "Touch NFC Tag to read it");
2257 if (res || !file_exists("nfc-success")) {
2258 send_resp(dut, conn, SIGMA_ERROR,
2259 "ErrorCode,Failed to read tag");
2260 wpa_ctrl_detach(ctrl);
2261 wpa_ctrl_close(ctrl);
2262 return 0;
2263 }
2264
2265 if (dut->p2p_mode == P2P_DISABLE)
2266 return wps_connection_event(dut, conn, ctrl, intf, 1);
2267
2268 if (dut->go || dut->p2p_client) {
2269 wpa_ctrl_detach(ctrl);
2270 wpa_ctrl_close(ctrl);
2271 send_resp(dut, conn, SIGMA_COMPLETE,
2272 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2273 return 0;
2274 }
2275
2276 /* FIX: PeerRole */
2277 return p2p_group_formation_event(dut, conn, ctrl, intf, "0", 1);
2278}
2279
2280
2281static int nfc_wps_read_tag(struct sigma_dut *dut,
2282 struct sigma_conn *conn,
2283 struct sigma_cmd *cmd)
2284{
2285 int res;
2286 struct wpa_ctrl *ctrl;
2287 const char *intf = get_param(cmd, "Interface");
2288 char buf[300];
2289
2290 run_system(dut, "killall wps-nfc.py");
2291 run_system(dut, "killall p2p-nfc.py");
2292
2293 ctrl = open_wpa_mon(intf);
2294 if (ctrl == NULL) {
2295 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2296 "wpa_supplicant monitor connection");
2297 return -2;
2298 }
2299
2300 unlink("nfc-success");
2301 snprintf(buf, sizeof(buf),
2302 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success",
2303 dut->summary_log ? "--summary " : "",
2304 dut->summary_log ? dut->summary_log : "");
2305 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
2306 if (res || !file_exists("nfc-success")) {
2307 send_resp(dut, conn, SIGMA_ERROR,
2308 "ErrorCode,Failed to read tag");
2309 wpa_ctrl_detach(ctrl);
2310 wpa_ctrl_close(ctrl);
2311 return 0;
2312 }
2313
2314 return wps_connection_event(dut, conn, ctrl, intf, 1);
2315}
2316
2317
2318static int er_ap_add_match(const char *event, const char *bssid,
2319 const char *req_uuid,
2320 char *ret_uuid, size_t max_uuid_len)
2321{
2322 const char *pos, *uuid;
2323
2324 pos = strchr(event, ' ');
2325 if (pos == NULL)
2326 return 0;
2327 pos++;
2328 uuid = pos;
2329
2330 pos = strchr(pos, ' ');
2331 if (pos == NULL)
2332 return 0;
2333 if (ret_uuid) {
2334 if ((size_t) (pos - uuid + 1) < max_uuid_len) {
2335 memcpy(ret_uuid, uuid, pos - uuid);
2336 ret_uuid[pos - uuid] = '\0';
2337 } else
2338 ret_uuid[0] = '\0';
2339 }
2340
2341 if (req_uuid && strncasecmp(req_uuid, uuid, pos - uuid) == 0)
2342 return 1;
2343
2344 pos++;
2345 /* at BSSID */
2346
2347 return strncasecmp(pos, bssid, strlen(bssid)) == 0;
2348}
2349
2350
2351static int er_start(struct sigma_dut *dut, struct sigma_conn *conn,
2352 struct wpa_ctrl *ctrl, const char *intf, const char *bssid,
2353 const char *uuid, char *ret_uuid, size_t max_uuid_len)
2354{
2355 char id[10];
2356 int res;
2357 char buf[1000];
2358
2359 sigma_dut_print(dut, DUT_MSG_INFO, "Trying to find WPS AP %s over UPnP",
2360 bssid);
2361
2362 if (wpa_command(intf, "WPS_ER_START") < 0) {
2363 send_resp(dut, conn, SIGMA_ERROR,
2364 "ErrorCode,Failed to start ER");
2365 return 0;
2366 }
2367
2368 for (;;) {
2369 res = get_wpa_cli_event(dut, ctrl, "WPS-ER-AP-ADD",
2370 buf, sizeof(buf));
2371 if (res < 0) {
2372#ifdef USE_ERROR_RETURNS
2373 send_resp(dut, conn, SIGMA_ERROR,
2374 "ErrorCode,Could not find the AP over UPnP");
2375#else
2376 send_resp(dut, conn, SIGMA_COMPLETE,
2377 "ErrorCode,Could not find the AP over UPnP");
2378#endif
2379 return 0;
2380 }
2381
2382 if (er_ap_add_match(buf, bssid, uuid, ret_uuid, max_uuid_len)) {
2383 sigma_dut_print(dut, DUT_MSG_INFO,
2384 "Found WPS AP over UPnP: %s", buf);
2385 break;
2386 }
2387 }
2388
2389 if (get_wpa_status(intf, "id", id, sizeof(id)) < 0) {
2390 send_resp(dut, conn, SIGMA_ERROR,
2391 "ErrorCode,Could not find AP configuration");
2392 return 0;
2393 }
2394
2395 if (ret_uuid) {
2396 snprintf(buf, sizeof(buf), "WPS_ER_SET_CONFIG %s %s",
2397 ret_uuid, id);
2398 } else if (uuid) {
2399 snprintf(buf, sizeof(buf), "WPS_ER_SET_CONFIG %s %s",
2400 uuid, id);
2401 } else {
2402 snprintf(buf, sizeof(buf), "WPS_ER_SET_CONFIG %s %s",
2403 bssid, id);
2404 }
2405 if (wpa_command(intf, buf) < 0) {
2406 send_resp(dut, conn, SIGMA_ERROR,
2407 "ErrorCode,Failed to select network configuration for ER");
2408 return 0;
2409 }
2410
2411 return 1;
2412}
2413
2414
2415static int nfc_wps_read_passwd(struct sigma_dut *dut,
2416 struct sigma_conn *conn,
2417 struct sigma_cmd *cmd)
2418{
2419 int res;
2420 struct wpa_ctrl *ctrl;
2421 const char *intf = get_param(cmd, "Interface");
2422 const char *bssid = get_param(cmd, "Bssid");
2423 const char *ssid = get_param(cmd, "SSID");
2424 const char *security = get_param(cmd, "Security");
2425 const char *passphrase = get_param(cmd, "Passphrase");
2426 char ssid_hex[200], passphrase_hex[200];
2427 const char *val;
2428 int sta_action;
2429 char buf[1000];
2430 const char *keymgmt, *cipher;
2431
2432 run_system(dut, "killall wps-nfc.py");
2433 run_system(dut, "killall p2p-nfc.py");
2434
2435 if ((ssid && strlen(ssid) >= 2 * sizeof(ssid_hex)) ||
2436 (passphrase && strlen(passphrase) >= 2 * sizeof(passphrase_hex))) {
2437 send_resp(dut, conn, SIGMA_ERROR,
2438 "ErrorCode,Too long SSID/passphrase");
2439 return 0;
2440 }
2441
2442 val = get_param(cmd, "WpsStaAction");
2443 if (!val) {
2444 send_resp(dut, conn, SIGMA_ERROR,
2445 "ErrorCode,Missing WpsStaAction argument");
2446 return 0;
2447 }
2448
2449 sta_action = atoi(val);
2450 if (sta_action != 1 && sta_action != 2) {
2451 send_resp(dut, conn, SIGMA_ERROR,
2452 "ErrorCode,Unsupported WpsStaAction value");
2453 return 0;
2454 }
2455
2456 if (!bssid) {
2457 send_resp(dut, conn, SIGMA_ERROR,
2458 "ErrorCode,Missing Bssid argument");
2459 return 0;
2460 }
2461
2462 if (sta_action == 2) {
2463 if (!ssid) {
2464 send_resp(dut, conn, SIGMA_ERROR,
2465 "ErrorCode,Missing SSID argument");
2466 return 0;
2467 }
2468
2469 if (!security) {
2470 send_resp(dut, conn, SIGMA_ERROR,
2471 "ErrorCode,Missing Security argument");
2472 return 0;
2473 }
2474
2475 if (!passphrase) {
2476 send_resp(dut, conn, SIGMA_ERROR,
2477 "ErrorCode,Missing Passphrase argument");
2478 return 0;
2479 }
2480 }
2481
2482 ctrl = open_wpa_mon(intf);
2483 if (ctrl == NULL) {
2484 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2485 "wpa_supplicant monitor connection");
2486 return -2;
2487 }
2488
2489 if (sta_action == 1) {
2490 const char *uuid = get_param(cmd, "UUID");
2491 res = er_start(dut, conn, ctrl, intf, bssid, uuid, NULL, 0);
2492 if (res != 1) {
2493 wpa_ctrl_detach(ctrl);
2494 wpa_ctrl_close(ctrl);
2495 return res;
2496 }
2497 }
2498
2499 unlink("nfc-success");
2500 snprintf(buf, sizeof(buf),
2501 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success",
2502 dut->summary_log ? "--summary " : "",
2503 dut->summary_log ? dut->summary_log : "");
2504 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
2505 if (res || !file_exists("nfc-success")) {
2506 wpa_ctrl_detach(ctrl);
2507 wpa_ctrl_close(ctrl);
2508 send_resp(dut, conn, SIGMA_ERROR,
2509 "ErrorCode,Failed to read tag");
2510 return 0;
2511 }
2512
2513 if (sta_action == 1) {
2514 sigma_dut_print(dut, DUT_MSG_INFO, "Prepared device password for ER to enroll a new station");
2515 wpa_ctrl_detach(ctrl);
2516 wpa_ctrl_close(ctrl);
2517 send_resp(dut, conn, SIGMA_COMPLETE,
2518 "Result,,GroupID,,PeerRole,");
2519 return 0;
2520 }
2521 if (strcasecmp(security, "wpa2-psk") == 0) {
2522 keymgmt = "WPA2PSK";
2523 cipher = "CCMP";
2524 } else {
2525 wpa_ctrl_detach(ctrl);
2526 wpa_ctrl_close(ctrl);
2527 send_resp(dut, conn, SIGMA_ERROR,
2528 "ErrorCode,Unsupported Security value");
2529 return 0;
2530 }
2531
2532 ascii2hexstr(ssid, ssid_hex);
2533 ascii2hexstr(passphrase, passphrase_hex);
2534 snprintf(buf, sizeof(buf), "WPS_REG %s nfc-pw %s %s %s %s",
2535 bssid, ssid_hex, keymgmt, cipher, passphrase_hex);
2536
2537 if (wpa_command(intf, buf) < 0) {
2538 wpa_ctrl_detach(ctrl);
2539 wpa_ctrl_close(ctrl);
2540 send_resp(dut, conn, SIGMA_ERROR,
2541 "ErrorCode,Failed to start registrar");
2542 return 0;
2543 }
2544
2545 return wps_connection_event(dut, conn, ctrl, intf, 1);
2546}
2547
2548
2549static int nfc_wps_read_config(struct sigma_dut *dut,
2550 struct sigma_conn *conn,
2551 struct sigma_cmd *cmd)
2552{
2553 int res;
2554 struct wpa_ctrl *ctrl;
2555 const char *intf = get_param(cmd, "Interface");
2556 char buf[300];
2557
2558 run_system(dut, "killall wps-nfc.py");
2559 run_system(dut, "killall p2p-nfc.py");
2560
2561 ctrl = open_wpa_mon(intf);
2562 if (ctrl == NULL) {
2563 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2564 "wpa_supplicant monitor connection");
2565 return -2;
2566 }
2567
2568 unlink("nfc-success");
2569 snprintf(buf, sizeof(buf),
2570 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success",
2571 dut->summary_log ? "--summary " : "",
2572 dut->summary_log ? dut->summary_log : "");
2573 res = run_nfc_command(dut, buf, "Touch NFC Tag to read it");
2574 if (res || !file_exists("nfc-success")) {
2575 send_resp(dut, conn, SIGMA_ERROR,
2576 "ErrorCode,Failed to read tag");
2577 wpa_ctrl_detach(ctrl);
2578 wpa_ctrl_close(ctrl);
2579 return 0;
2580 }
2581
2582 return wps_connection_event(dut, conn, ctrl, intf, 1);
2583}
2584
2585
2586static int nfc_wps_connection_handover(struct sigma_dut *dut,
2587 struct sigma_conn *conn,
2588 struct sigma_cmd *cmd)
2589{
2590 const char *intf = get_param(cmd, "Interface");
2591 int res;
2592 const char *init = get_param(cmd, "Init");
2593 struct wpa_ctrl *ctrl = NULL;
2594 char buf[300];
2595
2596 run_system(dut, "killall wps-nfc.py");
2597 run_system(dut, "killall p2p-nfc.py");
2598
2599 ctrl = open_wpa_mon(intf);
2600 if (ctrl == NULL) {
2601 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2602 "wpa_supplicant monitor connection");
2603 return -2;
2604 }
2605
2606 unlink("nfc-success");
2607 if ((!init || atoi(init) == 0) && dut->er_oper_performed) {
2608 const char *bssid = get_param(cmd, "Bssid");
2609 const char *req_uuid = get_param(cmd, "UUID");
2610 char uuid[100];
2611
2612 if (bssid == NULL)
2613 bssid = dut->er_oper_bssid;
2614
2615 res = er_start(dut, conn, ctrl, intf, bssid, req_uuid, uuid,
2616 sizeof(uuid));
2617 if (res != 1) {
2618 wpa_ctrl_detach(ctrl);
2619 wpa_ctrl_close(ctrl);
2620 return res;
2621 }
2622
2623 snprintf(buf, sizeof(buf),
2624 "./wps-nfc.py -1 --uuid %s %s%s --success nfc-success",
2625 uuid,
2626 dut->summary_log ? "--summary " : "",
2627 dut->summary_log ? dut->summary_log : "");
2628 res = run_nfc_command(dut, buf,
2629 "Touch NFC Device to respond to WPS connection handover");
2630 } else if (!init || atoi(init)) {
2631 snprintf(buf, sizeof(buf),
2632 "./wps-nfc.py -1 --no-wait %s%s --success nfc-success",
2633 dut->summary_log ? "--summary " : "",
2634 dut->summary_log ? dut->summary_log : "");
2635 res = run_nfc_command(dut, buf,
2636 "Touch NFC Device to initiate WPS connection handover");
2637 } else {
2638 snprintf(buf, sizeof(buf),
2639 "./p2p-nfc.py -1 --no-wait --no-input %s%s --success nfc-success --handover-only",
2640 dut->summary_log ? "--summary " : "",
2641 dut->summary_log ? dut->summary_log : "");
2642 res = run_nfc_command(dut, buf,
2643 "Touch NFC Device to respond to WPS connection handover");
2644 }
2645 if (res) {
2646 wpa_ctrl_detach(ctrl);
2647 wpa_ctrl_close(ctrl);
2648 send_resp(dut, conn, SIGMA_ERROR,
2649 "ErrorCode,Failed to enable NFC for connection "
2650 "handover");
2651 return 0;
2652 }
2653 if (!file_exists("nfc-success")) {
2654 wpa_ctrl_detach(ctrl);
2655 wpa_ctrl_close(ctrl);
2656 send_resp(dut, conn, SIGMA_ERROR,
2657 "ErrorCode,Failed to complete NFC connection handover");
2658 return 0;
2659 }
2660
2661 if (init && atoi(init))
2662 return wps_connection_event(dut, conn, ctrl, intf, 1);
2663
2664 wpa_ctrl_detach(ctrl);
2665 wpa_ctrl_close(ctrl);
2666
2667 send_resp(dut, conn, SIGMA_COMPLETE,
2668 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2669 return 0;
2670}
2671
2672
2673static int nfc_p2p_connection_handover(struct sigma_dut *dut,
2674 struct sigma_conn *conn,
2675 struct sigma_cmd *cmd)
2676{
2677 const char *intf = get_param(cmd, "Interface");
2678 int res;
2679 const char *init = get_param(cmd, "Init");
2680 const char *oper_chn = get_param(cmd, "OPER_CHN");
2681 struct wpa_ctrl *ctrl;
2682 char buf[1000], freq_str[20];
2683
2684 run_system(dut, "killall wps-nfc.py");
2685 run_system(dut, "killall p2p-nfc.py");
2686
2687 ctrl = open_wpa_mon(intf);
2688 if (ctrl == NULL) {
2689 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
2690 "wpa_supplicant monitor connection");
2691 return -2;
2692 }
2693
2694 freq_str[0] = '\0';
2695 if (oper_chn) {
2696 int chan = atoi(oper_chn);
2697 if (chan >= 1 && chan <= 11)
2698 snprintf(freq_str, sizeof(freq_str), " --freq %d",
2699 2407 + chan * 5);
2700 }
2701
2702 unlink("nfc-success");
2703 if (init && atoi(init)) {
2704 snprintf(buf, sizeof(buf),
2705 "./p2p-nfc.py -1 -I -N --no-wait %s%s --success nfc-success --no-input%s --handover-only",
2706 dut->summary_log ? "--summary " : "",
2707 dut->summary_log ? dut->summary_log : "",
2708 freq_str);
2709 res = run_nfc_command(dut, buf,
2710 "Touch NFC Device to initiate P2P connection handover");
2711 } else {
2712 snprintf(buf, sizeof(buf),
2713 "./p2p-nfc.py -1 --no-wait %s%s --success nfc-success --no-input%s --handover-only",
2714 dut->summary_log ? "--summary " : "",
2715 dut->summary_log ? dut->summary_log : "",
2716 freq_str);
2717 res = run_nfc_command(dut, buf,
2718 "Touch NFC Device to respond to P2P connection handover");
2719 }
2720 if (res) {
2721 wpa_ctrl_detach(ctrl);
2722 wpa_ctrl_close(ctrl);
2723 send_resp(dut, conn, SIGMA_ERROR,
2724 "ErrorCode,Failed to enable NFC for connection "
2725 "handover");
2726 return 0;
2727 }
2728 if (!file_exists("nfc-success")) {
2729 wpa_ctrl_detach(ctrl);
2730 wpa_ctrl_close(ctrl);
2731 send_resp(dut, conn, SIGMA_ERROR,
2732 "ErrorCode,Failed to complete NFC connection handover");
2733 return 0;
2734 }
2735
2736 if (dut->go || dut->p2p_client) {
2737 wpa_ctrl_detach(ctrl);
2738 wpa_ctrl_close(ctrl);
2739 send_resp(dut, conn, SIGMA_COMPLETE,
2740 "Result,,GroupID,,PeerRole,,PauseFlag,0");
2741 return 0;
2742 }
2743
2744 /* FIX: peer role from handover message */
2745 return p2p_group_formation_event(dut, conn, ctrl, intf, "0", 1);
2746}
2747
2748
2749static int cmd_sta_nfc_action(struct sigma_dut *dut, struct sigma_conn *conn,
2750 struct sigma_cmd *cmd)
2751{
2752 const char *intf = get_param(cmd, "Interface");
2753 const char *oper = get_param(cmd, "Operation");
2754 const char *ssid_param = get_param(cmd, "SSID");
2755 const char *intent_val = get_param(cmd, "INTENT_VAL");
2756 const char *oper_chn = get_param(cmd, "OPER_CHN");
2757 char buf[256];
2758
2759 if (oper == NULL)
2760 return -1;
2761
2762 if (ssid_param)
2763 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix %s",
2764 ssid_param);
2765 else
2766 snprintf(buf, sizeof(buf), "P2P_SET ssid_postfix ");
2767 if (wpa_command(intf, buf) < 0)
2768 sigma_dut_print(dut, DUT_MSG_INFO, "Failed P2P ssid_postfix - ignore and assume this is for non-P2P case");
2769
2770 if (intent_val) {
2771 snprintf(buf, sizeof(buf), "SET p2p_go_intent %s", intent_val);
2772 if (wpa_command(intf, buf) < 0)
2773 return -2;
2774 }
2775
2776 if (oper_chn) {
2777 int chan = atoi(oper_chn);
2778 if (chan < 1 || chan > 11) {
2779 send_resp(dut, conn, SIGMA_ERROR,
2780 "ErrorCode,Unsupported operating channel");
2781 return 0;
2782 }
2783 snprintf(buf, sizeof(buf), "SET p2p_oper_channel %d", chan);
2784 if (wpa_command(intf, "SET p2p_oper_reg_class 81") < 0 ||
2785 wpa_command(intf, buf) < 0) {
2786 send_resp(dut, conn, SIGMA_ERROR,
2787 "ErrorCode,Failed to set operating channel");
2788 return 0;
2789 }
2790 }
2791
2792 if (strcasecmp(oper, "WRITE_SELECT") == 0)
2793 return nfc_write_p2p_select(dut, conn, cmd);
2794 if (strcasecmp(oper, "WRITE_CONFIG") == 0)
2795 return nfc_write_config_token(dut, conn, cmd);
2796 if (strcasecmp(oper, "WRITE_PASSWD") == 0)
2797 return nfc_write_password_token(dut, conn, cmd);
2798 if (strcasecmp(oper, "READ_TAG") == 0)
2799 return nfc_read_tag(dut, conn, cmd);
2800 if (strcasecmp(oper, "WPS_READ_TAG") == 0)
2801 return nfc_wps_read_tag(dut, conn, cmd);
2802 if (strcasecmp(oper, "WPS_READ_PASSWD") == 0)
2803 return nfc_wps_read_passwd(dut, conn, cmd);
2804 if (strcasecmp(oper, "WPS_READ_CONFIG") == 0)
2805 return nfc_wps_read_config(dut, conn, cmd);
2806 if (strcasecmp(oper, "CONN_HNDOVR") == 0)
2807 return nfc_p2p_connection_handover(dut, conn, cmd);
2808 if (strcasecmp(oper, "WPS_CONN_HNDOVR") == 0)
2809 return nfc_wps_connection_handover(dut, conn, cmd);
2810
2811 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported operation");
2812 return 0;
2813}
2814
2815
2816int p2p_cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
2817 struct sigma_cmd *cmd)
2818{
2819 const char *parameter = get_param(cmd, "Parameter");
2820 char buf[100];
2821
2822 if (parameter == NULL)
2823 return -1;
2824 if (strcasecmp(parameter, "ListenChannel") == 0) {
2825 snprintf(buf, sizeof(buf), "ListenChnl,%u", dut->listen_chn);
2826 send_resp(dut, conn, SIGMA_COMPLETE, buf);
2827 return 0;
2828 }
2829
2830 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
2831 return 0;
2832}
2833
2834
2835static int req_intf(struct sigma_cmd *cmd)
2836{
2837 return get_param(cmd, "interface") == NULL ? -1 : 0;
2838}
2839
2840
2841void p2p_register_cmds(void)
2842{
2843 sigma_dut_reg_cmd("sta_get_p2p_dev_address", req_intf,
2844 cmd_sta_get_p2p_dev_address);
2845 sigma_dut_reg_cmd("sta_set_p2p", req_intf, cmd_sta_set_p2p);
2846 sigma_dut_reg_cmd("sta_start_autonomous_go", req_intf,
2847 cmd_sta_start_autonomous_go);
2848 sigma_dut_reg_cmd("sta_p2p_connect", req_intf, cmd_sta_p2p_connect);
2849 sigma_dut_reg_cmd("sta_p2p_start_group_formation", req_intf,
2850 cmd_sta_p2p_start_group_formation);
2851 sigma_dut_reg_cmd("sta_p2p_dissolve", req_intf, cmd_sta_p2p_dissolve);
2852 sigma_dut_reg_cmd("sta_send_p2p_invitation_req", req_intf,
2853 cmd_sta_send_p2p_invitation_req);
2854 sigma_dut_reg_cmd("sta_accept_p2p_invitation_req", req_intf,
2855 cmd_sta_accept_p2p_invitation_req);
2856 sigma_dut_reg_cmd("sta_send_p2p_provision_dis_req", req_intf,
2857 cmd_sta_send_p2p_provision_dis_req);
2858 sigma_dut_reg_cmd("sta_set_wps_pbc", req_intf, cmd_sta_set_wps_pbc);
2859 sigma_dut_reg_cmd("sta_wps_read_pin", req_intf, cmd_sta_wps_read_pin);
2860 sigma_dut_reg_cmd("sta_wps_read_label", req_intf,
2861 cmd_sta_wps_read_label);
2862 sigma_dut_reg_cmd("sta_wps_enter_pin", req_intf,
2863 cmd_sta_wps_enter_pin);
2864 sigma_dut_reg_cmd("sta_get_psk", req_intf, cmd_sta_get_psk);
2865 sigma_dut_reg_cmd("sta_p2p_reset", req_intf, cmd_sta_p2p_reset);
2866 sigma_dut_reg_cmd("sta_get_p2p_ip_config", req_intf,
2867 cmd_sta_get_p2p_ip_config);
2868 sigma_dut_reg_cmd("sta_send_p2p_presence_req", req_intf,
2869 cmd_sta_send_p2p_presence_req);
2870 sigma_dut_reg_cmd("sta_set_sleep", req_intf, cmd_sta_set_sleep);
2871 sigma_dut_reg_cmd("sta_set_opportunistic_ps", req_intf,
2872 cmd_sta_set_opportunistic_ps);
2873 sigma_dut_reg_cmd("sta_send_service_discovery_req", req_intf,
2874 cmd_sta_send_service_discovery_req);
2875 sigma_dut_reg_cmd("sta_add_arp_table_entry", req_intf,
2876 cmd_sta_add_arp_table_entry);
2877 sigma_dut_reg_cmd("sta_block_icmp_response", req_intf,
2878 cmd_sta_block_icmp_response);
2879 sigma_dut_reg_cmd("sta_nfc_action", req_intf, cmd_sta_nfc_action);
2880}