blob: a641a5641134f4bcf4baf7eeb0e55cef31d06594 [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (station/AP)
3 * Copyright (c) 2010-2011, Atheros Communications, Inc.
Jouni Malinen9d7e31d2017-12-22 18:55:04 +02004 * Copyright (c) 2011-2014, 2016, Qualcomm Atheros, Inc.
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07005 * Copyright (c) 2018, The Linux Foundation
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006 * All Rights Reserved.
7 * Licensed under the Clear BSD license. See README for more details.
8 */
9
10#include "sigma_dut.h"
11#include <sys/stat.h>
12#include "wpa_ctrl.h"
13#include "wpa_helpers.h"
14
15
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +020016#define DEFAULT_HAPD_CTRL_PATH "/var/run/hostapd/"
17
Jouni Malinencd4e3c32015-10-29 12:39:56 +020018extern char *sigma_wpas_ctrl;
Rajiv Ranjan525dbfd2018-04-20 17:42:48 +053019extern char *client_socket_path;
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +020020extern char *sigma_hapd_ctrl;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020021
22
Jouni Malinen016ae6c2019-11-04 17:00:01 +020023const char * get_main_ifname(struct sigma_dut *dut)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020024{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020025 enum driver_type drv = get_driver_type(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020026 enum openwrt_driver_type openwrt_drv = get_openwrt_driver_type();
27
Jouni Malinenb21f0542019-11-04 17:53:38 +020028 if (dut->main_ifname) {
29 if (dut->use_5g && dut->main_ifname_5g)
30 return dut->main_ifname_5g;
31 if (!dut->use_5g && dut->main_ifname_2g)
32 return dut->main_ifname_2g;
Jouni Malinend2095482019-11-04 17:10:43 +020033 return dut->main_ifname;
Jouni Malinenb21f0542019-11-04 17:53:38 +020034 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020035
Rajesh Babu Sarvepalli96c347d2016-04-18 12:15:32 +053036 if (drv == DRIVER_ATHEROS || openwrt_drv == OPENWRT_DRIVER_ATHEROS) {
37 if (if_nametoindex("ath2") > 0)
38 return "ath2";
39 else if (if_nametoindex("ath1") > 0)
40 return "ath1";
41 else
42 return "ath0";
43 }
44
Rajesh Babu Sarvepalli78d1a882016-04-18 12:15:32 +053045 if (if_nametoindex("p2p0") > 0)
46 return "p2p0";
47 if (if_nametoindex("wlan1") > 0) {
48 struct stat s;
49 if (stat("/sys/module/mac80211", &s) == 0 &&
50 if_nametoindex("wlan0")) {
51 /*
52 * Likely a dual-radio AP device; use wlan0 for STA/P2P
53 * operations.
54 */
55 return "wlan0";
56 }
57 return "wlan1";
58 }
59 if (if_nametoindex("wlan0") > 0)
60 return "wlan0";
Jouni Malinencd4e3c32015-10-29 12:39:56 +020061
Rajesh Babu Sarvepalli78d1a882016-04-18 12:15:32 +053062 return "unknown";
Jouni Malinencd4e3c32015-10-29 12:39:56 +020063}
64
65
Jouni Malinen016ae6c2019-11-04 17:00:01 +020066const char * get_station_ifname(struct sigma_dut *dut)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020067{
Jouni Malinenb21f0542019-11-04 17:53:38 +020068 if (dut->station_ifname) {
69 if (dut->use_5g && dut->station_ifname_5g)
70 return dut->station_ifname_5g;
71 if (!dut->use_5g && dut->station_ifname_2g)
72 return dut->station_ifname_2g;
Jouni Malinend2095482019-11-04 17:10:43 +020073 return dut->station_ifname;
Jouni Malinenb21f0542019-11-04 17:53:38 +020074 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020075
76 /*
77 * If we have both wlan0 and wlan1, assume the first one is the station
78 * interface.
79 */
80 if (if_nametoindex("wlan1") > 0 && if_nametoindex("wlan0") > 0)
81 return "wlan0";
82
83 if (if_nametoindex("ath0") > 0)
84 return "ath0";
85
86 /* If nothing else matches, hope for best and guess.. */
87 return "wlan0";
88}
89
90
Jouni Malinen016ae6c2019-11-04 17:00:01 +020091const char * get_p2p_ifname(struct sigma_dut *dut, const char *primary_ifname)
Danny Segalf2af39b2016-04-10 16:23:11 +030092{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020093 if (strcmp(get_station_ifname(dut), primary_ifname) != 0)
Danny Segalf2af39b2016-04-10 16:23:11 +030094 return primary_ifname;
95
Jouni Malinen1f76fa62019-11-04 17:30:12 +020096 if (dut->p2p_ifname)
97 return dut->p2p_ifname;
Danny Segalf2af39b2016-04-10 16:23:11 +030098
Jouni Malinen016ae6c2019-11-04 17:00:01 +020099 return get_station_ifname(dut);
Danny Segalf2af39b2016-04-10 16:23:11 +0300100}
101
102
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200103void dut_ifc_reset(struct sigma_dut *dut)
104{
105 char buf[256];
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200106 const char *ifc = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200107
108 snprintf(buf, sizeof(buf), "ifconfig %s down", ifc);
109 run_system(dut, buf);
110 snprintf(buf, sizeof(buf), "ifconfig %s up", ifc);
111 run_system(dut, buf);
112}
113
114
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200115int wpa_ctrl_command(const char *path, const char *ifname, const char *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200116{
117 struct wpa_ctrl *ctrl;
118 char buf[128];
119 size_t len;
120
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200121 snprintf(buf, sizeof(buf), "%s%s", path, ifname);
Rajiv Ranjan525dbfd2018-04-20 17:42:48 +0530122 ctrl = wpa_ctrl_open2(buf, client_socket_path);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200123 if (ctrl == NULL) {
Rajiv Ranjan525dbfd2018-04-20 17:42:48 +0530124 printf("wpa_command: wpa_ctrl_open2(%s) failed\n", buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200125 return -1;
126 }
127 len = sizeof(buf);
128 if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
129 printf("wpa_command: wpa_ctrl_request failed\n");
130 wpa_ctrl_close(ctrl);
131 return -1;
132 }
133 wpa_ctrl_close(ctrl);
134 buf[len] = '\0';
135 if (strncmp(buf, "FAIL", 4) == 0) {
136 printf("wpa_command: Command failed (FAIL received)\n");
137 return -1;
138 }
139 return 0;
140}
141
142
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200143int wpa_command(const char *ifname, const char *cmd)
144{
145 printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
146 return wpa_ctrl_command(sigma_wpas_ctrl, ifname, cmd);
147}
148
149
Alexei Avshalom Lazardc7bf052018-12-23 16:49:49 +0200150int hapd_command(const char *ifname, const char *cmd)
151{
152 const char *path = sigma_hapd_ctrl ? sigma_hapd_ctrl :
153 DEFAULT_HAPD_CTRL_PATH;
154
155 printf("hapd_command(ifname='%s', cmd='%s')\n", ifname, cmd);
156 return wpa_ctrl_command(path, ifname, cmd);
157}
158
159
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200160int wpa_ctrl_command_resp(const char *path, const char *ifname,
161 const char *cmd, char *resp, size_t resp_size)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200162{
163 struct wpa_ctrl *ctrl;
164 char buf[128];
165 size_t len;
166
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200167 snprintf(buf, sizeof(buf), "%s%s", path, ifname);
Rajiv Ranjan525dbfd2018-04-20 17:42:48 +0530168 ctrl = wpa_ctrl_open2(buf, client_socket_path);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200169 if (ctrl == NULL) {
Rajiv Ranjan525dbfd2018-04-20 17:42:48 +0530170 printf("wpa_command: wpa_ctrl_open2(%s) failed\n", buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200171 return -1;
172 }
173 len = resp_size;
174 if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), resp, &len, NULL) < 0) {
175 printf("wpa_command: wpa_ctrl_request failed\n");
176 wpa_ctrl_close(ctrl);
177 return -1;
178 }
179 wpa_ctrl_close(ctrl);
180 resp[len] = '\0';
181 return 0;
182}
183
184
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200185int wpa_command_resp(const char *ifname, const char *cmd,
186 char *resp, size_t resp_size)
187{
188 printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
189 return wpa_ctrl_command_resp(sigma_wpas_ctrl, ifname, cmd,
190 resp, resp_size);
191}
192
193
Alexei Avshalom Lazardc7bf052018-12-23 16:49:49 +0200194int hapd_command_resp(const char *ifname, const char *cmd,
195 char *resp, size_t resp_size)
196{
197 const char *path = sigma_hapd_ctrl ? sigma_hapd_ctrl :
198 DEFAULT_HAPD_CTRL_PATH;
199
200 printf("hapd_command(ifname='%s', cmd='%s')\n", ifname, cmd);
201 return wpa_ctrl_command_resp(path, ifname, cmd, resp, resp_size);
202}
203
204
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200205struct wpa_ctrl * open_wpa_ctrl_mon(const char *ctrl_path, const char *ifname)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200206{
207 struct wpa_ctrl *ctrl;
208 char path[256];
209
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200210 snprintf(path, sizeof(path), "%s%s", ctrl_path, ifname);
Rajiv Ranjan525dbfd2018-04-20 17:42:48 +0530211 ctrl = wpa_ctrl_open2(path, client_socket_path);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200212 if (ctrl == NULL)
213 return NULL;
214 if (wpa_ctrl_attach(ctrl) < 0) {
215 wpa_ctrl_close(ctrl);
216 return NULL;
217 }
218
219 return ctrl;
220}
221
222
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200223struct wpa_ctrl * open_wpa_mon(const char *ifname)
224{
225 return open_wpa_ctrl_mon(sigma_wpas_ctrl, ifname);
226}
227
228
229struct wpa_ctrl * open_hapd_mon(const char *ifname)
230{
231 const char *path = sigma_hapd_ctrl ?
232 sigma_hapd_ctrl : DEFAULT_HAPD_CTRL_PATH;
233
234 return open_wpa_ctrl_mon(path, ifname);
235}
236
237
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200238int get_wpa_cli_events(struct sigma_dut *dut, struct wpa_ctrl *mon,
239 const char **events, char *buf, size_t buf_size)
240{
241 int fd, ret;
242 fd_set rfd;
243 char *pos;
244 struct timeval tv;
245 time_t start, now;
246 int i;
247
248 for (i = 0; events[i]; i++) {
249 sigma_dut_print(dut, DUT_MSG_DEBUG,
250 "Waiting for wpa_cli event: %s", events[i]);
251 }
252 fd = wpa_ctrl_get_fd(mon);
253 if (fd < 0)
254 return -1;
255
256 time(&start);
257 while (1) {
258 size_t len;
259
260 FD_ZERO(&rfd);
261 FD_SET(fd, &rfd);
262
263 time(&now);
264 if ((unsigned int) (now - start) >= dut->default_timeout)
265 tv.tv_sec = 1;
266 else
267 tv.tv_sec = dut->default_timeout -
268 (unsigned int) (now - start) + 1;
269 tv.tv_usec = 0;
270 ret = select(fd + 1, &rfd, NULL, NULL, &tv);
271 if (ret == 0) {
272 sigma_dut_print(dut, DUT_MSG_INFO, "Timeout on "
273 "waiting for events");
274 return -1;
275 }
276 if (ret < 0) {
277 sigma_dut_print(dut, DUT_MSG_INFO, "select: %s",
278 strerror(errno));
279 return -1;
280 }
281 len = buf_size;
282 if (wpa_ctrl_recv(mon, buf, &len) < 0) {
283 sigma_dut_print(dut, DUT_MSG_ERROR, "Failure while "
284 "waiting for events");
285 return -1;
286 }
287 if (len == buf_size)
288 len--;
289 buf[len] = '\0';
290
291 pos = strchr(buf, '>');
292 if (pos) {
293 for (i = 0; events[i]; i++) {
294 if (strncmp(pos + 1, events[i],
295 strlen(events[i])) == 0)
296 return 0; /* Event found */
297 }
298 }
299
300 time(&now);
301 if ((unsigned int) (now - start) > dut->default_timeout) {
302 sigma_dut_print(dut, DUT_MSG_INFO, "Timeout on "
303 "waiting for event");
304 return -1;
305 }
306 }
307}
308
309
310int get_wpa_cli_event2(struct sigma_dut *dut, struct wpa_ctrl *mon,
311 const char *event, const char *event2,
312 char *buf, size_t buf_size)
313{
314 const char *events[3] = { event, event2, NULL };
315 return get_wpa_cli_events(dut, mon, events, buf, buf_size);
316}
317
318
319int get_wpa_cli_event(struct sigma_dut *dut, struct wpa_ctrl *mon,
320 const char *event, char *buf, size_t buf_size)
321{
322 return get_wpa_cli_event2(dut, mon, event, NULL, buf, buf_size);
323}
324
325
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -0700326/*
327 * signal_poll cmd output sample
328 * RSSI=-51
329 * LINKSPEED=866
330 * NOISE=-101
331 * FREQUENCY=5180
332 * AVG_RSSI=-50
333 */
334int get_wpa_signal_poll(struct sigma_dut *dut, const char *ifname,
335 const char *field, char *obuf, size_t obuf_size)
336{
337 struct wpa_ctrl *ctrl;
338 char buf[4096];
339 char *pos, *end;
340 size_t len, flen;
341
342 snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl, ifname);
343 ctrl = wpa_ctrl_open2(buf, client_socket_path);
344 if (!ctrl) {
345 sigma_dut_print(dut, DUT_MSG_ERROR,
346 "Failed to connect to wpa_supplicant");
347 return -1;
348 }
349
350 len = sizeof(buf);
351 if (wpa_ctrl_request(ctrl, "SIGNAL_POLL", 11, buf, &len, NULL) < 0) {
352 wpa_ctrl_close(ctrl);
353 sigma_dut_print(dut, DUT_MSG_ERROR, "ctrl request failed");
354 return -1;
355 }
356 buf[len] = '\0';
357
358 wpa_ctrl_close(ctrl);
359
360 flen = strlen(field);
361 pos = buf;
362 while (pos + flen < buf + len) {
363 if (pos > buf) {
364 if (*pos != '\n') {
365 pos++;
366 continue;
367 }
368 pos++;
369 }
370 if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') {
371 pos++;
372 continue;
373 }
374 pos += flen + 1;
375 end = strchr(pos, '\n');
376 if (!end) {
377 sigma_dut_print(dut, DUT_MSG_ERROR,
378 "Could not find signal poll field '%s' - end is NULL",
379 field);
380 return -1;
381 }
382 *end++ = '\0';
383 if (end - pos > (int) obuf_size) {
384 sigma_dut_print(dut, DUT_MSG_ERROR,
385 "signal poll out buffer is too small");
386 return -1;
387 }
388 memcpy(obuf, pos, end - pos);
389 return 0;
390 }
391
392 sigma_dut_print(dut, DUT_MSG_ERROR, "signal poll param not found");
393 return -1;
394}
395
396
Arif Hussain66a4af02019-02-07 15:04:51 -0800397int get_wpa_ssid_bssid(struct sigma_dut *dut, const char *ifname,
398 char *buf, size_t buf_size)
399{
400 struct wpa_ctrl *ctrl;
401 char buf_local[4096];
402 char *network, *ssid, *bssid;
403 size_t buf_size_local;
404 unsigned int count = 0;
405 int len, res;
406 char *save_ptr_network = NULL;
407
408 ctrl = open_wpa_mon(ifname);
409 if (!ctrl) {
410 sigma_dut_print(dut, DUT_MSG_ERROR,
411 "Failed to connect to wpa_supplicant");
412 return -1;
413 }
414
415 wpa_command(ifname, "BSS_FLUSH");
416 if (wpa_command(ifname, "SCAN TYPE=ONLY")) {
417 wpa_ctrl_detach(ctrl);
418 wpa_ctrl_close(ctrl);
419 sigma_dut_print(dut, DUT_MSG_ERROR, "SCAN command failed");
420 return -1;
421 }
422
423 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
424 buf_local, sizeof(buf_local));
425 wpa_ctrl_detach(ctrl);
426 buf_size_local = sizeof(buf_local);
427 if (res < 0 || wpa_ctrl_request(ctrl, "BSS RANGE=ALL MASK=0x1002", 25,
428 buf_local, &buf_size_local, NULL) < 0) {
429 wpa_ctrl_close(ctrl);
430 sigma_dut_print(dut, DUT_MSG_ERROR, "BSS ctrl request failed");
431 return -1;
432 }
433 buf_local[buf_size_local] = '\0';
434
435 wpa_ctrl_close(ctrl);
436
437 /* Below is BSS RANGE=ALL MASK=0x1002 command sample output which is
438 * parsed to get the BSSID and SSID parameters.
439 * Even number of lines, first line BSSID of network 1, second line SSID
440 * of network 1, ...
441 *
442 * bssid=xx:xx:xx:xx:xx:x1
443 * ssid=SSID1
444 * bssid=xx:xx:xx:xx:xx:x2
445 * ssid=SSID2
446 */
447
448 network = strtok_r(buf_local, "\n", &save_ptr_network);
449
450 while (network) {
451 sigma_dut_print(dut, DUT_MSG_DEBUG, "BSSID: %s", network);
452 bssid = NULL;
453 if (!strtok_r(network, "=", &bssid)) {
454 sigma_dut_print(dut, DUT_MSG_ERROR,
455 "Invalid BSS result: BSSID not found");
456 return -1;
457 }
458 network = strtok_r(NULL, "\n", &save_ptr_network);
459 if (network) {
460 sigma_dut_print(dut, DUT_MSG_DEBUG, "SSID: %s",
461 network);
462 ssid = NULL;
463 if (!strtok_r(network, "=", &ssid)) {
464 sigma_dut_print(dut, DUT_MSG_ERROR,
465 "Invalid BSS result: SSID is null");
466 return -1;
467 }
468 } else {
469 sigma_dut_print(dut, DUT_MSG_ERROR,
470 "Invalid BSS result: SSID not found");
471 return -1;
472 }
473
474 /* Skip comma for first entry */
475 count++;
476 len = snprintf(buf, buf_size, "%sSSID%d,%s,BSSID%d,%s",
477 count > 1 ? "," : "",
478 count, ssid, count, bssid);
Jouni Malinen8400c082019-04-26 13:26:07 +0300479 if (len < 0 || (size_t) len >= buf_size) {
Arif Hussain66a4af02019-02-07 15:04:51 -0800480 buf[0] = '\0';
481 return 0;
482 }
483
484 buf_size -= len;
485 buf += len;
486
487 network = strtok_r(NULL, "\n", &save_ptr_network);
488 }
489
490 return 0;
491}
492
493
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200494static int get_wpa_ctrl_status_field(const char *path, const char *ifname,
495 const char *cmd, const char *field,
496 char *obuf, size_t obuf_size)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200497{
498 struct wpa_ctrl *ctrl;
499 char buf[4096];
500 char *pos, *end;
501 size_t len, flen;
502
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200503 snprintf(buf, sizeof(buf), "%s%s", path, ifname);
Rajiv Ranjan525dbfd2018-04-20 17:42:48 +0530504 ctrl = wpa_ctrl_open2(buf, client_socket_path);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200505 if (ctrl == NULL)
506 return -1;
507 len = sizeof(buf);
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200508 if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200509 wpa_ctrl_close(ctrl);
510 return -1;
511 }
512 wpa_ctrl_close(ctrl);
513 buf[len] = '\0';
514
515 flen = strlen(field);
516 pos = buf;
517 while (pos + flen < buf + len) {
518 if (pos > buf) {
519 if (*pos != '\n') {
520 pos++;
521 continue;
522 }
523 pos++;
524 }
525 if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') {
526 pos++;
527 continue;
528 }
529 pos += flen + 1;
530 end = strchr(pos, '\n');
531 if (end == NULL)
532 return -1;
533 *end++ = '\0';
534 if (end - pos > (int) obuf_size)
535 return -1;
536 memcpy(obuf, pos, end - pos);
537 return 0;
538 }
539
540 return -1;
541}
542
543
Alexei Avshalom Lazar52ec2362018-12-18 15:58:31 +0200544int get_wpa_status(const char *ifname, const char *field, char *obuf,
545 size_t obuf_size)
546{
547 return get_wpa_ctrl_status_field(sigma_wpas_ctrl, ifname, "STATUS",
548 field, obuf, obuf_size);
549}
550
551
Alexei Avshalom Lazar0c1d82d2018-12-23 17:02:42 +0200552int get_hapd_config(const char *ifname, const char *field, char *obuf,
553 size_t obuf_size)
554{
555 const char *path = sigma_hapd_ctrl ?
556 sigma_hapd_ctrl : DEFAULT_HAPD_CTRL_PATH;
557
558 return get_wpa_ctrl_status_field(path, ifname, "GET_CONFIG",
559 field, obuf, obuf_size);
560}
561
562
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200563int wait_ip_addr(struct sigma_dut *dut, const char *ifname, int timeout)
564{
565 char ip[30];
566 int count = timeout;
567
568 while (count > 0) {
569 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: ifname='%s' - %d "
570 "seconds remaining",
571 __func__, ifname, count);
572 count--;
573 if (get_wpa_status(ifname, "ip_address", ip, sizeof(ip)) == 0
574 && strlen(ip) > 0) {
575 sigma_dut_print(dut, DUT_MSG_INFO, "IP address "
576 "found: '%s'", ip);
577 return 0;
578 }
579 sleep(1);
580 }
581 sigma_dut_print(dut, DUT_MSG_INFO, "%s: Could not get IP address for "
582 "ifname='%s'", __func__, ifname);
583 return -1;
584}
585
586
587void remove_wpa_networks(const char *ifname)
588{
589 char buf[4096];
590 char cmd[256];
591 char *pos;
592
593 if (wpa_command_resp(ifname, "LIST_NETWORKS", buf, sizeof(buf)) < 0)
594 return;
595
596 /* Skip the first line (header) */
597 pos = strchr(buf, '\n');
598 if (pos == NULL)
599 return;
600 pos++;
601 while (pos && pos[0]) {
602 int id = atoi(pos);
603 snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", id);
604 wpa_command(ifname, cmd);
605 pos = strchr(pos, '\n');
606 if (pos)
607 pos++;
608 }
609}
610
611
612int add_network(const char *ifname)
613{
614 char res[30];
615
616 if (wpa_command_resp(ifname, "ADD_NETWORK", res, sizeof(res)) < 0)
617 return -1;
618 return atoi(res);
619}
620
621
622int set_network(const char *ifname, int id, const char *field,
623 const char *value)
624{
625 char buf[200];
626 snprintf(buf, sizeof(buf), "SET_NETWORK %d %s %s", id, field, value);
627 return wpa_command(ifname, buf);
628}
629
630
631int set_network_quoted(const char *ifname, int id, const char *field,
632 const char *value)
633{
634 char buf[200];
635 snprintf(buf, sizeof(buf), "SET_NETWORK %d %s \"%s\"",
636 id, field, value);
637 return wpa_command(ifname, buf);
638}
639
640
641int add_cred(const char *ifname)
642{
643 char res[30];
644
645 if (wpa_command_resp(ifname, "ADD_CRED", res, sizeof(res)) < 0)
646 return -1;
647 return atoi(res);
648}
649
650
651int set_cred(const char *ifname, int id, const char *field, const char *value)
652{
653 char buf[200];
654 snprintf(buf, sizeof(buf), "SET_CRED %d %s %s", id, field, value);
655 return wpa_command(ifname, buf);
656}
657
658
659int set_cred_quoted(const char *ifname, int id, const char *field,
660 const char *value)
661{
662 char buf[200];
663 snprintf(buf, sizeof(buf), "SET_CRED %d %s \"%s\"",
664 id, field, value);
665 return wpa_command(ifname, buf);
666}
667
668
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +0200669const char * concat_sigma_tmpdir(struct sigma_dut *dut, const char *src,
670 char *dst, size_t len)
671{
672 snprintf(dst, len, "%s%s", dut->sigma_tmpdir, src);
673
674 return dst;
675}
676
677
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200678int start_sta_mode(struct sigma_dut *dut)
679{
680 FILE *f;
Alexei Avshalom Lazar3e8267e2018-12-18 15:58:54 +0200681 char buf[256];
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +0200682 char sta_conf_path[100];
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200683 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200684 char *tmp, *pos;
685
Jouni Malinen78217db2019-11-06 18:46:08 +0200686 if (dut->mode == SIGMA_MODE_STATION) {
687 if ((dut->use_5g && dut->sta_2g_started) ||
688 (!dut->use_5g && dut->sta_5g_started)) {
689 stop_sta_mode(dut);
690 sleep(1);
691 } else {
692 return 0;
693 }
694 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200695
696 if (dut->mode == SIGMA_MODE_AP) {
697 if (system("killall hostapd") == 0) {
698 int i;
699
700 /* Wait some time to allow hostapd to complete cleanup
701 * before starting a new process */
702 for (i = 0; i < 10; i++) {
703 usleep(500000);
704 if (system("pidof hostapd") != 0)
705 break;
706 }
707 }
708 }
709
710 if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) {
711 snprintf(buf, sizeof(buf), "ifconfig %s down",
712 dut->sniffer_ifname);
713 if (system(buf) != 0) {
714 sigma_dut_print(dut, DUT_MSG_INFO,
715 "Failed to run '%s'", buf);
716 }
717 snprintf(buf, sizeof(buf), "iw dev %s set type station",
718 dut->sniffer_ifname);
719 if (system(buf) != 0) {
720 sigma_dut_print(dut, DUT_MSG_INFO,
721 "Failed to run '%s'", buf);
722 }
723 }
724
725 dut->mode = SIGMA_MODE_STATION;
726
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200727 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200728 if (wpa_command(ifname, "PING") == 0)
729 return 0; /* wpa_supplicant is already running */
730
731 /* Start wpa_supplicant */
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +0200732 f = fopen(concat_sigma_tmpdir(dut, "/sigma_dut-sta.conf", sta_conf_path,
733 sizeof(sta_conf_path)), "w");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200734 if (f == NULL)
735 return -1;
736
737 tmp = strdup(sigma_wpas_ctrl);
738 if (tmp == NULL) {
739 fclose(f);
740 return -1;
741 }
742 pos = tmp;
743 while (pos[0] != '\0' && pos[1] != '\0')
744 pos++;
745 if (*pos == '/')
746 *pos = '\0';
747 fprintf(f, "ctrl_interface=%s\n", tmp);
748 free(tmp);
749 fprintf(f, "device_name=Test client\n");
750 fprintf(f, "device_type=1-0050F204-1\n");
Alexei Avshalom Lazar1080c582018-12-20 17:40:55 +0200751 if (is_60g_sigma_dut(dut)) {
752 fprintf(f, "eapol_version=2\n");
753 fprintf(f,
754 "config_methods=display push_button keypad virtual_display physical_display virtual_push_button\n");
755 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200756 fclose(f);
757
758#ifdef __QNXNTO__
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +0200759 snprintf(buf, sizeof(buf),
760 "wpa_supplicant -Dqca -i%s -B %s%s%s -c %s/sigma_dut-sta.conf",
761 ifname,
Alexei Avshalom Lazar02254ee2020-01-27 13:02:22 +0200762 dut->wpa_supplicant_debug_log ? "-K -t -ddd " : "",
763 (dut->wpa_supplicant_debug_log &&
764 dut->wpa_supplicant_debug_log[0]) ? "-f " : "",
Alexei Avshalom Lazar3e8267e2018-12-18 15:58:54 +0200765 dut->wpa_supplicant_debug_log ?
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +0200766 dut->wpa_supplicant_debug_log : "",
767 dut->sigma_tmpdir);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200768#else /*__QNXNTO__*/
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +0200769 snprintf(buf, sizeof(buf),
770 "%swpa_supplicant -Dnl80211 -i%s -B %s%s%s -c %s/sigma_dut-sta.conf",
Jouni Malinen43757092019-11-05 17:07:53 +0200771 file_exists("wpa_supplicant") ? "./" : "",
772 ifname,
Alexei Avshalom Lazar02254ee2020-01-27 13:02:22 +0200773 dut->wpa_supplicant_debug_log ? "-K -t -ddd " : "",
774 (dut->wpa_supplicant_debug_log &&
775 dut->wpa_supplicant_debug_log[0]) ? "-f " : "",
Alexei Avshalom Lazar3e8267e2018-12-18 15:58:54 +0200776 dut->wpa_supplicant_debug_log ?
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +0200777 dut->wpa_supplicant_debug_log : "",
778 dut->sigma_tmpdir);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200779#endif /*__QNXNTO__*/
780 if (system(buf) != 0) {
781 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s'", buf);
782 return -1;
783 }
784
785 sleep(1);
786
787 if (wpa_command(ifname, "PING")) {
788 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to communicate "
789 "with wpa_supplicant");
790 return -1;
791 }
Jouni Malinen78217db2019-11-06 18:46:08 +0200792 if (dut->use_5g)
793 dut->sta_5g_started = 1;
794 else
795 dut->sta_2g_started = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200796
797 return 0;
798}
799
800
801void stop_sta_mode(struct sigma_dut *dut)
802{
Alexei Avshalom Lazar80566092018-12-18 16:01:50 +0200803 if (is_60g_sigma_dut(dut)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200804 wpa_command(get_main_ifname(dut), "TERMINATE");
Alexei Avshalom Lazar80566092018-12-18 16:01:50 +0200805 return;
806 }
807
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200808 wpa_command("wlan0", "TERMINATE");
809 wpa_command("wlan1", "TERMINATE");
810 wpa_command("ath0", "TERMINATE");
811 wpa_command("ath1", "TERMINATE");
Jouni Malinend8956812019-11-05 17:01:37 +0200812 if (dut->main_ifname_2g)
813 wpa_command(dut->main_ifname_2g, "TERMINATE");
814 if (dut->main_ifname_5g)
815 wpa_command(dut->main_ifname_5g, "TERMINATE");
816 if (dut->station_ifname_2g)
817 wpa_command(dut->station_ifname_2g, "TERMINATE");
818 if (dut->station_ifname_5g)
819 wpa_command(dut->station_ifname_5g, "TERMINATE");
Jouni Malinen78217db2019-11-06 18:46:08 +0200820 dut->sta_2g_started = 0;
821 dut->sta_5g_started = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200822}