blob: a037eab278af985f97645b4110749812dbb2db47 [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (station/AP)
3 * Copyright (c) 2010-2011, Atheros Communications, Inc.
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004 * Copyright (c) 2011-2017, Qualcomm Atheros, Inc.
Jouni Malinen5404f5f2019-02-19 11:56:49 +02005 * Copyright (c) 2018-2019, The Linux Foundation
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006 * All Rights Reserved.
7 * Licensed under the Clear BSD license. See README for more details.
8 */
9
10#include "sigma_dut.h"
11#ifdef __linux__
12#include <signal.h>
13#include <netinet/tcp.h>
14#endif /* __linux__ */
Danny Segalf2af39b2016-04-10 16:23:11 +030015#include "wpa_ctrl.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016#include "wpa_helpers.h"
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070017#include "miracast.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020018
19#define SIGMA_DUT_PORT 9000
20#define MAX_CONNECTIONS 4
21
22extern enum driver_type wifi_chip_type;
23
24static struct sigma_dut sigma_dut;
25
Jouni Malinencd4e3c32015-10-29 12:39:56 +020026char *sigma_radio_ifname[MAX_RADIO] = {};
Jouni Malinencd4e3c32015-10-29 12:39:56 +020027char *sigma_wpas_ctrl = "/var/run/wpa_supplicant/";
28char *sigma_hapd_ctrl = NULL;
Rajiv Ranjan525dbfd2018-04-20 17:42:48 +053029char *client_socket_path = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020030char *ap_inet_addr = "192.168.43.1";
31char *ap_inet_mask = "255.255.255.0";
32char *sigma_cert_path = "/etc/wpa_supplicant";
33
34/* For WMM-AC testing this set to 1 through argument,
35 * otherwise default WMM-PS 0 */
36int sigma_wmm_ac = 0;
37
Purushottam Kushwahab7f56d42018-06-11 12:59:45 +053038/* For VO-Enterprise testing set this to 1 through argument
39 * to send periodic data.
40 */
41int sigma_periodic_data = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020042
43#ifdef ANDROID
44#include <android/log.h>
45
Vinay Gannevaram2dfb1da2019-06-14 15:24:08 +053046#ifdef ANDROID_WIFI_HAL
47
48static void * wifi_hal_event_thread(void *ptr)
49{
50 struct sigma_dut *dut = ptr;
51
52 wifi_event_loop(dut->wifi_hal_handle);
53 pthread_exit(0);
54
55 return NULL;
56}
57
58
59int wifi_hal_initialize(struct sigma_dut *dut)
60{
61 pthread_t thread1;
62 wifi_error err;
Ajit Vaishyac2ae9612020-02-28 00:09:07 +053063 const char *ifname;
Vinay Gannevaram2dfb1da2019-06-14 15:24:08 +053064
65 if (dut->wifi_hal_initialized)
66 return 0;
67
68 err = wifi_initialize(&dut->wifi_hal_handle);
69 if (err) {
70 sigma_dut_print(dut, DUT_MSG_ERROR,
71 "wifi hal initialize failed");
72 return -1;
73 }
74
Ajit Vaishyac2ae9612020-02-28 00:09:07 +053075 if (if_nametoindex(NAN_AWARE_IFACE))
76 ifname = NAN_AWARE_IFACE;
77 else
78 ifname = "wlan0";
79
Vinay Gannevaram2dfb1da2019-06-14 15:24:08 +053080 dut->wifi_hal_iface_handle = wifi_get_iface_handle(dut->wifi_hal_handle,
Ajit Vaishyac2ae9612020-02-28 00:09:07 +053081 (char *) ifname);
82
Vinay Gannevaram2dfb1da2019-06-14 15:24:08 +053083 pthread_create(&thread1, NULL, &wifi_hal_event_thread, (void *) dut);
84 dut->wifi_hal_initialized = true;
85
86 return 0;
87}
88
89#endif /* ANDROID_WIFI_HAL */
90
91
Jouni Malinencd4e3c32015-10-29 12:39:56 +020092static enum android_LogPriority level_to_android_priority(int level)
93{
94 switch (level) {
95 case DUT_MSG_ERROR:
96 return ANDROID_LOG_ERROR;
97 case DUT_MSG_INFO:
98 return ANDROID_LOG_INFO;
99 case DUT_MSG_DEBUG:
100 return ANDROID_LOG_DEBUG;
101 default:
102 return ANDROID_LOG_VERBOSE;
103 }
104}
Vinay Gannevaram2dfb1da2019-06-14 15:24:08 +0530105
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200106#endif /* ANDROID */
107
108
109void sigma_dut_print(struct sigma_dut *dut, int level, const char *fmt, ...)
110{
111 va_list ap;
112 struct timeval tv;
113
114 if (level < dut->debug_level)
115 return;
116
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700117 gettimeofday(&tv, NULL);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200118#ifdef ANDROID
119 va_start(ap, fmt);
120 __android_log_vprint(level_to_android_priority(level),
121 "sigma_dut", fmt, ap);
122 va_end(ap);
123 if (!dut->stdout_debug)
124 return;
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -0700125#else /* ANDROID */
126 if (dut->log_file_fd) {
127 va_start(ap, fmt);
128 fprintf(dut->log_file_fd, "%ld.%06u: ",
129 (long) tv.tv_sec, (unsigned int) tv.tv_usec);
130 vfprintf(dut->log_file_fd, fmt, ap);
131 fprintf(dut->log_file_fd, "\n");
132 va_end(ap);
133 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200134#endif /* ANDROID */
135
136 va_start(ap, fmt);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200137 printf("%ld.%06u: ", (long) tv.tv_sec,
138 (unsigned int) tv.tv_usec);
139 vprintf(fmt, ap);
140 printf("\n");
141 va_end(ap);
142}
143
144
145void sigma_dut_summary(struct sigma_dut *dut, const char *fmt, ...)
146{
147 va_list ap;
148 FILE *f;
149
150 if (!dut->summary_log)
151 return;
152
153 f = fopen(dut->summary_log, "a");
154 if (f == NULL)
155 return;
156
157 va_start(ap, fmt);
158 vfprintf(f, fmt, ap);
159 fprintf(f, "\n");
160 va_end(ap);
161 fclose(f);
162}
163
164
165int sigma_dut_reg_cmd(const char *cmd,
166 int (*validate)(struct sigma_cmd *cmd),
Jouni Malinen26a5b762019-02-19 01:17:48 +0200167 enum sigma_cmd_result (*process)(struct sigma_dut *dut,
168 struct sigma_conn *conn,
169 struct sigma_cmd *cmd))
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200170{
171 struct sigma_cmd_handler *h;
172 size_t clen, len;
173
Jouni Malinen5404f5f2019-02-19 11:56:49 +0200174 for (h = sigma_dut.cmds; h; h = h->next) {
175 if (strcmp(h->cmd, cmd) == 0) {
176 printf("ERROR: Duplicate sigma_dut command registration for '%s'\n",
177 cmd);
178 return -1;
179 }
180 }
181
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200182 clen = strlen(cmd);
183 len = sizeof(*h) + clen + 1;
184 h = malloc(len);
185 if (h == NULL)
186 return -1;
187 memset(h, 0, len);
188 h->cmd = (char *) (h + 1); /* include in same allocation */
189 memcpy(h->cmd, cmd, clen);
190 h->validate = validate;
191 h->process= process;
192
193 h->next = sigma_dut.cmds;
194 sigma_dut.cmds = h;
195
196 return 0;
197}
198
199
200static void sigma_dut_unreg_cmds(struct sigma_dut *dut)
201{
202 struct sigma_cmd_handler *cmd, *prev;
203 cmd = dut->cmds;
204 dut->cmds = NULL;
205 while (cmd) {
206 prev = cmd;
207 cmd = cmd->next;
208 free(prev);
209 }
210}
211
212
213static int open_socket(struct sigma_dut *dut, int port)
214{
215 struct sockaddr_in addr;
216#ifndef __QNXNTO__
217 int val;
218#endif /* !__QNXNTO__ */
219
220#ifdef __QNXNTO__
221 dut->s = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
222#else /* __QNXNTO__ */
223 dut->s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
224#endif /* __QNXNTO__ */
225 if (dut->s < 0) {
226 sigma_dut_print(dut, DUT_MSG_ERROR, "socket: %s",
227 strerror(errno));
228 return -1;
229 }
230
231#ifndef __QNXNTO__
232 val = 1;
233 if (setsockopt(dut->s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) <
234 0)
235 sigma_dut_print(dut, DUT_MSG_INFO, "setsockopt SO_REUSEADDR: "
236 "%s", strerror(errno));
237#endif /* !__QNXNTO__ */
238
239#ifdef __linux__
240 val = 1;
241 if (setsockopt(dut->s, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)) <
242 0)
243 sigma_dut_print(dut, DUT_MSG_INFO, "setsockopt TCP_NODELAY: "
244 "%s", strerror(errno));
245#endif /* __linux__ */
246
247 memset(&addr, 0, sizeof(addr));
248 addr.sin_family = AF_INET;
249 addr.sin_port = htons(port);
250
251 if (bind(dut->s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
252 sigma_dut_print(dut, DUT_MSG_ERROR, "bind: %s",
253 strerror(errno));
254 goto fail;
255 }
256
257 if (listen(dut->s, 5) < 0) {
258 sigma_dut_print(dut, DUT_MSG_ERROR, "listen: %s",
259 strerror(errno));
260 goto fail;
261 }
262
263 return 0;
264
265fail:
266 shutdown(dut->s, SHUT_RDWR);
267 close(dut->s);
268 dut->s = -1;
269 return -1;
270}
271
272
273static void close_socket(struct sigma_dut *dut)
274{
275 shutdown(dut->s, SHUT_RDWR);
276 close(dut->s);
277 dut->s = -1;
278}
279
280
281void send_resp(struct sigma_dut *dut, struct sigma_conn *conn,
Jouni Malinen76401f52017-03-18 01:04:55 +0200282 enum sigma_status status, const char *buf)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200283{
284 struct msghdr msg;
285 struct iovec iov[4];
286 size_t elems;
287
Jouni Malinena326d7b2017-09-04 13:46:02 +0300288 if (!conn)
289 return;
290
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200291 sigma_dut_print(dut, DUT_MSG_INFO, "resp: status=%d buf=%s",
292 status, buf ? buf : "N/A");
293
294 iov[0].iov_base = "status,";
295 iov[0].iov_len = 7;
296 switch (status) {
297 case SIGMA_RUNNING:
298 iov[1].iov_base = "RUNNING,";
299 iov[1].iov_len = 8;
300 break;
301 case SIGMA_INVALID:
302 iov[1].iov_base = "INVALID,";
303 iov[1].iov_len = 8;
304 break;
305 case SIGMA_ERROR:
306 iov[1].iov_base = "ERROR,";
307 iov[1].iov_len = 6;
308 break;
309 case SIGMA_COMPLETE:
310 iov[1].iov_base = "COMPLETE,";
311 iov[1].iov_len = 9;
312 break;
313 }
314 if (status != SIGMA_RUNNING) {
315 sigma_dut_summary(dut, "CAPI resp: status,%s%s",
316 (char *) iov[1].iov_base, buf ? buf : "");
317 }
318 if (buf) {
Jouni Malinen76401f52017-03-18 01:04:55 +0200319 iov[2].iov_base = (void *) buf;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200320 iov[2].iov_len = strlen(buf);
321 iov[3].iov_base = "\r\n";
322 iov[3].iov_len = 2;
323 elems = 4;
324 } else {
325 iov[1].iov_len--;
326 iov[2].iov_base = "\r\n";
327 iov[2].iov_len = 2;
328 elems = 3;
329 }
330
331 memset(&msg, 0, sizeof(msg));
332 msg.msg_iov = iov;
333 msg.msg_iovlen = elems;
334 if (sendmsg(conn->s, &msg, 0) < 0)
335 sigma_dut_print(dut, DUT_MSG_INFO, "sendmsg: %s",
336 strerror(errno));
Jouni Malinen0fee7012019-02-19 12:41:07 +0200337 dut->response_sent++;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200338}
339
340
341const char * get_param(struct sigma_cmd *cmd, const char *name)
342{
343 int i;
344 for (i = 0; i < cmd->count; i++) {
345 if (strcasecmp(name, cmd->params[i]) == 0)
346 return cmd->values[i];
347 }
348 return NULL;
349}
350
351
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200352const char * get_param_indexed(struct sigma_cmd *cmd, const char *name,
353 int index)
354{
355 int i, j;
356
357 for (i = 0, j = 0; i < cmd->count; i++) {
358 if (strcasecmp(name, cmd->params[i]) == 0) {
359 j++;
360 if (j > index)
361 return cmd->values[i];
362 }
363 }
364
365 return NULL;
366}
367
368
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200369static void process_cmd(struct sigma_dut *dut, struct sigma_conn *conn,
370 char *buf)
371{
372 struct sigma_cmd_handler *h;
373 struct sigma_cmd c;
374 char *cmd, *pos, *pos2;
375 int len;
Alexei Avshalom Lazar5fdd8652018-11-13 14:08:27 +0200376 char txt[300];
Jouni Malinen26a5b762019-02-19 01:17:48 +0200377 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200378
379 while (*buf == '\r' || *buf == '\n' || *buf == '\t' || *buf == ' ')
380 buf++;
381 len = strlen(buf);
382 while (len > 0 && buf[len - 1] == ' ') {
383 buf[len - 1] = '\0';
384 len--;
385 }
386
387 if (dut->debug_level < DUT_MSG_INFO) {
388 pos = strchr(buf, ',');
389 if (pos == NULL)
390 pos = buf + len;
391 if (pos - buf > 50)
392 pos = buf + 50;
393 memcpy(txt, "/====[ ", 7);
394 pos2 = txt + 7;
395 memcpy(pos2, buf, pos - buf);
396 pos2 += pos - buf;
397 *pos2++ = ' ';
398 *pos2++ = ']';
399 while (pos2 - txt < 70)
400 *pos2++ = '=';
401 *pos2++ = '\\';
402 *pos2 = '\0';
403 printf("\n%s\n\n", txt);
404 }
405
406 sigma_dut_print(dut, DUT_MSG_INFO, "cmd: %s", buf);
407 sigma_dut_summary(dut, "CAPI cmd: %s", buf);
408 snprintf(txt, sizeof(txt), "NOTE CAPI:%s", buf);
409 txt[sizeof(txt) - 1] = '\0';
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200410 wpa_command(get_main_ifname(dut), txt);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200411
412 memset(&c, 0, sizeof(c));
413 cmd = buf;
414 pos = strchr(cmd, ',');
415 if (pos) {
416 *pos++ = '\0';
417 if (strcasecmp(cmd, "AccessPoint") == 0 ||
418 strcasecmp(cmd, "PowerSwitch") == 0) {
419 pos2 = strchr(pos, ',');
420 if (pos2 == NULL)
421 goto invalid_params;
422 c.params[c.count] = pos;
423 c.values[c.count] = pos2;
424 c.count++;
425 pos = strchr(pos2, ',');
426 if (pos)
427 *pos++ = '\0';
428 }
429 while (pos) {
430 pos2 = strchr(pos, ',');
431 if (pos2 == NULL)
432 goto invalid_params;
433 *pos2++ = '\0';
434 if (c.count == MAX_PARAMS) {
435 sigma_dut_print(dut, DUT_MSG_INFO, "Too many "
436 "parameters");
437 goto invalid_params;
438 }
439 c.params[c.count] = pos;
440 c.values[c.count] = pos2;
441 c.count++;
442 pos = strchr(pos2, ',');
443 if (pos)
444 *pos++ = '\0';
445 }
446 }
447 h = dut->cmds;
448 while (h) {
449 if (strcasecmp(cmd, h->cmd) == 0)
450 break;
451 h = h->next;
452 }
453
454 if (h == NULL) {
455 sigma_dut_print(dut, DUT_MSG_INFO, "Unknown command: '%s'",
456 cmd);
457 send_resp(dut, conn, SIGMA_INVALID,
458 "errorCode,Unknown command");
459 goto out;
460 }
461
462 if (h->validate && h->validate(&c) < 0) {
463 invalid_params:
464 sigma_dut_print(dut, DUT_MSG_INFO, "Invalid parameters");
465 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid "
466 "parameters");
467 goto out;
468 }
469
Jouni Malinen0fee7012019-02-19 12:41:07 +0200470 dut->response_sent = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200471 send_resp(dut, conn, SIGMA_RUNNING, NULL);
472 sigma_dut_print(dut, DUT_MSG_INFO, "Run command: %s", cmd);
473 res = h->process(dut, conn, &c);
Jouni Malinen26a5b762019-02-19 01:17:48 +0200474 switch (res) {
475 case ERROR_SEND_STATUS:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200476 send_resp(dut, conn, SIGMA_ERROR, NULL);
Jouni Malinen26a5b762019-02-19 01:17:48 +0200477 break;
478 case INVALID_SEND_STATUS:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200479 send_resp(dut, conn, SIGMA_INVALID, NULL);
Jouni Malinen26a5b762019-02-19 01:17:48 +0200480 break;
481 case STATUS_SENT:
Jouni Malinen53264f62019-05-03 13:04:40 +0300482 case STATUS_SENT_ERROR:
Jouni Malinen26a5b762019-02-19 01:17:48 +0200483 break;
484 case SUCCESS_SEND_STATUS:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200485 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
Jouni Malinen26a5b762019-02-19 01:17:48 +0200486 break;
487 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200488
Jouni Malinen0fee7012019-02-19 12:41:07 +0200489 if (!conn->waiting_completion && dut->response_sent != 2) {
490 sigma_dut_print(dut, DUT_MSG_ERROR,
491 "ERROR: Unexpected number of status lines sent (%d) for command '%s'",
492 dut->response_sent, cmd);
493 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200494
495out:
496 if (dut->debug_level < DUT_MSG_INFO) {
497 pos2 = txt;
498 *pos2++ = '\\';
499 memset(pos2, '-', 69);
500 pos2 += 69;
501 *pos2++ = '/';
502 *pos2 = '\0';
503 printf("\n%s\n\n", txt);
504 }
505}
506
507
508static void process_conn(struct sigma_dut *dut, struct sigma_conn *conn)
509{
510 ssize_t res;
511 int i;
512
513 sigma_dut_print(dut, DUT_MSG_DEBUG, "Read from %s:%d",
514 inet_ntoa(conn->addr.sin_addr),
515 ntohs(conn->addr.sin_port));
516
517 res = recv(conn->s, conn->buf + conn->pos, MAX_CMD_LEN + 5 - conn->pos,
518 0);
519 if (res < 0) {
520 sigma_dut_print(dut, DUT_MSG_INFO, "recv: %s",
521 strerror(errno));
522 }
523 if (res <= 0) {
524 sigma_dut_print(dut, DUT_MSG_DEBUG, "Close connection from "
525 "%s:%d",
526 inet_ntoa(conn->addr.sin_addr),
527 ntohs(conn->addr.sin_port));
528 shutdown(conn->s, SHUT_RDWR);
529 close(conn->s);
530 conn->s = -1;
531 return;
532 }
533
534 sigma_dut_print(dut, DUT_MSG_DEBUG, "Received %d bytes",
535 (int) res);
536
537 for (;;) {
538 for (i = conn->pos; i < conn->pos + res; i++) {
539 if (conn->buf[i] == '\r' || conn->buf[i] == '\n')
540 break;
541 }
542
543 if (i == conn->pos + res) {
544 /* Full command not yet received */
545 conn->pos += res;
546 if (conn->pos >= MAX_CMD_LEN + 5) {
547 sigma_dut_print(dut, DUT_MSG_INFO, "Too long "
548 "command dropped");
549 conn->pos = 0;
550 }
551 break;
552 }
553
554 /* Full command received */
555 conn->buf[i++] = '\0';
556 process_cmd(dut, conn, conn->buf);
557 while (i < conn->pos + res &&
558 (conn->buf[i] == '\r' || conn->buf[i] == '\n'))
559 i++;
560 memmove(conn->buf, &conn->buf[i], conn->pos + res - i);
561 res = conn->pos + res - i;
562 conn->pos = 0;
563 }
564}
565
566
567static int stop_loop = 0;
568
569#ifdef __linux__
570static void handle_term(int sig)
571{
Jouni Malinenad4c6752019-11-06 18:51:19 +0200572 struct sigma_dut *dut = &sigma_dut;
573
574 if (dut->sta_2g_started || dut->sta_5g_started)
575 stop_sta_mode(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200576 stop_loop = 1;
Purushottam Kushwaha091e2532016-08-23 11:52:21 +0530577 stop_event_thread();
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200578 printf("sigma_dut terminating\n");
579}
580#endif /* __linux__ */
581
582static void run_loop(struct sigma_dut *dut)
583{
584 struct sigma_conn conn[MAX_CONNECTIONS];
585 int i, res, maxfd, can_accept;
586 fd_set rfds;
587
588 memset(&conn, 0, sizeof(conn));
589 for (i = 0; i < MAX_CONNECTIONS; i++)
590 conn[i].s = -1;
591
592#ifdef __linux__
593 signal(SIGINT, handle_term);
594 signal(SIGTERM, handle_term);
595 signal(SIGPIPE, SIG_IGN);
596#endif /* __linux__ */
597
598 while (!stop_loop) {
599 FD_ZERO(&rfds);
600 maxfd = -1;
601 can_accept = 0;
602 for (i = 0; i < MAX_CONNECTIONS; i++) {
603 if (conn[i].s >= 0) {
604 FD_SET(conn[i].s, &rfds);
605 if (conn[i].s > maxfd)
606 maxfd = conn[i].s;
607 } else if (!conn[i].waiting_completion)
608 can_accept = 1;
609 }
610
611 if (can_accept) {
612 FD_SET(dut->s, &rfds);
613 if (dut->s > maxfd)
614 maxfd = dut->s;
615 }
616
617
618 sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting for next "
619 "command (can_accept=%d)", can_accept);
620 res = select(maxfd + 1, &rfds, NULL, NULL, NULL);
621 if (res < 0) {
622 perror("select");
623 if (!stop_loop)
624 sleep(1);
625 continue;
626 }
627
628 if (!res) {
629 sigma_dut_print(dut, DUT_MSG_DEBUG, "Nothing ready");
630 sleep(1);
631 continue;
632 }
633
634 if (FD_ISSET(dut->s, &rfds)) {
635 for (i = 0; i < MAX_CONNECTIONS; i++) {
636 if (conn[i].s < 0 &&
637 !conn[i].waiting_completion)
638 break;
639 }
640 if (i == MAX_CONNECTIONS) {
641 /*
642 * This cannot really happen since can_accept
643 * would not be set to one.
644 */
645 sigma_dut_print(dut, DUT_MSG_DEBUG,
646 "No room for new connection");
647 continue;
648 }
649 conn[i].addrlen = sizeof(conn[i].addr);
650 conn[i].s = accept(dut->s,
651 (struct sockaddr *) &conn[i].addr,
652 &conn[i].addrlen);
653 if (conn[i].s < 0) {
654 sigma_dut_print(dut, DUT_MSG_INFO,
655 "accept: %s",
656 strerror(errno));
657 continue;
658 }
659
660 sigma_dut_print(dut, DUT_MSG_DEBUG,
661 "Connection %d from %s:%d", i,
662 inet_ntoa(conn[i].addr.sin_addr),
663 ntohs(conn[i].addr.sin_port));
664 conn[i].pos = 0;
665 }
666
667 for (i = 0; i < MAX_CONNECTIONS; i++) {
668 if (conn[i].s < 0)
669 continue;
670 if (FD_ISSET(conn[i].s, &rfds))
671 process_conn(dut, &conn[i]);
672 }
673 }
674}
675
676
677static int run_local_cmd(int port, char *lcmd)
678{
679 int s, len;
680 struct sockaddr_in addr;
681 char cmd[MAX_CMD_LEN];
682 ssize_t res;
683 int count;
684 char resp[MAX_CMD_LEN];
685 int pos;
686
687
688 if (strlen(lcmd) > sizeof(cmd) - 4) {
689 printf("Too long command\n");
690 return -1;
691 }
692 len = snprintf(cmd, sizeof(cmd), "%s \r\n", lcmd);
693
694 memset(&addr, 0, sizeof(addr));
695 addr.sin_family = AF_INET;
696 inet_aton("127.0.0.1", &addr.sin_addr);
697 addr.sin_port = htons(port);
698
699 /* Make sure we do not get stuck indefinitely */
700 alarm(150);
701
702 s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
703 if (s < 0) {
704 perror("socket");
705 return -1;
706 }
707
708 if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
709 perror("connect");
710 close(s);
711 return -1;
712 }
713
714 res = send(s, cmd, len, 0);
715 if (res < 0) {
716 perror("send");
717 close(s);
718 return -1;
719 }
720 if (res != len) {
721 printf("Unexpected send result: %d (expected %d)\n",
722 (int) res, len);
723 close(s);
724 return -1;
725 }
726
727 count = 0;
728 pos = 0;
729 len = 0;
730 for (;;) {
731 char *e;
732 res = recv(s, resp + len, sizeof(resp) - len, 0);
733 if (res < 0) {
734 perror("recv");
735 close(s);
736 return -1;
737 }
738 if (res == 0) {
739 printf("Could not read response\n");
740 close(s);
741 return -1;
742 }
743 len += res;
744 next_line:
745 e = memchr(resp + pos, '\r', len - pos);
746 if (e == NULL)
747 continue;
748 *e++ = '\0';
749 if (e - resp < len && *e == '\n')
750 *e++ = '\n';
751 printf("%s\n", resp + pos);
752 if (strncasecmp(resp + pos, "status,RUNNING", 14) != 0)
753 break;
754 count++;
755 if (count == 2)
756 break;
757 pos = e - resp;
758 goto next_line;
759 }
760
761 close(s);
762
763 return 0;
764}
765
766
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200767static void determine_sigma_p2p_ifname(struct sigma_dut *dut)
Danny Segalf2af39b2016-04-10 16:23:11 +0300768{
769 char buf[256];
770 struct wpa_ctrl *ctrl;
771
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200772 if (dut->p2p_ifname)
773 return;
Danny Segalf2af39b2016-04-10 16:23:11 +0300774
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200775 snprintf(buf, sizeof(buf), "p2p-dev-%s", get_station_ifname(dut));
Danny Segalf2af39b2016-04-10 16:23:11 +0300776 ctrl = open_wpa_mon(buf);
777 if (ctrl) {
778 wpa_ctrl_detach(ctrl);
779 wpa_ctrl_close(ctrl);
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200780 dut->p2p_ifname_buf = strdup(buf);
781 dut->p2p_ifname = dut->p2p_ifname_buf;
Danny Segalf2af39b2016-04-10 16:23:11 +0300782 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
783 "Using interface %s for P2P operations instead of interface %s",
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200784 dut->p2p_ifname ? dut->p2p_ifname : "NULL",
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200785 get_station_ifname(dut));
Danny Segalf2af39b2016-04-10 16:23:11 +0300786 } else {
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200787 dut->p2p_ifname = get_station_ifname(dut);
Danny Segalf2af39b2016-04-10 16:23:11 +0300788 }
789}
790
791
Priyadharshini Gowthamand06f1002019-04-22 15:45:41 -0700792static int get_nl80211_config_enable_option(struct sigma_dut *dut)
793{
794 char cmd[100], result[5];
795 FILE *f;
796 size_t len;
797 int ap_nl80211_enable;
798
799 snprintf(cmd, sizeof(cmd), "uci get qcacfg80211.config.enable");
800 f = popen(cmd, "r");
801 if (!f)
802 return -1;
803
804 len = fread(result, 1, sizeof(result) - 1, f);
805 pclose(f);
806
807 if (len == 0)
808 return -1;
809
810 result[len] = '\0';
811 ap_nl80211_enable = atoi(result);
812
813 if (ap_nl80211_enable)
814 dut->priv_cmd = "cfg80211tool";
815
816 return 0;
817}
818
819
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200820static void set_defaults(struct sigma_dut *dut)
821{
Jouni Malinen1dd0b612019-11-04 16:32:33 +0200822 dut->debug_level = DUT_MSG_INFO;
823 dut->default_timeout = 120;
824 dut->dialog_token = 0;
825 dut->dpp_conf_id = -1;
826 dut->dpp_local_bootstrap = -1;
827 dut->sta_nss = 2; /* Make default nss 2 */
828 dut->trans_proto = NAN_TRANSPORT_PROTOCOL_DEFAULT;
829 dut->trans_port = NAN_TRANSPORT_PORT_DEFAULT;
830 dut->nan_ipv6_len = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200831 dut->ap_p2p_cross_connect = -1;
832 dut->ap_chwidth = AP_AUTO;
Pradeep Reddy Pottetibf8af292017-02-15 15:28:39 +0530833 dut->default_11na_ap_chwidth = AP_AUTO;
834 dut->default_11ng_ap_chwidth = AP_AUTO;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200835 /* by default, enable writing of traffic stream stats */
836 dut->write_stats = 1;
Priyadharshini Gowthamand06f1002019-04-22 15:45:41 -0700837 dut->priv_cmd = "iwpriv";
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +0200838 dut->sigma_tmpdir = SIGMA_TMPDIR;
Priyadharshini Gowthamance7ba822020-05-27 13:03:09 -0700839 dut->ap_ocvc = -1;
Jouni Malinen0a9876c2020-06-08 19:15:36 +0300840 dut->ap_sae_commit_status = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200841}
842
843
Jouni Malinen829b7de2019-11-04 16:39:55 +0200844static void deinit_sigma_dut(struct sigma_dut *dut)
845{
846 free(dut->non_pref_ch_list);
847 dut->non_pref_ch_list = NULL;
848 free(dut->btm_query_cand_list);
849 dut->btm_query_cand_list = NULL;
850 free(dut->rsne_override);
851 dut->rsne_override = NULL;
Jouni Malinen7960e3a2019-12-07 17:04:35 +0200852 free(dut->rsnxe_override_eapol);
853 dut->rsnxe_override_eapol = NULL;
Jouni Malinen829b7de2019-11-04 16:39:55 +0200854 free(dut->ap_sae_groups);
855 dut->ap_sae_groups = NULL;
856 free(dut->dpp_peer_uri);
857 dut->dpp_peer_uri = NULL;
858 free(dut->ap_sae_passwords);
859 dut->ap_sae_passwords = NULL;
Jouni Malinen59fab0f2020-06-05 16:59:55 +0300860 free(dut->ap_sae_pk_modifier);
861 dut->ap_sae_pk_modifier = NULL;
862 free(dut->ap_sae_pk_keypair);
863 dut->ap_sae_pk_keypair = NULL;
Jouni Malinenfbf12ef2020-06-08 19:49:40 +0300864 free(dut->ap_sae_pk_keypair_sig);
865 dut->ap_sae_pk_keypair_sig = NULL;
Jouni Malinen829b7de2019-11-04 16:39:55 +0200866 free(dut->ar_ltf);
867 dut->ar_ltf = NULL;
868 free(dut->ap_dpp_conf_addr);
869 dut->ap_dpp_conf_addr = NULL;
870 free(dut->ap_dpp_conf_pkhash);
871 dut->ap_dpp_conf_pkhash = NULL;
872 if (dut->log_file_fd) {
873 fclose(dut->log_file_fd);
874 dut->log_file_fd = NULL;
875 }
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200876 free(dut->p2p_ifname_buf);
877 dut->p2p_ifname_buf = NULL;
Jouni Malinenb21f0542019-11-04 17:53:38 +0200878 free(dut->main_ifname_2g);
879 dut->main_ifname_2g = NULL;
880 free(dut->main_ifname_5g);
881 dut->main_ifname_5g = NULL;
882 free(dut->station_ifname_2g);
883 dut->station_ifname_2g = NULL;
884 free(dut->station_ifname_5g);
885 dut->station_ifname_5g = NULL;
886}
887
888
889static void set_main_ifname(struct sigma_dut *dut, const char *val)
890{
891 const char *pos;
892
893 dut->main_ifname = optarg;
894 pos = strchr(val, '/');
895 if (!pos)
896 return;
897 free(dut->main_ifname_2g);
898 dut->main_ifname_2g = malloc(pos - val + 1);
899 if (dut->main_ifname_2g) {
900 memcpy(dut->main_ifname_2g, val, pos - val);
901 dut->main_ifname_2g[pos - val] = '\0';
902 }
903 free(dut->main_ifname_5g);
904 dut->main_ifname_5g = strdup(pos + 1);
905}
906
907
908static void set_station_ifname(struct sigma_dut *dut, const char *val)
909{
910 const char *pos;
911
912 dut->station_ifname = optarg;
913 pos = strchr(val, '/');
914 if (!pos)
915 return;
916 free(dut->station_ifname_2g);
917 dut->station_ifname_2g = malloc(pos - val + 1);
918 if (dut->station_ifname_2g) {
919 memcpy(dut->station_ifname_2g, val, pos - val);
920 dut->station_ifname_2g[pos - val] = '\0';
921 }
922 free(dut->station_ifname_5g);
923 dut->station_ifname_5g = strdup(pos + 1);
Jouni Malinen829b7de2019-11-04 16:39:55 +0200924}
925
926
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200927static const char * const license1 =
928"sigma_dut - WFA Sigma DUT/CA\n"
929"----------------------------\n"
930"\n"
931"Copyright (c) 2010-2011, Atheros Communications, Inc.\n"
Jouni Malinen9d7e31d2017-12-22 18:55:04 +0200932"Copyright (c) 2011-2017, Qualcomm Atheros, Inc.\n"
Jouni Malinen5b16b512019-02-19 12:29:53 +0200933"Copyright (c) 2018-2019, The Linux Foundation\n"
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200934"All Rights Reserved.\n"
935"Licensed under the Clear BSD license.\n"
936"\n";
937static const char * const license2 =
938"Redistribution and use in source and binary forms, with or without\n"
939"modification, are permitted (subject to the limitations in the\n"
940"disclaimer below) provided that the following conditions are met:\n"
941"\n";
942static const char * const license3 =
943"* Redistributions of source code must retain the above copyright notice,\n"
944" this list of conditions and the following disclaimer.\n"
945"\n"
946"* Redistributions in binary form must reproduce the above copyright\n"
947" notice, this list of conditions and the following disclaimer in the\n"
948" documentation and/or other materials provided with the distribution.\n"
949"\n"
950"* Neither the name of Qualcomm Atheros, Inc. nor the names of its\n"
951" contributors may be used to endorse or promote products derived from\n"
952" this software without specific prior written permission.\n"
953"\n";
954static const char * const license4 =
955"NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED\n"
956"BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n"
957"CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\n"
958"BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\n"
959"FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n"
960"COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n"
961"INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n"
962"NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\n"
963"USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n"
964"ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
965"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n"
966"THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n";
967
968
969static void print_license(void)
970{
971 printf("%s%s%s%s\n",
972 license1, license2, license3, license4);
973}
974
975
Jouni Malinen5174e022019-11-04 16:35:03 +0200976static void usage(void)
977{
Veerendranath Jakkam47867202020-12-21 01:53:52 +0530978 printf("usage: sigma_dut [-aABdfGqDIntuVW234] [-p<port>] "
Jouni Malinen5174e022019-11-04 16:35:03 +0200979 "[-s<sniffer>] [-m<set_maccaddr.sh>] \\\n"
980 " [-M<main ifname>] [-R<radio ifname>] "
981 "[-S<station ifname>] [-P<p2p_ifname>]\\\n"
982 " [-T<throughput pktsize>] \\\n"
983 " [-w<wpa_supplicant/hostapd ctrl_iface dir>] \\\n"
984 " [-H <hostapd log file>] \\\n"
985 " [-F <hostapd binary path>] \\\n"
986 " [-j <hostapd ifname>] \\\n"
987 " [-J <wpa_supplicant debug log>] \\\n"
988 " [-C <certificate path>] \\\n"
989 " [-v <version string>] \\\n"
990 " [-L <summary log>] \\\n"
991 " [-c <wifi chip type: WCN or ATHEROS or "
992 "AR6003 or MAC80211 or QNXNTO or OPENWRT or LINUX-WCN>] \\\n"
993 " [-i <IP address of the AP>] \\\n"
994 " [-k <subnet mask for the AP>] \\\n"
995 " [-K <sigma_dut log file directory>] \\\n"
996 " [-e <hostapd entropy file>] \\\n"
997 " [-N <device_get_info vendor>] \\\n"
998 " [-o <device_get_info model>] \\\n"
999 " [-O <device_get_info version>] \\\n"
1000#ifdef MIRACAST
1001 " [-x <sink|source>] \\\n"
1002 " [-y <Miracast library path>] \\\n"
1003#endif /* MIRACAST */
1004 " [-z <client socket directory path \\\n"
1005 " Ex: </data/vendor/wifi/sockets>] \\\n"
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +02001006 " [-Z <Override default tmp dir path>] \\\n"
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05301007 " [-5 <WFD timeout override>] \\\n"
Jouni Malinen5174e022019-11-04 16:35:03 +02001008 " [-r <HT40 or 2.4_HT40>]\n");
1009 printf("local command: sigma_dut [-p<port>] <-l<cmd>>\n");
1010}
1011
1012
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001013int main(int argc, char *argv[])
1014{
1015 int c;
1016 int daemonize = 0;
1017 int port = SIGMA_DUT_PORT;
1018 char *local_cmd = NULL;
Purushottam Kushwaha091e2532016-08-23 11:52:21 +05301019 int internal_dhcp_enabled = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001020#ifdef __QNXNTO__
1021 char *env_str = NULL;
1022 char buf[20];
1023 char *sigma_ctrl_sock = NULL; /* env used for QNX */
1024#endif /* __QNXNTO__ */
1025
1026 memset(&sigma_dut, 0, sizeof(sigma_dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001027 set_defaults(&sigma_dut);
1028
1029 for (;;) {
1030 c = getopt(argc, argv,
Mohammad Asaad Akram796da612021-03-09 17:55:03 +05301031 "aAb:Bc:C:dDE:e:fF:gGhH:j:J:i:Ik:K:l:L:m:M:nN:o:O:p:P:qQr:R:s:S:tT:uv:VWw:x:y:z:Z:2345:");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001032 if (c < 0)
1033 break;
1034 switch (c) {
1035 case 'a':
1036 sigma_dut.ap_anqpserver = 1;
1037 break;
1038 case 'b':
1039 sigma_dut.bridge = optarg;
1040 break;
1041 case 'B':
1042 daemonize++;
1043 break;
1044 case 'C':
1045 sigma_cert_path = optarg;
1046 break;
1047 case 'd':
1048 if (sigma_dut.debug_level > 0)
1049 sigma_dut.debug_level--;
1050 break;
1051#ifdef __QNXNTO__
1052 case 'E':
1053 sigma_ctrl_sock = optarg;
1054 break;
1055#endif /* __QNXNTO__ */
1056 case 'D':
1057 sigma_dut.stdout_debug = 1;
1058 break;
1059 case 'e':
1060 sigma_dut.hostapd_entropy_log = optarg;
1061 break;
1062 case 'f':
1063 /* Disable writing stats */
1064 sigma_dut.write_stats = 0;
1065 break;
Jouni Malinend6bf1b42017-06-23 17:51:01 +03001066 case 'F':
1067 sigma_dut.hostapd_bin = optarg;
1068 break;
Purushottam Kushwaha091e2532016-08-23 11:52:21 +05301069 case 'g':
1070 /* Enable internal processing of P2P group formation
1071 * events to start/stop DHCP server/client. */
1072 internal_dhcp_enabled = 1;
1073 break;
Jouni Malinend6bf1b42017-06-23 17:51:01 +03001074 case 'G':
1075 sigma_dut.use_hostapd_pid_file = 1;
1076 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001077 case 'H':
1078 sigma_dut.hostapd_debug_log = optarg;
1079 break;
1080 case 'I':
1081 print_license();
1082 exit(0);
1083 break;
Jouni Malinend6bf1b42017-06-23 17:51:01 +03001084 case 'j':
1085 sigma_dut.hostapd_ifname = optarg;
1086 break;
Alexei Avshalom Lazar3e8267e2018-12-18 15:58:54 +02001087 case 'J':
1088 sigma_dut.wpa_supplicant_debug_log = optarg;
1089 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001090 case 'l':
1091 local_cmd = optarg;
1092 break;
1093 case 'L':
1094 sigma_dut.summary_log = optarg;
1095 break;
1096 case 'p':
1097 port = atoi(optarg);
1098 break;
Danny Segalf2af39b2016-04-10 16:23:11 +03001099 case 'P':
Jouni Malinen1f76fa62019-11-04 17:30:12 +02001100 sigma_dut.p2p_ifname = optarg;
Danny Segalf2af39b2016-04-10 16:23:11 +03001101 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001102 case 'q':
1103 sigma_dut.debug_level++;
1104 break;
Purushottam Kushwahab7f56d42018-06-11 12:59:45 +05301105 case 'Q':
1106 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1107 "Send Periodic data");
1108 sigma_periodic_data = 1;
1109 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001110 case 'r':
1111 if (strcmp(optarg, "HT40") == 0) {
Pradeep Reddy Pottetibf8af292017-02-15 15:28:39 +05301112 sigma_dut.default_11na_ap_chwidth = AP_40;
1113 } else if (strcmp(optarg, "2.4_HT40") == 0) {
1114 sigma_dut.default_11ng_ap_chwidth = AP_40;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001115 } else {
1116 printf("Unsupported -r value\n");
1117 exit(1);
1118 }
1119 break;
1120 case 'R': {
1121 static int num_radio = 0;
1122 static char **radio_ptr = sigma_radio_ifname;
1123
1124 num_radio++;
1125 if (num_radio > MAX_RADIO) {
1126 printf("Multiple radio support limit (%d) exceeded\n",
1127 MAX_RADIO);
1128 exit(1);
1129 }
1130 *radio_ptr++ = optarg;
1131 break;
1132 }
1133 case 's':
1134 sigma_dut.sniffer_ifname = optarg;
1135 break;
1136 case 't':
1137 sigma_dut.no_timestamps = 1;
1138 break;
1139 case 'T':
1140 sigma_dut.throughput_pktsize = atoi(optarg);
Jouni Malinenc2493f82016-06-05 18:01:33 +03001141 if (sigma_dut.throughput_pktsize == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001142 printf("Invalid -T value\n");
1143 exit(0);
1144 }
1145 break;
1146 case 'm':
1147 sigma_dut.set_macaddr = optarg;
1148 break;
1149 case 'M':
Jouni Malinenb21f0542019-11-04 17:53:38 +02001150 set_main_ifname(&sigma_dut, optarg);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001151 break;
1152 case 'n':
1153 sigma_dut.no_ip_addr_set = 1;
1154 break;
Jouni Malinen5db3b102016-08-04 12:27:18 +03001155 case 'N':
1156 sigma_dut.vendor_name = optarg;
1157 break;
1158 case 'o':
1159 sigma_dut.model_name = optarg;
1160 break;
1161 case 'O':
1162 sigma_dut.version_name = optarg;
1163 break;
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -07001164 case 'K':
1165 sigma_dut.log_file_dir = optarg;
1166 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001167 case 'S':
Jouni Malinenb21f0542019-11-04 17:53:38 +02001168 set_station_ifname(&sigma_dut, optarg);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001169 break;
1170 case 'w':
1171 sigma_hapd_ctrl = optarg;
1172 sigma_wpas_ctrl = optarg;
1173 break;
1174 case 'i':
1175 ap_inet_addr = optarg;
1176 break;
1177 case 'k':
1178 ap_inet_mask = optarg;
1179 break;
1180 case 'c':
1181 printf("%s", optarg);
1182 if (set_wifi_chip(optarg) < 0)
1183 sigma_dut_print(&sigma_dut, DUT_MSG_ERROR,
1184 "WRONG CHIP TYPE: SAP will "
1185 "not load");
1186 break;
1187 case 'v':
1188 sigma_dut.version = optarg;
1189 break;
1190 case 'V':
1191 printf("sigma_dut " SIGMA_DUT_VER "\n");
1192 exit(0);
1193 break;
1194 case 'W':
1195 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1196 "Running WMM-AC test suite");
1197 sigma_wmm_ac = 1;
1198 break;
1199 case 'u':
1200 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1201 "Use iface down/up in reset cmd");
1202 sigma_dut.iface_down_on_reset = 1;
1203 break;
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301204 case 'A':
1205 sigma_dut.sim_no_username = 1;
1206 break;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07001207#ifdef MIRACAST
1208 case 'x':
1209 if (strcmp(optarg, "sink") == 0) {
1210 sigma_dut.wfd_device_type = 1;
1211 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1212 "Device Type is SINK");
1213 } else if (strcmp(optarg, "source") == 0) {
1214 sigma_dut.wfd_device_type = 0;
1215 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1216 "Device Type is SOURCE");
1217 }
1218 break;
1219 case 'y':
1220 sigma_dut.miracast_lib_path = optarg;
1221 break;
1222#endif /* MIRACAST */
Rajiv Ranjan525dbfd2018-04-20 17:42:48 +05301223 case 'z':
1224 client_socket_path = optarg;
1225 break;
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +02001226 case 'Z':
1227 sigma_dut.sigma_tmpdir = optarg;
1228 break;
Jouni Malinen11e55212019-11-22 21:46:59 +02001229 case '2':
1230 sigma_dut.sae_h2e_default = 1;
1231 break;
Hu Wang6010ce72020-03-05 19:33:53 +08001232 case '3':
1233 sigma_dut.owe_ptk_workaround = 1;
1234 break;
Veerendranath Jakkam47867202020-12-21 01:53:52 +05301235 case '4':
1236 sigma_dut.client_privacy_default = 1;
1237 break;
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05301238 case '5': {
1239 int timeout;
1240
1241 errno = 0;
1242 timeout = strtol(optarg, NULL, 10);
1243 if (errno || timeout < 0) {
1244 sigma_dut_print(&sigma_dut, DUT_MSG_ERROR,
1245 "failed to set default_timeout");
1246 return -1;
1247 }
1248 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1249 "default timeout set to %d", timeout);
1250 sigma_dut.user_config_timeout = timeout;
1251 break;
1252 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001253 case 'h':
1254 default:
Jouni Malinen5174e022019-11-04 16:35:03 +02001255 usage();
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001256 exit(0);
1257 break;
1258 }
1259 }
1260
Jouni Malinen1f76fa62019-11-04 17:30:12 +02001261 determine_sigma_p2p_ifname(&sigma_dut);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07001262#ifdef MIRACAST
1263 miracast_init(&sigma_dut);
1264#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001265 if (local_cmd)
1266 return run_local_cmd(port, local_cmd);
1267
Pradeep Reddy Potteti08eaeba2017-06-14 12:43:19 +05301268 if ((wifi_chip_type == DRIVER_QNXNTO ||
1269 wifi_chip_type == DRIVER_LINUX_WCN) &&
Jouni Malinend2095482019-11-04 17:10:43 +02001270 (!sigma_dut.main_ifname || !sigma_dut.station_ifname)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001271 sigma_dut_print(&sigma_dut, DUT_MSG_ERROR,
Pradeep Reddy Potteti08eaeba2017-06-14 12:43:19 +05301272 "Interface should be provided for QNX/LINUX-WCN driver - check option M and S");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001273 }
1274
Priyadharshini Gowthamand06f1002019-04-22 15:45:41 -07001275 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
1276 get_nl80211_config_enable_option(&sigma_dut);
1277
Venkateswara Naralasettyf0f88052020-11-11 19:15:17 +05301278 sigma_dut_get_device_driver_name(get_main_ifname(&sigma_dut),
1279 sigma_dut.device_driver,
1280 sizeof(sigma_dut.device_driver));
1281 if (sigma_dut.device_driver[0])
1282 sigma_dut_print(&sigma_dut, DUT_MSG_DEBUG, "device driver: %s",
1283 sigma_dut.device_driver);
1284
Peng Xu291d97d2018-01-31 16:34:03 -08001285#ifdef NL80211_SUPPORT
1286 sigma_dut.nl_ctx = nl80211_init(&sigma_dut);
1287#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001288 sigma_dut_register_cmds();
1289
1290#ifdef __QNXNTO__
1291 /* Try to open socket in other env dev */
1292 if (sigma_ctrl_sock) {
1293 env_str = getenv("SOCK");
1294 if (env_str) {
1295 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1296 "SOCK=%s", env_str);
1297 }
1298 snprintf(buf, sizeof(buf), "SOCK=%s", sigma_ctrl_sock);
1299 if (putenv(buf) != 0) {
1300 sigma_dut_print(&sigma_dut, DUT_MSG_ERROR,
1301 "putenv() failed setting SOCK");
1302 return EXIT_FAILURE;
1303 }
1304 }
1305#endif /* __QNXNTO__ */
1306
1307 if (open_socket(&sigma_dut, port) < 0)
1308 return -1;
1309
1310#ifdef __QNXNTO__
1311 /* restore back the SOCK */
1312 if (sigma_ctrl_sock) {
1313 if (env_str) {
1314 snprintf(buf, sizeof(buf), "SOCK=%s", env_str);
1315 if (putenv(buf) != 0) {
1316 sigma_dut_print(&sigma_dut, DUT_MSG_ERROR,
1317 "putenv() failed setting SOCK");
1318 return EXIT_FAILURE;
1319 }
1320 } else {
1321 /* unset the env for sock */
1322 unsetenv("SOCK");
1323 }
1324 }
1325#endif /* __QNXNTO__ */
1326
1327 if (daemonize) {
1328 if (daemon(0, 0) < 0) {
1329 perror("daemon");
1330 exit(-1);
1331 }
1332 } else {
1333#ifdef __linux__
1334 setlinebuf(stdout);
1335#endif /* __linux__ */
1336 }
1337
Purushottam Kushwaha091e2532016-08-23 11:52:21 +05301338 if (internal_dhcp_enabled)
1339 p2p_create_event_thread(&sigma_dut);
1340
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001341 run_loop(&sigma_dut);
1342
1343#ifdef CONFIG_SNIFFER
1344 sniffer_close(&sigma_dut);
1345#endif /* CONFIG_SNIFFER */
1346
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001347 close_socket(&sigma_dut);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07001348#ifdef MIRACAST
1349 miracast_deinit(&sigma_dut);
1350#endif /* MIRACAST */
Jouni Malinen829b7de2019-11-04 16:39:55 +02001351 deinit_sigma_dut(&sigma_dut);
Peng Xu291d97d2018-01-31 16:34:03 -08001352#ifdef NL80211_SUPPORT
1353 nl80211_deinit(&sigma_dut, sigma_dut.nl_ctx);
1354#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001355 sigma_dut_unreg_cmds(&sigma_dut);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301356#ifdef ANDROID
1357 hlp_thread_cleanup(&sigma_dut);
1358#endif /* ANDROID */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001359
1360 return 0;
1361}