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