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