1cd4e3c3eSJouni Malinen /* 2cd4e3c3eSJouni Malinen * Sigma Control API DUT (station/AP) 3cd4e3c3eSJouni Malinen * Copyright (c) 2010-2011, Atheros Communications, Inc. 49c381f59SAmarnath Hullur Subramanyam * Copyright (c) 2011-2017, Qualcomm Atheros, Inc. 55404f5fdSJouni Malinen * Copyright (c) 2018-2019, 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 #ifdef __linux__ 12cd4e3c3eSJouni Malinen #include <signal.h> 13cd4e3c3eSJouni Malinen #include <netinet/tcp.h> 14cd4e3c3eSJouni Malinen #endif /* __linux__ */ 15f2af39bfSDanny Segal #include "wpa_ctrl.h" 16cd4e3c3eSJouni Malinen #include "wpa_helpers.h" 179c381f59SAmarnath Hullur Subramanyam #include "miracast.h" 18cd4e3c3eSJouni Malinen 19cd4e3c3eSJouni Malinen #define SIGMA_DUT_PORT 9000 20cd4e3c3eSJouni Malinen #define MAX_CONNECTIONS 4 21cd4e3c3eSJouni Malinen 22cd4e3c3eSJouni Malinen extern enum driver_type wifi_chip_type; 23cd4e3c3eSJouni Malinen 24cd4e3c3eSJouni Malinen static struct sigma_dut sigma_dut; 25cd4e3c3eSJouni Malinen 26cd4e3c3eSJouni Malinen char *sigma_main_ifname = NULL; 27cd4e3c3eSJouni Malinen char *sigma_radio_ifname[MAX_RADIO] = {}; 28cd4e3c3eSJouni Malinen char *sigma_station_ifname = NULL; 29f2af39bfSDanny Segal char *sigma_p2p_ifname = NULL; 30f2af39bfSDanny Segal static char *sigma_p2p_ifname_buf = NULL; 31cd4e3c3eSJouni Malinen char *sigma_wpas_ctrl = "/var/run/wpa_supplicant/"; 32cd4e3c3eSJouni Malinen char *sigma_hapd_ctrl = NULL; 33525dbfd1SRajiv Ranjan char *client_socket_path = NULL; 34cd4e3c3eSJouni Malinen char *ap_inet_addr = "192.168.43.1"; 35cd4e3c3eSJouni Malinen char *ap_inet_mask = "255.255.255.0"; 36cd4e3c3eSJouni Malinen char *sigma_cert_path = "/etc/wpa_supplicant"; 37cd4e3c3eSJouni Malinen 38cd4e3c3eSJouni Malinen /* For WMM-AC testing this set to 1 through argument, 39cd4e3c3eSJouni Malinen * otherwise default WMM-PS 0 */ 40cd4e3c3eSJouni Malinen int sigma_wmm_ac = 0; 41cd4e3c3eSJouni Malinen 42cd4e3c3eSJouni Malinen 43cd4e3c3eSJouni Malinen #ifdef ANDROID 44cd4e3c3eSJouni Malinen #include <android/log.h> 45cd4e3c3eSJouni Malinen 46cd4e3c3eSJouni Malinen static enum android_LogPriority level_to_android_priority(int level) 47cd4e3c3eSJouni Malinen { 48cd4e3c3eSJouni Malinen switch (level) { 49cd4e3c3eSJouni Malinen case DUT_MSG_ERROR: 50cd4e3c3eSJouni Malinen return ANDROID_LOG_ERROR; 51cd4e3c3eSJouni Malinen case DUT_MSG_INFO: 52cd4e3c3eSJouni Malinen return ANDROID_LOG_INFO; 53cd4e3c3eSJouni Malinen case DUT_MSG_DEBUG: 54cd4e3c3eSJouni Malinen return ANDROID_LOG_DEBUG; 55cd4e3c3eSJouni Malinen default: 56cd4e3c3eSJouni Malinen return ANDROID_LOG_VERBOSE; 57cd4e3c3eSJouni Malinen } 58cd4e3c3eSJouni Malinen } 59cd4e3c3eSJouni Malinen #endif /* ANDROID */ 60cd4e3c3eSJouni Malinen 61cd4e3c3eSJouni Malinen 62cd4e3c3eSJouni Malinen void sigma_dut_print(struct sigma_dut *dut, int level, const char *fmt, ...) 63cd4e3c3eSJouni Malinen { 64cd4e3c3eSJouni Malinen va_list ap; 65cd4e3c3eSJouni Malinen struct timeval tv; 66cd4e3c3eSJouni Malinen 67cd4e3c3eSJouni Malinen if (level < dut->debug_level) 68cd4e3c3eSJouni Malinen return; 69cd4e3c3eSJouni Malinen 70cd4e3c3eSJouni Malinen #ifdef ANDROID 71cd4e3c3eSJouni Malinen va_start(ap, fmt); 72cd4e3c3eSJouni Malinen __android_log_vprint(level_to_android_priority(level), 73cd4e3c3eSJouni Malinen "sigma_dut", fmt, ap); 74cd4e3c3eSJouni Malinen va_end(ap); 75cd4e3c3eSJouni Malinen if (!dut->stdout_debug) 76cd4e3c3eSJouni Malinen return; 77cd4e3c3eSJouni Malinen #endif /* ANDROID */ 78cd4e3c3eSJouni Malinen 79cd4e3c3eSJouni Malinen va_start(ap, fmt); 80cd4e3c3eSJouni Malinen gettimeofday(&tv, NULL); 81cd4e3c3eSJouni Malinen printf("%ld.%06u: ", (long) tv.tv_sec, 82cd4e3c3eSJouni Malinen (unsigned int) tv.tv_usec); 83cd4e3c3eSJouni Malinen vprintf(fmt, ap); 84cd4e3c3eSJouni Malinen printf("\n"); 85cd4e3c3eSJouni Malinen va_end(ap); 86cd4e3c3eSJouni Malinen } 87cd4e3c3eSJouni Malinen 88cd4e3c3eSJouni Malinen 89cd4e3c3eSJouni Malinen void sigma_dut_summary(struct sigma_dut *dut, const char *fmt, ...) 90cd4e3c3eSJouni Malinen { 91cd4e3c3eSJouni Malinen va_list ap; 92cd4e3c3eSJouni Malinen FILE *f; 93cd4e3c3eSJouni Malinen 94cd4e3c3eSJouni Malinen if (!dut->summary_log) 95cd4e3c3eSJouni Malinen return; 96cd4e3c3eSJouni Malinen 97cd4e3c3eSJouni Malinen f = fopen(dut->summary_log, "a"); 98cd4e3c3eSJouni Malinen if (f == NULL) 99cd4e3c3eSJouni Malinen return; 100cd4e3c3eSJouni Malinen 101cd4e3c3eSJouni Malinen va_start(ap, fmt); 102cd4e3c3eSJouni Malinen vfprintf(f, fmt, ap); 103cd4e3c3eSJouni Malinen fprintf(f, "\n"); 104cd4e3c3eSJouni Malinen va_end(ap); 105cd4e3c3eSJouni Malinen fclose(f); 106cd4e3c3eSJouni Malinen } 107cd4e3c3eSJouni Malinen 108cd4e3c3eSJouni Malinen 109cd4e3c3eSJouni Malinen int sigma_dut_reg_cmd(const char *cmd, 110cd4e3c3eSJouni Malinen int (*validate)(struct sigma_cmd *cmd), 11126a5b76dSJouni Malinen enum sigma_cmd_result (*process)(struct sigma_dut *dut, 112cd4e3c3eSJouni Malinen struct sigma_conn *conn, 113cd4e3c3eSJouni Malinen struct sigma_cmd *cmd)) 114cd4e3c3eSJouni Malinen { 115cd4e3c3eSJouni Malinen struct sigma_cmd_handler *h; 116cd4e3c3eSJouni Malinen size_t clen, len; 117cd4e3c3eSJouni Malinen 1185404f5fdSJouni Malinen for (h = sigma_dut.cmds; h; h = h->next) { 1195404f5fdSJouni Malinen if (strcmp(h->cmd, cmd) == 0) { 1205404f5fdSJouni Malinen printf("ERROR: Duplicate sigma_dut command registration for '%s'\n", 1215404f5fdSJouni Malinen cmd); 1225404f5fdSJouni Malinen return -1; 1235404f5fdSJouni Malinen } 1245404f5fdSJouni Malinen } 1255404f5fdSJouni Malinen 126cd4e3c3eSJouni Malinen clen = strlen(cmd); 127cd4e3c3eSJouni Malinen len = sizeof(*h) + clen + 1; 128cd4e3c3eSJouni Malinen h = malloc(len); 129cd4e3c3eSJouni Malinen if (h == NULL) 130cd4e3c3eSJouni Malinen return -1; 131cd4e3c3eSJouni Malinen memset(h, 0, len); 132cd4e3c3eSJouni Malinen h->cmd = (char *) (h + 1); /* include in same allocation */ 133cd4e3c3eSJouni Malinen memcpy(h->cmd, cmd, clen); 134cd4e3c3eSJouni Malinen h->validate = validate; 135cd4e3c3eSJouni Malinen h->process= process; 136cd4e3c3eSJouni Malinen 137cd4e3c3eSJouni Malinen h->next = sigma_dut.cmds; 138cd4e3c3eSJouni Malinen sigma_dut.cmds = h; 139cd4e3c3eSJouni Malinen 140cd4e3c3eSJouni Malinen return 0; 141cd4e3c3eSJouni Malinen } 142cd4e3c3eSJouni Malinen 143cd4e3c3eSJouni Malinen 144cd4e3c3eSJouni Malinen static void sigma_dut_unreg_cmds(struct sigma_dut *dut) 145cd4e3c3eSJouni Malinen { 146cd4e3c3eSJouni Malinen struct sigma_cmd_handler *cmd, *prev; 147cd4e3c3eSJouni Malinen cmd = dut->cmds; 148cd4e3c3eSJouni Malinen dut->cmds = NULL; 149cd4e3c3eSJouni Malinen while (cmd) { 150cd4e3c3eSJouni Malinen prev = cmd; 151cd4e3c3eSJouni Malinen cmd = cmd->next; 152cd4e3c3eSJouni Malinen free(prev); 153cd4e3c3eSJouni Malinen } 154cd4e3c3eSJouni Malinen } 155cd4e3c3eSJouni Malinen 156cd4e3c3eSJouni Malinen 157cd4e3c3eSJouni Malinen static int open_socket(struct sigma_dut *dut, int port) 158cd4e3c3eSJouni Malinen { 159cd4e3c3eSJouni Malinen struct sockaddr_in addr; 160cd4e3c3eSJouni Malinen #ifndef __QNXNTO__ 161cd4e3c3eSJouni Malinen int val; 162cd4e3c3eSJouni Malinen #endif /* !__QNXNTO__ */ 163cd4e3c3eSJouni Malinen 164cd4e3c3eSJouni Malinen #ifdef __QNXNTO__ 165cd4e3c3eSJouni Malinen dut->s = socket(PF_INET, SOCK_STREAM, IPPROTO_IP); 166cd4e3c3eSJouni Malinen #else /* __QNXNTO__ */ 167cd4e3c3eSJouni Malinen dut->s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 168cd4e3c3eSJouni Malinen #endif /* __QNXNTO__ */ 169cd4e3c3eSJouni Malinen if (dut->s < 0) { 170cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "socket: %s", 171cd4e3c3eSJouni Malinen strerror(errno)); 172cd4e3c3eSJouni Malinen return -1; 173cd4e3c3eSJouni Malinen } 174cd4e3c3eSJouni Malinen 175cd4e3c3eSJouni Malinen #ifndef __QNXNTO__ 176cd4e3c3eSJouni Malinen val = 1; 177cd4e3c3eSJouni Malinen if (setsockopt(dut->s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) < 178cd4e3c3eSJouni Malinen 0) 179cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "setsockopt SO_REUSEADDR: " 180cd4e3c3eSJouni Malinen "%s", strerror(errno)); 181cd4e3c3eSJouni Malinen #endif /* !__QNXNTO__ */ 182cd4e3c3eSJouni Malinen 183cd4e3c3eSJouni Malinen #ifdef __linux__ 184cd4e3c3eSJouni Malinen val = 1; 185cd4e3c3eSJouni Malinen if (setsockopt(dut->s, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) < 186cd4e3c3eSJouni Malinen 0) 187cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "setsockopt TCP_NODELAY: " 188cd4e3c3eSJouni Malinen "%s", strerror(errno)); 189cd4e3c3eSJouni Malinen #endif /* __linux__ */ 190cd4e3c3eSJouni Malinen 191cd4e3c3eSJouni Malinen memset(&addr, 0, sizeof(addr)); 192cd4e3c3eSJouni Malinen addr.sin_family = AF_INET; 193cd4e3c3eSJouni Malinen addr.sin_port = htons(port); 194cd4e3c3eSJouni Malinen 195cd4e3c3eSJouni Malinen if (bind(dut->s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 196cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "bind: %s", 197cd4e3c3eSJouni Malinen strerror(errno)); 198cd4e3c3eSJouni Malinen goto fail; 199cd4e3c3eSJouni Malinen } 200cd4e3c3eSJouni Malinen 201cd4e3c3eSJouni Malinen if (listen(dut->s, 5) < 0) { 202cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, "listen: %s", 203cd4e3c3eSJouni Malinen strerror(errno)); 204cd4e3c3eSJouni Malinen goto fail; 205cd4e3c3eSJouni Malinen } 206cd4e3c3eSJouni Malinen 207cd4e3c3eSJouni Malinen return 0; 208cd4e3c3eSJouni Malinen 209cd4e3c3eSJouni Malinen fail: 210cd4e3c3eSJouni Malinen shutdown(dut->s, SHUT_RDWR); 211cd4e3c3eSJouni Malinen close(dut->s); 212cd4e3c3eSJouni Malinen dut->s = -1; 213cd4e3c3eSJouni Malinen return -1; 214cd4e3c3eSJouni Malinen } 215cd4e3c3eSJouni Malinen 216cd4e3c3eSJouni Malinen 217cd4e3c3eSJouni Malinen static void close_socket(struct sigma_dut *dut) 218cd4e3c3eSJouni Malinen { 219cd4e3c3eSJouni Malinen shutdown(dut->s, SHUT_RDWR); 220cd4e3c3eSJouni Malinen close(dut->s); 221cd4e3c3eSJouni Malinen dut->s = -1; 222cd4e3c3eSJouni Malinen } 223cd4e3c3eSJouni Malinen 224cd4e3c3eSJouni Malinen 225cd4e3c3eSJouni Malinen void send_resp(struct sigma_dut *dut, struct sigma_conn *conn, 22676401f50SJouni Malinen enum sigma_status status, const char *buf) 227cd4e3c3eSJouni Malinen { 228cd4e3c3eSJouni Malinen struct msghdr msg; 229cd4e3c3eSJouni Malinen struct iovec iov[4]; 230cd4e3c3eSJouni Malinen size_t elems; 231cd4e3c3eSJouni Malinen 232a326d7b5SJouni Malinen if (!conn) 233a326d7b5SJouni Malinen return; 234a326d7b5SJouni Malinen 235cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "resp: status=%d buf=%s", 236cd4e3c3eSJouni Malinen status, buf ? buf : "N/A"); 237cd4e3c3eSJouni Malinen 238cd4e3c3eSJouni Malinen iov[0].iov_base = "status,"; 239cd4e3c3eSJouni Malinen iov[0].iov_len = 7; 240cd4e3c3eSJouni Malinen switch (status) { 241cd4e3c3eSJouni Malinen case SIGMA_RUNNING: 242cd4e3c3eSJouni Malinen iov[1].iov_base = "RUNNING,"; 243cd4e3c3eSJouni Malinen iov[1].iov_len = 8; 244cd4e3c3eSJouni Malinen break; 245cd4e3c3eSJouni Malinen case SIGMA_INVALID: 246cd4e3c3eSJouni Malinen iov[1].iov_base = "INVALID,"; 247cd4e3c3eSJouni Malinen iov[1].iov_len = 8; 248cd4e3c3eSJouni Malinen break; 249cd4e3c3eSJouni Malinen case SIGMA_ERROR: 250cd4e3c3eSJouni Malinen iov[1].iov_base = "ERROR,"; 251cd4e3c3eSJouni Malinen iov[1].iov_len = 6; 252cd4e3c3eSJouni Malinen break; 253cd4e3c3eSJouni Malinen case SIGMA_COMPLETE: 254cd4e3c3eSJouni Malinen iov[1].iov_base = "COMPLETE,"; 255cd4e3c3eSJouni Malinen iov[1].iov_len = 9; 256cd4e3c3eSJouni Malinen break; 257cd4e3c3eSJouni Malinen } 258cd4e3c3eSJouni Malinen if (status != SIGMA_RUNNING) { 259cd4e3c3eSJouni Malinen sigma_dut_summary(dut, "CAPI resp: status,%s%s", 260cd4e3c3eSJouni Malinen (char *) iov[1].iov_base, buf ? buf : ""); 261cd4e3c3eSJouni Malinen } 262cd4e3c3eSJouni Malinen if (buf) { 26376401f50SJouni Malinen iov[2].iov_base = (void *) buf; 264cd4e3c3eSJouni Malinen iov[2].iov_len = strlen(buf); 265cd4e3c3eSJouni Malinen iov[3].iov_base = "\r\n"; 266cd4e3c3eSJouni Malinen iov[3].iov_len = 2; 267cd4e3c3eSJouni Malinen elems = 4; 268cd4e3c3eSJouni Malinen } else { 269cd4e3c3eSJouni Malinen iov[1].iov_len--; 270cd4e3c3eSJouni Malinen iov[2].iov_base = "\r\n"; 271cd4e3c3eSJouni Malinen iov[2].iov_len = 2; 272cd4e3c3eSJouni Malinen elems = 3; 273cd4e3c3eSJouni Malinen } 274cd4e3c3eSJouni Malinen 275cd4e3c3eSJouni Malinen memset(&msg, 0, sizeof(msg)); 276cd4e3c3eSJouni Malinen msg.msg_iov = iov; 277cd4e3c3eSJouni Malinen msg.msg_iovlen = elems; 278cd4e3c3eSJouni Malinen if (sendmsg(conn->s, &msg, 0) < 0) 279cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "sendmsg: %s", 280cd4e3c3eSJouni Malinen strerror(errno)); 2810fee701cSJouni Malinen dut->response_sent++; 282cd4e3c3eSJouni Malinen } 283cd4e3c3eSJouni Malinen 284cd4e3c3eSJouni Malinen 285cd4e3c3eSJouni Malinen const char * get_param(struct sigma_cmd *cmd, const char *name) 286cd4e3c3eSJouni Malinen { 287cd4e3c3eSJouni Malinen int i; 288cd4e3c3eSJouni Malinen for (i = 0; i < cmd->count; i++) { 289cd4e3c3eSJouni Malinen if (strcasecmp(name, cmd->params[i]) == 0) 290cd4e3c3eSJouni Malinen return cmd->values[i]; 291cd4e3c3eSJouni Malinen } 292cd4e3c3eSJouni Malinen return NULL; 293cd4e3c3eSJouni Malinen } 294cd4e3c3eSJouni Malinen 295cd4e3c3eSJouni Malinen 296bc180dc5SAlexei Avshalom Lazar const char * get_param_indexed(struct sigma_cmd *cmd, const char *name, 297bc180dc5SAlexei Avshalom Lazar int index) 298bc180dc5SAlexei Avshalom Lazar { 299bc180dc5SAlexei Avshalom Lazar int i, j; 300bc180dc5SAlexei Avshalom Lazar 301bc180dc5SAlexei Avshalom Lazar for (i = 0, j = 0; i < cmd->count; i++) { 302bc180dc5SAlexei Avshalom Lazar if (strcasecmp(name, cmd->params[i]) == 0) { 303bc180dc5SAlexei Avshalom Lazar j++; 304bc180dc5SAlexei Avshalom Lazar if (j > index) 305bc180dc5SAlexei Avshalom Lazar return cmd->values[i]; 306bc180dc5SAlexei Avshalom Lazar } 307bc180dc5SAlexei Avshalom Lazar } 308bc180dc5SAlexei Avshalom Lazar 309bc180dc5SAlexei Avshalom Lazar return NULL; 310bc180dc5SAlexei Avshalom Lazar } 311bc180dc5SAlexei Avshalom Lazar 312bc180dc5SAlexei Avshalom Lazar 313cd4e3c3eSJouni Malinen static void process_cmd(struct sigma_dut *dut, struct sigma_conn *conn, 314cd4e3c3eSJouni Malinen char *buf) 315cd4e3c3eSJouni Malinen { 316cd4e3c3eSJouni Malinen struct sigma_cmd_handler *h; 317cd4e3c3eSJouni Malinen struct sigma_cmd c; 318cd4e3c3eSJouni Malinen char *cmd, *pos, *pos2; 319cd4e3c3eSJouni Malinen int len; 3205fdd8650SAlexei Avshalom Lazar char txt[300]; 32126a5b76dSJouni Malinen enum sigma_cmd_result res; 322cd4e3c3eSJouni Malinen 323cd4e3c3eSJouni Malinen while (*buf == '\r' || *buf == '\n' || *buf == '\t' || *buf == ' ') 324cd4e3c3eSJouni Malinen buf++; 325cd4e3c3eSJouni Malinen len = strlen(buf); 326cd4e3c3eSJouni Malinen while (len > 0 && buf[len - 1] == ' ') { 327cd4e3c3eSJouni Malinen buf[len - 1] = '\0'; 328cd4e3c3eSJouni Malinen len--; 329cd4e3c3eSJouni Malinen } 330cd4e3c3eSJouni Malinen 331cd4e3c3eSJouni Malinen if (dut->debug_level < DUT_MSG_INFO) { 332cd4e3c3eSJouni Malinen pos = strchr(buf, ','); 333cd4e3c3eSJouni Malinen if (pos == NULL) 334cd4e3c3eSJouni Malinen pos = buf + len; 335cd4e3c3eSJouni Malinen if (pos - buf > 50) 336cd4e3c3eSJouni Malinen pos = buf + 50; 337cd4e3c3eSJouni Malinen memcpy(txt, "/====[ ", 7); 338cd4e3c3eSJouni Malinen pos2 = txt + 7; 339cd4e3c3eSJouni Malinen memcpy(pos2, buf, pos - buf); 340cd4e3c3eSJouni Malinen pos2 += pos - buf; 341cd4e3c3eSJouni Malinen *pos2++ = ' '; 342cd4e3c3eSJouni Malinen *pos2++ = ']'; 343cd4e3c3eSJouni Malinen while (pos2 - txt < 70) 344cd4e3c3eSJouni Malinen *pos2++ = '='; 345cd4e3c3eSJouni Malinen *pos2++ = '\\'; 346cd4e3c3eSJouni Malinen *pos2 = '\0'; 347cd4e3c3eSJouni Malinen printf("\n%s\n\n", txt); 348cd4e3c3eSJouni Malinen } 349cd4e3c3eSJouni Malinen 350cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "cmd: %s", buf); 351cd4e3c3eSJouni Malinen sigma_dut_summary(dut, "CAPI cmd: %s", buf); 352cd4e3c3eSJouni Malinen snprintf(txt, sizeof(txt), "NOTE CAPI:%s", buf); 353cd4e3c3eSJouni Malinen txt[sizeof(txt) - 1] = '\0'; 354cd4e3c3eSJouni Malinen wpa_command(get_main_ifname(), txt); 355cd4e3c3eSJouni Malinen 356cd4e3c3eSJouni Malinen memset(&c, 0, sizeof(c)); 357cd4e3c3eSJouni Malinen cmd = buf; 358cd4e3c3eSJouni Malinen pos = strchr(cmd, ','); 359cd4e3c3eSJouni Malinen if (pos) { 360cd4e3c3eSJouni Malinen *pos++ = '\0'; 361cd4e3c3eSJouni Malinen if (strcasecmp(cmd, "AccessPoint") == 0 || 362cd4e3c3eSJouni Malinen strcasecmp(cmd, "PowerSwitch") == 0) { 363cd4e3c3eSJouni Malinen pos2 = strchr(pos, ','); 364cd4e3c3eSJouni Malinen if (pos2 == NULL) 365cd4e3c3eSJouni Malinen goto invalid_params; 366cd4e3c3eSJouni Malinen c.params[c.count] = pos; 367cd4e3c3eSJouni Malinen c.values[c.count] = pos2; 368cd4e3c3eSJouni Malinen c.count++; 369cd4e3c3eSJouni Malinen pos = strchr(pos2, ','); 370cd4e3c3eSJouni Malinen if (pos) 371cd4e3c3eSJouni Malinen *pos++ = '\0'; 372cd4e3c3eSJouni Malinen } 373cd4e3c3eSJouni Malinen while (pos) { 374cd4e3c3eSJouni Malinen pos2 = strchr(pos, ','); 375cd4e3c3eSJouni Malinen if (pos2 == NULL) 376cd4e3c3eSJouni Malinen goto invalid_params; 377cd4e3c3eSJouni Malinen *pos2++ = '\0'; 378cd4e3c3eSJouni Malinen if (c.count == MAX_PARAMS) { 379cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Too many " 380cd4e3c3eSJouni Malinen "parameters"); 381cd4e3c3eSJouni Malinen goto invalid_params; 382cd4e3c3eSJouni Malinen } 383cd4e3c3eSJouni Malinen c.params[c.count] = pos; 384cd4e3c3eSJouni Malinen c.values[c.count] = pos2; 385cd4e3c3eSJouni Malinen c.count++; 386cd4e3c3eSJouni Malinen pos = strchr(pos2, ','); 387cd4e3c3eSJouni Malinen if (pos) 388cd4e3c3eSJouni Malinen *pos++ = '\0'; 389cd4e3c3eSJouni Malinen } 390cd4e3c3eSJouni Malinen } 391cd4e3c3eSJouni Malinen h = dut->cmds; 392cd4e3c3eSJouni Malinen while (h) { 393cd4e3c3eSJouni Malinen if (strcasecmp(cmd, h->cmd) == 0) 394cd4e3c3eSJouni Malinen break; 395cd4e3c3eSJouni Malinen h = h->next; 396cd4e3c3eSJouni Malinen } 397cd4e3c3eSJouni Malinen 398cd4e3c3eSJouni Malinen if (h == NULL) { 399cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Unknown command: '%s'", 400cd4e3c3eSJouni Malinen cmd); 401cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_INVALID, 402cd4e3c3eSJouni Malinen "errorCode,Unknown command"); 403cd4e3c3eSJouni Malinen goto out; 404cd4e3c3eSJouni Malinen } 405cd4e3c3eSJouni Malinen 406cd4e3c3eSJouni Malinen if (h->validate && h->validate(&c) < 0) { 407cd4e3c3eSJouni Malinen invalid_params: 408cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Invalid parameters"); 409cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid " 410cd4e3c3eSJouni Malinen "parameters"); 411cd4e3c3eSJouni Malinen goto out; 412cd4e3c3eSJouni Malinen } 413cd4e3c3eSJouni Malinen 4140fee701cSJouni Malinen dut->response_sent = 0; 415cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_RUNNING, NULL); 416cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Run command: %s", cmd); 417cd4e3c3eSJouni Malinen res = h->process(dut, conn, &c); 41826a5b76dSJouni Malinen switch (res) { 41926a5b76dSJouni Malinen case ERROR_SEND_STATUS: 420cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_ERROR, NULL); 42126a5b76dSJouni Malinen break; 42226a5b76dSJouni Malinen case INVALID_SEND_STATUS: 423cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_INVALID, NULL); 42426a5b76dSJouni Malinen break; 42526a5b76dSJouni Malinen case STATUS_SENT: 42626a5b76dSJouni Malinen break; 42726a5b76dSJouni Malinen case SUCCESS_SEND_STATUS: 428cd4e3c3eSJouni Malinen send_resp(dut, conn, SIGMA_COMPLETE, NULL); 42926a5b76dSJouni Malinen break; 43026a5b76dSJouni Malinen } 431cd4e3c3eSJouni Malinen 4320fee701cSJouni Malinen if (!conn->waiting_completion && dut->response_sent != 2) { 4330fee701cSJouni Malinen sigma_dut_print(dut, DUT_MSG_ERROR, 4340fee701cSJouni Malinen "ERROR: Unexpected number of status lines sent (%d) for command '%s'", 4350fee701cSJouni Malinen dut->response_sent, cmd); 4360fee701cSJouni Malinen } 4370fee701cSJouni Malinen 438cd4e3c3eSJouni Malinen out: 439cd4e3c3eSJouni Malinen if (dut->debug_level < DUT_MSG_INFO) { 440cd4e3c3eSJouni Malinen pos2 = txt; 441cd4e3c3eSJouni Malinen *pos2++ = '\\'; 442cd4e3c3eSJouni Malinen memset(pos2, '-', 69); 443cd4e3c3eSJouni Malinen pos2 += 69; 444cd4e3c3eSJouni Malinen *pos2++ = '/'; 445cd4e3c3eSJouni Malinen *pos2 = '\0'; 446cd4e3c3eSJouni Malinen printf("\n%s\n\n", txt); 447cd4e3c3eSJouni Malinen } 448cd4e3c3eSJouni Malinen } 449cd4e3c3eSJouni Malinen 450cd4e3c3eSJouni Malinen 451cd4e3c3eSJouni Malinen static void process_conn(struct sigma_dut *dut, struct sigma_conn *conn) 452cd4e3c3eSJouni Malinen { 453cd4e3c3eSJouni Malinen ssize_t res; 454cd4e3c3eSJouni Malinen int i; 455cd4e3c3eSJouni Malinen 456cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "Read from %s:%d", 457cd4e3c3eSJouni Malinen inet_ntoa(conn->addr.sin_addr), 458cd4e3c3eSJouni Malinen ntohs(conn->addr.sin_port)); 459cd4e3c3eSJouni Malinen 460cd4e3c3eSJouni Malinen res = recv(conn->s, conn->buf + conn->pos, MAX_CMD_LEN + 5 - conn->pos, 461cd4e3c3eSJouni Malinen 0); 462cd4e3c3eSJouni Malinen if (res < 0) { 463cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "recv: %s", 464cd4e3c3eSJouni Malinen strerror(errno)); 465cd4e3c3eSJouni Malinen } 466cd4e3c3eSJouni Malinen if (res <= 0) { 467cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "Close connection from " 468cd4e3c3eSJouni Malinen "%s:%d", 469cd4e3c3eSJouni Malinen inet_ntoa(conn->addr.sin_addr), 470cd4e3c3eSJouni Malinen ntohs(conn->addr.sin_port)); 471cd4e3c3eSJouni Malinen shutdown(conn->s, SHUT_RDWR); 472cd4e3c3eSJouni Malinen close(conn->s); 473cd4e3c3eSJouni Malinen conn->s = -1; 474cd4e3c3eSJouni Malinen return; 475cd4e3c3eSJouni Malinen } 476cd4e3c3eSJouni Malinen 477cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "Received %d bytes", 478cd4e3c3eSJouni Malinen (int) res); 479cd4e3c3eSJouni Malinen 480cd4e3c3eSJouni Malinen for (;;) { 481cd4e3c3eSJouni Malinen for (i = conn->pos; i < conn->pos + res; i++) { 482cd4e3c3eSJouni Malinen if (conn->buf[i] == '\r' || conn->buf[i] == '\n') 483cd4e3c3eSJouni Malinen break; 484cd4e3c3eSJouni Malinen } 485cd4e3c3eSJouni Malinen 486cd4e3c3eSJouni Malinen if (i == conn->pos + res) { 487cd4e3c3eSJouni Malinen /* Full command not yet received */ 488cd4e3c3eSJouni Malinen conn->pos += res; 489cd4e3c3eSJouni Malinen if (conn->pos >= MAX_CMD_LEN + 5) { 490cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, "Too long " 491cd4e3c3eSJouni Malinen "command dropped"); 492cd4e3c3eSJouni Malinen conn->pos = 0; 493cd4e3c3eSJouni Malinen } 494cd4e3c3eSJouni Malinen break; 495cd4e3c3eSJouni Malinen } 496cd4e3c3eSJouni Malinen 497cd4e3c3eSJouni Malinen /* Full command received */ 498cd4e3c3eSJouni Malinen conn->buf[i++] = '\0'; 499cd4e3c3eSJouni Malinen process_cmd(dut, conn, conn->buf); 500cd4e3c3eSJouni Malinen while (i < conn->pos + res && 501cd4e3c3eSJouni Malinen (conn->buf[i] == '\r' || conn->buf[i] == '\n')) 502cd4e3c3eSJouni Malinen i++; 503cd4e3c3eSJouni Malinen memmove(conn->buf, &conn->buf[i], conn->pos + res - i); 504cd4e3c3eSJouni Malinen res = conn->pos + res - i; 505cd4e3c3eSJouni Malinen conn->pos = 0; 506cd4e3c3eSJouni Malinen } 507cd4e3c3eSJouni Malinen } 508cd4e3c3eSJouni Malinen 509cd4e3c3eSJouni Malinen 510cd4e3c3eSJouni Malinen static int stop_loop = 0; 511cd4e3c3eSJouni Malinen 512cd4e3c3eSJouni Malinen #ifdef __linux__ 513cd4e3c3eSJouni Malinen static void handle_term(int sig) 514cd4e3c3eSJouni Malinen { 515cd4e3c3eSJouni Malinen stop_loop = 1; 516091e253dSPurushottam Kushwaha stop_event_thread(); 517cd4e3c3eSJouni Malinen printf("sigma_dut terminating\n"); 518cd4e3c3eSJouni Malinen } 519cd4e3c3eSJouni Malinen #endif /* __linux__ */ 520cd4e3c3eSJouni Malinen 521cd4e3c3eSJouni Malinen static void run_loop(struct sigma_dut *dut) 522cd4e3c3eSJouni Malinen { 523cd4e3c3eSJouni Malinen struct sigma_conn conn[MAX_CONNECTIONS]; 524cd4e3c3eSJouni Malinen int i, res, maxfd, can_accept; 525cd4e3c3eSJouni Malinen fd_set rfds; 526cd4e3c3eSJouni Malinen 527cd4e3c3eSJouni Malinen memset(&conn, 0, sizeof(conn)); 528cd4e3c3eSJouni Malinen for (i = 0; i < MAX_CONNECTIONS; i++) 529cd4e3c3eSJouni Malinen conn[i].s = -1; 530cd4e3c3eSJouni Malinen 531cd4e3c3eSJouni Malinen #ifdef __linux__ 532cd4e3c3eSJouni Malinen signal(SIGINT, handle_term); 533cd4e3c3eSJouni Malinen signal(SIGTERM, handle_term); 534cd4e3c3eSJouni Malinen signal(SIGPIPE, SIG_IGN); 535cd4e3c3eSJouni Malinen #endif /* __linux__ */ 536cd4e3c3eSJouni Malinen 537cd4e3c3eSJouni Malinen while (!stop_loop) { 538cd4e3c3eSJouni Malinen FD_ZERO(&rfds); 539cd4e3c3eSJouni Malinen maxfd = -1; 540cd4e3c3eSJouni Malinen can_accept = 0; 541cd4e3c3eSJouni Malinen for (i = 0; i < MAX_CONNECTIONS; i++) { 542cd4e3c3eSJouni Malinen if (conn[i].s >= 0) { 543cd4e3c3eSJouni Malinen FD_SET(conn[i].s, &rfds); 544cd4e3c3eSJouni Malinen if (conn[i].s > maxfd) 545cd4e3c3eSJouni Malinen maxfd = conn[i].s; 546cd4e3c3eSJouni Malinen } else if (!conn[i].waiting_completion) 547cd4e3c3eSJouni Malinen can_accept = 1; 548cd4e3c3eSJouni Malinen } 549cd4e3c3eSJouni Malinen 550cd4e3c3eSJouni Malinen if (can_accept) { 551cd4e3c3eSJouni Malinen FD_SET(dut->s, &rfds); 552cd4e3c3eSJouni Malinen if (dut->s > maxfd) 553cd4e3c3eSJouni Malinen maxfd = dut->s; 554cd4e3c3eSJouni Malinen } 555cd4e3c3eSJouni Malinen 556cd4e3c3eSJouni Malinen 557cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting for next " 558cd4e3c3eSJouni Malinen "command (can_accept=%d)", can_accept); 559cd4e3c3eSJouni Malinen res = select(maxfd + 1, &rfds, NULL, NULL, NULL); 560cd4e3c3eSJouni Malinen if (res < 0) { 561cd4e3c3eSJouni Malinen perror("select"); 562cd4e3c3eSJouni Malinen if (!stop_loop) 563cd4e3c3eSJouni Malinen sleep(1); 564cd4e3c3eSJouni Malinen continue; 565cd4e3c3eSJouni Malinen } 566cd4e3c3eSJouni Malinen 567cd4e3c3eSJouni Malinen if (!res) { 568cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, "Nothing ready"); 569cd4e3c3eSJouni Malinen sleep(1); 570cd4e3c3eSJouni Malinen continue; 571cd4e3c3eSJouni Malinen } 572cd4e3c3eSJouni Malinen 573cd4e3c3eSJouni Malinen if (FD_ISSET(dut->s, &rfds)) { 574cd4e3c3eSJouni Malinen for (i = 0; i < MAX_CONNECTIONS; i++) { 575cd4e3c3eSJouni Malinen if (conn[i].s < 0 && 576cd4e3c3eSJouni Malinen !conn[i].waiting_completion) 577cd4e3c3eSJouni Malinen break; 578cd4e3c3eSJouni Malinen } 579cd4e3c3eSJouni Malinen if (i == MAX_CONNECTIONS) { 580cd4e3c3eSJouni Malinen /* 581cd4e3c3eSJouni Malinen * This cannot really happen since can_accept 582cd4e3c3eSJouni Malinen * would not be set to one. 583cd4e3c3eSJouni Malinen */ 584cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, 585cd4e3c3eSJouni Malinen "No room for new connection"); 586cd4e3c3eSJouni Malinen continue; 587cd4e3c3eSJouni Malinen } 588cd4e3c3eSJouni Malinen conn[i].addrlen = sizeof(conn[i].addr); 589cd4e3c3eSJouni Malinen conn[i].s = accept(dut->s, 590cd4e3c3eSJouni Malinen (struct sockaddr *) &conn[i].addr, 591cd4e3c3eSJouni Malinen &conn[i].addrlen); 592cd4e3c3eSJouni Malinen if (conn[i].s < 0) { 593cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_INFO, 594cd4e3c3eSJouni Malinen "accept: %s", 595cd4e3c3eSJouni Malinen strerror(errno)); 596cd4e3c3eSJouni Malinen continue; 597cd4e3c3eSJouni Malinen } 598cd4e3c3eSJouni Malinen 599cd4e3c3eSJouni Malinen sigma_dut_print(dut, DUT_MSG_DEBUG, 600cd4e3c3eSJouni Malinen "Connection %d from %s:%d", i, 601cd4e3c3eSJouni Malinen inet_ntoa(conn[i].addr.sin_addr), 602cd4e3c3eSJouni Malinen ntohs(conn[i].addr.sin_port)); 603cd4e3c3eSJouni Malinen conn[i].pos = 0; 604cd4e3c3eSJouni Malinen } 605cd4e3c3eSJouni Malinen 606cd4e3c3eSJouni Malinen for (i = 0; i < MAX_CONNECTIONS; i++) { 607cd4e3c3eSJouni Malinen if (conn[i].s < 0) 608cd4e3c3eSJouni Malinen continue; 609cd4e3c3eSJouni Malinen if (FD_ISSET(conn[i].s, &rfds)) 610cd4e3c3eSJouni Malinen process_conn(dut, &conn[i]); 611cd4e3c3eSJouni Malinen } 612cd4e3c3eSJouni Malinen } 613cd4e3c3eSJouni Malinen } 614cd4e3c3eSJouni Malinen 615cd4e3c3eSJouni Malinen 616cd4e3c3eSJouni Malinen static int run_local_cmd(int port, char *lcmd) 617cd4e3c3eSJouni Malinen { 618cd4e3c3eSJouni Malinen int s, len; 619cd4e3c3eSJouni Malinen struct sockaddr_in addr; 620cd4e3c3eSJouni Malinen char cmd[MAX_CMD_LEN]; 621cd4e3c3eSJouni Malinen ssize_t res; 622cd4e3c3eSJouni Malinen int count; 623cd4e3c3eSJouni Malinen char resp[MAX_CMD_LEN]; 624cd4e3c3eSJouni Malinen int pos; 625cd4e3c3eSJouni Malinen 626cd4e3c3eSJouni Malinen 627cd4e3c3eSJouni Malinen if (strlen(lcmd) > sizeof(cmd) - 4) { 628cd4e3c3eSJouni Malinen printf("Too long command\n"); 629cd4e3c3eSJouni Malinen return -1; 630cd4e3c3eSJouni Malinen } 631cd4e3c3eSJouni Malinen len = snprintf(cmd, sizeof(cmd), "%s \r\n", lcmd); 632cd4e3c3eSJouni Malinen 633cd4e3c3eSJouni Malinen memset(&addr, 0, sizeof(addr)); 634cd4e3c3eSJouni Malinen addr.sin_family = AF_INET; 635cd4e3c3eSJouni Malinen inet_aton("127.0.0.1", &addr.sin_addr); 636cd4e3c3eSJouni Malinen addr.sin_port = htons(port); 637cd4e3c3eSJouni Malinen 638cd4e3c3eSJouni Malinen /* Make sure we do not get stuck indefinitely */ 639cd4e3c3eSJouni Malinen alarm(150); 640cd4e3c3eSJouni Malinen 641cd4e3c3eSJouni Malinen s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 642cd4e3c3eSJouni Malinen if (s < 0) { 643cd4e3c3eSJouni Malinen perror("socket"); 644cd4e3c3eSJouni Malinen return -1; 645cd4e3c3eSJouni Malinen } 646cd4e3c3eSJouni Malinen 647cd4e3c3eSJouni Malinen if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 648cd4e3c3eSJouni Malinen perror("connect"); 649cd4e3c3eSJouni Malinen close(s); 650cd4e3c3eSJouni Malinen return -1; 651cd4e3c3eSJouni Malinen } 652cd4e3c3eSJouni Malinen 653cd4e3c3eSJouni Malinen res = send(s, cmd, len, 0); 654cd4e3c3eSJouni Malinen if (res < 0) { 655cd4e3c3eSJouni Malinen perror("send"); 656cd4e3c3eSJouni Malinen close(s); 657cd4e3c3eSJouni Malinen return -1; 658cd4e3c3eSJouni Malinen } 659cd4e3c3eSJouni Malinen if (res != len) { 660cd4e3c3eSJouni Malinen printf("Unexpected send result: %d (expected %d)\n", 661cd4e3c3eSJouni Malinen (int) res, len); 662cd4e3c3eSJouni Malinen close(s); 663cd4e3c3eSJouni Malinen return -1; 664cd4e3c3eSJouni Malinen } 665cd4e3c3eSJouni Malinen 666cd4e3c3eSJouni Malinen count = 0; 667cd4e3c3eSJouni Malinen pos = 0; 668cd4e3c3eSJouni Malinen len = 0; 669cd4e3c3eSJouni Malinen for (;;) { 670cd4e3c3eSJouni Malinen char *e; 671cd4e3c3eSJouni Malinen res = recv(s, resp + len, sizeof(resp) - len, 0); 672cd4e3c3eSJouni Malinen if (res < 0) { 673cd4e3c3eSJouni Malinen perror("recv"); 674cd4e3c3eSJouni Malinen close(s); 675cd4e3c3eSJouni Malinen return -1; 676cd4e3c3eSJouni Malinen } 677cd4e3c3eSJouni Malinen if (res == 0) { 678cd4e3c3eSJouni Malinen printf("Could not read response\n"); 679cd4e3c3eSJouni Malinen close(s); 680cd4e3c3eSJouni Malinen return -1; 681cd4e3c3eSJouni Malinen } 682cd4e3c3eSJouni Malinen len += res; 683cd4e3c3eSJouni Malinen next_line: 684cd4e3c3eSJouni Malinen e = memchr(resp + pos, '\r', len - pos); 685cd4e3c3eSJouni Malinen if (e == NULL) 686cd4e3c3eSJouni Malinen continue; 687cd4e3c3eSJouni Malinen *e++ = '\0'; 688cd4e3c3eSJouni Malinen if (e - resp < len && *e == '\n') 689cd4e3c3eSJouni Malinen *e++ = '\n'; 690cd4e3c3eSJouni Malinen printf("%s\n", resp + pos); 691cd4e3c3eSJouni Malinen if (strncasecmp(resp + pos, "status,RUNNING", 14) != 0) 692cd4e3c3eSJouni Malinen break; 693cd4e3c3eSJouni Malinen count++; 694cd4e3c3eSJouni Malinen if (count == 2) 695cd4e3c3eSJouni Malinen break; 696cd4e3c3eSJouni Malinen pos = e - resp; 697cd4e3c3eSJouni Malinen goto next_line; 698cd4e3c3eSJouni Malinen } 699cd4e3c3eSJouni Malinen 700cd4e3c3eSJouni Malinen close(s); 701cd4e3c3eSJouni Malinen 702cd4e3c3eSJouni Malinen return 0; 703cd4e3c3eSJouni Malinen } 704cd4e3c3eSJouni Malinen 705cd4e3c3eSJouni Malinen 706091e253dSPurushottam Kushwaha static char * determine_sigma_p2p_ifname(void) 707f2af39bfSDanny Segal { 708f2af39bfSDanny Segal char buf[256]; 709f2af39bfSDanny Segal struct wpa_ctrl *ctrl; 710f2af39bfSDanny Segal 711f2af39bfSDanny Segal if (sigma_p2p_ifname) 712091e253dSPurushottam Kushwaha return sigma_p2p_ifname; 713f2af39bfSDanny Segal 714f2af39bfSDanny Segal snprintf(buf, sizeof(buf), "p2p-dev-%s", get_station_ifname()); 715f2af39bfSDanny Segal ctrl = open_wpa_mon(buf); 716f2af39bfSDanny Segal if (ctrl) { 717f2af39bfSDanny Segal wpa_ctrl_detach(ctrl); 718f2af39bfSDanny Segal wpa_ctrl_close(ctrl); 719f2af39bfSDanny Segal sigma_p2p_ifname_buf = strdup(buf); 720f2af39bfSDanny Segal sigma_p2p_ifname = sigma_p2p_ifname_buf; 721f2af39bfSDanny Segal sigma_dut_print(&sigma_dut, DUT_MSG_INFO, 722f2af39bfSDanny Segal "Using interface %s for P2P operations instead of interface %s", 723f2af39bfSDanny Segal sigma_p2p_ifname ? sigma_p2p_ifname : "NULL", 724f2af39bfSDanny Segal get_station_ifname()); 725f2af39bfSDanny Segal } else { 726f2af39bfSDanny Segal sigma_p2p_ifname = get_station_ifname(); 727f2af39bfSDanny Segal } 728091e253dSPurushottam Kushwaha 729091e253dSPurushottam Kushwaha return sigma_p2p_ifname; 730f2af39bfSDanny Segal } 731f2af39bfSDanny Segal 732f2af39bfSDanny Segal 733*d06f100bSPriyadharshini Gowthaman static int get_nl80211_config_enable_option(struct sigma_dut *dut) 734*d06f100bSPriyadharshini Gowthaman { 735*d06f100bSPriyadharshini Gowthaman char cmd[100], result[5]; 736*d06f100bSPriyadharshini Gowthaman FILE *f; 737*d06f100bSPriyadharshini Gowthaman size_t len; 738*d06f100bSPriyadharshini Gowthaman int ap_nl80211_enable; 739*d06f100bSPriyadharshini Gowthaman 740*d06f100bSPriyadharshini Gowthaman snprintf(cmd, sizeof(cmd), "uci get qcacfg80211.config.enable"); 741*d06f100bSPriyadharshini Gowthaman f = popen(cmd, "r"); 742*d06f100bSPriyadharshini Gowthaman if (!f) 743*d06f100bSPriyadharshini Gowthaman return -1; 744*d06f100bSPriyadharshini Gowthaman 745*d06f100bSPriyadharshini Gowthaman len = fread(result, 1, sizeof(result) - 1, f); 746*d06f100bSPriyadharshini Gowthaman pclose(f); 747*d06f100bSPriyadharshini Gowthaman 748*d06f100bSPriyadharshini Gowthaman if (len == 0) 749*d06f100bSPriyadharshini Gowthaman return -1; 750*d06f100bSPriyadharshini Gowthaman 751*d06f100bSPriyadharshini Gowthaman result[len] = '\0'; 752*d06f100bSPriyadharshini Gowthaman ap_nl80211_enable = atoi(result); 753*d06f100bSPriyadharshini Gowthaman 754*d06f100bSPriyadharshini Gowthaman if (ap_nl80211_enable) 755*d06f100bSPriyadharshini Gowthaman dut->priv_cmd = "cfg80211tool"; 756*d06f100bSPriyadharshini Gowthaman 757*d06f100bSPriyadharshini Gowthaman return 0; 758*d06f100bSPriyadharshini Gowthaman } 759*d06f100bSPriyadharshini Gowthaman 760*d06f100bSPriyadharshini Gowthaman 761cd4e3c3eSJouni Malinen static void set_defaults(struct sigma_dut *dut) 762cd4e3c3eSJouni Malinen { 763cd4e3c3eSJouni Malinen dut->ap_p2p_cross_connect = -1; 764cd4e3c3eSJouni Malinen dut->ap_chwidth = AP_AUTO; 765bf8af292SPradeep Reddy Potteti dut->default_11na_ap_chwidth = AP_AUTO; 766bf8af292SPradeep Reddy Potteti dut->default_11ng_ap_chwidth = AP_AUTO; 767cd4e3c3eSJouni Malinen /* by default, enable writing of traffic stream stats */ 768cd4e3c3eSJouni Malinen dut->write_stats = 1; 769*d06f100bSPriyadharshini Gowthaman dut->priv_cmd = "iwpriv"; 770cd4e3c3eSJouni Malinen } 771cd4e3c3eSJouni Malinen 772cd4e3c3eSJouni Malinen 773cd4e3c3eSJouni Malinen static const char * const license1 = 774cd4e3c3eSJouni Malinen "sigma_dut - WFA Sigma DUT/CA\n" 775cd4e3c3eSJouni Malinen "----------------------------\n" 776cd4e3c3eSJouni Malinen "\n" 777cd4e3c3eSJouni Malinen "Copyright (c) 2010-2011, Atheros Communications, Inc.\n" 7789d7e31d5SJouni Malinen "Copyright (c) 2011-2017, Qualcomm Atheros, Inc.\n" 7795b16b51eSJouni Malinen "Copyright (c) 2018-2019, The Linux Foundation\n" 780cd4e3c3eSJouni Malinen "All Rights Reserved.\n" 781cd4e3c3eSJouni Malinen "Licensed under the Clear BSD license.\n" 782cd4e3c3eSJouni Malinen "\n"; 783cd4e3c3eSJouni Malinen static const char * const license2 = 784cd4e3c3eSJouni Malinen "Redistribution and use in source and binary forms, with or without\n" 785cd4e3c3eSJouni Malinen "modification, are permitted (subject to the limitations in the\n" 786cd4e3c3eSJouni Malinen "disclaimer below) provided that the following conditions are met:\n" 787cd4e3c3eSJouni Malinen "\n"; 788cd4e3c3eSJouni Malinen static const char * const license3 = 789cd4e3c3eSJouni Malinen "* Redistributions of source code must retain the above copyright notice,\n" 790cd4e3c3eSJouni Malinen " this list of conditions and the following disclaimer.\n" 791cd4e3c3eSJouni Malinen "\n" 792cd4e3c3eSJouni Malinen "* Redistributions in binary form must reproduce the above copyright\n" 793cd4e3c3eSJouni Malinen " notice, this list of conditions and the following disclaimer in the\n" 794cd4e3c3eSJouni Malinen " documentation and/or other materials provided with the distribution.\n" 795cd4e3c3eSJouni Malinen "\n" 796cd4e3c3eSJouni Malinen "* Neither the name of Qualcomm Atheros, Inc. nor the names of its\n" 797cd4e3c3eSJouni Malinen " contributors may be used to endorse or promote products derived from\n" 798cd4e3c3eSJouni Malinen " this software without specific prior written permission.\n" 799cd4e3c3eSJouni Malinen "\n"; 800cd4e3c3eSJouni Malinen static const char * const license4 = 801cd4e3c3eSJouni Malinen "NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED\n" 802cd4e3c3eSJouni Malinen "BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n" 803cd4e3c3eSJouni Malinen "CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\n" 804cd4e3c3eSJouni Malinen "BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\n" 805cd4e3c3eSJouni Malinen "FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n" 806cd4e3c3eSJouni Malinen "COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n" 807cd4e3c3eSJouni Malinen "INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n" 808cd4e3c3eSJouni Malinen "NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\n" 809cd4e3c3eSJouni Malinen "USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n" 810cd4e3c3eSJouni Malinen "ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" 811cd4e3c3eSJouni Malinen "(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n" 812cd4e3c3eSJouni Malinen "THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"; 813cd4e3c3eSJouni Malinen 814cd4e3c3eSJouni Malinen 815cd4e3c3eSJouni Malinen static void print_license(void) 816cd4e3c3eSJouni Malinen { 817cd4e3c3eSJouni Malinen printf("%s%s%s%s\n", 818cd4e3c3eSJouni Malinen license1, license2, license3, license4); 819cd4e3c3eSJouni Malinen } 820cd4e3c3eSJouni Malinen 821cd4e3c3eSJouni Malinen 822cd4e3c3eSJouni Malinen int main(int argc, char *argv[]) 823cd4e3c3eSJouni Malinen { 824cd4e3c3eSJouni Malinen int c; 825cd4e3c3eSJouni Malinen int daemonize = 0; 826cd4e3c3eSJouni Malinen int port = SIGMA_DUT_PORT; 827cd4e3c3eSJouni Malinen char *local_cmd = NULL; 828091e253dSPurushottam Kushwaha int internal_dhcp_enabled = 0; 829cd4e3c3eSJouni Malinen #ifdef __QNXNTO__ 830cd4e3c3eSJouni Malinen char *env_str = NULL; 831cd4e3c3eSJouni Malinen char buf[20]; 832cd4e3c3eSJouni Malinen char *sigma_ctrl_sock = NULL; /* env used for QNX */ 833cd4e3c3eSJouni Malinen #endif /* __QNXNTO__ */ 834cd4e3c3eSJouni Malinen 835cd4e3c3eSJouni Malinen memset(&sigma_dut, 0, sizeof(sigma_dut)); 836cd4e3c3eSJouni Malinen sigma_dut.debug_level = DUT_MSG_INFO; 837cd4e3c3eSJouni Malinen sigma_dut.default_timeout = 120; 838cd4e3c3eSJouni Malinen sigma_dut.dialog_token = 0; 839d86e5828SJouni Malinen sigma_dut.dpp_conf_id = -1; 84063d5041cSJouni Malinen sigma_dut.dpp_local_bootstrap = -1; 841ac6c511cSArif Hussain sigma_dut.sta_nss = 2; /* Make default nss 2 */ 8428863ec7cSPeng Xu sigma_dut.trans_proto = NAN_TRANSPORT_PROTOCOL_DEFAULT; 8438863ec7cSPeng Xu sigma_dut.trans_port = NAN_TRANSPORT_PORT_DEFAULT; 844cd4e3c3eSJouni Malinen set_defaults(&sigma_dut); 845cd4e3c3eSJouni Malinen 846cd4e3c3eSJouni Malinen for (;;) { 847cd4e3c3eSJouni Malinen c = getopt(argc, argv, 8483e8267ecSAlexei Avshalom Lazar "aAb:Bc:C:dDE:e:fF:gGhH:j:J:i:Ik:l:L:m:M:nN:o:O:p:P:qr:R:s:S:tT:uv:VWw:x:y:z:"); 849cd4e3c3eSJouni Malinen if (c < 0) 850cd4e3c3eSJouni Malinen break; 851cd4e3c3eSJouni Malinen switch (c) { 852cd4e3c3eSJouni Malinen case 'a': 853cd4e3c3eSJouni Malinen sigma_dut.ap_anqpserver = 1; 854cd4e3c3eSJouni Malinen break; 855cd4e3c3eSJouni Malinen case 'b': 856cd4e3c3eSJouni Malinen sigma_dut.bridge = optarg; 857cd4e3c3eSJouni Malinen break; 858cd4e3c3eSJouni Malinen case 'B': 859cd4e3c3eSJouni Malinen daemonize++; 860cd4e3c3eSJouni Malinen break; 861cd4e3c3eSJouni Malinen case 'C': 862cd4e3c3eSJouni Malinen sigma_cert_path = optarg; 863cd4e3c3eSJouni Malinen break; 864cd4e3c3eSJouni Malinen case 'd': 865cd4e3c3eSJouni Malinen if (sigma_dut.debug_level > 0) 866cd4e3c3eSJouni Malinen sigma_dut.debug_level--; 867cd4e3c3eSJouni Malinen break; 868cd4e3c3eSJouni Malinen #ifdef __QNXNTO__ 869cd4e3c3eSJouni Malinen case 'E': 870cd4e3c3eSJouni Malinen sigma_ctrl_sock = optarg; 871cd4e3c3eSJouni Malinen break; 872cd4e3c3eSJouni Malinen #endif /* __QNXNTO__ */ 873cd4e3c3eSJouni Malinen case 'D': 874cd4e3c3eSJouni Malinen sigma_dut.stdout_debug = 1; 875cd4e3c3eSJouni Malinen break; 876cd4e3c3eSJouni Malinen case 'e': 877cd4e3c3eSJouni Malinen sigma_dut.hostapd_entropy_log = optarg; 878cd4e3c3eSJouni Malinen break; 879cd4e3c3eSJouni Malinen case 'f': 880cd4e3c3eSJouni Malinen /* Disable writing stats */ 881cd4e3c3eSJouni Malinen sigma_dut.write_stats = 0; 882cd4e3c3eSJouni Malinen break; 883d6bf1b4aSJouni Malinen case 'F': 884d6bf1b4aSJouni Malinen sigma_dut.hostapd_bin = optarg; 885d6bf1b4aSJouni Malinen break; 886091e253dSPurushottam Kushwaha case 'g': 887091e253dSPurushottam Kushwaha /* Enable internal processing of P2P group formation 888091e253dSPurushottam Kushwaha * events to start/stop DHCP server/client. */ 889091e253dSPurushottam Kushwaha internal_dhcp_enabled = 1; 890091e253dSPurushottam Kushwaha break; 891d6bf1b4aSJouni Malinen case 'G': 892d6bf1b4aSJouni Malinen sigma_dut.use_hostapd_pid_file = 1; 893d6bf1b4aSJouni Malinen break; 894cd4e3c3eSJouni Malinen case 'H': 895cd4e3c3eSJouni Malinen sigma_dut.hostapd_debug_log = optarg; 896cd4e3c3eSJouni Malinen break; 897cd4e3c3eSJouni Malinen case 'I': 898cd4e3c3eSJouni Malinen print_license(); 899cd4e3c3eSJouni Malinen exit(0); 900cd4e3c3eSJouni Malinen break; 901d6bf1b4aSJouni Malinen case 'j': 902d6bf1b4aSJouni Malinen sigma_dut.hostapd_ifname = optarg; 903d6bf1b4aSJouni Malinen break; 9043e8267ecSAlexei Avshalom Lazar case 'J': 9053e8267ecSAlexei Avshalom Lazar sigma_dut.wpa_supplicant_debug_log = optarg; 9063e8267ecSAlexei Avshalom Lazar break; 907cd4e3c3eSJouni Malinen case 'l': 908cd4e3c3eSJouni Malinen local_cmd = optarg; 909cd4e3c3eSJouni Malinen break; 910cd4e3c3eSJouni Malinen case 'L': 911cd4e3c3eSJouni Malinen sigma_dut.summary_log = optarg; 912cd4e3c3eSJouni Malinen break; 913cd4e3c3eSJouni Malinen case 'p': 914cd4e3c3eSJouni Malinen port = atoi(optarg); 915cd4e3c3eSJouni Malinen break; 916f2af39bfSDanny Segal case 'P': 917f2af39bfSDanny Segal sigma_p2p_ifname = optarg; 918f2af39bfSDanny Segal break; 919cd4e3c3eSJouni Malinen case 'q': 920cd4e3c3eSJouni Malinen sigma_dut.debug_level++; 921cd4e3c3eSJouni Malinen break; 922cd4e3c3eSJouni Malinen case 'r': 923cd4e3c3eSJouni Malinen if (strcmp(optarg, "HT40") == 0) { 924bf8af292SPradeep Reddy Potteti sigma_dut.default_11na_ap_chwidth = AP_40; 925bf8af292SPradeep Reddy Potteti } else if (strcmp(optarg, "2.4_HT40") == 0) { 926bf8af292SPradeep Reddy Potteti sigma_dut.default_11ng_ap_chwidth = AP_40; 927cd4e3c3eSJouni Malinen } else { 928cd4e3c3eSJouni Malinen printf("Unsupported -r value\n"); 929cd4e3c3eSJouni Malinen exit(1); 930cd4e3c3eSJouni Malinen } 931cd4e3c3eSJouni Malinen break; 932cd4e3c3eSJouni Malinen case 'R': { 933cd4e3c3eSJouni Malinen static int num_radio = 0; 934cd4e3c3eSJouni Malinen static char **radio_ptr = sigma_radio_ifname; 935cd4e3c3eSJouni Malinen 936cd4e3c3eSJouni Malinen num_radio++; 937cd4e3c3eSJouni Malinen if (num_radio > MAX_RADIO) { 938cd4e3c3eSJouni Malinen printf("Multiple radio support limit (%d) exceeded\n", 939cd4e3c3eSJouni Malinen MAX_RADIO); 940cd4e3c3eSJouni Malinen exit(1); 941cd4e3c3eSJouni Malinen } 942cd4e3c3eSJouni Malinen *radio_ptr++ = optarg; 943cd4e3c3eSJouni Malinen break; 944cd4e3c3eSJouni Malinen } 945cd4e3c3eSJouni Malinen case 's': 946cd4e3c3eSJouni Malinen sigma_dut.sniffer_ifname = optarg; 947cd4e3c3eSJouni Malinen break; 948cd4e3c3eSJouni Malinen case 't': 949cd4e3c3eSJouni Malinen sigma_dut.no_timestamps = 1; 950cd4e3c3eSJouni Malinen break; 951cd4e3c3eSJouni Malinen case 'T': 952cd4e3c3eSJouni Malinen sigma_dut.throughput_pktsize = atoi(optarg); 953c2493f83SJouni Malinen if (sigma_dut.throughput_pktsize == 0) { 954cd4e3c3eSJouni Malinen printf("Invalid -T value\n"); 955cd4e3c3eSJouni Malinen exit(0); 956cd4e3c3eSJouni Malinen } 957cd4e3c3eSJouni Malinen break; 958cd4e3c3eSJouni Malinen case 'm': 959cd4e3c3eSJouni Malinen sigma_dut.set_macaddr = optarg; 960cd4e3c3eSJouni Malinen break; 961cd4e3c3eSJouni Malinen case 'M': 962cd4e3c3eSJouni Malinen sigma_main_ifname = optarg; 963cd4e3c3eSJouni Malinen break; 964cd4e3c3eSJouni Malinen case 'n': 965cd4e3c3eSJouni Malinen sigma_dut.no_ip_addr_set = 1; 966cd4e3c3eSJouni Malinen break; 9675db3b104SJouni Malinen case 'N': 9685db3b104SJouni Malinen sigma_dut.vendor_name = optarg; 9695db3b104SJouni Malinen break; 9705db3b104SJouni Malinen case 'o': 9715db3b104SJouni Malinen sigma_dut.model_name = optarg; 9725db3b104SJouni Malinen break; 9735db3b104SJouni Malinen case 'O': 9745db3b104SJouni Malinen sigma_dut.version_name = optarg; 9755db3b104SJouni Malinen break; 976cd4e3c3eSJouni Malinen case 'S': 977cd4e3c3eSJouni Malinen sigma_station_ifname = optarg; 978cd4e3c3eSJouni Malinen break; 979cd4e3c3eSJouni Malinen case 'w': 980cd4e3c3eSJouni Malinen sigma_hapd_ctrl = optarg; 981cd4e3c3eSJouni Malinen sigma_wpas_ctrl = optarg; 982cd4e3c3eSJouni Malinen break; 983cd4e3c3eSJouni Malinen case 'i': 984cd4e3c3eSJouni Malinen ap_inet_addr = optarg; 985cd4e3c3eSJouni Malinen break; 986cd4e3c3eSJouni Malinen case 'k': 987cd4e3c3eSJouni Malinen ap_inet_mask = optarg; 988cd4e3c3eSJouni Malinen break; 989cd4e3c3eSJouni Malinen case 'c': 990cd4e3c3eSJouni Malinen printf("%s", optarg); 991cd4e3c3eSJouni Malinen if (set_wifi_chip(optarg) < 0) 992cd4e3c3eSJouni Malinen sigma_dut_print(&sigma_dut, DUT_MSG_ERROR, 993cd4e3c3eSJouni Malinen "WRONG CHIP TYPE: SAP will " 994cd4e3c3eSJouni Malinen "not load"); 995cd4e3c3eSJouni Malinen break; 996cd4e3c3eSJouni Malinen case 'v': 997cd4e3c3eSJouni Malinen sigma_dut.version = optarg; 998cd4e3c3eSJouni Malinen break; 999cd4e3c3eSJouni Malinen case 'V': 1000cd4e3c3eSJouni Malinen printf("sigma_dut " SIGMA_DUT_VER "\n"); 1001cd4e3c3eSJouni Malinen exit(0); 1002cd4e3c3eSJouni Malinen break; 1003cd4e3c3eSJouni Malinen case 'W': 1004cd4e3c3eSJouni Malinen sigma_dut_print(&sigma_dut, DUT_MSG_INFO, 1005cd4e3c3eSJouni Malinen "Running WMM-AC test suite"); 1006cd4e3c3eSJouni Malinen sigma_wmm_ac = 1; 1007cd4e3c3eSJouni Malinen break; 1008cd4e3c3eSJouni Malinen case 'u': 1009cd4e3c3eSJouni Malinen sigma_dut_print(&sigma_dut, DUT_MSG_INFO, 1010cd4e3c3eSJouni Malinen "Use iface down/up in reset cmd"); 1011cd4e3c3eSJouni Malinen sigma_dut.iface_down_on_reset = 1; 1012cd4e3c3eSJouni Malinen break; 101373d7af09SBala Krishna Bhamidipati case 'A': 101473d7af09SBala Krishna Bhamidipati sigma_dut.sim_no_username = 1; 101573d7af09SBala Krishna Bhamidipati break; 10169c381f59SAmarnath Hullur Subramanyam #ifdef MIRACAST 10179c381f59SAmarnath Hullur Subramanyam case 'x': 10189c381f59SAmarnath Hullur Subramanyam if (strcmp(optarg, "sink") == 0) { 10199c381f59SAmarnath Hullur Subramanyam sigma_dut.wfd_device_type = 1; 10209c381f59SAmarnath Hullur Subramanyam sigma_dut_print(&sigma_dut, DUT_MSG_INFO, 10219c381f59SAmarnath Hullur Subramanyam "Device Type is SINK"); 10229c381f59SAmarnath Hullur Subramanyam } else if (strcmp(optarg, "source") == 0) { 10239c381f59SAmarnath Hullur Subramanyam sigma_dut.wfd_device_type = 0; 10249c381f59SAmarnath Hullur Subramanyam sigma_dut_print(&sigma_dut, DUT_MSG_INFO, 10259c381f59SAmarnath Hullur Subramanyam "Device Type is SOURCE"); 10269c381f59SAmarnath Hullur Subramanyam } 10279c381f59SAmarnath Hullur Subramanyam break; 10289c381f59SAmarnath Hullur Subramanyam case 'y': 10299c381f59SAmarnath Hullur Subramanyam sigma_dut.miracast_lib_path = optarg; 10309c381f59SAmarnath Hullur Subramanyam break; 10319c381f59SAmarnath Hullur Subramanyam #endif /* MIRACAST */ 1032525dbfd1SRajiv Ranjan case 'z': 1033525dbfd1SRajiv Ranjan client_socket_path = optarg; 1034525dbfd1SRajiv Ranjan break; 1035cd4e3c3eSJouni Malinen case 'h': 1036cd4e3c3eSJouni Malinen default: 1037d6bf1b4aSJouni Malinen printf("usage: sigma_dut [-aABdfGqDIntuVW] [-p<port>] " 1038cd4e3c3eSJouni Malinen "[-s<sniffer>] [-m<set_maccaddr.sh>] \\\n" 1039cd4e3c3eSJouni Malinen " [-M<main ifname>] [-R<radio ifname>] " 1040f2af39bfSDanny Segal "[-S<station ifname>] [-P<p2p_ifname>]\\\n" 1041cd4e3c3eSJouni Malinen " [-T<throughput pktsize>] \\\n" 1042cd4e3c3eSJouni Malinen " [-w<wpa_supplicant/hostapd ctrl_iface " 1043cd4e3c3eSJouni Malinen "dir>] \\\n" 1044cd4e3c3eSJouni Malinen " [-H <hostapd log file>] \\\n" 1045d6bf1b4aSJouni Malinen " [-F <hostapd binary path>] \\\n" 1046d6bf1b4aSJouni Malinen " [-j <hostapd ifname>] \\\n" 10473e8267ecSAlexei Avshalom Lazar " [-J <wpa_supplicant debug log>] \\\n" 1048cd4e3c3eSJouni Malinen " [-C <certificate path>] \\\n" 1049cd4e3c3eSJouni Malinen " [-v <version string>] \\\n" 1050cd4e3c3eSJouni Malinen " [-L <summary log>] \\\n" 1051cd4e3c3eSJouni Malinen " [-c <wifi chip type: WCN or ATHEROS or " 1052b692f107SSreelakshmi Konamki "AR6003 or MAC80211 or QNXNTO or OPENWRT or " 1053b692f107SSreelakshmi Konamki "LINUX-WCN>] " 1054cd4e3c3eSJouni Malinen "\\\n" 1055cd4e3c3eSJouni Malinen " [-i <IP address of the AP>] \\\n" 1056cd4e3c3eSJouni Malinen " [-k <subnet mask for the AP>] \\\n" 1057cd4e3c3eSJouni Malinen " [-e <hostapd entropy file>] \\\n" 10585db3b104SJouni Malinen " [-N <device_get_info vendor>] \\\n" 10595db3b104SJouni Malinen " [-o <device_get_info model>] \\\n" 10605db3b104SJouni Malinen " [-O <device_get_info version>] \\\n" 10619c381f59SAmarnath Hullur Subramanyam #ifdef MIRACAST 10629c381f59SAmarnath Hullur Subramanyam " [-x <sink|source>] \\\n" 10639c381f59SAmarnath Hullur Subramanyam " [-y <Miracast library path>] \\\n" 10649c381f59SAmarnath Hullur Subramanyam #endif /* MIRACAST */ 1065525dbfd1SRajiv Ranjan " [-z <client socket directory path \\\n" 1066525dbfd1SRajiv Ranjan " Ex: </data/vendor/wifi/sockets>] \\\n" 1067bf8af292SPradeep Reddy Potteti " [-r <HT40 or 2.4_HT40>]\n"); 1068cd4e3c3eSJouni Malinen printf("local command: sigma_dut [-p<port>] " 1069cd4e3c3eSJouni Malinen "<-l<cmd>>\n"); 1070cd4e3c3eSJouni Malinen exit(0); 1071cd4e3c3eSJouni Malinen break; 1072cd4e3c3eSJouni Malinen } 1073cd4e3c3eSJouni Malinen } 1074cd4e3c3eSJouni Malinen 1075091e253dSPurushottam Kushwaha sigma_dut.p2p_ifname = determine_sigma_p2p_ifname(); 10769c381f59SAmarnath Hullur Subramanyam #ifdef MIRACAST 10779c381f59SAmarnath Hullur Subramanyam miracast_init(&sigma_dut); 10789c381f59SAmarnath Hullur Subramanyam #endif /* MIRACAST */ 1079cd4e3c3eSJouni Malinen if (local_cmd) 1080cd4e3c3eSJouni Malinen return run_local_cmd(port, local_cmd); 1081cd4e3c3eSJouni Malinen 108208eaeba2SPradeep Reddy Potteti if ((wifi_chip_type == DRIVER_QNXNTO || 108308eaeba2SPradeep Reddy Potteti wifi_chip_type == DRIVER_LINUX_WCN) && 1084cd4e3c3eSJouni Malinen (sigma_main_ifname == NULL || sigma_station_ifname == NULL)) { 1085cd4e3c3eSJouni Malinen sigma_dut_print(&sigma_dut, DUT_MSG_ERROR, 108608eaeba2SPradeep Reddy Potteti "Interface should be provided for QNX/LINUX-WCN driver - check option M and S"); 1087cd4e3c3eSJouni Malinen } 1088cd4e3c3eSJouni Malinen 1089*d06f100bSPriyadharshini Gowthaman if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS) 1090*d06f100bSPriyadharshini Gowthaman get_nl80211_config_enable_option(&sigma_dut); 1091*d06f100bSPriyadharshini Gowthaman 1092291d97daSPeng Xu #ifdef NL80211_SUPPORT 1093291d97daSPeng Xu sigma_dut.nl_ctx = nl80211_init(&sigma_dut); 1094291d97daSPeng Xu #endif /* NL80211_SUPPORT */ 1095cd4e3c3eSJouni Malinen sigma_dut_register_cmds(); 1096cd4e3c3eSJouni Malinen 1097cd4e3c3eSJouni Malinen #ifdef __QNXNTO__ 1098cd4e3c3eSJouni Malinen /* Try to open socket in other env dev */ 1099cd4e3c3eSJouni Malinen if (sigma_ctrl_sock) { 1100cd4e3c3eSJouni Malinen env_str = getenv("SOCK"); 1101cd4e3c3eSJouni Malinen if (env_str) { 1102cd4e3c3eSJouni Malinen sigma_dut_print(&sigma_dut, DUT_MSG_INFO, 1103cd4e3c3eSJouni Malinen "SOCK=%s", env_str); 1104cd4e3c3eSJouni Malinen } 1105cd4e3c3eSJouni Malinen snprintf(buf, sizeof(buf), "SOCK=%s", sigma_ctrl_sock); 1106cd4e3c3eSJouni Malinen if (putenv(buf) != 0) { 1107cd4e3c3eSJouni Malinen sigma_dut_print(&sigma_dut, DUT_MSG_ERROR, 1108cd4e3c3eSJouni Malinen "putenv() failed setting SOCK"); 1109cd4e3c3eSJouni Malinen return EXIT_FAILURE; 1110cd4e3c3eSJouni Malinen } 1111cd4e3c3eSJouni Malinen } 1112cd4e3c3eSJouni Malinen #endif /* __QNXNTO__ */ 1113cd4e3c3eSJouni Malinen 1114cd4e3c3eSJouni Malinen if (open_socket(&sigma_dut, port) < 0) 1115cd4e3c3eSJouni Malinen return -1; 1116cd4e3c3eSJouni Malinen 1117cd4e3c3eSJouni Malinen #ifdef __QNXNTO__ 1118cd4e3c3eSJouni Malinen /* restore back the SOCK */ 1119cd4e3c3eSJouni Malinen if (sigma_ctrl_sock) { 1120cd4e3c3eSJouni Malinen if (env_str) { 1121cd4e3c3eSJouni Malinen snprintf(buf, sizeof(buf), "SOCK=%s", env_str); 1122cd4e3c3eSJouni Malinen if (putenv(buf) != 0) { 1123cd4e3c3eSJouni Malinen sigma_dut_print(&sigma_dut, DUT_MSG_ERROR, 1124cd4e3c3eSJouni Malinen "putenv() failed setting SOCK"); 1125cd4e3c3eSJouni Malinen return EXIT_FAILURE; 1126cd4e3c3eSJouni Malinen } 1127cd4e3c3eSJouni Malinen } else { 1128cd4e3c3eSJouni Malinen /* unset the env for sock */ 1129cd4e3c3eSJouni Malinen unsetenv("SOCK"); 1130cd4e3c3eSJouni Malinen } 1131cd4e3c3eSJouni Malinen } 1132cd4e3c3eSJouni Malinen #endif /* __QNXNTO__ */ 1133cd4e3c3eSJouni Malinen 1134cd4e3c3eSJouni Malinen if (daemonize) { 1135cd4e3c3eSJouni Malinen if (daemon(0, 0) < 0) { 1136cd4e3c3eSJouni Malinen perror("daemon"); 1137cd4e3c3eSJouni Malinen exit(-1); 1138cd4e3c3eSJouni Malinen } 1139cd4e3c3eSJouni Malinen } else { 1140cd4e3c3eSJouni Malinen #ifdef __linux__ 1141cd4e3c3eSJouni Malinen setlinebuf(stdout); 1142cd4e3c3eSJouni Malinen #endif /* __linux__ */ 1143cd4e3c3eSJouni Malinen } 1144cd4e3c3eSJouni Malinen 1145091e253dSPurushottam Kushwaha if (internal_dhcp_enabled) 1146091e253dSPurushottam Kushwaha p2p_create_event_thread(&sigma_dut); 1147091e253dSPurushottam Kushwaha 1148cd4e3c3eSJouni Malinen run_loop(&sigma_dut); 1149cd4e3c3eSJouni Malinen 1150cd4e3c3eSJouni Malinen #ifdef CONFIG_SNIFFER 1151cd4e3c3eSJouni Malinen sniffer_close(&sigma_dut); 1152cd4e3c3eSJouni Malinen #endif /* CONFIG_SNIFFER */ 1153cd4e3c3eSJouni Malinen 1154f2af39bfSDanny Segal free(sigma_p2p_ifname_buf); 1155cd4e3c3eSJouni Malinen close_socket(&sigma_dut); 11569c381f59SAmarnath Hullur Subramanyam #ifdef MIRACAST 11579c381f59SAmarnath Hullur Subramanyam miracast_deinit(&sigma_dut); 11589c381f59SAmarnath Hullur Subramanyam #endif /* MIRACAST */ 11590040258bSAshwini Patil free(sigma_dut.non_pref_ch_list); 11600040258bSAshwini Patil sigma_dut.non_pref_ch_list = NULL; 11615acd738cSAshwini Patil free(sigma_dut.btm_query_cand_list); 11625acd738cSAshwini Patil sigma_dut.btm_query_cand_list = NULL; 11633c367e8dSJouni Malinen free(sigma_dut.rsne_override); 1164ed670f4cSJouni Malinen free(sigma_dut.ap_sae_groups); 1165b1dd21f8SJouni Malinen free(sigma_dut.dpp_peer_uri); 116609550de6SJouni Malinen free(sigma_dut.ap_sae_passwords); 1167291d97daSPeng Xu #ifdef NL80211_SUPPORT 1168291d97daSPeng Xu nl80211_deinit(&sigma_dut, sigma_dut.nl_ctx); 1169291d97daSPeng Xu #endif /* NL80211_SUPPORT */ 1170cd4e3c3eSJouni Malinen sigma_dut_unreg_cmds(&sigma_dut); 11711bde7947SAnkita Bajaj #ifdef ANDROID 11721bde7947SAnkita Bajaj hlp_thread_cleanup(&sigma_dut); 11731bde7947SAnkita Bajaj #endif /* ANDROID */ 1174cd4e3c3eSJouni Malinen 1175cd4e3c3eSJouni Malinen return 0; 1176cd4e3c3eSJouni Malinen } 1177