blob: c4d13aa16ee7fdd06b3440d16f853c81e21798fb [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 Malinen2feb9132021-11-16 00:53:06 +02005 * Copyright (c) 2018-2021, 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
Vinita S. Maloo8d7a28d2021-01-21 22:55:00 +0530369const char * get_param_fmt(struct sigma_cmd *cmd, const char *name, ...)
370{
371 va_list ap;
372 char buf[100];
373 int ret;
374
375 va_start(ap, name);
376 ret = vsnprintf(buf, sizeof(buf), name, ap);
377 va_end(ap);
378
379 if (ret < 0 || ret >= sizeof(buf))
380 return NULL;
381
382 return get_param(cmd, buf);
383}
384
385
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200386static void process_cmd(struct sigma_dut *dut, struct sigma_conn *conn,
387 char *buf)
388{
389 struct sigma_cmd_handler *h;
390 struct sigma_cmd c;
391 char *cmd, *pos, *pos2;
392 int len;
Alexei Avshalom Lazar5fdd8652018-11-13 14:08:27 +0200393 char txt[300];
Jouni Malinen26a5b762019-02-19 01:17:48 +0200394 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200395
396 while (*buf == '\r' || *buf == '\n' || *buf == '\t' || *buf == ' ')
397 buf++;
398 len = strlen(buf);
399 while (len > 0 && buf[len - 1] == ' ') {
400 buf[len - 1] = '\0';
401 len--;
402 }
403
404 if (dut->debug_level < DUT_MSG_INFO) {
405 pos = strchr(buf, ',');
406 if (pos == NULL)
407 pos = buf + len;
408 if (pos - buf > 50)
409 pos = buf + 50;
410 memcpy(txt, "/====[ ", 7);
411 pos2 = txt + 7;
412 memcpy(pos2, buf, pos - buf);
413 pos2 += pos - buf;
414 *pos2++ = ' ';
415 *pos2++ = ']';
416 while (pos2 - txt < 70)
417 *pos2++ = '=';
418 *pos2++ = '\\';
419 *pos2 = '\0';
420 printf("\n%s\n\n", txt);
421 }
422
423 sigma_dut_print(dut, DUT_MSG_INFO, "cmd: %s", buf);
424 sigma_dut_summary(dut, "CAPI cmd: %s", buf);
425 snprintf(txt, sizeof(txt), "NOTE CAPI:%s", buf);
426 txt[sizeof(txt) - 1] = '\0';
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200427 wpa_command(get_main_ifname(dut), txt);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200428
429 memset(&c, 0, sizeof(c));
430 cmd = buf;
431 pos = strchr(cmd, ',');
432 if (pos) {
433 *pos++ = '\0';
434 if (strcasecmp(cmd, "AccessPoint") == 0 ||
435 strcasecmp(cmd, "PowerSwitch") == 0) {
436 pos2 = strchr(pos, ',');
437 if (pos2 == NULL)
438 goto invalid_params;
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 while (pos) {
447 pos2 = strchr(pos, ',');
448 if (pos2 == NULL)
449 goto invalid_params;
450 *pos2++ = '\0';
451 if (c.count == MAX_PARAMS) {
452 sigma_dut_print(dut, DUT_MSG_INFO, "Too many "
453 "parameters");
454 goto invalid_params;
455 }
456 c.params[c.count] = pos;
457 c.values[c.count] = pos2;
458 c.count++;
459 pos = strchr(pos2, ',');
460 if (pos)
461 *pos++ = '\0';
462 }
463 }
464 h = dut->cmds;
465 while (h) {
466 if (strcasecmp(cmd, h->cmd) == 0)
467 break;
468 h = h->next;
469 }
470
471 if (h == NULL) {
472 sigma_dut_print(dut, DUT_MSG_INFO, "Unknown command: '%s'",
473 cmd);
474 send_resp(dut, conn, SIGMA_INVALID,
475 "errorCode,Unknown command");
476 goto out;
477 }
478
479 if (h->validate && h->validate(&c) < 0) {
480 invalid_params:
481 sigma_dut_print(dut, DUT_MSG_INFO, "Invalid parameters");
482 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Invalid "
483 "parameters");
484 goto out;
485 }
486
Jouni Malinen0fee7012019-02-19 12:41:07 +0200487 dut->response_sent = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200488 send_resp(dut, conn, SIGMA_RUNNING, NULL);
489 sigma_dut_print(dut, DUT_MSG_INFO, "Run command: %s", cmd);
490 res = h->process(dut, conn, &c);
Jouni Malinen26a5b762019-02-19 01:17:48 +0200491 switch (res) {
492 case ERROR_SEND_STATUS:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200493 send_resp(dut, conn, SIGMA_ERROR, NULL);
Jouni Malinen26a5b762019-02-19 01:17:48 +0200494 break;
495 case INVALID_SEND_STATUS:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200496 send_resp(dut, conn, SIGMA_INVALID, NULL);
Jouni Malinen26a5b762019-02-19 01:17:48 +0200497 break;
498 case STATUS_SENT:
Jouni Malinen53264f62019-05-03 13:04:40 +0300499 case STATUS_SENT_ERROR:
Jouni Malinen26a5b762019-02-19 01:17:48 +0200500 break;
501 case SUCCESS_SEND_STATUS:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200502 send_resp(dut, conn, SIGMA_COMPLETE, NULL);
Jouni Malinen26a5b762019-02-19 01:17:48 +0200503 break;
504 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200505
Jouni Malinen0fee7012019-02-19 12:41:07 +0200506 if (!conn->waiting_completion && dut->response_sent != 2) {
507 sigma_dut_print(dut, DUT_MSG_ERROR,
508 "ERROR: Unexpected number of status lines sent (%d) for command '%s'",
509 dut->response_sent, cmd);
510 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200511
512out:
513 if (dut->debug_level < DUT_MSG_INFO) {
514 pos2 = txt;
515 *pos2++ = '\\';
516 memset(pos2, '-', 69);
517 pos2 += 69;
518 *pos2++ = '/';
519 *pos2 = '\0';
520 printf("\n%s\n\n", txt);
521 }
522}
523
524
525static void process_conn(struct sigma_dut *dut, struct sigma_conn *conn)
526{
527 ssize_t res;
528 int i;
529
530 sigma_dut_print(dut, DUT_MSG_DEBUG, "Read from %s:%d",
531 inet_ntoa(conn->addr.sin_addr),
532 ntohs(conn->addr.sin_port));
533
534 res = recv(conn->s, conn->buf + conn->pos, MAX_CMD_LEN + 5 - conn->pos,
535 0);
536 if (res < 0) {
537 sigma_dut_print(dut, DUT_MSG_INFO, "recv: %s",
538 strerror(errno));
539 }
540 if (res <= 0) {
541 sigma_dut_print(dut, DUT_MSG_DEBUG, "Close connection from "
542 "%s:%d",
543 inet_ntoa(conn->addr.sin_addr),
544 ntohs(conn->addr.sin_port));
545 shutdown(conn->s, SHUT_RDWR);
546 close(conn->s);
547 conn->s = -1;
548 return;
549 }
550
551 sigma_dut_print(dut, DUT_MSG_DEBUG, "Received %d bytes",
552 (int) res);
553
554 for (;;) {
555 for (i = conn->pos; i < conn->pos + res; i++) {
556 if (conn->buf[i] == '\r' || conn->buf[i] == '\n')
557 break;
558 }
559
560 if (i == conn->pos + res) {
561 /* Full command not yet received */
562 conn->pos += res;
563 if (conn->pos >= MAX_CMD_LEN + 5) {
564 sigma_dut_print(dut, DUT_MSG_INFO, "Too long "
565 "command dropped");
566 conn->pos = 0;
567 }
568 break;
569 }
570
571 /* Full command received */
572 conn->buf[i++] = '\0';
573 process_cmd(dut, conn, conn->buf);
574 while (i < conn->pos + res &&
575 (conn->buf[i] == '\r' || conn->buf[i] == '\n'))
576 i++;
577 memmove(conn->buf, &conn->buf[i], conn->pos + res - i);
578 res = conn->pos + res - i;
579 conn->pos = 0;
580 }
581}
582
583
584static int stop_loop = 0;
585
586#ifdef __linux__
587static void handle_term(int sig)
588{
Jouni Malinenad4c6752019-11-06 18:51:19 +0200589 struct sigma_dut *dut = &sigma_dut;
590
591 if (dut->sta_2g_started || dut->sta_5g_started)
592 stop_sta_mode(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200593 stop_loop = 1;
Purushottam Kushwaha091e2532016-08-23 11:52:21 +0530594 stop_event_thread();
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200595 printf("sigma_dut terminating\n");
596}
597#endif /* __linux__ */
598
599static void run_loop(struct sigma_dut *dut)
600{
601 struct sigma_conn conn[MAX_CONNECTIONS];
602 int i, res, maxfd, can_accept;
603 fd_set rfds;
604
605 memset(&conn, 0, sizeof(conn));
606 for (i = 0; i < MAX_CONNECTIONS; i++)
607 conn[i].s = -1;
608
609#ifdef __linux__
610 signal(SIGINT, handle_term);
611 signal(SIGTERM, handle_term);
612 signal(SIGPIPE, SIG_IGN);
613#endif /* __linux__ */
614
615 while (!stop_loop) {
616 FD_ZERO(&rfds);
617 maxfd = -1;
618 can_accept = 0;
619 for (i = 0; i < MAX_CONNECTIONS; i++) {
620 if (conn[i].s >= 0) {
621 FD_SET(conn[i].s, &rfds);
622 if (conn[i].s > maxfd)
623 maxfd = conn[i].s;
624 } else if (!conn[i].waiting_completion)
625 can_accept = 1;
626 }
627
628 if (can_accept) {
629 FD_SET(dut->s, &rfds);
630 if (dut->s > maxfd)
631 maxfd = dut->s;
632 }
633
634
635 sigma_dut_print(dut, DUT_MSG_DEBUG, "Waiting for next "
636 "command (can_accept=%d)", can_accept);
637 res = select(maxfd + 1, &rfds, NULL, NULL, NULL);
638 if (res < 0) {
639 perror("select");
640 if (!stop_loop)
641 sleep(1);
642 continue;
643 }
644
645 if (!res) {
646 sigma_dut_print(dut, DUT_MSG_DEBUG, "Nothing ready");
647 sleep(1);
648 continue;
649 }
650
651 if (FD_ISSET(dut->s, &rfds)) {
652 for (i = 0; i < MAX_CONNECTIONS; i++) {
653 if (conn[i].s < 0 &&
654 !conn[i].waiting_completion)
655 break;
656 }
657 if (i == MAX_CONNECTIONS) {
658 /*
659 * This cannot really happen since can_accept
660 * would not be set to one.
661 */
662 sigma_dut_print(dut, DUT_MSG_DEBUG,
663 "No room for new connection");
664 continue;
665 }
666 conn[i].addrlen = sizeof(conn[i].addr);
667 conn[i].s = accept(dut->s,
668 (struct sockaddr *) &conn[i].addr,
669 &conn[i].addrlen);
670 if (conn[i].s < 0) {
671 sigma_dut_print(dut, DUT_MSG_INFO,
672 "accept: %s",
673 strerror(errno));
674 continue;
675 }
676
677 sigma_dut_print(dut, DUT_MSG_DEBUG,
678 "Connection %d from %s:%d", i,
679 inet_ntoa(conn[i].addr.sin_addr),
680 ntohs(conn[i].addr.sin_port));
681 conn[i].pos = 0;
682 }
683
684 for (i = 0; i < MAX_CONNECTIONS; i++) {
685 if (conn[i].s < 0)
686 continue;
687 if (FD_ISSET(conn[i].s, &rfds))
688 process_conn(dut, &conn[i]);
689 }
690 }
691}
692
693
694static int run_local_cmd(int port, char *lcmd)
695{
696 int s, len;
697 struct sockaddr_in addr;
698 char cmd[MAX_CMD_LEN];
699 ssize_t res;
700 int count;
701 char resp[MAX_CMD_LEN];
702 int pos;
703
704
705 if (strlen(lcmd) > sizeof(cmd) - 4) {
706 printf("Too long command\n");
707 return -1;
708 }
709 len = snprintf(cmd, sizeof(cmd), "%s \r\n", lcmd);
710
711 memset(&addr, 0, sizeof(addr));
712 addr.sin_family = AF_INET;
713 inet_aton("127.0.0.1", &addr.sin_addr);
714 addr.sin_port = htons(port);
715
716 /* Make sure we do not get stuck indefinitely */
717 alarm(150);
718
719 s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
720 if (s < 0) {
721 perror("socket");
722 return -1;
723 }
724
725 if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
726 perror("connect");
727 close(s);
728 return -1;
729 }
730
731 res = send(s, cmd, len, 0);
732 if (res < 0) {
733 perror("send");
734 close(s);
735 return -1;
736 }
737 if (res != len) {
738 printf("Unexpected send result: %d (expected %d)\n",
739 (int) res, len);
740 close(s);
741 return -1;
742 }
743
744 count = 0;
745 pos = 0;
746 len = 0;
747 for (;;) {
748 char *e;
749 res = recv(s, resp + len, sizeof(resp) - len, 0);
750 if (res < 0) {
751 perror("recv");
752 close(s);
753 return -1;
754 }
755 if (res == 0) {
756 printf("Could not read response\n");
757 close(s);
758 return -1;
759 }
760 len += res;
761 next_line:
762 e = memchr(resp + pos, '\r', len - pos);
763 if (e == NULL)
764 continue;
765 *e++ = '\0';
766 if (e - resp < len && *e == '\n')
767 *e++ = '\n';
768 printf("%s\n", resp + pos);
769 if (strncasecmp(resp + pos, "status,RUNNING", 14) != 0)
770 break;
771 count++;
772 if (count == 2)
773 break;
774 pos = e - resp;
775 goto next_line;
776 }
777
778 close(s);
779
780 return 0;
781}
782
783
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200784static void determine_sigma_p2p_ifname(struct sigma_dut *dut)
Danny Segalf2af39b2016-04-10 16:23:11 +0300785{
786 char buf[256];
787 struct wpa_ctrl *ctrl;
788
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200789 if (dut->p2p_ifname)
790 return;
Danny Segalf2af39b2016-04-10 16:23:11 +0300791
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200792 snprintf(buf, sizeof(buf), "p2p-dev-%s", get_station_ifname(dut));
Danny Segalf2af39b2016-04-10 16:23:11 +0300793 ctrl = open_wpa_mon(buf);
794 if (ctrl) {
795 wpa_ctrl_detach(ctrl);
796 wpa_ctrl_close(ctrl);
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200797 dut->p2p_ifname_buf = strdup(buf);
798 dut->p2p_ifname = dut->p2p_ifname_buf;
Danny Segalf2af39b2016-04-10 16:23:11 +0300799 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
800 "Using interface %s for P2P operations instead of interface %s",
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200801 dut->p2p_ifname ? dut->p2p_ifname : "NULL",
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200802 get_station_ifname(dut));
Danny Segalf2af39b2016-04-10 16:23:11 +0300803 } else {
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200804 dut->p2p_ifname = get_station_ifname(dut);
Danny Segalf2af39b2016-04-10 16:23:11 +0300805 }
806}
807
808
Priyadharshini Gowthamand06f1002019-04-22 15:45:41 -0700809static int get_nl80211_config_enable_option(struct sigma_dut *dut)
810{
811 char cmd[100], result[5];
812 FILE *f;
813 size_t len;
814 int ap_nl80211_enable;
815
816 snprintf(cmd, sizeof(cmd), "uci get qcacfg80211.config.enable");
817 f = popen(cmd, "r");
818 if (!f)
819 return -1;
820
821 len = fread(result, 1, sizeof(result) - 1, f);
822 pclose(f);
823
824 if (len == 0)
825 return -1;
826
827 result[len] = '\0';
828 ap_nl80211_enable = atoi(result);
829
830 if (ap_nl80211_enable)
831 dut->priv_cmd = "cfg80211tool";
832
833 return 0;
834}
835
836
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200837static void set_defaults(struct sigma_dut *dut)
838{
Jouni Malinen1dd0b612019-11-04 16:32:33 +0200839 dut->debug_level = DUT_MSG_INFO;
840 dut->default_timeout = 120;
841 dut->dialog_token = 0;
842 dut->dpp_conf_id = -1;
843 dut->dpp_local_bootstrap = -1;
844 dut->sta_nss = 2; /* Make default nss 2 */
845 dut->trans_proto = NAN_TRANSPORT_PROTOCOL_DEFAULT;
846 dut->trans_port = NAN_TRANSPORT_PORT_DEFAULT;
847 dut->nan_ipv6_len = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200848 dut->ap_p2p_cross_connect = -1;
849 dut->ap_chwidth = AP_AUTO;
Pradeep Reddy Pottetibf8af292017-02-15 15:28:39 +0530850 dut->default_11na_ap_chwidth = AP_AUTO;
851 dut->default_11ng_ap_chwidth = AP_AUTO;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200852 /* by default, enable writing of traffic stream stats */
853 dut->write_stats = 1;
Priyadharshini Gowthamand06f1002019-04-22 15:45:41 -0700854 dut->priv_cmd = "iwpriv";
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +0200855 dut->sigma_tmpdir = SIGMA_TMPDIR;
Priyadharshini Gowthamance7ba822020-05-27 13:03:09 -0700856 dut->ap_ocvc = -1;
Vinita S. Maloo1ded3742021-07-28 16:55:21 +0530857 dut->user_config_ap_ocvc = -1;
Jouni Malinen0a9876c2020-06-08 19:15:36 +0300858 dut->ap_sae_commit_status = -1;
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -0700859 dut->sta_async_twt_supp = -1;
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +0530860#ifdef ANDROID
861 dut->dscp_use_iptables = 1;
862#endif /* ANDROID */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200863}
864
865
Jouni Malinen829b7de2019-11-04 16:39:55 +0200866static void deinit_sigma_dut(struct sigma_dut *dut)
867{
868 free(dut->non_pref_ch_list);
869 dut->non_pref_ch_list = NULL;
870 free(dut->btm_query_cand_list);
871 dut->btm_query_cand_list = NULL;
872 free(dut->rsne_override);
873 dut->rsne_override = NULL;
Jouni Malinen7960e3a2019-12-07 17:04:35 +0200874 free(dut->rsnxe_override_eapol);
875 dut->rsnxe_override_eapol = NULL;
Jouni Malinen829b7de2019-11-04 16:39:55 +0200876 free(dut->ap_sae_groups);
877 dut->ap_sae_groups = NULL;
878 free(dut->dpp_peer_uri);
879 dut->dpp_peer_uri = NULL;
880 free(dut->ap_sae_passwords);
881 dut->ap_sae_passwords = NULL;
Jouni Malinen59fab0f2020-06-05 16:59:55 +0300882 free(dut->ap_sae_pk_modifier);
883 dut->ap_sae_pk_modifier = NULL;
884 free(dut->ap_sae_pk_keypair);
885 dut->ap_sae_pk_keypair = NULL;
Jouni Malinenfbf12ef2020-06-08 19:49:40 +0300886 free(dut->ap_sae_pk_keypair_sig);
887 dut->ap_sae_pk_keypair_sig = NULL;
Jouni Malinen829b7de2019-11-04 16:39:55 +0200888 free(dut->ar_ltf);
889 dut->ar_ltf = NULL;
890 free(dut->ap_dpp_conf_addr);
891 dut->ap_dpp_conf_addr = NULL;
892 free(dut->ap_dpp_conf_pkhash);
893 dut->ap_dpp_conf_pkhash = NULL;
894 if (dut->log_file_fd) {
895 fclose(dut->log_file_fd);
896 dut->log_file_fd = NULL;
897 }
Jouni Malinen1f76fa62019-11-04 17:30:12 +0200898 free(dut->p2p_ifname_buf);
899 dut->p2p_ifname_buf = NULL;
Jouni Malinenb21f0542019-11-04 17:53:38 +0200900 free(dut->main_ifname_2g);
901 dut->main_ifname_2g = NULL;
902 free(dut->main_ifname_5g);
903 dut->main_ifname_5g = NULL;
904 free(dut->station_ifname_2g);
905 dut->station_ifname_2g = NULL;
906 free(dut->station_ifname_5g);
907 dut->station_ifname_5g = NULL;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +0530908 stop_dscp_policy_mon_thread(dut);
909 free_dscp_policy_table(dut);
Jouni Malinenb21f0542019-11-04 17:53:38 +0200910}
911
912
913static void set_main_ifname(struct sigma_dut *dut, const char *val)
914{
915 const char *pos;
916
917 dut->main_ifname = optarg;
918 pos = strchr(val, '/');
919 if (!pos)
920 return;
921 free(dut->main_ifname_2g);
922 dut->main_ifname_2g = malloc(pos - val + 1);
923 if (dut->main_ifname_2g) {
924 memcpy(dut->main_ifname_2g, val, pos - val);
925 dut->main_ifname_2g[pos - val] = '\0';
926 }
927 free(dut->main_ifname_5g);
928 dut->main_ifname_5g = strdup(pos + 1);
929}
930
931
932static void set_station_ifname(struct sigma_dut *dut, const char *val)
933{
934 const char *pos;
935
936 dut->station_ifname = optarg;
937 pos = strchr(val, '/');
938 if (!pos)
939 return;
940 free(dut->station_ifname_2g);
941 dut->station_ifname_2g = malloc(pos - val + 1);
942 if (dut->station_ifname_2g) {
943 memcpy(dut->station_ifname_2g, val, pos - val);
944 dut->station_ifname_2g[pos - val] = '\0';
945 }
946 free(dut->station_ifname_5g);
947 dut->station_ifname_5g = strdup(pos + 1);
Jouni Malinen829b7de2019-11-04 16:39:55 +0200948}
949
950
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200951static const char * const license1 =
952"sigma_dut - WFA Sigma DUT/CA\n"
953"----------------------------\n"
954"\n"
955"Copyright (c) 2010-2011, Atheros Communications, Inc.\n"
Jouni Malinen9d7e31d2017-12-22 18:55:04 +0200956"Copyright (c) 2011-2017, Qualcomm Atheros, Inc.\n"
Jouni Malinen2feb9132021-11-16 00:53:06 +0200957"Copyright (c) 2018-2021, The Linux Foundation\n"
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200958"All Rights Reserved.\n"
959"Licensed under the Clear BSD license.\n"
960"\n";
961static const char * const license2 =
962"Redistribution and use in source and binary forms, with or without\n"
963"modification, are permitted (subject to the limitations in the\n"
964"disclaimer below) provided that the following conditions are met:\n"
965"\n";
966static const char * const license3 =
967"* Redistributions of source code must retain the above copyright notice,\n"
968" this list of conditions and the following disclaimer.\n"
969"\n"
970"* Redistributions in binary form must reproduce the above copyright\n"
971" notice, this list of conditions and the following disclaimer in the\n"
972" documentation and/or other materials provided with the distribution.\n"
973"\n"
974"* Neither the name of Qualcomm Atheros, Inc. nor the names of its\n"
975" contributors may be used to endorse or promote products derived from\n"
976" this software without specific prior written permission.\n"
977"\n";
978static const char * const license4 =
979"NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED\n"
980"BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND\n"
981"CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\n"
982"BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\n"
983"FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n"
984"COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n"
985"INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n"
986"NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\n"
987"USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\n"
988"ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n"
989"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n"
990"THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n";
991
992
993static void print_license(void)
994{
995 printf("%s%s%s%s\n",
996 license1, license2, license3, license4);
997}
998
999
Jouni Malinen5174e022019-11-04 16:35:03 +02001000static void usage(void)
1001{
Veerendranath Jakkam47867202020-12-21 01:53:52 +05301002 printf("usage: sigma_dut [-aABdfGqDIntuVW234] [-p<port>] "
Jouni Malinen5174e022019-11-04 16:35:03 +02001003 "[-s<sniffer>] [-m<set_maccaddr.sh>] \\\n"
1004 " [-M<main ifname>] [-R<radio ifname>] "
1005 "[-S<station ifname>] [-P<p2p_ifname>]\\\n"
1006 " [-T<throughput pktsize>] \\\n"
1007 " [-w<wpa_supplicant/hostapd ctrl_iface dir>] \\\n"
1008 " [-H <hostapd log file>] \\\n"
1009 " [-F <hostapd binary path>] \\\n"
1010 " [-j <hostapd ifname>] \\\n"
1011 " [-J <wpa_supplicant debug log>] \\\n"
1012 " [-C <certificate path>] \\\n"
1013 " [-v <version string>] \\\n"
1014 " [-L <summary log>] \\\n"
1015 " [-c <wifi chip type: WCN or ATHEROS or "
1016 "AR6003 or MAC80211 or QNXNTO or OPENWRT or LINUX-WCN>] \\\n"
1017 " [-i <IP address of the AP>] \\\n"
1018 " [-k <subnet mask for the AP>] \\\n"
1019 " [-K <sigma_dut log file directory>] \\\n"
1020 " [-e <hostapd entropy file>] \\\n"
1021 " [-N <device_get_info vendor>] \\\n"
1022 " [-o <device_get_info model>] \\\n"
1023 " [-O <device_get_info version>] \\\n"
1024#ifdef MIRACAST
1025 " [-x <sink|source>] \\\n"
1026 " [-y <Miracast library path>] \\\n"
1027#endif /* MIRACAST */
1028 " [-z <client socket directory path \\\n"
1029 " Ex: </data/vendor/wifi/sockets>] \\\n"
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +02001030 " [-Z <Override default tmp dir path>] \\\n"
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05301031 " [-5 <WFD timeout override>] \\\n"
Vinita S. Maloo1ded3742021-07-28 16:55:21 +05301032 " [-r <HT40 or 2.4_HT40>] \\\n"
1033 " [-6 <ocv or bp or ocv_bp>]\n");
Jouni Malinen5174e022019-11-04 16:35:03 +02001034 printf("local command: sigma_dut [-p<port>] <-l<cmd>>\n");
1035}
1036
1037
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001038int main(int argc, char *argv[])
1039{
1040 int c;
1041 int daemonize = 0;
1042 int port = SIGMA_DUT_PORT;
1043 char *local_cmd = NULL;
Purushottam Kushwaha091e2532016-08-23 11:52:21 +05301044 int internal_dhcp_enabled = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001045#ifdef __QNXNTO__
1046 char *env_str = NULL;
1047 char buf[20];
1048 char *sigma_ctrl_sock = NULL; /* env used for QNX */
1049#endif /* __QNXNTO__ */
1050
1051 memset(&sigma_dut, 0, sizeof(sigma_dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001052 set_defaults(&sigma_dut);
1053
1054 for (;;) {
1055 c = getopt(argc, argv,
Xinyue Ling56a6e2c2021-11-17 11:39:48 +08001056 "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:6:");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001057 if (c < 0)
1058 break;
1059 switch (c) {
1060 case 'a':
1061 sigma_dut.ap_anqpserver = 1;
1062 break;
1063 case 'b':
1064 sigma_dut.bridge = optarg;
1065 break;
1066 case 'B':
1067 daemonize++;
1068 break;
1069 case 'C':
1070 sigma_cert_path = optarg;
1071 break;
1072 case 'd':
1073 if (sigma_dut.debug_level > 0)
1074 sigma_dut.debug_level--;
1075 break;
1076#ifdef __QNXNTO__
1077 case 'E':
1078 sigma_ctrl_sock = optarg;
1079 break;
1080#endif /* __QNXNTO__ */
1081 case 'D':
1082 sigma_dut.stdout_debug = 1;
1083 break;
1084 case 'e':
1085 sigma_dut.hostapd_entropy_log = optarg;
1086 break;
1087 case 'f':
1088 /* Disable writing stats */
1089 sigma_dut.write_stats = 0;
1090 break;
Jouni Malinend6bf1b42017-06-23 17:51:01 +03001091 case 'F':
1092 sigma_dut.hostapd_bin = optarg;
1093 break;
Purushottam Kushwaha091e2532016-08-23 11:52:21 +05301094 case 'g':
1095 /* Enable internal processing of P2P group formation
1096 * events to start/stop DHCP server/client. */
1097 internal_dhcp_enabled = 1;
1098 break;
Jouni Malinend6bf1b42017-06-23 17:51:01 +03001099 case 'G':
1100 sigma_dut.use_hostapd_pid_file = 1;
1101 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001102 case 'H':
1103 sigma_dut.hostapd_debug_log = optarg;
1104 break;
1105 case 'I':
1106 print_license();
1107 exit(0);
1108 break;
Jouni Malinend6bf1b42017-06-23 17:51:01 +03001109 case 'j':
1110 sigma_dut.hostapd_ifname = optarg;
1111 break;
Alexei Avshalom Lazar3e8267e2018-12-18 15:58:54 +02001112 case 'J':
1113 sigma_dut.wpa_supplicant_debug_log = optarg;
1114 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001115 case 'l':
1116 local_cmd = optarg;
1117 break;
1118 case 'L':
1119 sigma_dut.summary_log = optarg;
1120 break;
1121 case 'p':
1122 port = atoi(optarg);
1123 break;
Danny Segalf2af39b2016-04-10 16:23:11 +03001124 case 'P':
Jouni Malinen1f76fa62019-11-04 17:30:12 +02001125 sigma_dut.p2p_ifname = optarg;
Danny Segalf2af39b2016-04-10 16:23:11 +03001126 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001127 case 'q':
1128 sigma_dut.debug_level++;
1129 break;
Purushottam Kushwahab7f56d42018-06-11 12:59:45 +05301130 case 'Q':
1131 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1132 "Send Periodic data");
1133 sigma_periodic_data = 1;
1134 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001135 case 'r':
1136 if (strcmp(optarg, "HT40") == 0) {
Pradeep Reddy Pottetibf8af292017-02-15 15:28:39 +05301137 sigma_dut.default_11na_ap_chwidth = AP_40;
1138 } else if (strcmp(optarg, "2.4_HT40") == 0) {
1139 sigma_dut.default_11ng_ap_chwidth = AP_40;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001140 } else {
1141 printf("Unsupported -r value\n");
1142 exit(1);
1143 }
1144 break;
1145 case 'R': {
1146 static int num_radio = 0;
1147 static char **radio_ptr = sigma_radio_ifname;
1148
1149 num_radio++;
1150 if (num_radio > MAX_RADIO) {
1151 printf("Multiple radio support limit (%d) exceeded\n",
1152 MAX_RADIO);
1153 exit(1);
1154 }
1155 *radio_ptr++ = optarg;
1156 break;
1157 }
1158 case 's':
1159 sigma_dut.sniffer_ifname = optarg;
1160 break;
1161 case 't':
1162 sigma_dut.no_timestamps = 1;
1163 break;
1164 case 'T':
1165 sigma_dut.throughput_pktsize = atoi(optarg);
Jouni Malinenc2493f82016-06-05 18:01:33 +03001166 if (sigma_dut.throughput_pktsize == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001167 printf("Invalid -T value\n");
1168 exit(0);
1169 }
1170 break;
1171 case 'm':
1172 sigma_dut.set_macaddr = optarg;
1173 break;
1174 case 'M':
Jouni Malinenb21f0542019-11-04 17:53:38 +02001175 set_main_ifname(&sigma_dut, optarg);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001176 break;
1177 case 'n':
1178 sigma_dut.no_ip_addr_set = 1;
1179 break;
Jouni Malinen5db3b102016-08-04 12:27:18 +03001180 case 'N':
1181 sigma_dut.vendor_name = optarg;
1182 break;
1183 case 'o':
1184 sigma_dut.model_name = optarg;
1185 break;
1186 case 'O':
1187 sigma_dut.version_name = optarg;
1188 break;
Kiran Kumar Lokere0128bf92019-04-08 18:36:16 -07001189 case 'K':
1190 sigma_dut.log_file_dir = optarg;
1191 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001192 case 'S':
Jouni Malinenb21f0542019-11-04 17:53:38 +02001193 set_station_ifname(&sigma_dut, optarg);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001194 break;
1195 case 'w':
1196 sigma_hapd_ctrl = optarg;
1197 sigma_wpas_ctrl = optarg;
1198 break;
1199 case 'i':
1200 ap_inet_addr = optarg;
1201 break;
1202 case 'k':
1203 ap_inet_mask = optarg;
1204 break;
1205 case 'c':
1206 printf("%s", optarg);
1207 if (set_wifi_chip(optarg) < 0)
1208 sigma_dut_print(&sigma_dut, DUT_MSG_ERROR,
1209 "WRONG CHIP TYPE: SAP will "
1210 "not load");
1211 break;
1212 case 'v':
1213 sigma_dut.version = optarg;
1214 break;
1215 case 'V':
1216 printf("sigma_dut " SIGMA_DUT_VER "\n");
1217 exit(0);
1218 break;
1219 case 'W':
1220 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1221 "Running WMM-AC test suite");
1222 sigma_wmm_ac = 1;
1223 break;
1224 case 'u':
1225 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1226 "Use iface down/up in reset cmd");
1227 sigma_dut.iface_down_on_reset = 1;
1228 break;
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301229 case 'A':
1230 sigma_dut.sim_no_username = 1;
1231 break;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07001232#ifdef MIRACAST
1233 case 'x':
1234 if (strcmp(optarg, "sink") == 0) {
1235 sigma_dut.wfd_device_type = 1;
1236 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1237 "Device Type is SINK");
1238 } else if (strcmp(optarg, "source") == 0) {
1239 sigma_dut.wfd_device_type = 0;
1240 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1241 "Device Type is SOURCE");
1242 }
1243 break;
1244 case 'y':
1245 sigma_dut.miracast_lib_path = optarg;
1246 break;
1247#endif /* MIRACAST */
Rajiv Ranjan525dbfd2018-04-20 17:42:48 +05301248 case 'z':
1249 client_socket_path = optarg;
1250 break;
Alexei Avshalom Lazarc9bc15d2020-01-29 10:52:13 +02001251 case 'Z':
1252 sigma_dut.sigma_tmpdir = optarg;
1253 break;
Jouni Malinen11e55212019-11-22 21:46:59 +02001254 case '2':
1255 sigma_dut.sae_h2e_default = 1;
1256 break;
Hu Wang6010ce72020-03-05 19:33:53 +08001257 case '3':
1258 sigma_dut.owe_ptk_workaround = 1;
1259 break;
Veerendranath Jakkam47867202020-12-21 01:53:52 +05301260 case '4':
1261 sigma_dut.client_privacy_default = 1;
1262 break;
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05301263 case '5': {
1264 int timeout;
1265
1266 errno = 0;
1267 timeout = strtol(optarg, NULL, 10);
1268 if (errno || timeout < 0) {
1269 sigma_dut_print(&sigma_dut, DUT_MSG_ERROR,
1270 "failed to set default_timeout");
1271 return -1;
1272 }
1273 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1274 "default timeout set to %d", timeout);
1275 sigma_dut.user_config_timeout = timeout;
1276 break;
1277 }
Vinita S. Maloo1ded3742021-07-28 16:55:21 +05301278 case '6':
1279 if (strcmp(optarg, "ocv") == 0) {
1280 sigma_dut.user_config_ap_ocvc = 1;
1281 } else if (strcmp(optarg, "bp") == 0) {
1282 sigma_dut.user_config_ap_beacon_prot = 1;
1283 } else if (strcmp(optarg, "ocv_bp") == 0) {
1284 sigma_dut.user_config_ap_beacon_prot = 1;
1285 sigma_dut.user_config_ap_ocvc = 1;
1286 } else {
1287 printf("Unsupported -6 value\n");
1288 exit(1);
1289 }
1290 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001291 case 'h':
1292 default:
Jouni Malinen5174e022019-11-04 16:35:03 +02001293 usage();
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001294 exit(0);
1295 break;
1296 }
1297 }
1298
Jouni Malinen1f76fa62019-11-04 17:30:12 +02001299 determine_sigma_p2p_ifname(&sigma_dut);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07001300#ifdef MIRACAST
1301 miracast_init(&sigma_dut);
1302#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001303 if (local_cmd)
1304 return run_local_cmd(port, local_cmd);
1305
Pradeep Reddy Potteti08eaeba2017-06-14 12:43:19 +05301306 if ((wifi_chip_type == DRIVER_QNXNTO ||
1307 wifi_chip_type == DRIVER_LINUX_WCN) &&
Jouni Malinend2095482019-11-04 17:10:43 +02001308 (!sigma_dut.main_ifname || !sigma_dut.station_ifname)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001309 sigma_dut_print(&sigma_dut, DUT_MSG_ERROR,
Pradeep Reddy Potteti08eaeba2017-06-14 12:43:19 +05301310 "Interface should be provided for QNX/LINUX-WCN driver - check option M and S");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001311 }
1312
Priyadharshini Gowthamand06f1002019-04-22 15:45:41 -07001313 if (get_openwrt_driver_type() == OPENWRT_DRIVER_ATHEROS)
1314 get_nl80211_config_enable_option(&sigma_dut);
1315
Venkateswara Naralasettyf0f88052020-11-11 19:15:17 +05301316 sigma_dut_get_device_driver_name(get_main_ifname(&sigma_dut),
1317 sigma_dut.device_driver,
1318 sizeof(sigma_dut.device_driver));
1319 if (sigma_dut.device_driver[0])
1320 sigma_dut_print(&sigma_dut, DUT_MSG_DEBUG, "device driver: %s",
1321 sigma_dut.device_driver);
1322
Peng Xu291d97d2018-01-31 16:34:03 -08001323#ifdef NL80211_SUPPORT
1324 sigma_dut.nl_ctx = nl80211_init(&sigma_dut);
Sai Pavan Akhil Remella6469f0c2021-12-20 15:49:53 +05301325 get_wiphy_capabilities(&sigma_dut);
Peng Xu291d97d2018-01-31 16:34:03 -08001326#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001327 sigma_dut_register_cmds();
1328
1329#ifdef __QNXNTO__
1330 /* Try to open socket in other env dev */
1331 if (sigma_ctrl_sock) {
1332 env_str = getenv("SOCK");
1333 if (env_str) {
1334 sigma_dut_print(&sigma_dut, DUT_MSG_INFO,
1335 "SOCK=%s", env_str);
1336 }
1337 snprintf(buf, sizeof(buf), "SOCK=%s", sigma_ctrl_sock);
1338 if (putenv(buf) != 0) {
1339 sigma_dut_print(&sigma_dut, DUT_MSG_ERROR,
1340 "putenv() failed setting SOCK");
1341 return EXIT_FAILURE;
1342 }
1343 }
1344#endif /* __QNXNTO__ */
1345
1346 if (open_socket(&sigma_dut, port) < 0)
1347 return -1;
1348
1349#ifdef __QNXNTO__
1350 /* restore back the SOCK */
1351 if (sigma_ctrl_sock) {
1352 if (env_str) {
1353 snprintf(buf, sizeof(buf), "SOCK=%s", env_str);
1354 if (putenv(buf) != 0) {
1355 sigma_dut_print(&sigma_dut, DUT_MSG_ERROR,
1356 "putenv() failed setting SOCK");
1357 return EXIT_FAILURE;
1358 }
1359 } else {
1360 /* unset the env for sock */
1361 unsetenv("SOCK");
1362 }
1363 }
1364#endif /* __QNXNTO__ */
1365
1366 if (daemonize) {
1367 if (daemon(0, 0) < 0) {
1368 perror("daemon");
1369 exit(-1);
1370 }
1371 } else {
1372#ifdef __linux__
1373 setlinebuf(stdout);
1374#endif /* __linux__ */
1375 }
1376
Purushottam Kushwaha091e2532016-08-23 11:52:21 +05301377 if (internal_dhcp_enabled)
1378 p2p_create_event_thread(&sigma_dut);
1379
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001380 run_loop(&sigma_dut);
1381
1382#ifdef CONFIG_SNIFFER
1383 sniffer_close(&sigma_dut);
1384#endif /* CONFIG_SNIFFER */
1385
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001386 close_socket(&sigma_dut);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07001387#ifdef MIRACAST
1388 miracast_deinit(&sigma_dut);
1389#endif /* MIRACAST */
Jouni Malinen829b7de2019-11-04 16:39:55 +02001390 deinit_sigma_dut(&sigma_dut);
Peng Xu291d97d2018-01-31 16:34:03 -08001391#ifdef NL80211_SUPPORT
1392 nl80211_deinit(&sigma_dut, sigma_dut.nl_ctx);
1393#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001394 sigma_dut_unreg_cmds(&sigma_dut);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301395#ifdef ANDROID
1396 hlp_thread_cleanup(&sigma_dut);
1397#endif /* ANDROID */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001398
1399 return 0;
1400}