xref: /wlan-dirver/utils/sigma-dut/wpa_helpers.c (revision f2af39bf030363aa88508478e58a9b1001931f26)
1cd4e3c3eSJouni Malinen /*
2cd4e3c3eSJouni Malinen  * Sigma Control API DUT (station/AP)
3cd4e3c3eSJouni Malinen  * Copyright (c) 2010-2011, Atheros Communications, Inc.
4cd4e3c3eSJouni Malinen  * Copyright (c) 2011-2014, Qualcomm Atheros, Inc.
5cd4e3c3eSJouni Malinen  * All Rights Reserved.
6cd4e3c3eSJouni Malinen  * Licensed under the Clear BSD license. See README for more details.
7cd4e3c3eSJouni Malinen  */
8cd4e3c3eSJouni Malinen 
9cd4e3c3eSJouni Malinen #include "sigma_dut.h"
10cd4e3c3eSJouni Malinen #include <sys/stat.h>
11cd4e3c3eSJouni Malinen #include "wpa_ctrl.h"
12cd4e3c3eSJouni Malinen #include "wpa_helpers.h"
13cd4e3c3eSJouni Malinen 
14cd4e3c3eSJouni Malinen 
15cd4e3c3eSJouni Malinen extern char *sigma_main_ifname;
16cd4e3c3eSJouni Malinen extern char *sigma_station_ifname;
17*f2af39bfSDanny Segal extern char *sigma_p2p_ifname;
18cd4e3c3eSJouni Malinen extern char *sigma_wpas_ctrl;
19cd4e3c3eSJouni Malinen 
20cd4e3c3eSJouni Malinen 
21cd4e3c3eSJouni Malinen char * get_main_ifname(void)
22cd4e3c3eSJouni Malinen {
23cd4e3c3eSJouni Malinen 	enum driver_type drv = get_driver_type();
24cd4e3c3eSJouni Malinen 	enum openwrt_driver_type openwrt_drv = get_openwrt_driver_type();
25cd4e3c3eSJouni Malinen 
26cd4e3c3eSJouni Malinen 	if (sigma_main_ifname)
27cd4e3c3eSJouni Malinen 		return sigma_main_ifname;
28cd4e3c3eSJouni Malinen 
29cd4e3c3eSJouni Malinen       if (if_nametoindex("p2p0") > 0)
30cd4e3c3eSJouni Malinen 	      return "p2p0";
31cd4e3c3eSJouni Malinen       if (if_nametoindex("wlan1") > 0) {
32cd4e3c3eSJouni Malinen 	      struct stat s;
33cd4e3c3eSJouni Malinen 	      if (stat("/sys/module/mac80211", &s) == 0 &&
34cd4e3c3eSJouni Malinen 		  if_nametoindex("wlan0")) {
35cd4e3c3eSJouni Malinen 		      /*
36cd4e3c3eSJouni Malinen 		       * Likely a dual-radio AP device; use wlan0 for STA/P2P
37cd4e3c3eSJouni Malinen 		       * operations.
38cd4e3c3eSJouni Malinen 		       */
39cd4e3c3eSJouni Malinen 		      return "wlan0";
40cd4e3c3eSJouni Malinen 	      }
41cd4e3c3eSJouni Malinen 	      return "wlan1";
42cd4e3c3eSJouni Malinen       }
43cd4e3c3eSJouni Malinen       if (if_nametoindex("wlan0") > 0)
44cd4e3c3eSJouni Malinen 	      return "wlan0";
45cd4e3c3eSJouni Malinen 
46cd4e3c3eSJouni Malinen       if (drv == DRIVER_ATHEROS || openwrt_drv == OPENWRT_DRIVER_ATHEROS) {
47cd4e3c3eSJouni Malinen 	      if (if_nametoindex("ath2") > 0)
48cd4e3c3eSJouni Malinen 		      return "ath2";
49cd4e3c3eSJouni Malinen 	      else if (if_nametoindex("ath1") > 0)
50cd4e3c3eSJouni Malinen 		      return "ath1";
51cd4e3c3eSJouni Malinen 	      else
52cd4e3c3eSJouni Malinen 		      return "ath0";
53cd4e3c3eSJouni Malinen       }
54cd4e3c3eSJouni Malinen 
55cd4e3c3eSJouni Malinen       return "unknown";
56cd4e3c3eSJouni Malinen }
57cd4e3c3eSJouni Malinen 
58cd4e3c3eSJouni Malinen 
59cd4e3c3eSJouni Malinen char * get_station_ifname(void)
60cd4e3c3eSJouni Malinen {
61cd4e3c3eSJouni Malinen 	if (sigma_station_ifname)
62cd4e3c3eSJouni Malinen 		return sigma_station_ifname;
63cd4e3c3eSJouni Malinen 
64cd4e3c3eSJouni Malinen 	/*
65cd4e3c3eSJouni Malinen 	 * If we have both wlan0 and wlan1, assume the first one is the station
66cd4e3c3eSJouni Malinen 	 * interface.
67cd4e3c3eSJouni Malinen 	 */
68cd4e3c3eSJouni Malinen 	if (if_nametoindex("wlan1") > 0 && if_nametoindex("wlan0") > 0)
69cd4e3c3eSJouni Malinen 		return "wlan0";
70cd4e3c3eSJouni Malinen 
71cd4e3c3eSJouni Malinen 	if (if_nametoindex("ath0") > 0)
72cd4e3c3eSJouni Malinen 		return "ath0";
73cd4e3c3eSJouni Malinen 
74cd4e3c3eSJouni Malinen 	/* If nothing else matches, hope for best and guess.. */
75cd4e3c3eSJouni Malinen 	return "wlan0";
76cd4e3c3eSJouni Malinen }
77cd4e3c3eSJouni Malinen 
78cd4e3c3eSJouni Malinen 
79*f2af39bfSDanny Segal const char * get_p2p_ifname(const char *primary_ifname)
80*f2af39bfSDanny Segal {
81*f2af39bfSDanny Segal 	if (strcmp(get_station_ifname(), primary_ifname) != 0)
82*f2af39bfSDanny Segal 		return primary_ifname;
83*f2af39bfSDanny Segal 
84*f2af39bfSDanny Segal 	if (sigma_p2p_ifname)
85*f2af39bfSDanny Segal 		return sigma_p2p_ifname;
86*f2af39bfSDanny Segal 
87*f2af39bfSDanny Segal 	return get_station_ifname();
88*f2af39bfSDanny Segal }
89*f2af39bfSDanny Segal 
90*f2af39bfSDanny Segal 
91cd4e3c3eSJouni Malinen void dut_ifc_reset(struct sigma_dut *dut)
92cd4e3c3eSJouni Malinen {
93cd4e3c3eSJouni Malinen 	char buf[256];
94cd4e3c3eSJouni Malinen 	char *ifc = get_station_ifname();
95cd4e3c3eSJouni Malinen 
96cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "ifconfig %s down", ifc);
97cd4e3c3eSJouni Malinen 	run_system(dut, buf);
98cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "ifconfig %s up", ifc);
99cd4e3c3eSJouni Malinen 	run_system(dut, buf);
100cd4e3c3eSJouni Malinen }
101cd4e3c3eSJouni Malinen 
102cd4e3c3eSJouni Malinen 
103cd4e3c3eSJouni Malinen int wpa_command(const char *ifname, const char *cmd)
104cd4e3c3eSJouni Malinen {
105cd4e3c3eSJouni Malinen 	struct wpa_ctrl *ctrl;
106cd4e3c3eSJouni Malinen 	char buf[128];
107cd4e3c3eSJouni Malinen 	size_t len;
108cd4e3c3eSJouni Malinen 
109cd4e3c3eSJouni Malinen 	printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
110cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl, ifname);
111cd4e3c3eSJouni Malinen 	ctrl = wpa_ctrl_open(buf);
112cd4e3c3eSJouni Malinen 	if (ctrl == NULL) {
113cd4e3c3eSJouni Malinen 		printf("wpa_command: wpa_ctrl_open(%s) failed\n", buf);
114cd4e3c3eSJouni Malinen 		return -1;
115cd4e3c3eSJouni Malinen 	}
116cd4e3c3eSJouni Malinen 	len = sizeof(buf);
117cd4e3c3eSJouni Malinen 	if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
118cd4e3c3eSJouni Malinen 		printf("wpa_command: wpa_ctrl_request failed\n");
119cd4e3c3eSJouni Malinen 		wpa_ctrl_close(ctrl);
120cd4e3c3eSJouni Malinen 		return -1;
121cd4e3c3eSJouni Malinen 	}
122cd4e3c3eSJouni Malinen 	wpa_ctrl_close(ctrl);
123cd4e3c3eSJouni Malinen 	buf[len] = '\0';
124cd4e3c3eSJouni Malinen 	if (strncmp(buf, "FAIL", 4) == 0) {
125cd4e3c3eSJouni Malinen 		printf("wpa_command: Command failed (FAIL received)\n");
126cd4e3c3eSJouni Malinen 		return -1;
127cd4e3c3eSJouni Malinen 	}
128cd4e3c3eSJouni Malinen 	return 0;
129cd4e3c3eSJouni Malinen }
130cd4e3c3eSJouni Malinen 
131cd4e3c3eSJouni Malinen 
132cd4e3c3eSJouni Malinen int wpa_command_resp(const char *ifname, const char *cmd,
133cd4e3c3eSJouni Malinen 		     char *resp, size_t resp_size)
134cd4e3c3eSJouni Malinen {
135cd4e3c3eSJouni Malinen 	struct wpa_ctrl *ctrl;
136cd4e3c3eSJouni Malinen 	char buf[128];
137cd4e3c3eSJouni Malinen 	size_t len;
138cd4e3c3eSJouni Malinen 
139cd4e3c3eSJouni Malinen 	printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
140cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl, ifname);
141cd4e3c3eSJouni Malinen 	ctrl = wpa_ctrl_open(buf);
142cd4e3c3eSJouni Malinen 	if (ctrl == NULL) {
143cd4e3c3eSJouni Malinen 		printf("wpa_command: wpa_ctrl_open(%s) failed\n", buf);
144cd4e3c3eSJouni Malinen 		return -1;
145cd4e3c3eSJouni Malinen 	}
146cd4e3c3eSJouni Malinen 	len = resp_size;
147cd4e3c3eSJouni Malinen 	if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), resp, &len, NULL) < 0) {
148cd4e3c3eSJouni Malinen 		printf("wpa_command: wpa_ctrl_request failed\n");
149cd4e3c3eSJouni Malinen 		wpa_ctrl_close(ctrl);
150cd4e3c3eSJouni Malinen 		return -1;
151cd4e3c3eSJouni Malinen 	}
152cd4e3c3eSJouni Malinen 	wpa_ctrl_close(ctrl);
153cd4e3c3eSJouni Malinen 	resp[len] = '\0';
154cd4e3c3eSJouni Malinen 	return 0;
155cd4e3c3eSJouni Malinen }
156cd4e3c3eSJouni Malinen 
157cd4e3c3eSJouni Malinen 
158cd4e3c3eSJouni Malinen struct wpa_ctrl * open_wpa_mon(const char *ifname)
159cd4e3c3eSJouni Malinen {
160cd4e3c3eSJouni Malinen 	struct wpa_ctrl *ctrl;
161cd4e3c3eSJouni Malinen 	char path[256];
162cd4e3c3eSJouni Malinen 
163cd4e3c3eSJouni Malinen 	snprintf(path, sizeof(path), "%s%s", sigma_wpas_ctrl, ifname);
164cd4e3c3eSJouni Malinen 	ctrl = wpa_ctrl_open(path);
165cd4e3c3eSJouni Malinen 	if (ctrl == NULL)
166cd4e3c3eSJouni Malinen 		return NULL;
167cd4e3c3eSJouni Malinen 	if (wpa_ctrl_attach(ctrl) < 0) {
168cd4e3c3eSJouni Malinen 		wpa_ctrl_close(ctrl);
169cd4e3c3eSJouni Malinen 		return NULL;
170cd4e3c3eSJouni Malinen 	}
171cd4e3c3eSJouni Malinen 
172cd4e3c3eSJouni Malinen 	return ctrl;
173cd4e3c3eSJouni Malinen }
174cd4e3c3eSJouni Malinen 
175cd4e3c3eSJouni Malinen 
176cd4e3c3eSJouni Malinen int get_wpa_cli_events(struct sigma_dut *dut, struct wpa_ctrl *mon,
177cd4e3c3eSJouni Malinen 		       const char **events, char *buf, size_t buf_size)
178cd4e3c3eSJouni Malinen {
179cd4e3c3eSJouni Malinen 	int fd, ret;
180cd4e3c3eSJouni Malinen 	fd_set rfd;
181cd4e3c3eSJouni Malinen 	char *pos;
182cd4e3c3eSJouni Malinen 	struct timeval tv;
183cd4e3c3eSJouni Malinen 	time_t start, now;
184cd4e3c3eSJouni Malinen 	int i;
185cd4e3c3eSJouni Malinen 
186cd4e3c3eSJouni Malinen 	for (i = 0; events[i]; i++) {
187cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG,
188cd4e3c3eSJouni Malinen 				"Waiting for wpa_cli event: %s", events[i]);
189cd4e3c3eSJouni Malinen 	}
190cd4e3c3eSJouni Malinen 	fd = wpa_ctrl_get_fd(mon);
191cd4e3c3eSJouni Malinen 	if (fd < 0)
192cd4e3c3eSJouni Malinen 		return -1;
193cd4e3c3eSJouni Malinen 
194cd4e3c3eSJouni Malinen 	time(&start);
195cd4e3c3eSJouni Malinen 	while (1) {
196cd4e3c3eSJouni Malinen 		size_t len;
197cd4e3c3eSJouni Malinen 
198cd4e3c3eSJouni Malinen 		FD_ZERO(&rfd);
199cd4e3c3eSJouni Malinen 		FD_SET(fd, &rfd);
200cd4e3c3eSJouni Malinen 
201cd4e3c3eSJouni Malinen 		time(&now);
202cd4e3c3eSJouni Malinen 		if ((unsigned int) (now - start) >= dut->default_timeout)
203cd4e3c3eSJouni Malinen 			tv.tv_sec = 1;
204cd4e3c3eSJouni Malinen 		else
205cd4e3c3eSJouni Malinen 			tv.tv_sec = dut->default_timeout -
206cd4e3c3eSJouni Malinen 				(unsigned int) (now - start) + 1;
207cd4e3c3eSJouni Malinen 		tv.tv_usec = 0;
208cd4e3c3eSJouni Malinen 		ret = select(fd + 1, &rfd, NULL, NULL, &tv);
209cd4e3c3eSJouni Malinen 		if (ret == 0) {
210cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO, "Timeout on "
211cd4e3c3eSJouni Malinen 					"waiting for events");
212cd4e3c3eSJouni Malinen 			return -1;
213cd4e3c3eSJouni Malinen 		}
214cd4e3c3eSJouni Malinen 		if (ret < 0) {
215cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO, "select: %s",
216cd4e3c3eSJouni Malinen 					strerror(errno));
217cd4e3c3eSJouni Malinen 			return -1;
218cd4e3c3eSJouni Malinen 		}
219cd4e3c3eSJouni Malinen 		len = buf_size;
220cd4e3c3eSJouni Malinen 		if (wpa_ctrl_recv(mon, buf, &len) < 0) {
221cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_ERROR, "Failure while "
222cd4e3c3eSJouni Malinen 					"waiting for events");
223cd4e3c3eSJouni Malinen 			return -1;
224cd4e3c3eSJouni Malinen 		}
225cd4e3c3eSJouni Malinen 		if (len == buf_size)
226cd4e3c3eSJouni Malinen 			len--;
227cd4e3c3eSJouni Malinen 		buf[len] = '\0';
228cd4e3c3eSJouni Malinen 
229cd4e3c3eSJouni Malinen 		pos = strchr(buf, '>');
230cd4e3c3eSJouni Malinen 		if (pos) {
231cd4e3c3eSJouni Malinen 			for (i = 0; events[i]; i++) {
232cd4e3c3eSJouni Malinen 				if (strncmp(pos + 1, events[i],
233cd4e3c3eSJouni Malinen 					    strlen(events[i])) == 0)
234cd4e3c3eSJouni Malinen 					return 0; /* Event found */
235cd4e3c3eSJouni Malinen 			}
236cd4e3c3eSJouni Malinen 		}
237cd4e3c3eSJouni Malinen 
238cd4e3c3eSJouni Malinen 		time(&now);
239cd4e3c3eSJouni Malinen 		if ((unsigned int) (now - start) > dut->default_timeout) {
240cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO, "Timeout on "
241cd4e3c3eSJouni Malinen 					"waiting for event");
242cd4e3c3eSJouni Malinen 			return -1;
243cd4e3c3eSJouni Malinen 		}
244cd4e3c3eSJouni Malinen 	}
245cd4e3c3eSJouni Malinen }
246cd4e3c3eSJouni Malinen 
247cd4e3c3eSJouni Malinen 
248cd4e3c3eSJouni Malinen int get_wpa_cli_event2(struct sigma_dut *dut, struct wpa_ctrl *mon,
249cd4e3c3eSJouni Malinen 		       const char *event, const char *event2,
250cd4e3c3eSJouni Malinen 		       char *buf, size_t buf_size)
251cd4e3c3eSJouni Malinen {
252cd4e3c3eSJouni Malinen 	const char *events[3] = { event, event2, NULL };
253cd4e3c3eSJouni Malinen 	return get_wpa_cli_events(dut, mon, events, buf, buf_size);
254cd4e3c3eSJouni Malinen }
255cd4e3c3eSJouni Malinen 
256cd4e3c3eSJouni Malinen 
257cd4e3c3eSJouni Malinen int get_wpa_cli_event(struct sigma_dut *dut, struct wpa_ctrl *mon,
258cd4e3c3eSJouni Malinen 		      const char *event, char *buf, size_t buf_size)
259cd4e3c3eSJouni Malinen {
260cd4e3c3eSJouni Malinen 	return get_wpa_cli_event2(dut, mon, event, NULL, buf, buf_size);
261cd4e3c3eSJouni Malinen }
262cd4e3c3eSJouni Malinen 
263cd4e3c3eSJouni Malinen 
264cd4e3c3eSJouni Malinen int get_wpa_status(const char *ifname, const char *field, char *obuf,
265cd4e3c3eSJouni Malinen 		   size_t obuf_size)
266cd4e3c3eSJouni Malinen {
267cd4e3c3eSJouni Malinen 	struct wpa_ctrl *ctrl;
268cd4e3c3eSJouni Malinen 	char buf[4096];
269cd4e3c3eSJouni Malinen 	char *pos, *end;
270cd4e3c3eSJouni Malinen 	size_t len, flen;
271cd4e3c3eSJouni Malinen 
272cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl, ifname);
273cd4e3c3eSJouni Malinen 	ctrl = wpa_ctrl_open(buf);
274cd4e3c3eSJouni Malinen 	if (ctrl == NULL)
275cd4e3c3eSJouni Malinen 		return -1;
276cd4e3c3eSJouni Malinen 	len = sizeof(buf);
277cd4e3c3eSJouni Malinen 	if (wpa_ctrl_request(ctrl, "STATUS", 6, buf, &len, NULL) < 0) {
278cd4e3c3eSJouni Malinen 		wpa_ctrl_close(ctrl);
279cd4e3c3eSJouni Malinen 		return -1;
280cd4e3c3eSJouni Malinen 	}
281cd4e3c3eSJouni Malinen 	wpa_ctrl_close(ctrl);
282cd4e3c3eSJouni Malinen 	buf[len] = '\0';
283cd4e3c3eSJouni Malinen 
284cd4e3c3eSJouni Malinen 	flen = strlen(field);
285cd4e3c3eSJouni Malinen 	pos = buf;
286cd4e3c3eSJouni Malinen 	while (pos + flen < buf + len) {
287cd4e3c3eSJouni Malinen 		if (pos > buf) {
288cd4e3c3eSJouni Malinen 			if (*pos != '\n') {
289cd4e3c3eSJouni Malinen 				pos++;
290cd4e3c3eSJouni Malinen 				continue;
291cd4e3c3eSJouni Malinen 			}
292cd4e3c3eSJouni Malinen 			pos++;
293cd4e3c3eSJouni Malinen 		}
294cd4e3c3eSJouni Malinen 		if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') {
295cd4e3c3eSJouni Malinen 			pos++;
296cd4e3c3eSJouni Malinen 			continue;
297cd4e3c3eSJouni Malinen 		}
298cd4e3c3eSJouni Malinen 		pos += flen + 1;
299cd4e3c3eSJouni Malinen 		end = strchr(pos, '\n');
300cd4e3c3eSJouni Malinen 		if (end == NULL)
301cd4e3c3eSJouni Malinen 			return -1;
302cd4e3c3eSJouni Malinen 		*end++ = '\0';
303cd4e3c3eSJouni Malinen 		if (end - pos > (int) obuf_size)
304cd4e3c3eSJouni Malinen 			return -1;
305cd4e3c3eSJouni Malinen 		memcpy(obuf, pos, end - pos);
306cd4e3c3eSJouni Malinen 		return 0;
307cd4e3c3eSJouni Malinen 	}
308cd4e3c3eSJouni Malinen 
309cd4e3c3eSJouni Malinen 	return -1;
310cd4e3c3eSJouni Malinen }
311cd4e3c3eSJouni Malinen 
312cd4e3c3eSJouni Malinen 
313cd4e3c3eSJouni Malinen int wait_ip_addr(struct sigma_dut *dut, const char *ifname, int timeout)
314cd4e3c3eSJouni Malinen {
315cd4e3c3eSJouni Malinen 	char ip[30];
316cd4e3c3eSJouni Malinen 	int count = timeout;
317cd4e3c3eSJouni Malinen 
318cd4e3c3eSJouni Malinen 	while (count > 0) {
319cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: ifname='%s' - %d "
320cd4e3c3eSJouni Malinen 				"seconds remaining",
321cd4e3c3eSJouni Malinen 				__func__, ifname, count);
322cd4e3c3eSJouni Malinen 		count--;
323cd4e3c3eSJouni Malinen 		if (get_wpa_status(ifname, "ip_address", ip, sizeof(ip)) == 0
324cd4e3c3eSJouni Malinen 		    && strlen(ip) > 0) {
325cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO, "IP address "
326cd4e3c3eSJouni Malinen 					"found: '%s'", ip);
327cd4e3c3eSJouni Malinen 			return 0;
328cd4e3c3eSJouni Malinen 		}
329cd4e3c3eSJouni Malinen 		sleep(1);
330cd4e3c3eSJouni Malinen 	}
331cd4e3c3eSJouni Malinen 	sigma_dut_print(dut, DUT_MSG_INFO, "%s: Could not get IP address for "
332cd4e3c3eSJouni Malinen 			"ifname='%s'", __func__, ifname);
333cd4e3c3eSJouni Malinen 	return -1;
334cd4e3c3eSJouni Malinen }
335cd4e3c3eSJouni Malinen 
336cd4e3c3eSJouni Malinen 
337cd4e3c3eSJouni Malinen void remove_wpa_networks(const char *ifname)
338cd4e3c3eSJouni Malinen {
339cd4e3c3eSJouni Malinen 	char buf[4096];
340cd4e3c3eSJouni Malinen 	char cmd[256];
341cd4e3c3eSJouni Malinen 	char *pos;
342cd4e3c3eSJouni Malinen 
343cd4e3c3eSJouni Malinen 	if (wpa_command_resp(ifname, "LIST_NETWORKS", buf, sizeof(buf)) < 0)
344cd4e3c3eSJouni Malinen 		return;
345cd4e3c3eSJouni Malinen 
346cd4e3c3eSJouni Malinen 	/* Skip the first line (header) */
347cd4e3c3eSJouni Malinen 	pos = strchr(buf, '\n');
348cd4e3c3eSJouni Malinen 	if (pos == NULL)
349cd4e3c3eSJouni Malinen 		return;
350cd4e3c3eSJouni Malinen 	pos++;
351cd4e3c3eSJouni Malinen 	while (pos && pos[0]) {
352cd4e3c3eSJouni Malinen 		int id = atoi(pos);
353cd4e3c3eSJouni Malinen 		snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", id);
354cd4e3c3eSJouni Malinen 		wpa_command(ifname, cmd);
355cd4e3c3eSJouni Malinen 		pos = strchr(pos, '\n');
356cd4e3c3eSJouni Malinen 		if (pos)
357cd4e3c3eSJouni Malinen 			pos++;
358cd4e3c3eSJouni Malinen 	}
359cd4e3c3eSJouni Malinen }
360cd4e3c3eSJouni Malinen 
361cd4e3c3eSJouni Malinen 
362cd4e3c3eSJouni Malinen int add_network(const char *ifname)
363cd4e3c3eSJouni Malinen {
364cd4e3c3eSJouni Malinen 	char res[30];
365cd4e3c3eSJouni Malinen 
366cd4e3c3eSJouni Malinen 	if (wpa_command_resp(ifname, "ADD_NETWORK", res, sizeof(res)) < 0)
367cd4e3c3eSJouni Malinen 		return -1;
368cd4e3c3eSJouni Malinen 	return atoi(res);
369cd4e3c3eSJouni Malinen }
370cd4e3c3eSJouni Malinen 
371cd4e3c3eSJouni Malinen 
372cd4e3c3eSJouni Malinen int set_network(const char *ifname, int id, const char *field,
373cd4e3c3eSJouni Malinen 		const char *value)
374cd4e3c3eSJouni Malinen {
375cd4e3c3eSJouni Malinen 	char buf[200];
376cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "SET_NETWORK %d %s %s", id, field, value);
377cd4e3c3eSJouni Malinen 	return wpa_command(ifname, buf);
378cd4e3c3eSJouni Malinen }
379cd4e3c3eSJouni Malinen 
380cd4e3c3eSJouni Malinen 
381cd4e3c3eSJouni Malinen int set_network_quoted(const char *ifname, int id, const char *field,
382cd4e3c3eSJouni Malinen 		       const char *value)
383cd4e3c3eSJouni Malinen {
384cd4e3c3eSJouni Malinen 	char buf[200];
385cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "SET_NETWORK %d %s \"%s\"",
386cd4e3c3eSJouni Malinen 		 id, field, value);
387cd4e3c3eSJouni Malinen 	return wpa_command(ifname, buf);
388cd4e3c3eSJouni Malinen }
389cd4e3c3eSJouni Malinen 
390cd4e3c3eSJouni Malinen 
391cd4e3c3eSJouni Malinen int add_cred(const char *ifname)
392cd4e3c3eSJouni Malinen {
393cd4e3c3eSJouni Malinen 	char res[30];
394cd4e3c3eSJouni Malinen 
395cd4e3c3eSJouni Malinen 	if (wpa_command_resp(ifname, "ADD_CRED", res, sizeof(res)) < 0)
396cd4e3c3eSJouni Malinen 		return -1;
397cd4e3c3eSJouni Malinen 	return atoi(res);
398cd4e3c3eSJouni Malinen }
399cd4e3c3eSJouni Malinen 
400cd4e3c3eSJouni Malinen 
401cd4e3c3eSJouni Malinen int set_cred(const char *ifname, int id, const char *field, const char *value)
402cd4e3c3eSJouni Malinen {
403cd4e3c3eSJouni Malinen 	char buf[200];
404cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "SET_CRED %d %s %s", id, field, value);
405cd4e3c3eSJouni Malinen 	return wpa_command(ifname, buf);
406cd4e3c3eSJouni Malinen }
407cd4e3c3eSJouni Malinen 
408cd4e3c3eSJouni Malinen 
409cd4e3c3eSJouni Malinen int set_cred_quoted(const char *ifname, int id, const char *field,
410cd4e3c3eSJouni Malinen 		    const char *value)
411cd4e3c3eSJouni Malinen {
412cd4e3c3eSJouni Malinen 	char buf[200];
413cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "SET_CRED %d %s \"%s\"",
414cd4e3c3eSJouni Malinen 		 id, field, value);
415cd4e3c3eSJouni Malinen 	return wpa_command(ifname, buf);
416cd4e3c3eSJouni Malinen }
417cd4e3c3eSJouni Malinen 
418cd4e3c3eSJouni Malinen 
419cd4e3c3eSJouni Malinen int start_sta_mode(struct sigma_dut *dut)
420cd4e3c3eSJouni Malinen {
421cd4e3c3eSJouni Malinen 	FILE *f;
422cd4e3c3eSJouni Malinen 	char buf[100];
423cd4e3c3eSJouni Malinen 	char *ifname;
424cd4e3c3eSJouni Malinen 	char *tmp, *pos;
425cd4e3c3eSJouni Malinen 
426cd4e3c3eSJouni Malinen 	if (dut->mode == SIGMA_MODE_STATION)
427cd4e3c3eSJouni Malinen 		return 0;
428cd4e3c3eSJouni Malinen 
429cd4e3c3eSJouni Malinen 	if (dut->mode == SIGMA_MODE_AP) {
430cd4e3c3eSJouni Malinen 		if (system("killall hostapd") == 0) {
431cd4e3c3eSJouni Malinen 			int i;
432cd4e3c3eSJouni Malinen 
433cd4e3c3eSJouni Malinen 			/* Wait some time to allow hostapd to complete cleanup
434cd4e3c3eSJouni Malinen 			 * before starting a new process */
435cd4e3c3eSJouni Malinen 			for (i = 0; i < 10; i++) {
436cd4e3c3eSJouni Malinen 				usleep(500000);
437cd4e3c3eSJouni Malinen 				if (system("pidof hostapd") != 0)
438cd4e3c3eSJouni Malinen 					break;
439cd4e3c3eSJouni Malinen 			}
440cd4e3c3eSJouni Malinen 		}
441cd4e3c3eSJouni Malinen 	}
442cd4e3c3eSJouni Malinen 
443cd4e3c3eSJouni Malinen 	if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) {
444cd4e3c3eSJouni Malinen 		snprintf(buf, sizeof(buf), "ifconfig %s down",
445cd4e3c3eSJouni Malinen 			 dut->sniffer_ifname);
446cd4e3c3eSJouni Malinen 		if (system(buf) != 0) {
447cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
448cd4e3c3eSJouni Malinen 					"Failed to run '%s'", buf);
449cd4e3c3eSJouni Malinen 		}
450cd4e3c3eSJouni Malinen 		snprintf(buf, sizeof(buf), "iw dev %s set type station",
451cd4e3c3eSJouni Malinen 			 dut->sniffer_ifname);
452cd4e3c3eSJouni Malinen 		if (system(buf) != 0) {
453cd4e3c3eSJouni Malinen 			sigma_dut_print(dut, DUT_MSG_INFO,
454cd4e3c3eSJouni Malinen 					"Failed to run '%s'", buf);
455cd4e3c3eSJouni Malinen 		}
456cd4e3c3eSJouni Malinen 	}
457cd4e3c3eSJouni Malinen 
458cd4e3c3eSJouni Malinen 	dut->mode = SIGMA_MODE_STATION;
459cd4e3c3eSJouni Malinen 
460cd4e3c3eSJouni Malinen 	ifname = get_main_ifname();
461cd4e3c3eSJouni Malinen 	if (wpa_command(ifname, "PING") == 0)
462cd4e3c3eSJouni Malinen 		return 0; /* wpa_supplicant is already running */
463cd4e3c3eSJouni Malinen 
464cd4e3c3eSJouni Malinen 	/* Start wpa_supplicant */
465cd4e3c3eSJouni Malinen 	f = fopen(SIGMA_TMPDIR "/sigma_dut-sta.conf", "w");
466cd4e3c3eSJouni Malinen 	if (f == NULL)
467cd4e3c3eSJouni Malinen 		return -1;
468cd4e3c3eSJouni Malinen 
469cd4e3c3eSJouni Malinen 	tmp = strdup(sigma_wpas_ctrl);
470cd4e3c3eSJouni Malinen 	if (tmp == NULL) {
471cd4e3c3eSJouni Malinen 		fclose(f);
472cd4e3c3eSJouni Malinen 		return -1;
473cd4e3c3eSJouni Malinen 	}
474cd4e3c3eSJouni Malinen 	pos = tmp;
475cd4e3c3eSJouni Malinen 	while (pos[0] != '\0' && pos[1] != '\0')
476cd4e3c3eSJouni Malinen 		pos++;
477cd4e3c3eSJouni Malinen 	if (*pos == '/')
478cd4e3c3eSJouni Malinen 		*pos = '\0';
479cd4e3c3eSJouni Malinen 	fprintf(f, "ctrl_interface=%s\n", tmp);
480cd4e3c3eSJouni Malinen 	free(tmp);
481cd4e3c3eSJouni Malinen 	fprintf(f, "device_name=Test client\n");
482cd4e3c3eSJouni Malinen 	fprintf(f, "device_type=1-0050F204-1\n");
483cd4e3c3eSJouni Malinen 	fclose(f);
484cd4e3c3eSJouni Malinen 
485cd4e3c3eSJouni Malinen #ifdef  __QNXNTO__
486cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "wpa_supplicant -Dqca -i%s -B "
487cd4e3c3eSJouni Malinen 		 "-c" SIGMA_TMPDIR "/sigma_dut-sta.conf", ifname);
488cd4e3c3eSJouni Malinen #else /*__QNXNTO__*/
489cd4e3c3eSJouni Malinen 	snprintf(buf, sizeof(buf), "wpa_supplicant -Dnl80211 -i%s -B "
490cd4e3c3eSJouni Malinen 		 "-c" SIGMA_TMPDIR "/sigma_dut-sta.conf", ifname);
491cd4e3c3eSJouni Malinen #endif /*__QNXNTO__*/
492cd4e3c3eSJouni Malinen 	if (system(buf) != 0) {
493cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s'", buf);
494cd4e3c3eSJouni Malinen 		return -1;
495cd4e3c3eSJouni Malinen 	}
496cd4e3c3eSJouni Malinen 
497cd4e3c3eSJouni Malinen 	sleep(1);
498cd4e3c3eSJouni Malinen 
499cd4e3c3eSJouni Malinen 	if (wpa_command(ifname, "PING")) {
500cd4e3c3eSJouni Malinen 		sigma_dut_print(dut, DUT_MSG_INFO, "Failed to communicate "
501cd4e3c3eSJouni Malinen 				"with wpa_supplicant");
502cd4e3c3eSJouni Malinen 		return -1;
503cd4e3c3eSJouni Malinen 	}
504cd4e3c3eSJouni Malinen 
505cd4e3c3eSJouni Malinen 	return 0;
506cd4e3c3eSJouni Malinen }
507cd4e3c3eSJouni Malinen 
508cd4e3c3eSJouni Malinen 
509cd4e3c3eSJouni Malinen void stop_sta_mode(struct sigma_dut *dut)
510cd4e3c3eSJouni Malinen {
511cd4e3c3eSJouni Malinen 	wpa_command("wlan0", "TERMINATE");
512cd4e3c3eSJouni Malinen 	wpa_command("wlan1", "TERMINATE");
513cd4e3c3eSJouni Malinen 	wpa_command("ath0", "TERMINATE");
514cd4e3c3eSJouni Malinen 	wpa_command("ath1", "TERMINATE");
515cd4e3c3eSJouni Malinen }
516