xref: /wlan-dirver/utils/sigma-dut/wpa_helpers.c (revision c9bc15d17a819fcb399b5df722c4227d26799eb3)
1cd4e3c3eSJouni Malinen /*
2cd4e3c3eSJouni Malinen  * Sigma Control API DUT (station/AP)
3cd4e3c3eSJouni Malinen  * Copyright (c) 2010-2011, Atheros Communications, Inc.
49d7e31d5SJouni Malinen  * Copyright (c) 2011-2014, 2016, Qualcomm Atheros, Inc.
5c86d8021SKiran Kumar Lokere  * Copyright (c) 2018, The Linux Foundation
6cd4e3c3eSJouni Malinen  * All Rights Reserved.
7cd4e3c3eSJouni Malinen  * Licensed under the Clear BSD license. See README for more details.
8cd4e3c3eSJouni Malinen  */
9cd4e3c3eSJouni Malinen 
10cd4e3c3eSJouni Malinen #include "sigma_dut.h"
11cd4e3c3eSJouni Malinen #include <sys/stat.h>
12cd4e3c3eSJouni Malinen #include "wpa_ctrl.h"
13cd4e3c3eSJouni Malinen #include "wpa_helpers.h"
14cd4e3c3eSJouni Malinen 
15cd4e3c3eSJouni Malinen 
1652ec2363SAlexei Avshalom Lazar #define DEFAULT_HAPD_CTRL_PATH "/var/run/hostapd/"
1752ec2363SAlexei Avshalom Lazar 
18cd4e3c3eSJouni Malinen extern char *sigma_wpas_ctrl;
19525dbfd1SRajiv Ranjan extern char *client_socket_path;
2052ec2363SAlexei Avshalom Lazar extern char *sigma_hapd_ctrl;
21cd4e3c3eSJouni Malinen 
22cd4e3c3eSJouni Malinen 
get_main_ifname(struct sigma_dut * dut)23016ae6c8SJouni Malinen const char * get_main_ifname(struct sigma_dut *dut)
24cd4e3c3eSJouni Malinen {
25016ae6c8SJouni Malinen 	enum driver_type drv = get_driver_type(dut);
26cd4e3c3eSJouni Malinen 	enum openwrt_driver_type openwrt_drv = get_openwrt_driver_type();
27cd4e3c3eSJouni Malinen 
28b21f0542SJouni Malinen 	if (dut->main_ifname) {
29b21f0542SJouni Malinen 		if (dut->use_5g && dut->main_ifname_5g)
30b21f0542SJouni Malinen 			return dut->main_ifname_5g;
31b21f0542SJouni Malinen 		if (!dut->use_5g && dut->main_ifname_2g)
32b21f0542SJouni Malinen 			return dut->main_ifname_2g;
33d2095485SJouni Malinen 		return dut->main_ifname;
34b21f0542SJouni Malinen 	}
35cd4e3c3eSJouni Malinen 
3696c347d6SRajesh Babu Sarvepalli 	if (drv == DRIVER_ATHEROS || openwrt_drv == OPENWRT_DRIVER_ATHEROS) {
3796c347d6SRajesh Babu Sarvepalli 		if (if_nametoindex("ath2") > 0)
3896c347d6SRajesh Babu Sarvepalli 			return "ath2";
3996c347d6SRajesh Babu Sarvepalli 		else if (if_nametoindex("ath1") > 0)
4096c347d6SRajesh Babu Sarvepalli 			return "ath1";
4196c347d6SRajesh Babu Sarvepalli 		else
4296c347d6SRajesh Babu Sarvepalli 			return "ath0";
4396c347d6SRajesh Babu Sarvepalli 	}
4496c347d6SRajesh Babu Sarvepalli 
45cd4e3c3eSJouni Malinen 	if (if_nametoindex("p2p0") > 0)
46cd4e3c3eSJouni Malinen 		return "p2p0";
47cd4e3c3eSJouni Malinen 	if (if_nametoindex("wlan1") > 0) {
48cd4e3c3eSJouni Malinen 		struct stat s;
49cd4e3c3eSJouni Malinen 		if (stat("/sys/module/mac80211", &s) == 0 &&
50cd4e3c3eSJouni Malinen 		    if_nametoindex("wlan0")) {
51cd4e3c3eSJouni Malinen 			/*
52cd4e3c3eSJouni Malinen 			 * Likely a dual-radio AP device; use wlan0 for STA/P2P
53cd4e3c3eSJouni Malinen 			 * operations.
54cd4e3c3eSJouni Malinen 			 */
55cd4e3c3eSJouni Malinen 			return "wlan0";
56cd4e3c3eSJouni Malinen 		}
57cd4e3c3eSJouni Malinen 		return "wlan1";
58cd4e3c3eSJouni Malinen 	}
59cd4e3c3eSJouni Malinen 	if (if_nametoindex("wlan0") > 0)
60cd4e3c3eSJouni Malinen 		return "wlan0";
61cd4e3c3eSJouni Malinen 
62cd4e3c3eSJouni Malinen 	return "unknown";
63cd4e3c3eSJouni Malinen }
64cd4e3c3eSJouni Malinen 
65cd4e3c3eSJouni Malinen 
get_station_ifname(struct sigma_dut * dut)66016ae6c8SJouni Malinen const char * get_station_ifname(struct sigma_dut *dut)
67cd4e3c3eSJouni Malinen {
68b21f0542SJouni Malinen 	if (dut->station_ifname) {
69b21f0542SJouni Malinen 		if (dut->use_5g && dut->station_ifname_5g)
70b21f0542SJouni Malinen 			return dut->station_ifname_5g;
71b21f0542SJouni Malinen 		if (!dut->use_5g && dut->station_ifname_2g)
72b21f0542SJouni Malinen 			return dut->station_ifname_2g;
73d2095485SJouni Malinen 		return dut->station_ifname;
74b21f0542SJouni Malinen 	}
75cd4e3c3eSJouni Malinen 
76cd4e3c3eSJouni Malinen 	/*
77cd4e3c3eSJouni Malinen 	 * If we have both wlan0 and wlan1, assume the first one is the station
78cd4e3c3eSJouni Malinen 	 * interface.
79cd4e3c3eSJouni Malinen 	 */
80cd4e3c3eSJouni Malinen 	if (if_nametoindex("wlan1") > 0 && if_nametoindex("wlan0") > 0)
81cd4e3c3eSJouni Malinen 		return "wlan0";
82cd4e3c3eSJouni Malinen 
83cd4e3c3eSJouni Malinen 	if (if_nametoindex("ath0") > 0)
84cd4e3c3eSJouni Malinen 		return "ath0";
85cd4e3c3eSJouni Malinen 
86cd4e3c3eSJouni Malinen 	/* If nothing else matches, hope for best and guess.. */
87cd4e3c3eSJouni Malinen 	return "wlan0";
88cd4e3c3eSJouni Malinen }
89cd4e3c3eSJouni Malinen 
90cd4e3c3eSJouni Malinen 
get_p2p_ifname(struct sigma_dut * dut,const char * primary_ifname)91016ae6c8SJouni Malinen const char * get_p2p_ifname(struct sigma_dut *dut, const char *primary_ifname)
92f2af39bfSDanny Segal {
93016ae6c8SJouni Malinen 	if (strcmp(get_station_ifname(dut), primary_ifname) != 0)
94f2af39bfSDanny Segal 		return primary_ifname;
95f2af39bfSDanny Segal 
961f76fa6dSJouni Malinen 	if (dut->p2p_ifname)
971f76fa6dSJouni Malinen 		return dut->p2p_ifname;
98f2af39bfSDanny Segal 
99016ae6c8SJouni Malinen 	return get_station_ifname(dut);
100f2af39bfSDanny Segal }
101f2af39bfSDanny Segal 
102f2af39bfSDanny Segal 
dut_ifc_reset(struct sigma_dut * dut)103cd4e3c3eSJouni Malinen void dut_ifc_reset(struct sigma_dut *dut)
104cd4e3c3eSJouni Malinen {
105cd4e3c3eSJouni Malinen 	char buf[256];
106016ae6c8SJouni Malinen 	const char *ifc = get_station_ifname(dut);
107cd4e3c3eSJouni Malinen 
108cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "ifconfig %s down", ifc);
109cd4e3c3eSJouni Malinen 	run_system(dut, buf);
110cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "ifconfig %s up", ifc);
111cd4e3c3eSJouni Malinen 	run_system(dut, buf);
112cd4e3c3eSJouni Malinen }
113cd4e3c3eSJouni Malinen 
114cd4e3c3eSJouni Malinen 
wpa_ctrl_command(const char * path,const char * ifname,const char * cmd)11552ec2363SAlexei Avshalom Lazar int wpa_ctrl_command(const char *path, const char *ifname, const char *cmd)
116cd4e3c3eSJouni Malinen {
117cd4e3c3eSJouni Malinen 	struct wpa_ctrl *ctrl;
118cd4e3c3eSJouni Malinen 	char buf[128];
119cd4e3c3eSJouni Malinen 	size_t len;
120cd4e3c3eSJouni Malinen 
12152ec2363SAlexei Avshalom Lazar 	snprintf(buf, sizeof(buf), "%s%s", path, ifname);
122525dbfd1SRajiv Ranjan 	ctrl = wpa_ctrl_open2(buf, client_socket_path);
123cd4e3c3eSJouni Malinen 	if (ctrl == NULL) {
124525dbfd1SRajiv Ranjan 		printf("wpa_command: wpa_ctrl_open2(%s) failed\n", buf);
125cd4e3c3eSJouni Malinen 		return -1;
126cd4e3c3eSJouni Malinen 	}
127cd4e3c3eSJouni Malinen 	len = sizeof(buf);
128cd4e3c3eSJouni Malinen 	if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
129cd4e3c3eSJouni Malinen 		printf("wpa_command: wpa_ctrl_request failed\n");
130cd4e3c3eSJouni Malinen 		wpa_ctrl_close(ctrl);
131cd4e3c3eSJouni Malinen 		return -1;
132cd4e3c3eSJouni Malinen 	}
133cd4e3c3eSJouni Malinen 	wpa_ctrl_close(ctrl);
134cd4e3c3eSJouni Malinen 	buf[len] = '\0';
135cd4e3c3eSJouni Malinen 	if (strncmp(buf, "FAIL", 4) == 0) {
136cd4e3c3eSJouni Malinen 		printf("wpa_command: Command failed (FAIL received)\n");
137cd4e3c3eSJouni Malinen 		return -1;
138cd4e3c3eSJouni Malinen 	}
139cd4e3c3eSJouni Malinen 	return 0;
140cd4e3c3eSJouni Malinen }
141cd4e3c3eSJouni Malinen 
142cd4e3c3eSJouni Malinen 
wpa_command(const char * ifname,const char * cmd)14352ec2363SAlexei Avshalom Lazar int wpa_command(const char *ifname, const char *cmd)
14452ec2363SAlexei Avshalom Lazar {
14552ec2363SAlexei Avshalom Lazar 	printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
14652ec2363SAlexei Avshalom Lazar 	return wpa_ctrl_command(sigma_wpas_ctrl, ifname, cmd);
14752ec2363SAlexei Avshalom Lazar }
14852ec2363SAlexei Avshalom Lazar 
14952ec2363SAlexei Avshalom Lazar 
hapd_command(const char * ifname,const char * cmd)150dc7bf05eSAlexei Avshalom Lazar int hapd_command(const char *ifname, const char *cmd)
151dc7bf05eSAlexei Avshalom Lazar {
152dc7bf05eSAlexei Avshalom Lazar 	const char *path = sigma_hapd_ctrl ? sigma_hapd_ctrl :
153dc7bf05eSAlexei Avshalom Lazar 		DEFAULT_HAPD_CTRL_PATH;
154dc7bf05eSAlexei Avshalom Lazar 
155dc7bf05eSAlexei Avshalom Lazar 	printf("hapd_command(ifname='%s', cmd='%s')\n", ifname, cmd);
156dc7bf05eSAlexei Avshalom Lazar 	return wpa_ctrl_command(path, ifname, cmd);
157dc7bf05eSAlexei Avshalom Lazar }
158dc7bf05eSAlexei Avshalom Lazar 
159dc7bf05eSAlexei Avshalom Lazar 
wpa_ctrl_command_resp(const char * path,const char * ifname,const char * cmd,char * resp,size_t resp_size)16052ec2363SAlexei Avshalom Lazar int wpa_ctrl_command_resp(const char *path, const char *ifname,
16152ec2363SAlexei Avshalom Lazar 			  const char *cmd, char *resp, size_t resp_size)
162cd4e3c3eSJouni Malinen {
163cd4e3c3eSJouni Malinen 	struct wpa_ctrl *ctrl;
164cd4e3c3eSJouni Malinen 	char buf[128];
165cd4e3c3eSJouni Malinen 	size_t len;
166cd4e3c3eSJouni Malinen 
16752ec2363SAlexei Avshalom Lazar 	snprintf(buf, sizeof(buf), "%s%s", path, ifname);
168525dbfd1SRajiv Ranjan 	ctrl = wpa_ctrl_open2(buf, client_socket_path);
169cd4e3c3eSJouni Malinen 	if (ctrl == NULL) {
170525dbfd1SRajiv Ranjan 		printf("wpa_command: wpa_ctrl_open2(%s) failed\n", buf);
171cd4e3c3eSJouni Malinen 		return -1;
172cd4e3c3eSJouni Malinen 	}
173cd4e3c3eSJouni Malinen 	len = resp_size;
174cd4e3c3eSJouni Malinen 	if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), resp, &len, NULL) < 0) {
175cd4e3c3eSJouni Malinen 		printf("wpa_command: wpa_ctrl_request failed\n");
176cd4e3c3eSJouni Malinen 		wpa_ctrl_close(ctrl);
177cd4e3c3eSJouni Malinen 		return -1;
178cd4e3c3eSJouni Malinen 	}
179cd4e3c3eSJouni Malinen 	wpa_ctrl_close(ctrl);
180cd4e3c3eSJouni Malinen 	resp[len] = '\0';
181cd4e3c3eSJouni Malinen 	return 0;
182cd4e3c3eSJouni Malinen }
183cd4e3c3eSJouni Malinen 
184cd4e3c3eSJouni Malinen 
wpa_command_resp(const char * ifname,const char * cmd,char * resp,size_t resp_size)18552ec2363SAlexei Avshalom Lazar int wpa_command_resp(const char *ifname, const char *cmd,
18652ec2363SAlexei Avshalom Lazar 		     char *resp, size_t resp_size)
18752ec2363SAlexei Avshalom Lazar {
18852ec2363SAlexei Avshalom Lazar 	printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
18952ec2363SAlexei Avshalom Lazar 	return wpa_ctrl_command_resp(sigma_wpas_ctrl, ifname, cmd,
19052ec2363SAlexei Avshalom Lazar 				     resp, resp_size);
19152ec2363SAlexei Avshalom Lazar }
19252ec2363SAlexei Avshalom Lazar 
19352ec2363SAlexei Avshalom Lazar 
hapd_command_resp(const char * ifname,const char * cmd,char * resp,size_t resp_size)194dc7bf05eSAlexei Avshalom Lazar int hapd_command_resp(const char *ifname, const char *cmd,
195dc7bf05eSAlexei Avshalom Lazar 		      char *resp, size_t resp_size)
196dc7bf05eSAlexei Avshalom Lazar {
197dc7bf05eSAlexei Avshalom Lazar 	const char *path = sigma_hapd_ctrl ? sigma_hapd_ctrl :
198dc7bf05eSAlexei Avshalom Lazar 		DEFAULT_HAPD_CTRL_PATH;
199dc7bf05eSAlexei Avshalom Lazar 
200dc7bf05eSAlexei Avshalom Lazar 	printf("hapd_command(ifname='%s', cmd='%s')\n", ifname, cmd);
201dc7bf05eSAlexei Avshalom Lazar 	return wpa_ctrl_command_resp(path, ifname, cmd, resp, resp_size);
202dc7bf05eSAlexei Avshalom Lazar }
203dc7bf05eSAlexei Avshalom Lazar 
204dc7bf05eSAlexei Avshalom Lazar 
open_wpa_ctrl_mon(const char * ctrl_path,const char * ifname)20552ec2363SAlexei Avshalom Lazar struct wpa_ctrl * open_wpa_ctrl_mon(const char *ctrl_path, const char *ifname)
206cd4e3c3eSJouni Malinen {
207cd4e3c3eSJouni Malinen 	struct wpa_ctrl *ctrl;
208cd4e3c3eSJouni Malinen 	char path[256];
209cd4e3c3eSJouni Malinen 
21052ec2363SAlexei Avshalom Lazar 	snprintf(path, sizeof(path), "%s%s", ctrl_path, ifname);
211525dbfd1SRajiv Ranjan 	ctrl = wpa_ctrl_open2(path, client_socket_path);
212cd4e3c3eSJouni Malinen 	if (ctrl == NULL)
213cd4e3c3eSJouni Malinen 		return NULL;
214cd4e3c3eSJouni Malinen 	if (wpa_ctrl_attach(ctrl) < 0) {
215cd4e3c3eSJouni Malinen 		wpa_ctrl_close(ctrl);
216cd4e3c3eSJouni Malinen 		return NULL;
217cd4e3c3eSJouni Malinen 	}
218cd4e3c3eSJouni Malinen 
219cd4e3c3eSJouni Malinen 	return ctrl;
220cd4e3c3eSJouni Malinen }
221cd4e3c3eSJouni Malinen 
222cd4e3c3eSJouni Malinen 
open_wpa_mon(const char * ifname)22352ec2363SAlexei Avshalom Lazar struct wpa_ctrl * open_wpa_mon(const char *ifname)
22452ec2363SAlexei Avshalom Lazar {
22552ec2363SAlexei Avshalom Lazar 	return open_wpa_ctrl_mon(sigma_wpas_ctrl, ifname);
22652ec2363SAlexei Avshalom Lazar }
22752ec2363SAlexei Avshalom Lazar 
22852ec2363SAlexei Avshalom Lazar 
open_hapd_mon(const char * ifname)22952ec2363SAlexei Avshalom Lazar struct wpa_ctrl * open_hapd_mon(const char *ifname)
23052ec2363SAlexei Avshalom Lazar {
23152ec2363SAlexei Avshalom Lazar 	const char *path = sigma_hapd_ctrl ?
23252ec2363SAlexei Avshalom Lazar 		sigma_hapd_ctrl : DEFAULT_HAPD_CTRL_PATH;
23352ec2363SAlexei Avshalom Lazar 
23452ec2363SAlexei Avshalom Lazar 	return open_wpa_ctrl_mon(path, ifname);
23552ec2363SAlexei Avshalom Lazar }
23652ec2363SAlexei Avshalom Lazar 
23752ec2363SAlexei Avshalom Lazar 
get_wpa_cli_events(struct sigma_dut * dut,struct wpa_ctrl * mon,const char ** events,char * buf,size_t buf_size)238cd4e3c3eSJouni Malinen int get_wpa_cli_events(struct sigma_dut *dut, struct wpa_ctrl *mon,
239cd4e3c3eSJouni Malinen 		       const char **events, char *buf, size_t buf_size)
240cd4e3c3eSJouni Malinen {
241cd4e3c3eSJouni Malinen 	int fd, ret;
242cd4e3c3eSJouni Malinen 	fd_set rfd;
243cd4e3c3eSJouni Malinen 	char *pos;
244cd4e3c3eSJouni Malinen 	struct timeval tv;
245cd4e3c3eSJouni Malinen 	time_t start, now;
246cd4e3c3eSJouni Malinen 	int i;
247cd4e3c3eSJouni Malinen 
248cd4e3c3eSJouni Malinen 	for (i = 0; events[i]; i++) {
249cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG,
250cd4e3c3eSJouni Malinen 				"Waiting for wpa_cli event: %s", events[i]);
251cd4e3c3eSJouni Malinen 	}
252cd4e3c3eSJouni Malinen 	fd = wpa_ctrl_get_fd(mon);
253cd4e3c3eSJouni Malinen 	if (fd < 0)
254cd4e3c3eSJouni Malinen 		return -1;
255cd4e3c3eSJouni Malinen 
256cd4e3c3eSJouni Malinen 	time(&start);
257cd4e3c3eSJouni Malinen 	while (1) {
258cd4e3c3eSJouni Malinen 		size_t len;
259cd4e3c3eSJouni Malinen 
260cd4e3c3eSJouni Malinen 		FD_ZERO(&rfd);
261cd4e3c3eSJouni Malinen 		FD_SET(fd, &rfd);
262cd4e3c3eSJouni Malinen 
263cd4e3c3eSJouni Malinen 		time(&now);
264cd4e3c3eSJouni Malinen 		if ((unsigned int) (now - start) >= dut->default_timeout)
265cd4e3c3eSJouni Malinen 			tv.tv_sec = 1;
266cd4e3c3eSJouni Malinen 		else
267cd4e3c3eSJouni Malinen 			tv.tv_sec = dut->default_timeout -
268cd4e3c3eSJouni Malinen 				(unsigned int) (now - start) + 1;
269cd4e3c3eSJouni Malinen 		tv.tv_usec = 0;
270cd4e3c3eSJouni Malinen 		ret = select(fd + 1, &rfd, NULL, NULL, &tv);
271cd4e3c3eSJouni Malinen 		if (ret == 0) {
272cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO, "Timeout on "
273cd4e3c3eSJouni Malinen 					"waiting for events");
274cd4e3c3eSJouni Malinen 			return -1;
275cd4e3c3eSJouni Malinen 		}
276cd4e3c3eSJouni Malinen 		if (ret < 0) {
277cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO, "select: %s",
278cd4e3c3eSJouni Malinen 					strerror(errno));
279cd4e3c3eSJouni Malinen 			return -1;
280cd4e3c3eSJouni Malinen 		}
281cd4e3c3eSJouni Malinen 		len = buf_size;
282cd4e3c3eSJouni Malinen 		if (wpa_ctrl_recv(mon, buf, &len) < 0) {
283cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failure while "
284cd4e3c3eSJouni Malinen 					"waiting for events");
285cd4e3c3eSJouni Malinen 			return -1;
286cd4e3c3eSJouni Malinen 		}
287cd4e3c3eSJouni Malinen 		if (len == buf_size)
288cd4e3c3eSJouni Malinen 			len--;
289cd4e3c3eSJouni Malinen 		buf[len] = '\0';
290cd4e3c3eSJouni Malinen 
291cd4e3c3eSJouni Malinen 		pos = strchr(buf, '>');
292cd4e3c3eSJouni Malinen 		if (pos) {
293cd4e3c3eSJouni Malinen 			for (i = 0; events[i]; i++) {
294cd4e3c3eSJouni Malinen 				if (strncmp(pos + 1, events[i],
295cd4e3c3eSJouni Malinen 					    strlen(events[i])) == 0)
296cd4e3c3eSJouni Malinen 					return 0; /* Event found */
297cd4e3c3eSJouni Malinen 			}
298cd4e3c3eSJouni Malinen 		}
299cd4e3c3eSJouni Malinen 
300cd4e3c3eSJouni Malinen 		time(&now);
301cd4e3c3eSJouni Malinen 		if ((unsigned int) (now - start) > dut->default_timeout) {
302cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO, "Timeout on "
303cd4e3c3eSJouni Malinen 					"waiting for event");
304cd4e3c3eSJouni Malinen 			return -1;
305cd4e3c3eSJouni Malinen 		}
306cd4e3c3eSJouni Malinen 	}
307cd4e3c3eSJouni Malinen }
308cd4e3c3eSJouni Malinen 
309cd4e3c3eSJouni Malinen 
get_wpa_cli_event2(struct sigma_dut * dut,struct wpa_ctrl * mon,const char * event,const char * event2,char * buf,size_t buf_size)310cd4e3c3eSJouni Malinen int get_wpa_cli_event2(struct sigma_dut *dut, struct wpa_ctrl *mon,
311cd4e3c3eSJouni Malinen 		       const char *event, const char *event2,
312cd4e3c3eSJouni Malinen 		       char *buf, size_t buf_size)
313cd4e3c3eSJouni Malinen {
314cd4e3c3eSJouni Malinen 	const char *events[3] = { event, event2, NULL };
315cd4e3c3eSJouni Malinen 	return get_wpa_cli_events(dut, mon, events, buf, buf_size);
316cd4e3c3eSJouni Malinen }
317cd4e3c3eSJouni Malinen 
318cd4e3c3eSJouni Malinen 
get_wpa_cli_event(struct sigma_dut * dut,struct wpa_ctrl * mon,const char * event,char * buf,size_t buf_size)319cd4e3c3eSJouni Malinen int get_wpa_cli_event(struct sigma_dut *dut, struct wpa_ctrl *mon,
320cd4e3c3eSJouni Malinen 		      const char *event, char *buf, size_t buf_size)
321cd4e3c3eSJouni Malinen {
322cd4e3c3eSJouni Malinen 	return get_wpa_cli_event2(dut, mon, event, NULL, buf, buf_size);
323cd4e3c3eSJouni Malinen }
324cd4e3c3eSJouni Malinen 
325cd4e3c3eSJouni Malinen 
326c86d8021SKiran Kumar Lokere /*
327c86d8021SKiran Kumar Lokere  * signal_poll cmd output sample
328c86d8021SKiran Kumar Lokere  * RSSI=-51
329c86d8021SKiran Kumar Lokere  * LINKSPEED=866
330c86d8021SKiran Kumar Lokere  * NOISE=-101
331c86d8021SKiran Kumar Lokere  * FREQUENCY=5180
332c86d8021SKiran Kumar Lokere  * AVG_RSSI=-50
333c86d8021SKiran Kumar Lokere  */
get_wpa_signal_poll(struct sigma_dut * dut,const char * ifname,const char * field,char * obuf,size_t obuf_size)334c86d8021SKiran Kumar Lokere int get_wpa_signal_poll(struct sigma_dut *dut, const char *ifname,
335c86d8021SKiran Kumar Lokere 			const char *field, char *obuf, size_t obuf_size)
336c86d8021SKiran Kumar Lokere {
337c86d8021SKiran Kumar Lokere 	struct wpa_ctrl *ctrl;
338c86d8021SKiran Kumar Lokere 	char buf[4096];
339c86d8021SKiran Kumar Lokere 	char *pos, *end;
340c86d8021SKiran Kumar Lokere 	size_t len, flen;
341c86d8021SKiran Kumar Lokere 
342c86d8021SKiran Kumar Lokere 	snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl, ifname);
343c86d8021SKiran Kumar Lokere 	ctrl = wpa_ctrl_open2(buf, client_socket_path);
344c86d8021SKiran Kumar Lokere 	if (!ctrl) {
345c86d8021SKiran Kumar Lokere 		sigma_dut_print(dut, DUT_MSG_ERROR,
346c86d8021SKiran Kumar Lokere 				"Failed to connect to wpa_supplicant");
347c86d8021SKiran Kumar Lokere 		return -1;
348c86d8021SKiran Kumar Lokere 	}
349c86d8021SKiran Kumar Lokere 
350c86d8021SKiran Kumar Lokere 	len = sizeof(buf);
351c86d8021SKiran Kumar Lokere 	if (wpa_ctrl_request(ctrl, "SIGNAL_POLL", 11, buf, &len, NULL) < 0) {
352c86d8021SKiran Kumar Lokere 		wpa_ctrl_close(ctrl);
353c86d8021SKiran Kumar Lokere 		sigma_dut_print(dut, DUT_MSG_ERROR, "ctrl request failed");
354c86d8021SKiran Kumar Lokere 		return -1;
355c86d8021SKiran Kumar Lokere 	}
356c86d8021SKiran Kumar Lokere 	buf[len] = '\0';
357c86d8021SKiran Kumar Lokere 
358c86d8021SKiran Kumar Lokere 	wpa_ctrl_close(ctrl);
359c86d8021SKiran Kumar Lokere 
360c86d8021SKiran Kumar Lokere 	flen = strlen(field);
361c86d8021SKiran Kumar Lokere 	pos = buf;
362c86d8021SKiran Kumar Lokere 	while (pos + flen < buf + len) {
363c86d8021SKiran Kumar Lokere 		if (pos > buf) {
364c86d8021SKiran Kumar Lokere 			if (*pos != '\n') {
365c86d8021SKiran Kumar Lokere 				pos++;
366c86d8021SKiran Kumar Lokere 				continue;
367c86d8021SKiran Kumar Lokere 			}
368c86d8021SKiran Kumar Lokere 			pos++;
369c86d8021SKiran Kumar Lokere 		}
370c86d8021SKiran Kumar Lokere 		if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') {
371c86d8021SKiran Kumar Lokere 			pos++;
372c86d8021SKiran Kumar Lokere 			continue;
373c86d8021SKiran Kumar Lokere 		}
374c86d8021SKiran Kumar Lokere 		pos += flen + 1;
375c86d8021SKiran Kumar Lokere 		end = strchr(pos, '\n');
376c86d8021SKiran Kumar Lokere 		if (!end) {
377c86d8021SKiran Kumar Lokere 			sigma_dut_print(dut, DUT_MSG_ERROR,
378c86d8021SKiran Kumar Lokere 					"Could not find signal poll field '%s' - end is NULL",
379c86d8021SKiran Kumar Lokere 					field);
380c86d8021SKiran Kumar Lokere 			return -1;
381c86d8021SKiran Kumar Lokere 		}
382c86d8021SKiran Kumar Lokere 		*end++ = '\0';
383c86d8021SKiran Kumar Lokere 		if (end - pos > (int) obuf_size) {
384c86d8021SKiran Kumar Lokere 			sigma_dut_print(dut, DUT_MSG_ERROR,
385c86d8021SKiran Kumar Lokere 					"signal poll out buffer is too small");
386c86d8021SKiran Kumar Lokere 			return -1;
387c86d8021SKiran Kumar Lokere 		}
388c86d8021SKiran Kumar Lokere 		memcpy(obuf, pos, end - pos);
389c86d8021SKiran Kumar Lokere 		return 0;
390c86d8021SKiran Kumar Lokere 	}
391c86d8021SKiran Kumar Lokere 
392c86d8021SKiran Kumar Lokere 	sigma_dut_print(dut, DUT_MSG_ERROR, "signal poll param not found");
393c86d8021SKiran Kumar Lokere 	return -1;
394c86d8021SKiran Kumar Lokere }
395c86d8021SKiran Kumar Lokere 
396c86d8021SKiran Kumar Lokere 
get_wpa_ssid_bssid(struct sigma_dut * dut,const char * ifname,char * buf,size_t buf_size)39766a4af01SArif Hussain int get_wpa_ssid_bssid(struct sigma_dut *dut, const char *ifname,
39866a4af01SArif Hussain 		       char *buf, size_t buf_size)
39966a4af01SArif Hussain {
40066a4af01SArif Hussain 	struct wpa_ctrl *ctrl;
40166a4af01SArif Hussain 	char buf_local[4096];
40266a4af01SArif Hussain 	char *network, *ssid, *bssid;
40366a4af01SArif Hussain 	size_t buf_size_local;
40466a4af01SArif Hussain 	unsigned int count = 0;
40566a4af01SArif Hussain 	int len, res;
40666a4af01SArif Hussain 	char *save_ptr_network = NULL;
40766a4af01SArif Hussain 
40866a4af01SArif Hussain 	ctrl = open_wpa_mon(ifname);
40966a4af01SArif Hussain 	if (!ctrl) {
41066a4af01SArif Hussain 		sigma_dut_print(dut, DUT_MSG_ERROR,
41166a4af01SArif Hussain 				"Failed to connect to wpa_supplicant");
41266a4af01SArif Hussain 		return -1;
41366a4af01SArif Hussain 	}
41466a4af01SArif Hussain 
41566a4af01SArif Hussain 	wpa_command(ifname, "BSS_FLUSH");
41666a4af01SArif Hussain 	if (wpa_command(ifname, "SCAN TYPE=ONLY")) {
41766a4af01SArif Hussain 		wpa_ctrl_detach(ctrl);
41866a4af01SArif Hussain 		wpa_ctrl_close(ctrl);
41966a4af01SArif Hussain 		sigma_dut_print(dut, DUT_MSG_ERROR, "SCAN command failed");
42066a4af01SArif Hussain 		return -1;
42166a4af01SArif Hussain 	}
42266a4af01SArif Hussain 
42366a4af01SArif Hussain 	res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
42466a4af01SArif Hussain 				buf_local, sizeof(buf_local));
42566a4af01SArif Hussain 	wpa_ctrl_detach(ctrl);
42666a4af01SArif Hussain 	buf_size_local = sizeof(buf_local);
42766a4af01SArif Hussain 	if (res < 0 || wpa_ctrl_request(ctrl, "BSS RANGE=ALL MASK=0x1002", 25,
42866a4af01SArif Hussain 					buf_local, &buf_size_local, NULL) < 0) {
42966a4af01SArif Hussain 		wpa_ctrl_close(ctrl);
43066a4af01SArif Hussain 		sigma_dut_print(dut, DUT_MSG_ERROR, "BSS ctrl request failed");
43166a4af01SArif Hussain 		return -1;
43266a4af01SArif Hussain 	}
43366a4af01SArif Hussain 	buf_local[buf_size_local] = '\0';
43466a4af01SArif Hussain 
43566a4af01SArif Hussain 	wpa_ctrl_close(ctrl);
43666a4af01SArif Hussain 
43766a4af01SArif Hussain 	/* Below is BSS RANGE=ALL MASK=0x1002 command sample output which is
43866a4af01SArif Hussain 	 * parsed to get the BSSID and SSID parameters.
43966a4af01SArif Hussain 	 * Even number of lines, first line BSSID of network 1, second line SSID
44066a4af01SArif Hussain 	 * of network 1, ...
44166a4af01SArif Hussain 	 *
44266a4af01SArif Hussain 	 * bssid=xx:xx:xx:xx:xx:x1
44366a4af01SArif Hussain 	 * ssid=SSID1
44466a4af01SArif Hussain 	 * bssid=xx:xx:xx:xx:xx:x2
44566a4af01SArif Hussain 	 * ssid=SSID2
44666a4af01SArif Hussain 	 */
44766a4af01SArif Hussain 
44866a4af01SArif Hussain 	network = strtok_r(buf_local, "\n", &save_ptr_network);
44966a4af01SArif Hussain 
45066a4af01SArif Hussain 	while (network) {
45166a4af01SArif Hussain 		sigma_dut_print(dut, DUT_MSG_DEBUG, "BSSID: %s", network);
45266a4af01SArif Hussain 		bssid = NULL;
45366a4af01SArif Hussain 		if (!strtok_r(network, "=", &bssid)) {
45466a4af01SArif Hussain 			sigma_dut_print(dut, DUT_MSG_ERROR,
45566a4af01SArif Hussain 					"Invalid BSS result: BSSID not found");
45666a4af01SArif Hussain 			return -1;
45766a4af01SArif Hussain 		}
45866a4af01SArif Hussain 		network = strtok_r(NULL, "\n", &save_ptr_network);
45966a4af01SArif Hussain 		if (network) {
46066a4af01SArif Hussain 			sigma_dut_print(dut, DUT_MSG_DEBUG, "SSID: %s",
46166a4af01SArif Hussain 					network);
46266a4af01SArif Hussain 			ssid = NULL;
46366a4af01SArif Hussain 			if (!strtok_r(network, "=", &ssid)) {
46466a4af01SArif Hussain 				sigma_dut_print(dut, DUT_MSG_ERROR,
46566a4af01SArif Hussain 						"Invalid BSS result: SSID is null");
46666a4af01SArif Hussain 				return -1;
46766a4af01SArif Hussain 			}
46866a4af01SArif Hussain 		} else {
46966a4af01SArif Hussain 			sigma_dut_print(dut, DUT_MSG_ERROR,
47066a4af01SArif Hussain 					"Invalid BSS result: SSID not found");
47166a4af01SArif Hussain 			return -1;
47266a4af01SArif Hussain 		}
47366a4af01SArif Hussain 
47466a4af01SArif Hussain 		/* Skip comma for first entry */
47566a4af01SArif Hussain 		count++;
47666a4af01SArif Hussain 		len = snprintf(buf, buf_size, "%sSSID%d,%s,BSSID%d,%s",
47766a4af01SArif Hussain 			       count > 1 ? "," : "",
47866a4af01SArif Hussain 			       count, ssid, count, bssid);
4798400c089SJouni Malinen 		if (len < 0 || (size_t) len >= buf_size) {
48066a4af01SArif Hussain 			buf[0] = '\0';
48166a4af01SArif Hussain 			return 0;
48266a4af01SArif Hussain 		}
48366a4af01SArif Hussain 
48466a4af01SArif Hussain 		buf_size -= len;
48566a4af01SArif Hussain 		buf += len;
48666a4af01SArif Hussain 
48766a4af01SArif Hussain 		network = strtok_r(NULL, "\n", &save_ptr_network);
48866a4af01SArif Hussain 	}
48966a4af01SArif Hussain 
49066a4af01SArif Hussain 	return 0;
49166a4af01SArif Hussain }
49266a4af01SArif Hussain 
49366a4af01SArif Hussain 
get_wpa_ctrl_status_field(const char * path,const char * ifname,const char * cmd,const char * field,char * obuf,size_t obuf_size)49452ec2363SAlexei Avshalom Lazar static int get_wpa_ctrl_status_field(const char *path, const char *ifname,
49552ec2363SAlexei Avshalom Lazar 				     const char *cmd, const char *field,
49652ec2363SAlexei Avshalom Lazar 				     char *obuf, size_t obuf_size)
497cd4e3c3eSJouni Malinen {
498cd4e3c3eSJouni Malinen 	struct wpa_ctrl *ctrl;
499cd4e3c3eSJouni Malinen 	char buf[4096];
500cd4e3c3eSJouni Malinen 	char *pos, *end;
501cd4e3c3eSJouni Malinen 	size_t len, flen;
502cd4e3c3eSJouni Malinen 
50352ec2363SAlexei Avshalom Lazar 	snprintf(buf, sizeof(buf), "%s%s", path, ifname);
504525dbfd1SRajiv Ranjan 	ctrl = wpa_ctrl_open2(buf, client_socket_path);
505cd4e3c3eSJouni Malinen 	if (ctrl == NULL)
506cd4e3c3eSJouni Malinen 		return -1;
507cd4e3c3eSJouni Malinen 	len = sizeof(buf);
50852ec2363SAlexei Avshalom Lazar 	if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
509cd4e3c3eSJouni Malinen 		wpa_ctrl_close(ctrl);
510cd4e3c3eSJouni Malinen 		return -1;
511cd4e3c3eSJouni Malinen 	}
512cd4e3c3eSJouni Malinen 	wpa_ctrl_close(ctrl);
513cd4e3c3eSJouni Malinen 	buf[len] = '\0';
514cd4e3c3eSJouni Malinen 
515cd4e3c3eSJouni Malinen 	flen = strlen(field);
516cd4e3c3eSJouni Malinen 	pos = buf;
517cd4e3c3eSJouni Malinen 	while (pos + flen < buf + len) {
518cd4e3c3eSJouni Malinen 		if (pos > buf) {
519cd4e3c3eSJouni Malinen 			if (*pos != '\n') {
520cd4e3c3eSJouni Malinen 				pos++;
521cd4e3c3eSJouni Malinen 				continue;
522cd4e3c3eSJouni Malinen 			}
523cd4e3c3eSJouni Malinen 			pos++;
524cd4e3c3eSJouni Malinen 		}
525cd4e3c3eSJouni Malinen 		if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') {
526cd4e3c3eSJouni Malinen 			pos++;
527cd4e3c3eSJouni Malinen 			continue;
528cd4e3c3eSJouni Malinen 		}
529cd4e3c3eSJouni Malinen 		pos += flen + 1;
530cd4e3c3eSJouni Malinen 		end = strchr(pos, '\n');
531cd4e3c3eSJouni Malinen 		if (end == NULL)
532cd4e3c3eSJouni Malinen 			return -1;
533cd4e3c3eSJouni Malinen 		*end++ = '\0';
534cd4e3c3eSJouni Malinen 		if (end - pos > (int) obuf_size)
535cd4e3c3eSJouni Malinen 			return -1;
536cd4e3c3eSJouni Malinen 		memcpy(obuf, pos, end - pos);
537cd4e3c3eSJouni Malinen 		return 0;
538cd4e3c3eSJouni Malinen 	}
539cd4e3c3eSJouni Malinen 
540cd4e3c3eSJouni Malinen 	return -1;
541cd4e3c3eSJouni Malinen }
542cd4e3c3eSJouni Malinen 
543cd4e3c3eSJouni Malinen 
get_wpa_status(const char * ifname,const char * field,char * obuf,size_t obuf_size)54452ec2363SAlexei Avshalom Lazar int get_wpa_status(const char *ifname, const char *field, char *obuf,
54552ec2363SAlexei Avshalom Lazar 		   size_t obuf_size)
54652ec2363SAlexei Avshalom Lazar {
54752ec2363SAlexei Avshalom Lazar 	return get_wpa_ctrl_status_field(sigma_wpas_ctrl, ifname, "STATUS",
54852ec2363SAlexei Avshalom Lazar 					 field, obuf, obuf_size);
54952ec2363SAlexei Avshalom Lazar }
55052ec2363SAlexei Avshalom Lazar 
55152ec2363SAlexei Avshalom Lazar 
get_hapd_config(const char * ifname,const char * field,char * obuf,size_t obuf_size)5520c1d82d4SAlexei Avshalom Lazar int get_hapd_config(const char *ifname, const char *field, char *obuf,
5530c1d82d4SAlexei Avshalom Lazar 		    size_t obuf_size)
5540c1d82d4SAlexei Avshalom Lazar {
5550c1d82d4SAlexei Avshalom Lazar 	const char *path = sigma_hapd_ctrl ?
5560c1d82d4SAlexei Avshalom Lazar 		sigma_hapd_ctrl : DEFAULT_HAPD_CTRL_PATH;
5570c1d82d4SAlexei Avshalom Lazar 
5580c1d82d4SAlexei Avshalom Lazar 	return get_wpa_ctrl_status_field(path, ifname, "GET_CONFIG",
5590c1d82d4SAlexei Avshalom Lazar 					 field, obuf, obuf_size);
5600c1d82d4SAlexei Avshalom Lazar }
5610c1d82d4SAlexei Avshalom Lazar 
5620c1d82d4SAlexei Avshalom Lazar 
wait_ip_addr(struct sigma_dut * dut,const char * ifname,int timeout)563cd4e3c3eSJouni Malinen int wait_ip_addr(struct sigma_dut *dut, const char *ifname, int timeout)
564cd4e3c3eSJouni Malinen {
565cd4e3c3eSJouni Malinen 	char ip[30];
566cd4e3c3eSJouni Malinen 	int count = timeout;
567cd4e3c3eSJouni Malinen 
568cd4e3c3eSJouni Malinen 	while (count > 0) {
569cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: ifname='%s' - %d "
570cd4e3c3eSJouni Malinen 				"seconds remaining",
571cd4e3c3eSJouni Malinen 				__func__, ifname, count);
572cd4e3c3eSJouni Malinen 		count--;
573cd4e3c3eSJouni Malinen 		if (get_wpa_status(ifname, "ip_address", ip, sizeof(ip)) == 0
574cd4e3c3eSJouni Malinen 		    && strlen(ip) > 0) {
575cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO, "IP address "
576cd4e3c3eSJouni Malinen 					"found: '%s'", ip);
577cd4e3c3eSJouni Malinen 			return 0;
578cd4e3c3eSJouni Malinen 		}
579cd4e3c3eSJouni Malinen 		sleep(1);
580cd4e3c3eSJouni Malinen 	}
581cd4e3c3eSJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO, "%s: Could not get IP address for "
582cd4e3c3eSJouni Malinen 			"ifname='%s'", __func__, ifname);
583cd4e3c3eSJouni Malinen 	return -1;
584cd4e3c3eSJouni Malinen }
585cd4e3c3eSJouni Malinen 
586cd4e3c3eSJouni Malinen 
remove_wpa_networks(const char * ifname)587cd4e3c3eSJouni Malinen void remove_wpa_networks(const char *ifname)
588cd4e3c3eSJouni Malinen {
589cd4e3c3eSJouni Malinen 	char buf[4096];
590cd4e3c3eSJouni Malinen 	char cmd[256];
591cd4e3c3eSJouni Malinen 	char *pos;
592cd4e3c3eSJouni Malinen 
593cd4e3c3eSJouni Malinen 	if (wpa_command_resp(ifname, "LIST_NETWORKS", buf, sizeof(buf)) < 0)
594cd4e3c3eSJouni Malinen 		return;
595cd4e3c3eSJouni Malinen 
596cd4e3c3eSJouni Malinen 	/* Skip the first line (header) */
597cd4e3c3eSJouni Malinen 	pos = strchr(buf, '\n');
598cd4e3c3eSJouni Malinen 	if (pos == NULL)
599cd4e3c3eSJouni Malinen 		return;
600cd4e3c3eSJouni Malinen 	pos++;
601cd4e3c3eSJouni Malinen 	while (pos && pos[0]) {
602cd4e3c3eSJouni Malinen 		int id = atoi(pos);
603cd4e3c3eSJouni Malinen 		snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", id);
604cd4e3c3eSJouni Malinen 		wpa_command(ifname, cmd);
605cd4e3c3eSJouni Malinen 		pos = strchr(pos, '\n');
606cd4e3c3eSJouni Malinen 		if (pos)
607cd4e3c3eSJouni Malinen 			pos++;
608cd4e3c3eSJouni Malinen 	}
609cd4e3c3eSJouni Malinen }
610cd4e3c3eSJouni Malinen 
611cd4e3c3eSJouni Malinen 
add_network(const char * ifname)612cd4e3c3eSJouni Malinen int add_network(const char *ifname)
613cd4e3c3eSJouni Malinen {
614cd4e3c3eSJouni Malinen 	char res[30];
615cd4e3c3eSJouni Malinen 
616cd4e3c3eSJouni Malinen 	if (wpa_command_resp(ifname, "ADD_NETWORK", res, sizeof(res)) < 0)
617cd4e3c3eSJouni Malinen 		return -1;
618cd4e3c3eSJouni Malinen 	return atoi(res);
619cd4e3c3eSJouni Malinen }
620cd4e3c3eSJouni Malinen 
621cd4e3c3eSJouni Malinen 
set_network(const char * ifname,int id,const char * field,const char * value)622cd4e3c3eSJouni Malinen int set_network(const char *ifname, int id, const char *field,
623cd4e3c3eSJouni Malinen 		const char *value)
624cd4e3c3eSJouni Malinen {
625cd4e3c3eSJouni Malinen 	char buf[200];
626cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "SET_NETWORK %d %s %s", id, field, value);
627cd4e3c3eSJouni Malinen 	return wpa_command(ifname, buf);
628cd4e3c3eSJouni Malinen }
629cd4e3c3eSJouni Malinen 
630cd4e3c3eSJouni Malinen 
set_network_quoted(const char * ifname,int id,const char * field,const char * value)631cd4e3c3eSJouni Malinen int set_network_quoted(const char *ifname, int id, const char *field,
632cd4e3c3eSJouni Malinen 		       const char *value)
633cd4e3c3eSJouni Malinen {
634cd4e3c3eSJouni Malinen 	char buf[200];
635cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "SET_NETWORK %d %s \"%s\"",
636cd4e3c3eSJouni Malinen 		 id, field, value);
637cd4e3c3eSJouni Malinen 	return wpa_command(ifname, buf);
638cd4e3c3eSJouni Malinen }
639cd4e3c3eSJouni Malinen 
640cd4e3c3eSJouni Malinen 
add_cred(const char * ifname)641cd4e3c3eSJouni Malinen int add_cred(const char *ifname)
642cd4e3c3eSJouni Malinen {
643cd4e3c3eSJouni Malinen 	char res[30];
644cd4e3c3eSJouni Malinen 
645cd4e3c3eSJouni Malinen 	if (wpa_command_resp(ifname, "ADD_CRED", res, sizeof(res)) < 0)
646cd4e3c3eSJouni Malinen 		return -1;
647cd4e3c3eSJouni Malinen 	return atoi(res);
648cd4e3c3eSJouni Malinen }
649cd4e3c3eSJouni Malinen 
650cd4e3c3eSJouni Malinen 
set_cred(const char * ifname,int id,const char * field,const char * value)651cd4e3c3eSJouni Malinen int set_cred(const char *ifname, int id, const char *field, const char *value)
652cd4e3c3eSJouni Malinen {
653cd4e3c3eSJouni Malinen 	char buf[200];
654cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "SET_CRED %d %s %s", id, field, value);
655cd4e3c3eSJouni Malinen 	return wpa_command(ifname, buf);
656cd4e3c3eSJouni Malinen }
657cd4e3c3eSJouni Malinen 
658cd4e3c3eSJouni Malinen 
set_cred_quoted(const char * ifname,int id,const char * field,const char * value)659cd4e3c3eSJouni Malinen int set_cred_quoted(const char *ifname, int id, const char *field,
660cd4e3c3eSJouni Malinen 		    const char *value)
661cd4e3c3eSJouni Malinen {
662cd4e3c3eSJouni Malinen 	char buf[200];
663cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "SET_CRED %d %s \"%s\"",
664cd4e3c3eSJouni Malinen 		 id, field, value);
665cd4e3c3eSJouni Malinen 	return wpa_command(ifname, buf);
666cd4e3c3eSJouni Malinen }
667cd4e3c3eSJouni Malinen 
668cd4e3c3eSJouni Malinen 
concat_sigma_tmpdir(struct sigma_dut * dut,const char * src,char * dst,size_t len)669*c9bc15d1SAlexei Avshalom Lazar const char * concat_sigma_tmpdir(struct sigma_dut *dut, const char *src,
670*c9bc15d1SAlexei Avshalom Lazar 				 char *dst, size_t len)
671*c9bc15d1SAlexei Avshalom Lazar {
672*c9bc15d1SAlexei Avshalom Lazar 	snprintf(dst, len, "%s%s", dut->sigma_tmpdir, src);
673*c9bc15d1SAlexei Avshalom Lazar 
674*c9bc15d1SAlexei Avshalom Lazar 	return dst;
675*c9bc15d1SAlexei Avshalom Lazar }
676*c9bc15d1SAlexei Avshalom Lazar 
677*c9bc15d1SAlexei Avshalom Lazar 
start_sta_mode(struct sigma_dut * dut)678cd4e3c3eSJouni Malinen int start_sta_mode(struct sigma_dut *dut)
679cd4e3c3eSJouni Malinen {
680cd4e3c3eSJouni Malinen 	FILE *f;
6813e8267ecSAlexei Avshalom Lazar 	char buf[256];
682*c9bc15d1SAlexei Avshalom Lazar 	char sta_conf_path[100];
683016ae6c8SJouni Malinen 	const char *ifname;
684cd4e3c3eSJouni Malinen 	char *tmp, *pos;
685cd4e3c3eSJouni Malinen 
68678217db5SJouni Malinen 	if (dut->mode == SIGMA_MODE_STATION) {
68778217db5SJouni Malinen 		if ((dut->use_5g && dut->sta_2g_started) ||
68878217db5SJouni Malinen 		    (!dut->use_5g && dut->sta_5g_started)) {
68978217db5SJouni Malinen 			stop_sta_mode(dut);
69078217db5SJouni Malinen 			sleep(1);
69178217db5SJouni Malinen 		} else {
692cd4e3c3eSJouni Malinen 			return 0;
69378217db5SJouni Malinen 		}
69478217db5SJouni Malinen 	}
695cd4e3c3eSJouni Malinen 
696cd4e3c3eSJouni Malinen 	if (dut->mode == SIGMA_MODE_AP) {
697cd4e3c3eSJouni Malinen 		if (system("killall hostapd") == 0) {
698cd4e3c3eSJouni Malinen 			int i;
699cd4e3c3eSJouni Malinen 
700cd4e3c3eSJouni Malinen 			/* Wait some time to allow hostapd to complete cleanup
701cd4e3c3eSJouni Malinen 			 * before starting a new process */
702cd4e3c3eSJouni Malinen 			for (i = 0; i < 10; i++) {
703cd4e3c3eSJouni Malinen 				usleep(500000);
704cd4e3c3eSJouni Malinen 				if (system("pidof hostapd") != 0)
705cd4e3c3eSJouni Malinen 					break;
706cd4e3c3eSJouni Malinen 			}
707cd4e3c3eSJouni Malinen 		}
708cd4e3c3eSJouni Malinen 	}
709cd4e3c3eSJouni Malinen 
710cd4e3c3eSJouni Malinen 	if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) {
711cd4e3c3eSJouni Malinen 		snprintf(buf, sizeof(buf), "ifconfig %s down",
712cd4e3c3eSJouni Malinen 			 dut->sniffer_ifname);
713cd4e3c3eSJouni Malinen 		if (system(buf) != 0) {
714cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
715cd4e3c3eSJouni Malinen 					"Failed to run '%s'", buf);
716cd4e3c3eSJouni Malinen 		}
717cd4e3c3eSJouni Malinen 		snprintf(buf, sizeof(buf), "iw dev %s set type station",
718cd4e3c3eSJouni Malinen 			 dut->sniffer_ifname);
719cd4e3c3eSJouni Malinen 		if (system(buf) != 0) {
720cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
721cd4e3c3eSJouni Malinen 					"Failed to run '%s'", buf);
722cd4e3c3eSJouni Malinen 		}
723cd4e3c3eSJouni Malinen 	}
724cd4e3c3eSJouni Malinen 
725cd4e3c3eSJouni Malinen 	dut->mode = SIGMA_MODE_STATION;
726cd4e3c3eSJouni Malinen 
727016ae6c8SJouni Malinen 	ifname = get_main_ifname(dut);
728cd4e3c3eSJouni Malinen 	if (wpa_command(ifname, "PING") == 0)
729cd4e3c3eSJouni Malinen 		return 0; /* wpa_supplicant is already running */
730cd4e3c3eSJouni Malinen 
731cd4e3c3eSJouni Malinen 	/* Start wpa_supplicant */
732*c9bc15d1SAlexei Avshalom Lazar 	f = fopen(concat_sigma_tmpdir(dut, "/sigma_dut-sta.conf", sta_conf_path,
733*c9bc15d1SAlexei Avshalom Lazar 				      sizeof(sta_conf_path)), "w");
734cd4e3c3eSJouni Malinen 	if (f == NULL)
735cd4e3c3eSJouni Malinen 		return -1;
736cd4e3c3eSJouni Malinen 
737cd4e3c3eSJouni Malinen 	tmp = strdup(sigma_wpas_ctrl);
738cd4e3c3eSJouni Malinen 	if (tmp == NULL) {
739cd4e3c3eSJouni Malinen 		fclose(f);
740cd4e3c3eSJouni Malinen 		return -1;
741cd4e3c3eSJouni Malinen 	}
742cd4e3c3eSJouni Malinen 	pos = tmp;
743cd4e3c3eSJouni Malinen 	while (pos[0] != '\0' && pos[1] != '\0')
744cd4e3c3eSJouni Malinen 		pos++;
745cd4e3c3eSJouni Malinen 	if (*pos == '/')
746cd4e3c3eSJouni Malinen 		*pos = '\0';
747cd4e3c3eSJouni Malinen 	fprintf(f, "ctrl_interface=%s\n", tmp);
748cd4e3c3eSJouni Malinen 	free(tmp);
749cd4e3c3eSJouni Malinen 	fprintf(f, "device_name=Test client\n");
750cd4e3c3eSJouni Malinen 	fprintf(f, "device_type=1-0050F204-1\n");
7511080c586SAlexei Avshalom Lazar 	if (is_60g_sigma_dut(dut)) {
7521080c586SAlexei Avshalom Lazar 		fprintf(f, "eapol_version=2\n");
7531080c586SAlexei Avshalom Lazar 		fprintf(f,
7541080c586SAlexei Avshalom Lazar 			"config_methods=display push_button keypad virtual_display physical_display virtual_push_button\n");
7551080c586SAlexei Avshalom Lazar 	}
756cd4e3c3eSJouni Malinen 	fclose(f);
757cd4e3c3eSJouni Malinen 
758cd4e3c3eSJouni Malinen #ifdef  __QNXNTO__
759*c9bc15d1SAlexei Avshalom Lazar 	snprintf(buf, sizeof(buf),
760*c9bc15d1SAlexei Avshalom Lazar 		 "wpa_supplicant -Dqca -i%s -B %s%s%s -c %s/sigma_dut-sta.conf",
761*c9bc15d1SAlexei Avshalom Lazar 		 ifname,
76202254ee0SAlexei Avshalom Lazar 		 dut->wpa_supplicant_debug_log ? "-K -t -ddd " : "",
76302254ee0SAlexei Avshalom Lazar 		 (dut->wpa_supplicant_debug_log &&
76402254ee0SAlexei Avshalom Lazar 		  dut->wpa_supplicant_debug_log[0]) ? "-f " : "",
7653e8267ecSAlexei Avshalom Lazar 		 dut->wpa_supplicant_debug_log ?
766*c9bc15d1SAlexei Avshalom Lazar 		 dut->wpa_supplicant_debug_log : "",
767*c9bc15d1SAlexei Avshalom Lazar 		 dut->sigma_tmpdir);
768cd4e3c3eSJouni Malinen #else /*__QNXNTO__*/
769*c9bc15d1SAlexei Avshalom Lazar 	snprintf(buf, sizeof(buf),
770*c9bc15d1SAlexei Avshalom Lazar 		 "%swpa_supplicant -Dnl80211 -i%s -B %s%s%s -c %s/sigma_dut-sta.conf",
77143757097SJouni Malinen 		 file_exists("wpa_supplicant") ? "./" : "",
77243757097SJouni Malinen 		 ifname,
77302254ee0SAlexei Avshalom Lazar 		 dut->wpa_supplicant_debug_log ? "-K -t -ddd " : "",
77402254ee0SAlexei Avshalom Lazar 		 (dut->wpa_supplicant_debug_log &&
77502254ee0SAlexei Avshalom Lazar 		  dut->wpa_supplicant_debug_log[0]) ? "-f " : "",
7763e8267ecSAlexei Avshalom Lazar 		 dut->wpa_supplicant_debug_log ?
777*c9bc15d1SAlexei Avshalom Lazar 		 dut->wpa_supplicant_debug_log : "",
778*c9bc15d1SAlexei Avshalom Lazar 		 dut->sigma_tmpdir);
779cd4e3c3eSJouni Malinen #endif /*__QNXNTO__*/
780cd4e3c3eSJouni Malinen 	if (system(buf) != 0) {
781cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s'", buf);
782cd4e3c3eSJouni Malinen 		return -1;
783cd4e3c3eSJouni Malinen 	}
784cd4e3c3eSJouni Malinen 
785cd4e3c3eSJouni Malinen 	sleep(1);
786cd4e3c3eSJouni Malinen 
787cd4e3c3eSJouni Malinen 	if (wpa_command(ifname, "PING")) {
788cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_INFO, "Failed to communicate "
789cd4e3c3eSJouni Malinen 				"with wpa_supplicant");
790cd4e3c3eSJouni Malinen 		return -1;
791cd4e3c3eSJouni Malinen 	}
79278217db5SJouni Malinen 	if (dut->use_5g)
79378217db5SJouni Malinen 		dut->sta_5g_started = 1;
79478217db5SJouni Malinen 	else
79578217db5SJouni Malinen 		dut->sta_2g_started = 1;
796cd4e3c3eSJouni Malinen 
797cd4e3c3eSJouni Malinen 	return 0;
798cd4e3c3eSJouni Malinen }
799cd4e3c3eSJouni Malinen 
800cd4e3c3eSJouni Malinen 
stop_sta_mode(struct sigma_dut * dut)801cd4e3c3eSJouni Malinen void stop_sta_mode(struct sigma_dut *dut)
802cd4e3c3eSJouni Malinen {
80380566094SAlexei Avshalom Lazar 	if (is_60g_sigma_dut(dut)) {
804016ae6c8SJouni Malinen 		wpa_command(get_main_ifname(dut), "TERMINATE");
80580566094SAlexei Avshalom Lazar 		return;
80680566094SAlexei Avshalom Lazar 	}
80780566094SAlexei Avshalom Lazar 
808cd4e3c3eSJouni Malinen 	wpa_command("wlan0", "TERMINATE");
809cd4e3c3eSJouni Malinen 	wpa_command("wlan1", "TERMINATE");
810cd4e3c3eSJouni Malinen 	wpa_command("ath0", "TERMINATE");
811cd4e3c3eSJouni Malinen 	wpa_command("ath1", "TERMINATE");
812d8956817SJouni Malinen 	if (dut->main_ifname_2g)
813d8956817SJouni Malinen 		wpa_command(dut->main_ifname_2g, "TERMINATE");
814d8956817SJouni Malinen 	if (dut->main_ifname_5g)
815d8956817SJouni Malinen 		wpa_command(dut->main_ifname_5g, "TERMINATE");
816d8956817SJouni Malinen 	if (dut->station_ifname_2g)
817d8956817SJouni Malinen 		wpa_command(dut->station_ifname_2g, "TERMINATE");
818d8956817SJouni Malinen 	if (dut->station_ifname_5g)
819d8956817SJouni Malinen 		wpa_command(dut->station_ifname_5g, "TERMINATE");
82078217db5SJouni Malinen 	dut->sta_2g_started = 0;
82178217db5SJouni Malinen 	dut->sta_5g_started = 0;
822cd4e3c3eSJouni Malinen }
823