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