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