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