blob: 642a3b40c43f6fa65b88519d3c07b03a4cc8f248 [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.
4 * Copyright (c) 2011-2015, Qualcomm Atheros, Inc.
5 * All Rights Reserved.
6 * Licensed under the Clear BSD license. See README for more details.
7 */
8
9#include "sigma_dut.h"
10#include <sys/ioctl.h>
11#include <sys/stat.h>
12#ifdef __linux__
13#include <sys/time.h>
14#include <netpacket/packet.h>
15#include <linux/if_ether.h>
16#ifdef ANDROID
17#include <cutils/properties.h>
18#include <android/log.h>
19#include "keystore_get.h"
20#else /* ANDROID */
21#include <ifaddrs.h>
22#endif /* ANDROID */
23#include <netdb.h>
24#endif /* __linux__ */
25#ifdef __QNXNTO__
26#include <net/if_dl.h>
27#endif /* __QNXNTO__ */
28#include "wpa_ctrl.h"
29#include "wpa_helpers.h"
30
31/* Temporary files for sta_send_addba */
32#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
33#define VI_QOS_FILE "/tmp/vi-qos.txt"
34#define VI_QOS_REFFILE "/etc/vi-qos.txt"
35
36/*
37 * MTU for Ethernet need to take into account 8-byte SNAP header
38 * to be added when encapsulating Ethernet frame into 802.11
39 */
40#ifndef IEEE80211_MAX_DATA_LEN_DMG
41#define IEEE80211_MAX_DATA_LEN_DMG 7920
42#endif
43#ifndef IEEE80211_SNAP_LEN_DMG
44#define IEEE80211_SNAP_LEN_DMG 8
45#endif
46
47extern char *sigma_wpas_ctrl;
48extern char *sigma_cert_path;
49extern enum driver_type wifi_chip_type;
50extern char *sigma_radio_ifname[];
51
52
53#ifdef ANDROID
54
55static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
56
57#define ANDROID_KEYSTORE_GET 'g'
58#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
59
60static int android_keystore_get(char cmd, const char *key, unsigned char *val)
61{
62#ifdef ANDROID43
63 /* Android 4.3 changed keystore design, so need to use keystore_get() */
64#ifndef KEYSTORE_MESSAGE_SIZE
65#define KEYSTORE_MESSAGE_SIZE 65535
66#endif /* KEYSTORE_MESSAGE_SIZE */
67
68 ssize_t len;
69 uint8_t *value = NULL;
70
71 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
72 "keystore command '%c' key '%s' --> keystore_get",
73 cmd, key);
74
75 len = keystore_get(key, strlen(key), &value);
76 if (len < 0) {
77 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
78 "keystore_get() failed");
79 return -1;
80 }
81
82 if (len > KEYSTORE_MESSAGE_SIZE)
83 len = KEYSTORE_MESSAGE_SIZE;
84 memcpy(val, value, len);
85 free(value);
86 return len;
87#else /* ANDROID43 */
88 int s, res, reslen = -1, received;
89 size_t keylen;
90 unsigned char hdr[3];
91
92 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
93 "keystore command '%c' key '%s'", cmd, key);
94 keylen = strlen(key);
95 if (keylen > KEYSTORE_MESSAGE_SIZE)
96 return -1;
97
98 s = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
99 SOCK_STREAM);
100 if (s < 0) {
101 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
102 "could not connect to keystore");
103 return -1;
104 }
105
106 hdr[0] = cmd;
107 hdr[1] = keylen >> 8;
108 hdr[2] = keylen & 0xff;
109
110 if (send(s, hdr, sizeof(hdr), MSG_NOSIGNAL) != sizeof(hdr) ||
111 send(s, key, keylen, MSG_NOSIGNAL) != (int) keylen ||
112 shutdown(s, SHUT_WR) != 0) {
113 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
114 "could not send keystore command");
115 goto fail;
116 }
117
118 if (recv(s, hdr, 1, 0) != 1)
119 goto fail;
120 if (hdr[0] != 1) {
121 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
122 "unexpected keystore response %u", hdr[0]);
123 goto fail;
124 }
125 if (recv(s, hdr + 1, 2, 0) != 2)
126 goto fail;
127 reslen = hdr[1] * 256 + hdr[2];
128 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
129 "keystore response length %d", reslen);
130 if (reslen > KEYSTORE_MESSAGE_SIZE) {
131 reslen = -1;
132 goto fail;
133 }
134
135 received = 0;
136 while (received < reslen) {
137 res = recv(s, val + received, reslen - received, 0);
138 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
139 "keystore recv -> %d", res);
140 if (res <= 0) {
141 reslen = -1;
142 break;
143 }
144 received += res;
145 }
146
147fail:
148 close(s);
149 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
150 "keystore get -> %d", reslen);
151 return reslen;
152#endif /* ANDROID43 */
153}
154#endif /* ANDROID */
155
156
157int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
158{
159#ifdef __linux__
160 char buf[100];
161
162 if (wifi_chip_type == DRIVER_WCN) {
163 if (enabled) {
164 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 906");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530165 if (system(buf) != 0)
166 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200167 } else {
168 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 905");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530169 if (system(buf) != 0)
170 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200171 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 912");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530172 if (system(buf) != 0)
173 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200174 }
175
176 return 0;
177 }
178
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530179set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200180 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
181 intf, enabled ? "on" : "off");
182 if (system(buf) != 0) {
183 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
184 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530185 if (system(buf) != 0) {
186 sigma_dut_print(dut, DUT_MSG_ERROR,
187 "Failed to set power save %s",
188 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200189 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530190 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200191 }
192
193 return 0;
194#else /* __linux__ */
195 return -1;
196#endif /* __linux__ */
197}
198
199
200static void static_ip_file(int proto, const char *addr, const char *mask,
201 const char *gw)
202{
203 if (proto) {
204 FILE *f = fopen("static-ip", "w");
205 if (f) {
206 fprintf(f, "%d %s %s %s\n", proto, addr,
207 mask ? mask : "N/A",
208 gw ? gw : "N/A");
209 fclose(f);
210 }
211 } else {
212 unlink("static-ip");
213 }
214}
215
216
217static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
218 const char *ssid)
219{
220#ifdef __linux__
221 char buf[100];
222
223 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
224 intf, ssid);
225 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
226
227 if (system(buf) != 0) {
228 sigma_dut_print(dut, DUT_MSG_ERROR,
229 "iwpriv neighbor request failed");
230 return -1;
231 }
232
233 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
234
235 return 0;
236#else /* __linux__ */
237 return -1;
238#endif /* __linux__ */
239}
240
241
242static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
243 const char *ssid)
244{
245 /*
246 * In the earlier builds we used WNM_QUERY and in later
247 * builds used WNM_BSS_QUERY.
248 */
249
250 if (wpa_command(intf, "WNM_BSS_QUERY 0") != 0) {
251 sigma_dut_print(dut, DUT_MSG_ERROR,
252 "transition management query failed");
253 return -1;
254 }
255
256 sigma_dut_print(dut, DUT_MSG_DEBUG,
257 "transition management query sent");
258
259 return 0;
260}
261
262
263int is_ip_addr(const char *str)
264{
265 const char *pos = str;
266 struct in_addr addr;
267
268 while (*pos) {
269 if (*pos != '.' && (*pos < '0' || *pos > '9'))
270 return 0;
271 pos++;
272 }
273
274 return inet_aton(str, &addr);
275}
276
277
278int is_ipv6_addr(const char *str)
279{
280 struct sockaddr_in6 addr;
281
282 return inet_pton(AF_INET6, str, &(addr.sin6_addr));
283}
284
285
286int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
287 size_t buf_len)
288{
289 char tmp[256], *pos, *pos2;
290 FILE *f;
291 char ip[16], mask[15], dns[16], sec_dns[16];
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530292 const char *str_ps;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200293 int is_dhcp = 0;
294 int s;
295#ifdef ANDROID
296 char prop[PROPERTY_VALUE_MAX];
297#endif /* ANDROID */
298
299 ip[0] = '\0';
300 mask[0] = '\0';
301 dns[0] = '\0';
302 sec_dns[0] = '\0';
303
304 s = socket(PF_INET, SOCK_DGRAM, 0);
305 if (s >= 0) {
306 struct ifreq ifr;
307 struct sockaddr_in saddr;
308
309 memset(&ifr, 0, sizeof(ifr));
310 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
311 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
312 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
313 "%s IP address: %s",
314 ifname, strerror(errno));
315 } else {
316 memcpy(&saddr, &ifr.ifr_addr,
317 sizeof(struct sockaddr_in));
318 strncpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
319 }
320
321 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
322 memcpy(&saddr, &ifr.ifr_addr,
323 sizeof(struct sockaddr_in));
324 strncpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
325 }
326 close(s);
327 }
328
329#ifdef ANDROID
330 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
331 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
332 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
333 if (property_get(tmp, prop, NULL) != 0 &&
334 strcmp(prop, "ok") == 0) {
335 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
336 ifname);
337 if (property_get(tmp, prop, NULL) != 0 &&
338 strcmp(ip, prop) == 0)
339 is_dhcp = 1;
340 }
341 }
342
343 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
344 if (property_get(tmp, prop, NULL) != 0) {
345 strncpy(dns, prop, sizeof(dns));
346 dns[sizeof(dns) - 1] = '\0';
347 } else {
348 if (property_get("net.dns1", prop, NULL) != 0) {
349 strncpy(dns, prop, sizeof(dns));
350 dns[sizeof(dns) - 1] = '\0';
351 }
352 }
353
354 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
355 if (property_get(tmp, prop, NULL) != 0) {
356 strncpy(sec_dns, prop, sizeof(sec_dns));
357 sec_dns[sizeof(sec_dns) - 1] = '\0';
358 }
359#else /* ANDROID */
360#ifdef __linux__
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530361 if (get_driver_type() == DRIVER_OPENWRT)
362 str_ps = "ps -w";
363 else
364 str_ps = "ps ax";
365 snprintf(tmp, sizeof(tmp),
366 "%s | grep dhclient | grep -v grep | grep -q %s",
367 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200368 if (system(tmp) == 0)
369 is_dhcp = 1;
370 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530371 snprintf(tmp, sizeof(tmp),
372 "%s | grep udhcpc | grep -v grep | grep -q %s",
373 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200374 if (system(tmp) == 0)
375 is_dhcp = 1;
376 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530377 snprintf(tmp, sizeof(tmp),
378 "%s | grep dhcpcd | grep -v grep | grep -q %s",
379 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200380 if (system(tmp) == 0)
381 is_dhcp = 1;
382 }
383 }
384#endif /* __linux__ */
385
386 f = fopen("/etc/resolv.conf", "r");
387 if (f) {
388 while (fgets(tmp, sizeof(tmp), f)) {
389 if (strncmp(tmp, "nameserver", 10) != 0)
390 continue;
391 pos = tmp + 10;
392 while (*pos == ' ' || *pos == '\t')
393 pos++;
394 pos2 = pos;
395 while (*pos2) {
396 if (*pos2 == '\n' || *pos2 == '\r') {
397 *pos2 = '\0';
398 break;
399 }
400 pos2++;
401 }
402 if (!dns[0]) {
403 strncpy(dns, pos, sizeof(dns));
404 dns[sizeof(dns) - 1] = '\0';
405 } else if (!sec_dns[0]) {
406 strncpy(sec_dns, pos, sizeof(sec_dns));
407 sec_dns[sizeof(sec_dns) - 1] = '\0';
408 }
409 }
410 fclose(f);
411 }
412#endif /* ANDROID */
413
414 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
415 is_dhcp, ip, mask, dns);
416 buf[buf_len - 1] = '\0';
417
418 return 0;
419}
420
421
422
423
424int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
425 size_t buf_len)
426{
427#ifdef __linux__
428#ifdef ANDROID
429 char cmd[200], result[1000], *pos, *end;
430 FILE *f;
431 size_t len;
432
433 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
434 f = popen(cmd, "r");
435 if (f == NULL)
436 return -1;
437 len = fread(result, 1, sizeof(result) - 1, f);
438 pclose(f);
439 if (len == 0)
440 return -1;
441 result[len] = '\0';
442 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
443
444 pos = strstr(result, "inet6 ");
445 if (pos == NULL)
446 return -1;
447 pos += 6;
448 end = strchr(pos, ' ');
449 if (end)
450 *end = '\0';
451 end = strchr(pos, '/');
452 if (end)
453 *end = '\0';
454 snprintf(buf, buf_len, "ip,%s", pos);
455 buf[buf_len - 1] = '\0';
456 return 0;
457#else /* ANDROID */
458 struct ifaddrs *ifaddr, *ifa;
459 int res, found = 0;
460 char host[NI_MAXHOST];
461
462 if (getifaddrs(&ifaddr) < 0) {
463 perror("getifaddrs");
464 return -1;
465 }
466
467 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
468 if (strcasecmp(ifname, ifa->ifa_name) != 0)
469 continue;
470 if (ifa->ifa_addr == NULL ||
471 ifa->ifa_addr->sa_family != AF_INET6)
472 continue;
473
474 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
475 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
476 if (res != 0) {
477 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
478 gai_strerror(res));
479 continue;
480 }
481 if (strncmp(host, "fe80::", 6) == 0)
482 continue; /* skip link-local */
483
484 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
485 found = 1;
486 break;
487 }
488
489 freeifaddrs(ifaddr);
490
491 if (found) {
492 char *pos;
493 pos = strchr(host, '%');
494 if (pos)
495 *pos = '\0';
496 snprintf(buf, buf_len, "ip,%s", host);
497 buf[buf_len - 1] = '\0';
498 return 0;
499 }
500
501#endif /* ANDROID */
502#endif /* __linux__ */
503 return -1;
504}
505
506
507static int cmd_sta_get_ip_config(struct sigma_dut *dut,
508 struct sigma_conn *conn,
509 struct sigma_cmd *cmd)
510{
511 const char *intf = get_param(cmd, "Interface");
512 const char *ifname;
513 char buf[200];
514 const char *val;
515 int type = 1;
516
517 if (intf == NULL)
518 return -1;
519
520 if (strcmp(intf, get_main_ifname()) == 0)
521 ifname = get_station_ifname();
522 else
523 ifname = intf;
524
525 /*
526 * UCC may assume the IP address to be available immediately after
527 * association without trying to run sta_get_ip_config multiple times.
528 * Sigma CAPI does not specify this command as a block command that
529 * would wait for the address to become available, but to pass tests
530 * more reliably, it looks like such a wait may be needed here.
531 */
532 if (wait_ip_addr(dut, ifname, 15) < 0) {
533 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
534 "for sta_get_ip_config");
535 /*
536 * Try to continue anyway since many UCC tests do not really
537 * care about the return value from here..
538 */
539 }
540
541 val = get_param(cmd, "Type");
542 if (val)
543 type = atoi(val);
544 if (type == 2 || dut->last_set_ip_config_ipv6) {
545 int i;
546
547 /*
548 * Since we do not have proper wait for IPv6 addresses, use a
549 * fixed two second delay here as a workaround for UCC script
550 * assuming IPv6 address is available when this command returns.
551 * Some scripts did not use Type,2 properly for IPv6, so include
552 * also the cases where the previous sta_set_ip_config indicated
553 * use of IPv6.
554 */
555 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
556 for (i = 0; i < 10; i++) {
557 sleep(1);
558 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
559 {
560 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
561 send_resp(dut, conn, SIGMA_COMPLETE, buf);
562#ifdef ANDROID
563 sigma_dut_print(dut, DUT_MSG_INFO,
564 "Adding IPv6 rule on Android");
565 add_ipv6_rule(dut, intf);
566#endif /* ANDROID */
567
568 return 0;
569 }
570 }
571 }
572 if (type == 1) {
573 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
574 return -2;
575 } else if (type == 2) {
576 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
577 return -2;
578 } else {
579 send_resp(dut, conn, SIGMA_ERROR,
580 "errorCode,Unsupported address type");
581 return 0;
582 }
583
584 send_resp(dut, conn, SIGMA_COMPLETE, buf);
585 return 0;
586}
587
588
589static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
590{
591#ifdef __linux__
592 char buf[200];
593 char path[128];
594 struct stat s;
595
596#ifdef ANDROID
597 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
598#else /* ANDROID */
599 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
600#endif /* ANDROID */
601 if (stat(path, &s) == 0) {
602 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
603 sigma_dut_print(dut, DUT_MSG_INFO,
604 "Kill previous DHCP client: %s", buf);
605 if (system(buf) != 0)
606 sigma_dut_print(dut, DUT_MSG_INFO,
607 "Failed to kill DHCP client");
608 unlink(path);
609 sleep(1);
610 } else {
611 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
612
613 if (stat(path, &s) == 0) {
614 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
615 sigma_dut_print(dut, DUT_MSG_INFO,
616 "Kill previous DHCP client: %s", buf);
617 if (system(buf) != 0)
618 sigma_dut_print(dut, DUT_MSG_INFO,
619 "Failed to kill DHCP client");
620 unlink(path);
621 sleep(1);
622 }
623 }
624#endif /* __linux__ */
625}
626
627
628static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
629{
630#ifdef __linux__
631 char buf[200];
632
633#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +0530634 if (access("/system/bin/dhcpcd", F_OK) != -1) {
635 snprintf(buf, sizeof(buf),
636 "/system/bin/dhcpcd -b %s", ifname);
637 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
638 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
639 } else {
640 sigma_dut_print(dut, DUT_MSG_ERROR,
641 "DHCP client program missing");
642 return 0;
643 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200644#else /* ANDROID */
645 snprintf(buf, sizeof(buf),
646 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
647 ifname, ifname);
648#endif /* ANDROID */
649 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
650 if (system(buf) != 0) {
651 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
652 if (system(buf) != 0) {
653 sigma_dut_print(dut, DUT_MSG_INFO,
654 "Failed to start DHCP client");
655#ifndef ANDROID
656 return -1;
657#endif /* ANDROID */
658 }
659 }
660#endif /* __linux__ */
661
662 return 0;
663}
664
665
666static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
667{
668#ifdef __linux__
669 char buf[200];
670
671 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
672 if (system(buf) != 0) {
673 sigma_dut_print(dut, DUT_MSG_INFO,
674 "Failed to clear IP addresses");
675 return -1;
676 }
677#endif /* __linux__ */
678
679 return 0;
680}
681
682
683#ifdef ANDROID
684static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
685{
686 char cmd[200], *result, *pos;
687 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530688 int tableid;
689 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200690
691 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
692 ifname);
693 fp = popen(cmd, "r");
694 if (fp == NULL)
695 return -1;
696
697 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530698 if (result == NULL) {
699 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200700 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530701 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200702
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530703 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200704 fclose(fp);
705
706 if (len == 0) {
707 free(result);
708 return -1;
709 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530710 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200711
712 pos = strstr(result, "table ");
713 if (pos == NULL) {
714 free(result);
715 return -1;
716 }
717
718 pos += strlen("table ");
719 tableid = atoi(pos);
720 if (tableid != 0) {
721 if (system("ip -6 rule del prio 22000") != 0) {
722 /* ignore any error */
723 }
724 snprintf(cmd, sizeof(cmd),
725 "ip -6 rule add from all lookup %d prio 22000",
726 tableid);
727 if (system(cmd) != 0) {
728 sigma_dut_print(dut, DUT_MSG_INFO,
729 "Failed to run %s", cmd);
730 free(result);
731 return -1;
732 }
733 } else {
734 sigma_dut_print(dut, DUT_MSG_INFO,
735 "No Valid Table Id found %s", pos);
736 free(result);
737 return -1;
738 }
739 free(result);
740
741 return 0;
742}
743#endif /* ANDROID */
744
745
746static int cmd_sta_set_ip_config(struct sigma_dut *dut,
747 struct sigma_conn *conn,
748 struct sigma_cmd *cmd)
749{
750 const char *intf = get_param(cmd, "Interface");
751 const char *ifname;
752 char buf[200];
753 const char *val, *ip, *mask, *gw;
754 int type = 1;
755
756 if (intf == NULL)
757 return -1;
758
759 if (strcmp(intf, get_main_ifname()) == 0)
760 ifname = get_station_ifname();
761 else
762 ifname = intf;
763
764 if (if_nametoindex(ifname) == 0) {
765 send_resp(dut, conn, SIGMA_ERROR,
766 "ErrorCode,Unknown interface");
767 return 0;
768 }
769
770 val = get_param(cmd, "Type");
771 if (val) {
772 type = atoi(val);
773 if (type != 1 && type != 2) {
774 send_resp(dut, conn, SIGMA_ERROR,
775 "ErrorCode,Unsupported address type");
776 return 0;
777 }
778 }
779
780 dut->last_set_ip_config_ipv6 = 0;
781
782 val = get_param(cmd, "dhcp");
783 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
784 static_ip_file(0, NULL, NULL, NULL);
785#ifdef __linux__
786 if (type == 2) {
787 dut->last_set_ip_config_ipv6 = 1;
788 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
789 "stateless address autoconfiguration");
790#ifdef ANDROID
791 /*
792 * This sleep is required as the assignment in case of
793 * Android is taking time and is done by the kernel.
794 * The subsequent ping for IPv6 is impacting HS20 test
795 * case.
796 */
797 sleep(2);
798 add_ipv6_rule(dut, intf);
799#endif /* ANDROID */
800 /* Assume this happens by default */
801 return 1;
802 }
803
804 kill_dhcp_client(dut, ifname);
805 if (start_dhcp_client(dut, ifname) < 0)
806 return -2;
807 return 1;
808#endif /* __linux__ */
809 return -2;
810 }
811
812 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +0530813 if (!ip) {
814 send_resp(dut, conn, SIGMA_INVALID,
815 "ErrorCode,Missing IP address");
816 return 0;
817 }
818
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200819 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +0530820 if (!mask) {
821 send_resp(dut, conn, SIGMA_INVALID,
822 "ErrorCode,Missing subnet mask");
823 return 0;
824 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200825
826 if (type == 2) {
827 int net = atoi(mask);
828
829 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
830 return -1;
831
832 if (dut->no_ip_addr_set) {
833 snprintf(buf, sizeof(buf),
834 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
835 ifname);
836 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
837 if (system(buf) != 0) {
838 sigma_dut_print(dut, DUT_MSG_DEBUG,
839 "Failed to disable IPv6 address before association");
840 }
841 } else {
842 snprintf(buf, sizeof(buf),
843 "ip -6 addr del %s/%s dev %s",
844 ip, mask, ifname);
845 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
846 if (system(buf) != 0) {
847 /*
848 * This command may fail if the address being
849 * deleted does not exist. Inaction here is
850 * intentional.
851 */
852 }
853
854 snprintf(buf, sizeof(buf),
855 "ip -6 addr add %s/%s dev %s",
856 ip, mask, ifname);
857 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
858 if (system(buf) != 0) {
859 send_resp(dut, conn, SIGMA_ERROR,
860 "ErrorCode,Failed to set IPv6 address");
861 return 0;
862 }
863 }
864
865 dut->last_set_ip_config_ipv6 = 1;
866 static_ip_file(6, ip, mask, NULL);
867 return 1;
868 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +0530869 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200870 return -1;
871 }
872
873 kill_dhcp_client(dut, ifname);
874
875 if (!dut->no_ip_addr_set) {
876 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
877 ifname, ip, mask);
878 if (system(buf) != 0) {
879 send_resp(dut, conn, SIGMA_ERROR,
880 "ErrorCode,Failed to set IP address");
881 return 0;
882 }
883 }
884
885 gw = get_param(cmd, "defaultGateway");
886 if (gw) {
887 if (!is_ip_addr(gw))
888 return -1;
889 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
890 if (!dut->no_ip_addr_set && system(buf) != 0) {
891 snprintf(buf, sizeof(buf), "ip ro re default via %s",
892 gw);
893 if (system(buf) != 0) {
894 send_resp(dut, conn, SIGMA_ERROR,
895 "ErrorCode,Failed "
896 "to set default gateway");
897 return 0;
898 }
899 }
900 }
901
902 val = get_param(cmd, "primary-dns");
903 if (val) {
904 /* TODO */
905 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
906 "setting", val);
907 }
908
909 val = get_param(cmd, "secondary-dns");
910 if (val) {
911 /* TODO */
912 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
913 "setting", val);
914 }
915
916 static_ip_file(4, ip, mask, gw);
917
918 return 1;
919}
920
921
922static int cmd_sta_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
923 struct sigma_cmd *cmd)
924{
925 /* const char *intf = get_param(cmd, "Interface"); */
926 /* TODO: could report more details here */
927 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
928 return 0;
929}
930
931
932static int cmd_sta_get_mac_address(struct sigma_dut *dut,
933 struct sigma_conn *conn,
934 struct sigma_cmd *cmd)
935{
936 /* const char *intf = get_param(cmd, "Interface"); */
937 char addr[20], resp[50];
938
939 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
940 < 0)
941 return -2;
942
943 snprintf(resp, sizeof(resp), "mac,%s", addr);
944 send_resp(dut, conn, SIGMA_COMPLETE, resp);
945 return 0;
946}
947
948
949static int cmd_sta_is_connected(struct sigma_dut *dut, struct sigma_conn *conn,
950 struct sigma_cmd *cmd)
951{
952 /* const char *intf = get_param(cmd, "Interface"); */
953 int connected = 0;
954 char result[32];
955 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
956 sizeof(result)) < 0) {
957 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get interface "
958 "%s status", get_station_ifname());
959 return -2;
960 }
961
962 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
963 if (strncmp(result, "COMPLETED", 9) == 0)
964 connected = 1;
965
966 if (connected)
967 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
968 else
969 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
970
971 return 0;
972}
973
974
975static int cmd_sta_verify_ip_connection(struct sigma_dut *dut,
976 struct sigma_conn *conn,
977 struct sigma_cmd *cmd)
978{
979 /* const char *intf = get_param(cmd, "Interface"); */
980 const char *dst, *timeout;
981 int wait_time = 90;
982 char buf[100];
983 int res;
984
985 dst = get_param(cmd, "destination");
986 if (dst == NULL || !is_ip_addr(dst))
987 return -1;
988
989 timeout = get_param(cmd, "timeout");
990 if (timeout) {
991 wait_time = atoi(timeout);
992 if (wait_time < 1)
993 wait_time = 1;
994 }
995
996 /* TODO: force renewal of IP lease if DHCP is enabled */
997
998 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
999 res = system(buf);
1000 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1001 if (res == 0)
1002 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1003 else if (res == 256)
1004 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1005 else
1006 return -2;
1007
1008 return 0;
1009}
1010
1011
1012static int cmd_sta_get_bssid(struct sigma_dut *dut, struct sigma_conn *conn,
1013 struct sigma_cmd *cmd)
1014{
1015 /* const char *intf = get_param(cmd, "Interface"); */
1016 char bssid[20], resp[50];
1017
1018 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
1019 < 0)
1020 strncpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
1021
1022 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1023 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1024 return 0;
1025}
1026
1027
1028#ifdef __SAMSUNG__
1029static int add_use_network(const char *ifname)
1030{
1031 char buf[100];
1032
1033 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1034 wpa_command(ifname, buf);
1035 return 0;
1036}
1037#endif /* __SAMSUNG__ */
1038
1039
1040static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1041 const char *ifname, struct sigma_cmd *cmd)
1042{
1043 const char *ssid = get_param(cmd, "ssid");
1044 int id;
1045 const char *val;
1046
1047 if (ssid == NULL)
1048 return -1;
1049
1050 start_sta_mode(dut);
1051
1052#ifdef __SAMSUNG__
1053 add_use_network(ifname);
1054#endif /* __SAMSUNG__ */
1055
1056 id = add_network(ifname);
1057 if (id < 0)
1058 return -2;
1059 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1060
1061 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1062 return -2;
1063
1064 dut->infra_network_id = id;
1065 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1066
1067 val = get_param(cmd, "program");
1068 if (!val)
1069 val = get_param(cmd, "prog");
1070 if (val && strcasecmp(val, "hs2") == 0) {
1071 char buf[100];
1072 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1073 wpa_command(ifname, buf);
1074
1075 val = get_param(cmd, "prefer");
1076 if (val && atoi(val) > 0)
1077 set_network(ifname, id, "priority", "1");
1078 }
1079
1080 return id;
1081}
1082
1083
1084static int cmd_sta_set_encryption(struct sigma_dut *dut,
1085 struct sigma_conn *conn,
1086 struct sigma_cmd *cmd)
1087{
1088 const char *intf = get_param(cmd, "Interface");
1089 const char *ssid = get_param(cmd, "ssid");
1090 const char *type = get_param(cmd, "encpType");
1091 const char *ifname;
1092 char buf[200];
1093 int id;
1094
1095 if (intf == NULL || ssid == NULL)
1096 return -1;
1097
1098 if (strcmp(intf, get_main_ifname()) == 0)
1099 ifname = get_station_ifname();
1100 else
1101 ifname = intf;
1102
1103 id = add_network_common(dut, conn, ifname, cmd);
1104 if (id < 0)
1105 return id;
1106
1107 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1108 return -2;
1109
1110 if (type && strcasecmp(type, "wep") == 0) {
1111 const char *val;
1112 int i;
1113
1114 val = get_param(cmd, "activeKey");
1115 if (val) {
1116 int keyid;
1117 keyid = atoi(val);
1118 if (keyid < 1 || keyid > 4)
1119 return -1;
1120 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1121 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1122 return -2;
1123 }
1124
1125 for (i = 0; i < 4; i++) {
1126 snprintf(buf, sizeof(buf), "key%d", i + 1);
1127 val = get_param(cmd, buf);
1128 if (val == NULL)
1129 continue;
1130 snprintf(buf, sizeof(buf), "wep_key%d", i);
1131 if (set_network(ifname, id, buf, val) < 0)
1132 return -2;
1133 }
1134 }
1135
1136 return 1;
1137}
1138
1139
1140static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1141 const char *ifname, struct sigma_cmd *cmd)
1142{
1143 const char *val;
1144 int id;
1145
1146 id = add_network_common(dut, conn, ifname, cmd);
1147 if (id < 0)
1148 return id;
1149
1150 val = get_param(cmd, "keyMgmtType");
1151 if (val == NULL) {
1152 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Missing keyMgmtType");
1153 return 0;
1154 }
1155 if (strcasecmp(val, "wpa") == 0 ||
1156 strcasecmp(val, "wpa-psk") == 0) {
1157 if (set_network(ifname, id, "proto", "WPA") < 0)
1158 return -2;
1159 } else if (strcasecmp(val, "wpa2") == 0 ||
1160 strcasecmp(val, "wpa2-psk") == 0 ||
1161 strcasecmp(val, "wpa2-ft") == 0 ||
1162 strcasecmp(val, "wpa2-sha256") == 0) {
1163 if (set_network(ifname, id, "proto", "WPA2") < 0)
1164 return -2;
1165 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0) {
1166 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1167 return -2;
1168 } else {
1169 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1170 return 0;
1171 }
1172
1173 val = get_param(cmd, "encpType");
1174 if (val == NULL) {
1175 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Missing encpType");
1176 return 0;
1177 }
1178 if (strcasecmp(val, "tkip") == 0) {
1179 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1180 return -2;
1181 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1182 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1183 return -2;
1184 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1185 if (set_network(ifname, id, "pairwise", "CCMP TKIP") < 0)
1186 return -2;
1187 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1188 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1189 return -2;
1190 if (set_network(ifname, id, "group", "GCMP") < 0)
1191 return -2;
1192 } else {
1193 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized encpType value");
1194 return 0;
1195 }
1196
1197 dut->sta_pmf = STA_PMF_DISABLED;
1198 val = get_param(cmd, "PMF");
1199 if (val) {
1200 if (strcasecmp(val, "Required") == 0 ||
1201 strcasecmp(val, "Forced_Required") == 0) {
1202 dut->sta_pmf = STA_PMF_REQUIRED;
1203 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1204 return -2;
1205 } else if (strcasecmp(val, "Optional") == 0) {
1206 dut->sta_pmf = STA_PMF_OPTIONAL;
1207 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1208 return -2;
1209 } else if (strcasecmp(val, "Disabled") == 0 ||
1210 strcasecmp(val, "Forced_Disabled") == 0) {
1211 dut->sta_pmf = STA_PMF_DISABLED;
1212 } else {
1213 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
1214 return 0;
1215 }
1216 }
1217
1218 return id;
1219}
1220
1221
1222static int cmd_sta_set_psk(struct sigma_dut *dut, struct sigma_conn *conn,
1223 struct sigma_cmd *cmd)
1224{
1225 const char *intf = get_param(cmd, "Interface");
1226 const char *ifname, *val, *alg;
1227 int id;
1228
1229 if (intf == NULL)
1230 return -1;
1231
1232 if (strcmp(intf, get_main_ifname()) == 0)
1233 ifname = get_station_ifname();
1234 else
1235 ifname = intf;
1236
1237 id = set_wpa_common(dut, conn, ifname, cmd);
1238 if (id < 0)
1239 return id;
1240
1241 val = get_param(cmd, "keyMgmtType");
1242 alg = get_param(cmd, "micAlg");
1243
1244 if (alg && strcasecmp(alg, "SHA-256") == 0) {
1245 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
1246 return -2;
1247 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1248 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1249 return -2;
1250 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1251 dut->sta_pmf == STA_PMF_REQUIRED) {
1252 if (set_network(ifname, id, "key_mgmt",
1253 "WPA-PSK WPA-PSK-SHA256") < 0)
1254 return -2;
1255 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1256 if (set_network(ifname, id, "key_mgmt",
1257 "WPA-PSK WPA-PSK-SHA256") < 0)
1258 return -2;
1259 } else {
1260 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1261 return -2;
1262 }
1263
1264 val = get_param(cmd, "passPhrase");
1265 if (val == NULL)
1266 return -1;
1267 if (set_network_quoted(ifname, id, "psk", val) < 0)
1268 return -2;
1269
1270 return 1;
1271}
1272
1273
1274static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301275 const char *ifname, int username_identity,
1276 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001277{
1278 const char *val, *alg;
1279 int id;
1280 char buf[200];
1281#ifdef ANDROID
1282 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1283 int length;
1284#endif /* ANDROID */
1285
1286 id = set_wpa_common(dut, conn, ifname, cmd);
1287 if (id < 0)
1288 return id;
1289
1290 val = get_param(cmd, "keyMgmtType");
1291 alg = get_param(cmd, "micAlg");
1292
1293 if (alg && strcasecmp(alg, "SHA-256") == 0) {
1294 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
1295 return -2;
1296 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1297 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1298 return -2;
1299 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1300 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
1301 return -2;
1302 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1303 dut->sta_pmf == STA_PMF_REQUIRED) {
1304 if (set_network(ifname, id, "key_mgmt",
1305 "WPA-EAP WPA-EAP-SHA256") < 0)
1306 return -2;
1307 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1308 if (set_network(ifname, id, "key_mgmt",
1309 "WPA-EAP WPA-EAP-SHA256") < 0)
1310 return -2;
1311 } else {
1312 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1313 return -2;
1314 }
1315
1316 val = get_param(cmd, "trustedRootCA");
1317 if (val) {
1318#ifdef ANDROID
1319 snprintf(buf, sizeof(buf), "CACERT_%s", val);
1320 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf,
1321 kvalue);
1322 if (length > 0) {
1323 sigma_dut_print(dut, DUT_MSG_INFO,
1324 "Use Android keystore [%s]", buf);
1325 snprintf(buf, sizeof(buf), "keystore://CACERT_%s",
1326 val);
1327 goto ca_cert_selected;
1328 }
1329#endif /* ANDROID */
1330
1331 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1332#ifdef __linux__
1333 if (!file_exists(buf)) {
1334 char msg[300];
1335 snprintf(msg, sizeof(msg), "ErrorCode,trustedRootCA "
1336 "file (%s) not found", buf);
1337 send_resp(dut, conn, SIGMA_ERROR, msg);
1338 return -3;
1339 }
1340#endif /* __linux__ */
1341#ifdef ANDROID
1342ca_cert_selected:
1343#endif /* ANDROID */
1344 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
1345 return -2;
1346 }
1347
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301348 if (username_identity) {
1349 val = get_param(cmd, "username");
1350 if (val) {
1351 if (set_network_quoted(ifname, id, "identity", val) < 0)
1352 return -2;
1353 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001354
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301355 val = get_param(cmd, "password");
1356 if (val) {
1357 if (set_network_quoted(ifname, id, "password", val) < 0)
1358 return -2;
1359 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001360 }
1361
1362 return id;
1363}
1364
1365
1366static int cmd_sta_set_eaptls(struct sigma_dut *dut, struct sigma_conn *conn,
1367 struct sigma_cmd *cmd)
1368{
1369 const char *intf = get_param(cmd, "Interface");
1370 const char *ifname, *val;
1371 int id;
1372 char buf[200];
1373#ifdef ANDROID
1374 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1375 int length;
1376 int jb_or_newer = 0;
1377 char prop[PROPERTY_VALUE_MAX];
1378#endif /* ANDROID */
1379
1380 if (intf == NULL)
1381 return -1;
1382
1383 if (strcmp(intf, get_main_ifname()) == 0)
1384 ifname = get_station_ifname();
1385 else
1386 ifname = intf;
1387
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301388 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001389 if (id < 0)
1390 return id;
1391
1392 if (set_network(ifname, id, "eap", "TLS") < 0)
1393 return -2;
1394
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05301395 if (!get_param(cmd, "username") &&
1396 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001397 "wifi-user@wifilabs.local") < 0)
1398 return -2;
1399
1400 val = get_param(cmd, "clientCertificate");
1401 if (val == NULL)
1402 return -1;
1403#ifdef ANDROID
1404 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1405 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
1406 if (length < 0) {
1407 /*
1408 * JB started reporting keystore type mismatches, so retry with
1409 * the GET_PUBKEY command if the generic GET fails.
1410 */
1411 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
1412 buf, kvalue);
1413 }
1414
1415 if (property_get("ro.build.version.release", prop, NULL) != 0) {
1416 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
1417 if (strncmp(prop, "4.0", 3) != 0)
1418 jb_or_newer = 1;
1419 } else
1420 jb_or_newer = 1; /* assume newer */
1421
1422 if (jb_or_newer && length > 0) {
1423 sigma_dut_print(dut, DUT_MSG_INFO,
1424 "Use Android keystore [%s]", buf);
1425 if (set_network(ifname, id, "engine", "1") < 0)
1426 return -2;
1427 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
1428 return -2;
1429 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1430 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
1431 return -2;
1432 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
1433 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1434 return -2;
1435 return 1;
1436 } else if (length > 0) {
1437 sigma_dut_print(dut, DUT_MSG_INFO,
1438 "Use Android keystore [%s]", buf);
1439 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
1440 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
1441 return -2;
1442 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
1443 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1444 return -2;
1445 return 1;
1446 }
1447#endif /* ANDROID */
1448
1449 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1450#ifdef __linux__
1451 if (!file_exists(buf)) {
1452 char msg[300];
1453 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
1454 "(%s) not found", buf);
1455 send_resp(dut, conn, SIGMA_ERROR, msg);
1456 return -3;
1457 }
1458#endif /* __linux__ */
1459 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
1460 return -2;
1461 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1462 return -2;
1463
1464 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
1465 return -2;
1466
1467 return 1;
1468}
1469
1470
1471static int cmd_sta_set_eapttls(struct sigma_dut *dut, struct sigma_conn *conn,
1472 struct sigma_cmd *cmd)
1473{
1474 const char *intf = get_param(cmd, "Interface");
1475 const char *ifname;
1476 int id;
1477
1478 if (intf == NULL)
1479 return -1;
1480
1481 if (strcmp(intf, get_main_ifname()) == 0)
1482 ifname = get_station_ifname();
1483 else
1484 ifname = intf;
1485
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301486 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001487 if (id < 0)
1488 return id;
1489
1490 if (set_network(ifname, id, "eap", "TTLS") < 0) {
1491 send_resp(dut, conn, SIGMA_ERROR,
1492 "errorCode,Failed to set TTLS method");
1493 return 0;
1494 }
1495
1496 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
1497 send_resp(dut, conn, SIGMA_ERROR,
1498 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
1499 return 0;
1500 }
1501
1502 return 1;
1503}
1504
1505
1506static int cmd_sta_set_eapsim(struct sigma_dut *dut, struct sigma_conn *conn,
1507 struct sigma_cmd *cmd)
1508{
1509 const char *intf = get_param(cmd, "Interface");
1510 const char *ifname;
1511 int id;
1512
1513 if (intf == NULL)
1514 return -1;
1515
1516 if (strcmp(intf, get_main_ifname()) == 0)
1517 ifname = get_station_ifname();
1518 else
1519 ifname = intf;
1520
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301521 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001522 if (id < 0)
1523 return id;
1524
1525 if (set_network(ifname, id, "eap", "SIM") < 0)
1526 return -2;
1527
1528 return 1;
1529}
1530
1531
1532static int cmd_sta_set_peap(struct sigma_dut *dut, struct sigma_conn *conn,
1533 struct sigma_cmd *cmd)
1534{
1535 const char *intf = get_param(cmd, "Interface");
1536 const char *ifname, *val;
1537 int id;
1538 char buf[100];
1539
1540 if (intf == NULL)
1541 return -1;
1542
1543 if (strcmp(intf, get_main_ifname()) == 0)
1544 ifname = get_station_ifname();
1545 else
1546 ifname = intf;
1547
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301548 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001549 if (id < 0)
1550 return id;
1551
1552 if (set_network(ifname, id, "eap", "PEAP") < 0)
1553 return -2;
1554
1555 val = get_param(cmd, "innerEAP");
1556 if (val) {
1557 if (strcasecmp(val, "MSCHAPv2") == 0) {
1558 if (set_network_quoted(ifname, id, "phase2",
1559 "auth=MSCHAPV2") < 0)
1560 return -2;
1561 } else if (strcasecmp(val, "GTC") == 0) {
1562 if (set_network_quoted(ifname, id, "phase2",
1563 "auth=GTC") < 0)
1564 return -2;
1565 } else
1566 return -1;
1567 }
1568
1569 val = get_param(cmd, "peapVersion");
1570 if (val) {
1571 int ver = atoi(val);
1572 if (ver < 0 || ver > 1)
1573 return -1;
1574 snprintf(buf, sizeof(buf), "peapver=%d", ver);
1575 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
1576 return -2;
1577 }
1578
1579 return 1;
1580}
1581
1582
1583static int cmd_sta_set_eapfast(struct sigma_dut *dut, struct sigma_conn *conn,
1584 struct sigma_cmd *cmd)
1585{
1586 const char *intf = get_param(cmd, "Interface");
1587 const char *ifname, *val;
1588 int id;
1589 char buf[100];
1590
1591 if (intf == NULL)
1592 return -1;
1593
1594 if (strcmp(intf, get_main_ifname()) == 0)
1595 ifname = get_station_ifname();
1596 else
1597 ifname = intf;
1598
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301599 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001600 if (id < 0)
1601 return id;
1602
1603 if (set_network(ifname, id, "eap", "FAST") < 0)
1604 return -2;
1605
1606 val = get_param(cmd, "innerEAP");
1607 if (val) {
1608 if (strcasecmp(val, "MSCHAPV2") == 0) {
1609 if (set_network_quoted(ifname, id, "phase2",
1610 "auth=MSCHAPV2") < 0)
1611 return -2;
1612 } else if (strcasecmp(val, "GTC") == 0) {
1613 if (set_network_quoted(ifname, id, "phase2",
1614 "auth=GTC") < 0)
1615 return -2;
1616 } else
1617 return -1;
1618 }
1619
1620 val = get_param(cmd, "validateServer");
1621 if (val) {
1622 /* TODO */
1623 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
1624 "validateServer=%s", val);
1625 }
1626
1627 val = get_param(cmd, "pacFile");
1628 if (val) {
1629 snprintf(buf, sizeof(buf), "blob://%s", val);
1630 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
1631 return -2;
1632 }
1633
1634 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
1635 0)
1636 return -2;
1637
1638 return 1;
1639}
1640
1641
1642static int cmd_sta_set_eapaka(struct sigma_dut *dut, struct sigma_conn *conn,
1643 struct sigma_cmd *cmd)
1644{
1645 const char *intf = get_param(cmd, "Interface");
1646 const char *ifname;
1647 int id;
1648
1649 if (intf == NULL)
1650 return -1;
1651
1652 if (strcmp(intf, get_main_ifname()) == 0)
1653 ifname = get_station_ifname();
1654 else
1655 ifname = intf;
1656
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301657 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001658 if (id < 0)
1659 return id;
1660
1661 if (set_network(ifname, id, "eap", "AKA") < 0)
1662 return -2;
1663
1664 return 1;
1665}
1666
1667
1668static int cmd_sta_set_eapakaprime(struct sigma_dut *dut,
1669 struct sigma_conn *conn,
1670 struct sigma_cmd *cmd)
1671{
1672 const char *intf = get_param(cmd, "Interface");
1673 const char *ifname;
1674 int id;
1675
1676 if (intf == NULL)
1677 return -1;
1678
1679 if (strcmp(intf, get_main_ifname()) == 0)
1680 ifname = get_station_ifname();
1681 else
1682 ifname = intf;
1683
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301684 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001685 if (id < 0)
1686 return id;
1687
1688 if (set_network(ifname, id, "eap", "AKA'") < 0)
1689 return -2;
1690
1691 return 1;
1692}
1693
1694
1695static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
1696 struct sigma_cmd *cmd)
1697{
1698 const char *intf = get_param(cmd, "Interface");
1699 const char *ifname;
1700 int id;
1701
1702 if (strcmp(intf, get_main_ifname()) == 0)
1703 ifname = get_station_ifname();
1704 else
1705 ifname = intf;
1706
1707 id = add_network_common(dut, conn, ifname, cmd);
1708 if (id < 0)
1709 return id;
1710
1711 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1712 return -2;
1713
1714 return 1;
1715}
1716
1717
1718static int cmd_sta_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
1719 struct sigma_cmd *cmd)
1720{
1721 const char *type = get_param(cmd, "Type");
1722
1723 if (type == NULL) {
1724 send_resp(dut, conn, SIGMA_ERROR,
1725 "ErrorCode,Missing Type argument");
1726 return 0;
1727 }
1728
1729 if (strcasecmp(type, "OPEN") == 0)
1730 return sta_set_open(dut, conn, cmd);
1731 if (strcasecmp(type, "PSK") == 0)
1732 return cmd_sta_set_psk(dut, conn, cmd);
1733 if (strcasecmp(type, "EAPTLS") == 0)
1734 return cmd_sta_set_eaptls(dut, conn, cmd);
1735 if (strcasecmp(type, "EAPTTLS") == 0)
1736 return cmd_sta_set_eapttls(dut, conn, cmd);
1737 if (strcasecmp(type, "EAPPEAP") == 0)
1738 return cmd_sta_set_peap(dut, conn, cmd);
1739 if (strcasecmp(type, "EAPSIM") == 0)
1740 return cmd_sta_set_eapsim(dut, conn, cmd);
1741 if (strcasecmp(type, "EAPFAST") == 0)
1742 return cmd_sta_set_eapfast(dut, conn, cmd);
1743 if (strcasecmp(type, "EAPAKA") == 0)
1744 return cmd_sta_set_eapaka(dut, conn, cmd);
1745 if (strcasecmp(type, "EAPAKAPRIME") == 0)
1746 return cmd_sta_set_eapakaprime(dut, conn, cmd);
1747
1748 send_resp(dut, conn, SIGMA_ERROR,
1749 "ErrorCode,Unsupported Type value");
1750 return 0;
1751}
1752
1753
1754int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
1755{
1756#ifdef __linux__
1757 /* special handling for ath6kl */
1758 char path[128], fname[128], *pos;
1759 ssize_t res;
1760 FILE *f;
1761
1762 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", intf);
1763 res = readlink(path, path, sizeof(path));
1764 if (res < 0)
1765 return 0; /* not ath6kl */
1766
1767 if (res >= (int) sizeof(path))
1768 res = sizeof(path) - 1;
1769 path[res] = '\0';
1770 pos = strrchr(path, '/');
1771 if (pos == NULL)
1772 pos = path;
1773 else
1774 pos++;
1775 snprintf(fname, sizeof(fname),
1776 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
1777 "create_qos", pos);
1778 if (!file_exists(fname))
1779 return 0; /* not ath6kl */
1780
1781 if (uapsd) {
1782 f = fopen(fname, "w");
1783 if (f == NULL)
1784 return -1;
1785
1786 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
1787 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
1788 "45000 200 56789000 56789000 5678900 0 0 9999999 "
1789 "20000 0\n");
1790 fclose(f);
1791 } else {
1792 snprintf(fname, sizeof(fname),
1793 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
1794 "delete_qos", pos);
1795
1796 f = fopen(fname, "w");
1797 if (f == NULL)
1798 return -1;
1799
1800 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
1801 fprintf(f, "2 4\n");
1802 fclose(f);
1803 }
1804#endif /* __linux__ */
1805
1806 return 0;
1807}
1808
1809
1810static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
1811 struct sigma_cmd *cmd)
1812{
1813 const char *intf = get_param(cmd, "Interface");
1814 /* const char *ssid = get_param(cmd, "ssid"); */
1815 const char *val;
1816 int max_sp_len = 4;
1817 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
1818 char buf[100];
1819 int ret1, ret2;
1820
1821 val = get_param(cmd, "maxSPLength");
1822 if (val) {
1823 max_sp_len = atoi(val);
1824 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
1825 max_sp_len != 4)
1826 return -1;
1827 }
1828
1829 val = get_param(cmd, "acBE");
1830 if (val)
1831 ac_be = atoi(val);
1832
1833 val = get_param(cmd, "acBK");
1834 if (val)
1835 ac_bk = atoi(val);
1836
1837 val = get_param(cmd, "acVI");
1838 if (val)
1839 ac_vi = atoi(val);
1840
1841 val = get_param(cmd, "acVO");
1842 if (val)
1843 ac_vo = atoi(val);
1844
1845 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
1846
1847 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
1848 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
1849 ret1 = wpa_command(intf, buf);
1850
1851 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
1852 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
1853 ret2 = wpa_command(intf, buf);
1854
1855 if (ret1 && ret2) {
1856 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
1857 "UAPSD parameters.");
1858 return -2;
1859 }
1860
1861 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
1862 send_resp(dut, conn, SIGMA_ERROR,
1863 "ErrorCode,Failed to set ath6kl QoS parameters");
1864 return 0;
1865 }
1866
1867 return 1;
1868}
1869
1870
1871static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
1872 struct sigma_cmd *cmd)
1873{
1874 char buf[1000];
1875 const char *intf = get_param(cmd, "Interface");
1876 const char *grp = get_param(cmd, "Group");
1877 const char *act = get_param(cmd, "Action");
1878 const char *tid = get_param(cmd, "Tid");
1879 const char *dir = get_param(cmd, "Direction");
1880 const char *psb = get_param(cmd, "Psb");
1881 const char *up = get_param(cmd, "Up");
1882 const char *fixed = get_param(cmd, "Fixed");
1883 const char *size = get_param(cmd, "Size");
1884 const char *msize = get_param(cmd, "Maxsize");
1885 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
1886 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
1887 const char *inact = get_param(cmd, "Inactivity");
1888 const char *sus = get_param(cmd, "Suspension");
1889 const char *mindr = get_param(cmd, "Mindatarate");
1890 const char *meandr = get_param(cmd, "Meandatarate");
1891 const char *peakdr = get_param(cmd, "Peakdatarate");
1892 const char *phyrate = get_param(cmd, "Phyrate");
1893 const char *burstsize = get_param(cmd, "Burstsize");
1894 const char *sba = get_param(cmd, "Sba");
1895 int direction;
1896 int handle;
1897 float sba_fv;
1898 int fixed_int;
1899 int psb_ts;
1900
1901 if (intf == NULL || grp == NULL || act == NULL )
1902 return -1;
1903
1904 if (strcasecmp(act, "addts") == 0) {
1905 if (tid == NULL || dir == NULL || psb == NULL ||
1906 up == NULL || fixed == NULL || size == NULL)
1907 return -1;
1908
1909 /*
1910 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
1911 * possible values, but WMM-AC and V-E test scripts use "UP,
1912 * "DOWN", and "BIDI".
1913 */
1914 if (strcasecmp(dir, "uplink") == 0 ||
1915 strcasecmp(dir, "up") == 0) {
1916 direction = 0;
1917 } else if (strcasecmp(dir, "downlink") == 0 ||
1918 strcasecmp(dir, "down") == 0) {
1919 direction = 1;
1920 } else if (strcasecmp(dir, "bidi") == 0) {
1921 direction = 2;
1922 } else {
1923 sigma_dut_print(dut, DUT_MSG_ERROR,
1924 "Direction %s not supported", dir);
1925 return -1;
1926 }
1927
1928 if (strcasecmp(psb, "legacy") == 0) {
1929 psb_ts = 0;
1930 } else if (strcasecmp(psb, "uapsd") == 0) {
1931 psb_ts = 1;
1932 } else {
1933 sigma_dut_print(dut, DUT_MSG_ERROR,
1934 "PSB %s not supported", psb);
1935 return -1;
1936 }
1937
1938 if (atoi(tid) < 0 || atoi(tid) > 7) {
1939 sigma_dut_print(dut, DUT_MSG_ERROR,
1940 "TID %s not supported", tid);
1941 return -1;
1942 }
1943
1944 if (strcasecmp(fixed, "true") == 0) {
1945 fixed_int = 1;
1946 } else {
1947 fixed_int = 0;
1948 }
1949
1950 sba_fv = atof(sba);
1951
1952 dut->dialog_token++;
1953 handle = 7000 + dut->dialog_token;
1954
1955 /*
1956 * size: convert to hex
1957 * maxsi: convert to hex
1958 * mindr: convert to hex
1959 * meandr: convert to hex
1960 * peakdr: convert to hex
1961 * burstsize: convert to hex
1962 * phyrate: convert to hex
1963 * sba: convert to hex with modification
1964 * minsi: convert to integer
1965 * sus: convert to integer
1966 * inact: convert to integer
1967 * maxsi: convert to integer
1968 */
1969
1970 /*
1971 * The Nominal MSDU Size field is 2 octets long and contains an
1972 * unsigned integer that specifies the nominal size, in octets,
1973 * of MSDUs belonging to the traffic under this traffic
1974 * specification and is defined in Figure 16. If the Fixed
1975 * subfield is set to 1, then the size of the MSDU is fixed and
1976 * is indicated by the Size Subfield. If the Fixed subfield is
1977 * set to 0, then the size of the MSDU might not be fixed and
1978 * the Size indicates the nominal MSDU size.
1979 *
1980 * The Surplus Bandwidth Allowance Factor field is 2 octets long
1981 * and specifies the excess allocation of time (and bandwidth)
1982 * over and above the stated rates required to transport an MSDU
1983 * belonging to the traffic in this TSPEC. This field is
1984 * represented as an unsigned binary number with an implicit
1985 * binary point after the leftmost 3 bits. For example, an SBA
1986 * of 1.75 is represented as 0x3800. This field is included to
1987 * account for retransmissions. As such, the value of this field
1988 * must be greater than unity.
1989 */
1990
1991 snprintf(buf, sizeof(buf),
1992 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
1993 " 0x%X 0x%X 0x%X"
1994 " 0x%X 0x%X 0x%X"
1995 " 0x%X %d %d %d %d"
1996 " %d %d",
1997 intf, handle, tid, direction, psb_ts, up,
1998 (unsigned int) ((fixed_int << 15) | atoi(size)),
1999 msize ? atoi(msize) : 0,
2000 mindr ? atoi(mindr) : 0,
2001 meandr ? atoi(meandr) : 0,
2002 peakdr ? atoi(peakdr) : 0,
2003 burstsize ? atoi(burstsize) : 0,
2004 phyrate ? atoi(phyrate) : 0,
2005 sba ? ((unsigned int) (((int) sba_fv << 13) |
2006 (int)((sba_fv - (int) sba_fv) *
2007 8192))) : 0,
2008 minsi ? atoi(minsi) : 0,
2009 sus ? atoi(sus) : 0,
2010 0, 0,
2011 inact ? atoi(inact) : 0,
2012 maxsi ? atoi(maxsi) : 0);
2013
2014 if (system(buf) != 0) {
2015 sigma_dut_print(dut, DUT_MSG_ERROR,
2016 "iwpriv addtspec request failed");
2017 send_resp(dut, conn, SIGMA_ERROR,
2018 "errorCode,Failed to execute addTspec command");
2019 return 0;
2020 }
2021
2022 sigma_dut_print(dut, DUT_MSG_INFO,
2023 "iwpriv addtspec request send");
2024
2025 /* Mapping handle to a TID */
2026 dut->tid_to_handle[atoi(tid)] = handle;
2027 } else if (strcasecmp(act, "delts") == 0) {
2028 if (tid == NULL)
2029 return -1;
2030
2031 if (atoi(tid) < 0 || atoi(tid) > 7) {
2032 sigma_dut_print(dut, DUT_MSG_ERROR,
2033 "TID %s not supported", tid);
2034 send_resp(dut, conn, SIGMA_ERROR,
2035 "errorCode,Unsupported TID");
2036 return 0;
2037 }
2038
2039 handle = dut->tid_to_handle[atoi(tid)];
2040
2041 if (handle < 7000 || handle > 7255) {
2042 /* Invalid handle ie no mapping for that TID */
2043 sigma_dut_print(dut, DUT_MSG_ERROR,
2044 "handle-> %d not found", handle);
2045 }
2046
2047 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
2048 intf, handle);
2049
2050 if (system(buf) != 0) {
2051 sigma_dut_print(dut, DUT_MSG_ERROR,
2052 "iwpriv deltspec request failed");
2053 send_resp(dut, conn, SIGMA_ERROR,
2054 "errorCode,Failed to execute delTspec command");
2055 return 0;
2056 }
2057
2058 sigma_dut_print(dut, DUT_MSG_INFO,
2059 "iwpriv deltspec request send");
2060
2061 dut->tid_to_handle[atoi(tid)] = 0;
2062 } else {
2063 sigma_dut_print(dut, DUT_MSG_ERROR,
2064 "Action type %s not supported", act);
2065 send_resp(dut, conn, SIGMA_ERROR,
2066 "errorCode,Unsupported Action");
2067 return 0;
2068 }
2069
2070 return 1;
2071}
2072
2073
2074static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
2075 struct sigma_cmd *cmd)
2076{
2077 /* const char *intf = get_param(cmd, "Interface"); */
2078 const char *ssid = get_param(cmd, "ssid");
2079 const char *wps_param = get_param(cmd, "WPS");
2080 const char *bssid = get_param(cmd, "bssid");
2081 int wps = 0;
2082 char buf[100];
2083
2084 if (ssid == NULL)
2085 return -1;
2086
2087 if (wps_param &&
2088 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
2089 wps = 1;
2090
2091 if (wps) {
2092 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
2093 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
2094 "parameters not yet set");
2095 return 0;
2096 }
2097 if (dut->wps_method == WFA_CS_WPS_PBC) {
2098 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
2099 return -2;
2100 } else {
2101 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
2102 dut->wps_pin);
2103 if (wpa_command(get_station_ifname(), buf) < 0)
2104 return -2;
2105 }
2106 } else {
2107 if (strcmp(ssid, dut->infra_ssid) != 0) {
2108 printf("No network parameters known for network "
2109 "(ssid='%s')", ssid);
2110 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2111 "No network parameters known for network");
2112 return 0;
2113 }
2114
2115 if (bssid &&
2116 set_network(get_station_ifname(), dut->infra_network_id,
2117 "bssid", bssid) < 0) {
2118 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2119 "Invalid bssid argument");
2120 return 0;
2121 }
2122
2123 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d",
2124 dut->infra_network_id);
2125 if (wpa_command(get_station_ifname(), buf) < 0) {
2126 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
2127 "network id %d on %s",
2128 dut->infra_network_id,
2129 get_station_ifname());
2130 return -2;
2131 }
2132 }
2133
2134 return 1;
2135}
2136
2137
2138static int run_hs20_osu(struct sigma_dut *dut, const char *params)
2139{
2140 char buf[500], cmd[200];
2141 int res;
2142
2143 /* Use hs20-osu-client file at the current dir, if found; otherwise use
2144 * default path */
2145 res = snprintf(cmd, sizeof(cmd),
2146 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
2147 file_exists("./hs20-osu-client") ?
2148 "./hs20-osu-client" : "hs20-osu-client",
2149 sigma_wpas_ctrl,
2150 dut->summary_log ? "-s " : "",
2151 dut->summary_log ? dut->summary_log : "");
2152 if (res < 0 || res >= (int) sizeof(cmd))
2153 return -1;
2154
2155 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
2156 if (res < 0 || res >= (int) sizeof(buf))
2157 return -1;
2158 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
2159
2160 if (system(buf) != 0) {
2161 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
2162 return -1;
2163 }
2164 sigma_dut_print(dut, DUT_MSG_DEBUG,
2165 "Completed hs20-osu-client operation");
2166
2167 return 0;
2168}
2169
2170
2171static int download_ppsmo(struct sigma_dut *dut,
2172 struct sigma_conn *conn,
2173 const char *intf,
2174 struct sigma_cmd *cmd)
2175{
2176 const char *name, *path, *val;
2177 char url[500], buf[600], fbuf[100];
2178 char *fqdn = NULL;
2179
2180 name = get_param(cmd, "FileName");
2181 path = get_param(cmd, "FilePath");
2182 if (name == NULL || path == NULL)
2183 return -1;
2184
2185 if (strcasecmp(path, "VendorSpecific") == 0) {
2186 snprintf(url, sizeof(url), "PPS/%s", name);
2187 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
2188 "from the device (%s)", url);
2189 if (!file_exists(url)) {
2190 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2191 "PPS MO file does not exist");
2192 return 0;
2193 }
2194 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
2195 if (system(buf) != 0) {
2196 send_resp(dut, conn, SIGMA_ERROR,
2197 "errorCode,Failed to copy PPS MO");
2198 return 0;
2199 }
2200 } else if (strncasecmp(path, "http:", 5) != 0 &&
2201 strncasecmp(path, "https:", 6) != 0) {
2202 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2203 "Unsupported FilePath value");
2204 return 0;
2205 } else {
2206 snprintf(url, sizeof(url), "%s/%s", path, name);
2207 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
2208 url);
2209 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
2210 remove("pps-tnds.xml");
2211 if (system(buf) != 0) {
2212 send_resp(dut, conn, SIGMA_ERROR,
2213 "errorCode,Failed to download PPS MO");
2214 return 0;
2215 }
2216 }
2217
2218 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
2219 send_resp(dut, conn, SIGMA_ERROR,
2220 "errorCode,Failed to parse downloaded PPSMO");
2221 return 0;
2222 }
2223 unlink("pps-tnds.xml");
2224
2225 val = get_param(cmd, "managementTreeURI");
2226 if (val) {
2227 const char *pos, *end;
2228 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
2229 val);
2230 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
2231 send_resp(dut, conn, SIGMA_ERROR,
2232 "errorCode,Invalid managementTreeURI prefix");
2233 return 0;
2234 }
2235 pos = val + 8;
2236 end = strchr(pos, '/');
2237 if (end == NULL ||
2238 strcmp(end, "/PerProviderSubscription") != 0) {
2239 send_resp(dut, conn, SIGMA_ERROR,
2240 "errorCode,Invalid managementTreeURI postfix");
2241 return 0;
2242 }
2243 if (end - pos >= (int) sizeof(fbuf)) {
2244 send_resp(dut, conn, SIGMA_ERROR,
2245 "errorCode,Too long FQDN in managementTreeURI");
2246 return 0;
2247 }
2248 memcpy(fbuf, pos, end - pos);
2249 fbuf[end - pos] = '\0';
2250 fqdn = fbuf;
2251 sigma_dut_print(dut, DUT_MSG_INFO,
2252 "FQDN from managementTreeURI: %s", fqdn);
2253 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
2254 FILE *f = fopen("pps-fqdn", "r");
2255 if (f) {
2256 if (fgets(fbuf, sizeof(fbuf), f)) {
2257 fbuf[sizeof(fbuf) - 1] = '\0';
2258 fqdn = fbuf;
2259 sigma_dut_print(dut, DUT_MSG_DEBUG,
2260 "Use FQDN %s", fqdn);
2261 }
2262 fclose(f);
2263 }
2264 }
2265
2266 if (fqdn == NULL) {
2267 send_resp(dut, conn, SIGMA_ERROR,
2268 "errorCode,No FQDN specified");
2269 return 0;
2270 }
2271
2272 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2273 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
2274 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2275
2276 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
2277 if (rename("pps.xml", buf) < 0) {
2278 send_resp(dut, conn, SIGMA_ERROR,
2279 "errorCode,Could not move PPS MO");
2280 return 0;
2281 }
2282
2283 if (strcasecmp(path, "VendorSpecific") == 0) {
2284 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
2285 fqdn);
2286 if (system(buf)) {
2287 send_resp(dut, conn, SIGMA_ERROR,
2288 "errorCode,Failed to copy OSU CA cert");
2289 return 0;
2290 }
2291
2292 snprintf(buf, sizeof(buf),
2293 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
2294 fqdn);
2295 if (system(buf)) {
2296 send_resp(dut, conn, SIGMA_ERROR,
2297 "errorCode,Failed to copy AAA CA cert");
2298 return 0;
2299 }
2300 } else {
2301 snprintf(buf, sizeof(buf),
2302 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
2303 fqdn, fqdn);
2304 if (run_hs20_osu(dut, buf) < 0) {
2305 send_resp(dut, conn, SIGMA_ERROR,
2306 "errorCode,Failed to download OSU CA cert");
2307 return 0;
2308 }
2309
2310 snprintf(buf, sizeof(buf),
2311 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
2312 fqdn, fqdn);
2313 if (run_hs20_osu(dut, buf) < 0) {
2314 sigma_dut_print(dut, DUT_MSG_INFO,
2315 "Failed to download AAA CA cert");
2316 }
2317 }
2318
2319 if (file_exists("next-client-cert.pem")) {
2320 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
2321 if (rename("next-client-cert.pem", buf) < 0) {
2322 send_resp(dut, conn, SIGMA_ERROR,
2323 "errorCode,Could not move client certificate");
2324 return 0;
2325 }
2326 }
2327
2328 if (file_exists("next-client-key.pem")) {
2329 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
2330 if (rename("next-client-key.pem", buf) < 0) {
2331 send_resp(dut, conn, SIGMA_ERROR,
2332 "errorCode,Could not move client key");
2333 return 0;
2334 }
2335 }
2336
2337 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
2338 if (run_hs20_osu(dut, buf) < 0) {
2339 send_resp(dut, conn, SIGMA_ERROR,
2340 "errorCode,Failed to configure credential from "
2341 "PPSMO");
2342 return 0;
2343 }
2344
2345 return 1;
2346}
2347
2348
2349static int download_cert(struct sigma_dut *dut,
2350 struct sigma_conn *conn,
2351 const char *intf,
2352 struct sigma_cmd *cmd)
2353{
2354 const char *name, *path;
2355 char url[500], buf[600];
2356
2357 name = get_param(cmd, "FileName");
2358 path = get_param(cmd, "FilePath");
2359 if (name == NULL || path == NULL)
2360 return -1;
2361
2362 if (strcasecmp(path, "VendorSpecific") == 0) {
2363 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
2364 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2365 "certificate from the device (%s)", url);
2366 if (!file_exists(url)) {
2367 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2368 "certificate file does not exist");
2369 return 0;
2370 }
2371 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
2372 if (system(buf) != 0) {
2373 send_resp(dut, conn, SIGMA_ERROR,
2374 "errorCode,Failed to copy client "
2375 "certificate");
2376 return 0;
2377 }
2378
2379 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
2380 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2381 "private key from the device (%s)", url);
2382 if (!file_exists(url)) {
2383 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2384 "private key file does not exist");
2385 return 0;
2386 }
2387 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
2388 if (system(buf) != 0) {
2389 send_resp(dut, conn, SIGMA_ERROR,
2390 "errorCode,Failed to copy client key");
2391 return 0;
2392 }
2393 } else if (strncasecmp(path, "http:", 5) != 0 &&
2394 strncasecmp(path, "https:", 6) != 0) {
2395 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2396 "Unsupported FilePath value");
2397 return 0;
2398 } else {
2399 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
2400 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
2401 "certificate/key from %s", url);
2402 snprintf(buf, sizeof(buf),
2403 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
2404 if (system(buf) != 0) {
2405 send_resp(dut, conn, SIGMA_ERROR,
2406 "errorCode,Failed to download client "
2407 "certificate");
2408 return 0;
2409 }
2410
2411 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
2412 {
2413 send_resp(dut, conn, SIGMA_ERROR,
2414 "errorCode,Failed to copy client key");
2415 return 0;
2416 }
2417 }
2418
2419 return 1;
2420}
2421
2422
2423static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
2424 struct sigma_conn *conn,
2425 const char *intf,
2426 struct sigma_cmd *cmd)
2427{
2428 const char *val;
2429
2430 val = get_param(cmd, "FileType");
2431 if (val && strcasecmp(val, "PPSMO") == 0)
2432 return download_ppsmo(dut, conn, intf, cmd);
2433 if (val && strcasecmp(val, "CERT") == 0)
2434 return download_cert(dut, conn, intf, cmd);
2435 if (val) {
2436 send_resp(dut, conn, SIGMA_ERROR,
2437 "ErrorCode,Unsupported FileType");
2438 return 0;
2439 }
2440
2441 return 1;
2442}
2443
2444
2445static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
2446 const char *val)
2447{
2448 int counter = 0;
2449 char token[50];
2450 char *result;
2451 char buf[100];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05302452 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002453
2454 strncpy(token, val, sizeof(token));
2455 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05302456 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002457 while (result) {
2458 if (strcmp(result, "disable") == 0) {
2459 snprintf(buf, sizeof(buf),
2460 "iwpriv %s noackpolicy %d 1 0",
2461 intf, counter);
2462 } else {
2463 snprintf(buf, sizeof(buf),
2464 "iwpriv %s noackpolicy %d 1 1",
2465 intf, counter);
2466 }
2467 if (system(buf) != 0) {
2468 sigma_dut_print(dut, DUT_MSG_ERROR,
2469 "iwpriv noackpolicy failed");
2470 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05302471 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002472 counter++;
2473 }
2474}
2475
2476
2477static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
2478 const char *val)
2479{
2480 char buf[100];
2481
2482 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
2483 if (system(buf) != 0) {
2484 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
2485 }
2486}
2487
2488
2489static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
2490 const char *val)
2491{
2492 char buf[100];
2493
2494 if (strcasecmp(val, "off") == 0) {
2495 snprintf(buf, sizeof(buf), "iwpriv %s wmm 0", intf);
2496 if (system(buf) != 0) {
2497 sigma_dut_print(dut, DUT_MSG_ERROR,
2498 "Failed to turn off WMM");
2499 }
2500 }
2501}
2502
2503
2504static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
2505 const char *val)
2506{
2507 char buf[100];
2508 int sgi20;
2509
2510 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
2511
2512 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi20);
2513 if (system(buf) != 0)
2514 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv shortgi failed");
2515}
2516
2517
2518static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
2519 const char *val)
2520{
2521 char buf[100];
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05302522 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002523
2524 /* Disable Tx Beam forming when using a fixed rate */
2525 ath_disable_txbf(dut, intf);
2526
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05302527 v = atoi(val);
2528 if (v < 0 || v > 32) {
2529 sigma_dut_print(dut, DUT_MSG_ERROR,
2530 "Invalid Fixed MCS rate: %d", v);
2531 return;
2532 }
2533 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002534
2535 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0x%x",
2536 intf, rate_code);
2537 if (system(buf) != 0) {
2538 sigma_dut_print(dut, DUT_MSG_ERROR,
2539 "iwpriv set11NRates failed");
2540 }
2541
2542 /* Channel width gets messed up, fix this */
2543 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d", intf, dut->chwidth);
2544 if (system(buf) != 0)
2545 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
2546}
2547
2548
2549static void ath_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
2550 const char *val)
2551{
2552 char buf[60];
2553
2554 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
2555 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
2556 else
2557 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
2558
2559 if (system(buf) != 0)
2560 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
2561}
2562
2563
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07002564static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
2565 int ampdu)
2566{
2567 char buf[60];
2568
2569 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
2570 if (system(buf) != 0) {
2571 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
2572 return -1;
2573 }
2574
2575 return 0;
2576}
2577
2578
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002579static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
2580 const char *val)
2581{
2582 char buf[60];
2583
2584 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
2585 if (system(buf) != 0) {
2586 sigma_dut_print(dut, DUT_MSG_ERROR,
2587 "iwpriv tx_stbc failed");
2588 }
2589
2590 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
2591 if (system(buf) != 0) {
2592 sigma_dut_print(dut, DUT_MSG_ERROR,
2593 "iwpriv rx_stbc failed");
2594 }
2595}
2596
2597
2598static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
2599 const char *val)
2600{
2601 char buf[60];
2602
2603 if (strcmp(val, "80") == 0) {
2604 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
2605 } else if (strcmp(val, "40") == 0) {
2606 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
2607 } else if (strcmp(val, "20") == 0) {
2608 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
2609 } else if (strcasecmp(val, "Auto") == 0) {
2610 buf[0] = '\0';
2611 } else {
2612 sigma_dut_print(dut, DUT_MSG_ERROR,
2613 "WIDTH/CTS_WIDTH value not supported");
2614 return -1;
2615 }
2616
2617 if (buf[0] != '\0' && system(buf) != 0) {
2618 sigma_dut_print(dut, DUT_MSG_ERROR,
2619 "Failed to set WIDTH/CTS_WIDTH");
2620 return -1;
2621 }
2622
2623 return 0;
2624}
2625
2626
2627int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
2628 const char *intf, const char *val)
2629{
2630 char buf[60];
2631
2632 if (strcasecmp(val, "Auto") == 0) {
2633 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
2634 dut->chwidth = 0;
2635 } else if (strcasecmp(val, "20") == 0) {
2636 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
2637 dut->chwidth = 0;
2638 } else if (strcasecmp(val, "40") == 0) {
2639 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
2640 dut->chwidth = 1;
2641 } else if (strcasecmp(val, "80") == 0) {
2642 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
2643 dut->chwidth = 2;
2644 } else if (strcasecmp(val, "160") == 0) {
2645 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 3", intf);
2646 dut->chwidth = 3;
2647 } else {
2648 send_resp(dut, conn, SIGMA_ERROR,
2649 "ErrorCode,WIDTH not supported");
2650 return -1;
2651 }
2652
2653 if (system(buf) != 0) {
2654 sigma_dut_print(dut, DUT_MSG_ERROR,
2655 "iwpriv chwidth failed");
2656 }
2657
2658 return 0;
2659}
2660
2661
2662static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
2663 const char *val)
2664{
2665 char buf[60];
2666
2667 if (strcmp(val, "1SS") == 0) {
2668 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
2669 } else if (strcmp(val, "2SS") == 0) {
2670 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
2671 } else {
2672 sigma_dut_print(dut, DUT_MSG_ERROR,
2673 "SP_STREAM value not supported");
2674 return -1;
2675 }
2676
2677 if (system(buf) != 0) {
2678 sigma_dut_print(dut, DUT_MSG_ERROR,
2679 "Failed to set SP_STREAM");
2680 return -1;
2681 }
2682
2683 return 0;
2684}
2685
2686
2687static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
2688 struct sigma_conn *conn,
2689 struct sigma_cmd *cmd)
2690{
2691 const char *intf = get_param(cmd, "Interface");
2692 const char *val;
2693
2694 val = get_param(cmd, "Program");
2695 if (val && strcasecmp(val, "HS2-R2") == 0) {
2696 if (intf == NULL)
2697 return -1;
2698 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
2699 cmd);
2700 }
2701
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07002702 if (val && strcasecmp(val, "LOC") == 0)
2703 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
2704
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002705#ifdef ANDROID_NAN
2706 if (val && strcasecmp(val, "NAN") == 0)
2707 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
2708#endif /* ANDROID_NAN */
2709
2710#if 0
2711 val = get_param(cmd, "Supplicant");
2712 if (val && strcasecmp(val, "Default") != 0) {
2713 send_resp(dut, conn, SIGMA_ERROR,
2714 "ErrorCode,Only default(Vendor) supplicant "
2715 "supported");
2716 return 0;
2717 }
2718#endif
2719
2720 val = get_param(cmd, "RTS");
2721 if (val) {
2722 switch (get_driver_type()) {
2723 case DRIVER_ATHEROS:
2724 ath_sta_set_rts(dut, intf, val);
2725 break;
2726 default:
2727#if 0
2728 send_resp(dut, conn, SIGMA_ERROR,
2729 "ErrorCode,Setting RTS not supported");
2730 return 0;
2731#else
2732 sigma_dut_print(dut, DUT_MSG_DEBUG,
2733 "Setting RTS not supported");
2734 break;
2735#endif
2736 }
2737 }
2738
2739#if 0
2740 val = get_param(cmd, "FRGMNT");
2741 if (val) {
2742 /* TODO */
2743 send_resp(dut, conn, SIGMA_ERROR,
2744 "ErrorCode,Setting FRGMNT not supported");
2745 return 0;
2746 }
2747#endif
2748
2749#if 0
2750 val = get_param(cmd, "Preamble");
2751 if (val) {
2752 /* TODO: Long/Short */
2753 send_resp(dut, conn, SIGMA_ERROR,
2754 "ErrorCode,Setting Preamble not supported");
2755 return 0;
2756 }
2757#endif
2758
2759 val = get_param(cmd, "Mode");
2760 if (val) {
2761 if (strcmp(val, "11b") == 0 ||
2762 strcmp(val, "11g") == 0 ||
2763 strcmp(val, "11a") == 0 ||
2764 strcmp(val, "11n") == 0 ||
2765 strcmp(val, "11ng") == 0 ||
2766 strcmp(val, "11nl") == 0 ||
2767 strcmp(val, "11nl(nabg)") == 0 ||
2768 strcmp(val, "AC") == 0 ||
2769 strcmp(val, "11AC") == 0 ||
2770 strcmp(val, "11ac") == 0 ||
2771 strcmp(val, "11na") == 0 ||
2772 strcmp(val, "11an") == 0) {
2773 /* STA supports all modes by default */
2774 } else {
2775 send_resp(dut, conn, SIGMA_ERROR,
2776 "ErrorCode,Setting Mode not supported");
2777 return 0;
2778 }
2779 }
2780
2781 val = get_param(cmd, "wmm");
2782 if (val) {
2783 switch (get_driver_type()) {
2784 case DRIVER_ATHEROS:
2785 ath_sta_set_wmm(dut, intf, val);
2786 break;
2787 default:
2788 sigma_dut_print(dut, DUT_MSG_DEBUG,
2789 "Setting wmm not supported");
2790 break;
2791 }
2792 }
2793
2794 val = get_param(cmd, "Powersave");
2795 if (val) {
2796 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
2797 if (wpa_command(get_station_ifname(),
2798 "P2P_SET ps 0") < 0)
2799 return -2;
2800 /* Make sure test modes are disabled */
2801 wpa_command(get_station_ifname(), "P2P_SET ps 98");
2802 wpa_command(get_station_ifname(), "P2P_SET ps 96");
2803 } else if (strcmp(val, "1") == 0 ||
2804 strcasecmp(val, "PSPoll") == 0 ||
2805 strcasecmp(val, "on") == 0) {
2806 /* Disable default power save mode */
2807 wpa_command(get_station_ifname(), "P2P_SET ps 0");
2808 /* Enable PS-Poll test mode */
2809 if (wpa_command(get_station_ifname(),
2810 "P2P_SET ps 97") < 0 ||
2811 wpa_command(get_station_ifname(),
2812 "P2P_SET ps 99") < 0)
2813 return -2;
2814 } else if (strcmp(val, "2") == 0 ||
2815 strcasecmp(val, "Fast") == 0) {
2816 /* TODO */
2817 send_resp(dut, conn, SIGMA_ERROR,
2818 "ErrorCode,Powersave=Fast not supported");
2819 return 0;
2820 } else if (strcmp(val, "3") == 0 ||
2821 strcasecmp(val, "PSNonPoll") == 0) {
2822 /* Make sure test modes are disabled */
2823 wpa_command(get_station_ifname(), "P2P_SET ps 98");
2824 wpa_command(get_station_ifname(), "P2P_SET ps 96");
2825
2826 /* Enable default power save mode */
2827 if (wpa_command(get_station_ifname(),
2828 "P2P_SET ps 1") < 0)
2829 return -2;
2830 } else
2831 return -1;
2832 }
2833
2834 val = get_param(cmd, "NoAck");
2835 if (val) {
2836 switch (get_driver_type()) {
2837 case DRIVER_ATHEROS:
2838 ath_sta_set_noack(dut, intf, val);
2839 break;
2840 default:
2841 send_resp(dut, conn, SIGMA_ERROR,
2842 "ErrorCode,Setting NoAck not supported");
2843 return 0;
2844 }
2845 }
2846
2847 val = get_param(cmd, "IgnoreChswitchProhibit");
2848 if (val) {
2849 /* TODO: Enabled/disabled */
2850 if (strcasecmp(val, "Enabled") == 0) {
2851 send_resp(dut, conn, SIGMA_ERROR,
2852 "ErrorCode,Enabling IgnoreChswitchProhibit "
2853 "not supported");
2854 return 0;
2855 }
2856 }
2857
2858 val = get_param(cmd, "TDLS");
2859 if (val) {
2860 if (strcasecmp(val, "Disabled") == 0) {
2861 if (wpa_command(intf, "SET tdls_disabled 1")) {
2862 send_resp(dut, conn, SIGMA_ERROR,
2863 "ErrorCode,Failed to disable TDLS");
2864 return 0;
2865 }
2866 } else if (strcasecmp(val, "Enabled") == 0) {
2867 if (wpa_command(intf, "SET tdls_disabled 0")) {
2868 send_resp(dut, conn, SIGMA_ERROR,
2869 "ErrorCode,Failed to enable TDLS");
2870 return 0;
2871 }
2872 } else {
2873 send_resp(dut, conn, SIGMA_ERROR,
2874 "ErrorCode,Unsupported TDLS value");
2875 return 0;
2876 }
2877 }
2878
2879 val = get_param(cmd, "TDLSmode");
2880 if (val) {
2881 if (strcasecmp(val, "Default") == 0) {
2882 wpa_command(intf, "SET tdls_testing 0");
2883 } else if (strcasecmp(val, "APProhibit") == 0) {
2884 if (wpa_command(intf, "SET tdls_testing 0x400")) {
2885 send_resp(dut, conn, SIGMA_ERROR,
2886 "ErrorCode,Failed to enable ignore "
2887 "APProhibit TDLS mode");
2888 return 0;
2889 }
2890 } else if (strcasecmp(val, "HiLoMac") == 0) {
2891 /* STA should respond with TDLS setup req for a TDLS
2892 * setup req */
2893 if (wpa_command(intf, "SET tdls_testing 0x80")) {
2894 send_resp(dut, conn, SIGMA_ERROR,
2895 "ErrorCode,Failed to enable HiLoMac "
2896 "TDLS mode");
2897 return 0;
2898 }
2899 } else if (strcasecmp(val, "WeakSecurity") == 0) {
2900 /*
2901 * Since all security modes are enabled by default when
2902 * Sigma control is used, there is no need to do
2903 * anything here.
2904 */
2905 } else if (strcasecmp(val, "ExistLink") == 0) {
2906 /*
2907 * Since we allow new TDLS Setup Request even if there
2908 * is an existing link, nothing needs to be done for
2909 * this.
2910 */
2911 } else {
2912 /* TODO:
2913 * ExistLink: STA should send TDLS setup req even if
2914 * direct link already exists
2915 */
2916 send_resp(dut, conn, SIGMA_ERROR,
2917 "ErrorCode,Unsupported TDLSmode value");
2918 return 0;
2919 }
2920 }
2921
2922 val = get_param(cmd, "FakePubKey");
2923 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
2924 send_resp(dut, conn, SIGMA_ERROR,
2925 "ErrorCode,Failed to enable FakePubKey");
2926 return 0;
2927 }
2928
2929 return 1;
2930}
2931
2932
2933static const char * ath_get_radio_name(const char *radio_name)
2934{
2935 if (radio_name == NULL)
2936 return "wifi0";
2937 if (strcmp(radio_name, "wifi1") == 0)
2938 return "wifi1";
2939 if (strcmp(radio_name, "wifi2") == 0)
2940 return "wifi2";
2941 return "wifi0";
2942}
2943
2944
2945static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
2946 const char *val)
2947{
2948 char buf[60];
2949 unsigned int vht_mcsmap = 0;
2950 int txchainmask = 0;
2951 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
2952
2953 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
2954 if (dut->testbed_flag_txsp == 1) {
2955 vht_mcsmap = 0xfffc;
2956 dut->testbed_flag_txsp = 0;
2957 } else {
2958 vht_mcsmap = 0xfffe;
2959 }
2960 txchainmask = 1;
2961 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
2962 if (dut->testbed_flag_txsp == 1) {
2963 vht_mcsmap = 0xfff0;
2964 dut->testbed_flag_txsp = 0;
2965 } else {
2966 vht_mcsmap = 0xfffa;
2967 }
2968 txchainmask = 3;
2969 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
2970 if (dut->testbed_flag_txsp == 1) {
2971 vht_mcsmap = 0xffc0;
2972 dut->testbed_flag_txsp = 0;
2973 } else {
2974 vht_mcsmap = 0xffea;
2975 }
2976 txchainmask = 7;
2977 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
2978 if (dut->testbed_flag_txsp == 1) {
2979 vht_mcsmap = 0xff00;
2980 dut->testbed_flag_txsp = 0;
2981 } else {
2982 vht_mcsmap = 0xffaa;
2983 }
2984 txchainmask = 15;
2985 } else {
2986 if (dut->testbed_flag_txsp == 1) {
2987 vht_mcsmap = 0xffc0;
2988 dut->testbed_flag_txsp = 0;
2989 } else {
2990 vht_mcsmap = 0xffea;
2991 }
2992 }
2993
2994 if (txchainmask) {
2995 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
2996 basedev, txchainmask);
2997 if (system(buf) != 0) {
2998 sigma_dut_print(dut, DUT_MSG_ERROR,
2999 "iwpriv txchainmask failed");
3000 }
3001 }
3002
3003 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
3004 intf, vht_mcsmap);
3005 if (system(buf) != 0) {
3006 sigma_dut_print(dut, DUT_MSG_ERROR,
3007 "iwpriv %s vht_mcsmap 0x%04x failed",
3008 intf, vht_mcsmap);
3009 }
3010}
3011
3012
3013static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
3014 const char *val)
3015{
3016 char buf[60];
3017 unsigned int vht_mcsmap = 0;
3018 int rxchainmask = 0;
3019 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
3020
3021 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
3022 if (dut->testbed_flag_rxsp == 1) {
3023 vht_mcsmap = 0xfffc;
3024 dut->testbed_flag_rxsp = 0;
3025 } else {
3026 vht_mcsmap = 0xfffe;
3027 }
3028 rxchainmask = 1;
3029 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
3030 if (dut->testbed_flag_rxsp == 1) {
3031 vht_mcsmap = 0xfff0;
3032 dut->testbed_flag_rxsp = 0;
3033 } else {
3034 vht_mcsmap = 0xfffa;
3035 }
3036 rxchainmask = 3;
3037 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
3038 if (dut->testbed_flag_rxsp == 1) {
3039 vht_mcsmap = 0xffc0;
3040 dut->testbed_flag_rxsp = 0;
3041 } else {
3042 vht_mcsmap = 0xffea;
3043 }
3044 rxchainmask = 7;
3045 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
3046 if (dut->testbed_flag_rxsp == 1) {
3047 vht_mcsmap = 0xff00;
3048 dut->testbed_flag_rxsp = 0;
3049 } else {
3050 vht_mcsmap = 0xffaa;
3051 }
3052 rxchainmask = 15;
3053 } else {
3054 if (dut->testbed_flag_rxsp == 1) {
3055 vht_mcsmap = 0xffc0;
3056 dut->testbed_flag_rxsp = 0;
3057 } else {
3058 vht_mcsmap = 0xffea;
3059 }
3060 }
3061
3062 if (rxchainmask) {
3063 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
3064 basedev, rxchainmask);
3065 if (system(buf) != 0) {
3066 sigma_dut_print(dut, DUT_MSG_ERROR,
3067 "iwpriv rxchainmask failed");
3068 }
3069 }
3070
3071 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
3072 intf, vht_mcsmap);
3073 if (system(buf) != 0) {
3074 sigma_dut_print(dut, DUT_MSG_ERROR,
3075 "iwpriv %s vht_mcsmap 0x%04x",
3076 intf, vht_mcsmap);
3077 }
3078}
3079
3080
3081void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
3082{
3083 if (strcasecmp(val, "enable") == 0) {
3084 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
3085 != 0) {
3086 sigma_dut_print(dut, DUT_MSG_ERROR,
3087 "Disable BB_VHTSIGB_CRC_CALC failed");
3088 }
3089
3090 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
3091 != 0) {
3092 sigma_dut_print(dut, DUT_MSG_ERROR,
3093 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
3094 }
3095 } else {
3096 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
3097 != 0) {
3098 sigma_dut_print(dut, DUT_MSG_ERROR,
3099 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
3100 }
3101
3102 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
3103 != 0) {
3104 sigma_dut_print(dut, DUT_MSG_ERROR,
3105 "Enable BB_VHTSIGB_CRC_CALC failed");
3106 }
3107 }
3108}
3109
3110
3111static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
3112 struct sigma_conn *conn,
3113 struct sigma_cmd *cmd)
3114{
3115 const char *val;
3116 int ampdu = -1;
3117 char buf[30];
3118
3119 val = get_param(cmd, "40_INTOLERANT");
3120 if (val) {
3121 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
3122 /* TODO: iwpriv ht40intol through wpa_supplicant */
3123 send_resp(dut, conn, SIGMA_ERROR,
3124 "ErrorCode,40_INTOLERANT not supported");
3125 return 0;
3126 }
3127 }
3128
3129 val = get_param(cmd, "ADDBA_REJECT");
3130 if (val) {
3131 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
3132 /* reject any ADDBA with status "decline" */
3133 ampdu = 0;
3134 } else {
3135 /* accept ADDBA */
3136 ampdu = 1;
3137 }
3138 }
3139
3140 val = get_param(cmd, "AMPDU");
3141 if (val) {
3142 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
3143 /* enable AMPDU Aggregation */
3144 if (ampdu == 0) {
3145 send_resp(dut, conn, SIGMA_ERROR,
3146 "ErrorCode,Mismatch in "
3147 "addba_reject/ampdu - "
3148 "not supported");
3149 return 0;
3150 }
3151 ampdu = 1;
3152 } else {
3153 /* disable AMPDU Aggregation */
3154 if (ampdu == 1) {
3155 send_resp(dut, conn, SIGMA_ERROR,
3156 "ErrorCode,Mismatch in "
3157 "addba_reject/ampdu - "
3158 "not supported");
3159 return 0;
3160 }
3161 ampdu = 0;
3162 }
3163 }
3164
3165 if (ampdu >= 0) {
3166 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
3167 ampdu ? "Enabling" : "Disabling");
3168 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003169 if (wpa_command(intf, buf) < 0 &&
3170 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003171 send_resp(dut, conn, SIGMA_ERROR,
3172 "ErrorCode,set aggr failed");
3173 return 0;
3174 }
3175 }
3176
3177 val = get_param(cmd, "AMSDU");
3178 if (val) {
3179 switch (get_driver_type()) {
3180 case DRIVER_ATHEROS:
3181 ath_sta_set_amsdu(dut, intf, val);
3182 break;
3183 default:
3184 if (strcmp(val, "1") == 0 ||
3185 strcasecmp(val, "Enable") == 0) {
3186 /* Enable AMSDU Aggregation */
3187 send_resp(dut, conn, SIGMA_ERROR,
3188 "ErrorCode,AMSDU aggregation not supported");
3189 return 0;
3190 }
3191 break;
3192 }
3193 }
3194
3195 val = get_param(cmd, "STBC_RX");
3196 if (val) {
3197 switch (get_driver_type()) {
3198 case DRIVER_ATHEROS:
3199 ath_sta_set_stbc(dut, intf, val);
3200 break;
3201 default:
3202 send_resp(dut, conn, SIGMA_ERROR,
3203 "ErrorCode,STBC_RX not supported");
3204 return 0;
3205 }
3206 }
3207
3208 val = get_param(cmd, "WIDTH");
3209 if (val) {
3210 switch (get_driver_type()) {
3211 case DRIVER_WCN:
3212 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
3213 send_resp(dut, conn, SIGMA_ERROR,
3214 "ErrorCode,Failed to set WIDTH");
3215 return 0;
3216 }
3217 break;
3218 case DRIVER_ATHEROS:
3219 if (ath_set_width(dut, conn, intf, val) < 0)
3220 return 0;
3221 break;
3222 default:
3223 sigma_dut_print(dut, DUT_MSG_ERROR,
3224 "Setting WIDTH not supported");
3225 break;
3226 }
3227 }
3228
3229 val = get_param(cmd, "SMPS");
3230 if (val) {
3231 /* TODO: Dynamic/0, Static/1, No Limit/2 */
3232 send_resp(dut, conn, SIGMA_ERROR,
3233 "ErrorCode,SMPS not supported");
3234 return 0;
3235 }
3236
3237 val = get_param(cmd, "TXSP_STREAM");
3238 if (val) {
3239 switch (get_driver_type()) {
3240 case DRIVER_WCN:
3241 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
3242 send_resp(dut, conn, SIGMA_ERROR,
3243 "ErrorCode,Failed to set TXSP_STREAM");
3244 return 0;
3245 }
3246 break;
3247 case DRIVER_ATHEROS:
3248 ath_sta_set_txsp_stream(dut, intf, val);
3249 break;
3250 default:
3251 sigma_dut_print(dut, DUT_MSG_ERROR,
3252 "Setting TXSP_STREAM not supported");
3253 break;
3254 }
3255 }
3256
3257 val = get_param(cmd, "RXSP_STREAM");
3258 if (val) {
3259 switch (get_driver_type()) {
3260 case DRIVER_WCN:
3261 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
3262 send_resp(dut, conn, SIGMA_ERROR,
3263 "ErrorCode,Failed to set RXSP_STREAM");
3264 return 0;
3265 }
3266 break;
3267 case DRIVER_ATHEROS:
3268 ath_sta_set_rxsp_stream(dut, intf, val);
3269 break;
3270 default:
3271 sigma_dut_print(dut, DUT_MSG_ERROR,
3272 "Setting RXSP_STREAM not supported");
3273 break;
3274 }
3275 }
3276
3277 val = get_param(cmd, "DYN_BW_SGNL");
3278 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08003279 switch (get_driver_type()) {
3280 case DRIVER_WCN:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003281 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3282 if (system(buf) != 0) {
3283 sigma_dut_print(dut, DUT_MSG_ERROR,
3284 "Failed to set cts_cbw in DYN_BW_SGNL");
3285 return 0;
3286 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08003287 break;
3288 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08003289 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08003290 ath_config_dyn_bw_sig(dut, intf, val);
3291 break;
3292 default:
3293 sigma_dut_print(dut, DUT_MSG_ERROR,
3294 "Failed to set DYN_BW_SGNL");
3295 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003296 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003297 }
3298
3299 val = get_param(cmd, "RTS_FORCE");
3300 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08003301 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003302 if (strcasecmp(val, "Enable") == 0) {
3303 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02003304 if (system(buf) != 0) {
3305 sigma_dut_print(dut, DUT_MSG_ERROR,
3306 "Failed to set RTS_FORCE 64");
3307 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08003308 snprintf(buf, sizeof(buf),
3309 "wifitool %s beeliner_fw_test 100 1", intf);
3310 if (system(buf) != 0) {
3311 sigma_dut_print(dut, DUT_MSG_ERROR,
3312 "wifitool beeliner_fw_test 100 1 failed");
3313 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003314 } else if (strcasecmp(val, "Disable") == 0) {
3315 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
3316 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02003317 if (system(buf) != 0) {
3318 sigma_dut_print(dut, DUT_MSG_ERROR,
3319 "Failed to set RTS_FORCE 2347");
3320 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003321 } else {
3322 send_resp(dut, conn, SIGMA_ERROR,
3323 "ErrorCode,RTS_FORCE value not supported");
3324 return 0;
3325 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003326 }
3327
3328 val = get_param(cmd, "CTS_WIDTH");
3329 if (val) {
3330 switch (get_driver_type()) {
3331 case DRIVER_WCN:
3332 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
3333 send_resp(dut, conn, SIGMA_ERROR,
3334 "ErrorCode,Failed to set CTS_WIDTH");
3335 return 0;
3336 }
3337 break;
3338 case DRIVER_ATHEROS:
3339 ath_set_cts_width(dut, intf, val);
3340 break;
3341 default:
3342 sigma_dut_print(dut, DUT_MSG_ERROR,
3343 "Setting CTS_WIDTH not supported");
3344 break;
3345 }
3346 }
3347
3348 val = get_param(cmd, "BW_SGNL");
3349 if (val) {
3350 if (strcasecmp(val, "Enable") == 0) {
3351 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1",
3352 intf);
3353 } else if (strcasecmp(val, "Disable") == 0) {
3354 /* TODO: Disable */
3355 buf[0] = '\0';
3356 } else {
3357 send_resp(dut, conn, SIGMA_ERROR,
3358 "ErrorCode,BW_SGNL value not supported");
3359 return 0;
3360 }
3361
3362 if (buf[0] != '\0' && system(buf) != 0) {
3363 sigma_dut_print(dut, DUT_MSG_ERROR,
3364 "Failed to set BW_SGNL");
3365 }
3366 }
3367
3368 val = get_param(cmd, "Band");
3369 if (val) {
3370 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
3371 /* STA supports all bands by default */
3372 } else {
3373 send_resp(dut, conn, SIGMA_ERROR,
3374 "ErrorCode,Unsupported Band");
3375 return 0;
3376 }
3377 }
3378
3379 val = get_param(cmd, "zero_crc");
3380 if (val) {
3381 switch (get_driver_type()) {
3382 case DRIVER_ATHEROS:
3383 ath_set_zero_crc(dut, val);
3384 break;
3385 default:
3386 break;
3387 }
3388 }
3389
3390 return 1;
3391}
3392
3393
3394static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
3395 struct sigma_cmd *cmd)
3396{
3397 const char *val;
3398 char buf[100];
3399
3400 val = get_param(cmd, "MSDUSize");
3401 if (val) {
3402 int mtu;
3403
3404 dut->amsdu_size = atoi(val);
3405 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
3406 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
3407 sigma_dut_print(dut, DUT_MSG_ERROR,
3408 "MSDUSize %d is above max %d or below min %d",
3409 dut->amsdu_size,
3410 IEEE80211_MAX_DATA_LEN_DMG,
3411 IEEE80211_SNAP_LEN_DMG);
3412 dut->amsdu_size = 0;
3413 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3414 }
3415
3416 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
3417 sigma_dut_print(dut, DUT_MSG_DEBUG,
3418 "Setting amsdu_size to %d", mtu);
3419 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
3420 get_station_ifname(), mtu);
3421
3422 if (system(buf) != 0) {
3423 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
3424 buf);
3425 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3426 }
3427 }
3428
3429 val = get_param(cmd, "BAckRcvBuf");
3430 if (val) {
3431 dut->back_rcv_buf = atoi(val);
3432 if (dut->back_rcv_buf == 0) {
3433 sigma_dut_print(dut, DUT_MSG_ERROR,
3434 "Failed to convert %s or value is 0",
3435 val);
3436 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3437 }
3438
3439 sigma_dut_print(dut, DUT_MSG_DEBUG,
3440 "Setting BAckRcvBuf to %s", val);
3441 }
3442
3443 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
3444}
3445
3446
3447static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
3448 struct sigma_cmd *cmd)
3449{
3450 int net_id;
3451 char *ifname;
3452 const char *val;
3453 char buf[100];
3454
3455 dut->mode = SIGMA_MODE_STATION;
3456 ifname = get_main_ifname();
3457 if (wpa_command(ifname, "PING") != 0) {
3458 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
3459 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3460 }
3461
3462 wpa_command(ifname, "FLUSH");
3463 net_id = add_network_common(dut, conn, ifname, cmd);
3464 if (net_id < 0) {
3465 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
3466 return net_id;
3467 }
3468
3469 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
3470 if (set_network(ifname, net_id, "mode", "2") < 0) {
3471 sigma_dut_print(dut, DUT_MSG_ERROR,
3472 "Failed to set supplicant network mode");
3473 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3474 }
3475
3476 sigma_dut_print(dut, DUT_MSG_DEBUG,
3477 "Supplicant set network with mode 2");
3478
3479 val = get_param(cmd, "Security");
3480 if (val && strcasecmp(val, "OPEN") == 0) {
3481 dut->ap_key_mgmt = AP_OPEN;
3482 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
3483 sigma_dut_print(dut, DUT_MSG_ERROR,
3484 "Failed to set supplicant to %s security",
3485 val);
3486 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3487 }
3488 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
3489 dut->ap_key_mgmt = AP_WPA2_PSK;
3490 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
3491 sigma_dut_print(dut, DUT_MSG_ERROR,
3492 "Failed to set supplicant to %s security",
3493 val);
3494 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3495 }
3496
3497 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
3498 sigma_dut_print(dut, DUT_MSG_ERROR,
3499 "Failed to set supplicant to proto RSN");
3500 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3501 }
3502 } else if (val) {
3503 sigma_dut_print(dut, DUT_MSG_ERROR,
3504 "Requested Security %s is not supported on 60GHz",
3505 val);
3506 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
3507 }
3508
3509 val = get_param(cmd, "Encrypt");
3510 if (val && strcasecmp(val, "AES-GCMP") == 0) {
3511 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
3512 sigma_dut_print(dut, DUT_MSG_ERROR,
3513 "Failed to set supplicant to pairwise GCMP");
3514 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3515 }
3516 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
3517 sigma_dut_print(dut, DUT_MSG_ERROR,
3518 "Failed to set supplicant to group GCMP");
3519 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3520 }
3521 } else if (val) {
3522 sigma_dut_print(dut, DUT_MSG_ERROR,
3523 "Requested Encrypt %s is not supported on 60 GHz",
3524 val);
3525 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
3526 }
3527
3528 val = get_param(cmd, "PSK");
3529 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
3530 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
3531 val);
3532 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3533 }
3534
3535 /* Convert 60G channel to freq */
3536 switch (dut->ap_channel) {
3537 case 1:
3538 val = "58320";
3539 break;
3540 case 2:
3541 val = "60480";
3542 break;
3543 case 3:
3544 val = "62640";
3545 break;
3546 default:
3547 sigma_dut_print(dut, DUT_MSG_ERROR,
3548 "Failed to configure channel %d. Not supported",
3549 dut->ap_channel);
3550 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3551 }
3552
3553 if (set_network(ifname, net_id, "frequency", val) < 0) {
3554 sigma_dut_print(dut, DUT_MSG_ERROR,
3555 "Failed to set supplicant network frequency");
3556 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3557 }
3558
3559 sigma_dut_print(dut, DUT_MSG_DEBUG,
3560 "Supplicant set network with frequency");
3561
3562 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
3563 if (wpa_command(ifname, buf) < 0) {
3564 sigma_dut_print(dut, DUT_MSG_INFO,
3565 "Failed to select network id %d on %s",
3566 net_id, ifname);
3567 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3568 }
3569
3570 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
3571
3572 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
3573}
3574
3575
3576static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
3577 struct sigma_cmd *cmd)
3578{
3579 const char *val;
3580
3581 if (dut->dev_role != DEVROLE_PCP) {
3582 send_resp(dut, conn, SIGMA_INVALID,
3583 "ErrorCode,Invalid DevRole");
3584 return 0;
3585 }
3586
3587 val = get_param(cmd, "SSID");
3588 if (val) {
3589 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
3590 send_resp(dut, conn, SIGMA_INVALID,
3591 "ErrorCode,Invalid SSID");
3592 return -1;
3593 }
3594
3595 strncpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
3596 }
3597
3598 val = get_param(cmd, "CHANNEL");
3599 if (val) {
3600 const char *pos;
3601
3602 dut->ap_channel = atoi(val);
3603 pos = strchr(val, ';');
3604 if (pos) {
3605 pos++;
3606 dut->ap_channel_1 = atoi(pos);
3607 }
3608 }
3609
3610 switch (dut->ap_channel) {
3611 case 1:
3612 case 2:
3613 case 3:
3614 break;
3615 default:
3616 sigma_dut_print(dut, DUT_MSG_ERROR,
3617 "Channel %d is not supported", dut->ap_channel);
3618 send_resp(dut, conn, SIGMA_ERROR,
3619 "Requested channel is not supported");
3620 return -1;
3621 }
3622
3623 val = get_param(cmd, "BCNINT");
3624 if (val)
3625 dut->ap_bcnint = atoi(val);
3626
3627
3628 val = get_param(cmd, "ExtSchIE");
3629 if (val) {
3630 send_resp(dut, conn, SIGMA_ERROR,
3631 "ErrorCode,ExtSchIE is not supported yet");
3632 return -1;
3633 }
3634
3635 val = get_param(cmd, "AllocType");
3636 if (val) {
3637 send_resp(dut, conn, SIGMA_ERROR,
3638 "ErrorCode,AllocType is not supported yet");
3639 return -1;
3640 }
3641
3642 val = get_param(cmd, "PercentBI");
3643 if (val) {
3644 send_resp(dut, conn, SIGMA_ERROR,
3645 "ErrorCode,PercentBI is not supported yet");
3646 return -1;
3647 }
3648
3649 val = get_param(cmd, "CBAPOnly");
3650 if (val) {
3651 send_resp(dut, conn, SIGMA_ERROR,
3652 "ErrorCode,CBAPOnly is not supported yet");
3653 return -1;
3654 }
3655
3656 val = get_param(cmd, "AMPDU");
3657 if (val) {
3658 if (strcasecmp(val, "Enable") == 0)
3659 dut->ap_ampdu = 1;
3660 else if (strcasecmp(val, "Disable") == 0)
3661 dut->ap_ampdu = 2;
3662 else {
3663 send_resp(dut, conn, SIGMA_ERROR,
3664 "ErrorCode,AMPDU value is not Enable nor Disabled");
3665 return -1;
3666 }
3667 }
3668
3669 val = get_param(cmd, "AMSDU");
3670 if (val) {
3671 if (strcasecmp(val, "Enable") == 0)
3672 dut->ap_amsdu = 1;
3673 else if (strcasecmp(val, "Disable") == 0)
3674 dut->ap_amsdu = 2;
3675 }
3676
3677 val = get_param(cmd, "NumMSDU");
3678 if (val) {
3679 send_resp(dut, conn, SIGMA_ERROR,
3680 "ErrorCode, NumMSDU is not supported yet");
3681 return -1;
3682 }
3683
3684 val = get_param(cmd, "ABFTLRang");
3685 if (val) {
3686 sigma_dut_print(dut, DUT_MSG_DEBUG,
3687 "Ignoring ABFTLRang parameter since FW default is greater than 1");
3688 }
3689
3690 if (sta_pcp_start(dut, conn, cmd) < 0) {
3691 send_resp(dut, conn, SIGMA_ERROR,
3692 "ErrorCode, Can't start PCP role");
3693 return -1;
3694 }
3695
3696 return sta_set_60g_common(dut, conn, cmd);
3697}
3698
3699
3700static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
3701 struct sigma_cmd *cmd)
3702{
3703 const char *val = get_param(cmd, "DiscoveryMode");
3704
3705 if (dut->dev_role != DEVROLE_STA) {
3706 send_resp(dut, conn, SIGMA_INVALID,
3707 "ErrorCode,Invalid DevRole");
3708 return 0;
3709 }
3710
3711 if (val) {
3712 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
3713 /* Ignore Discovery mode till Driver expose API. */
3714#if 0
3715 if (strcasecmp(val, "1") == 0) {
3716 send_resp(dut, conn, SIGMA_INVALID,
3717 "ErrorCode,DiscoveryMode 1 not supported");
3718 return 0;
3719 }
3720
3721 if (strcasecmp(val, "0") == 0) {
3722 /* OK */
3723 } else {
3724 send_resp(dut, conn, SIGMA_INVALID,
3725 "ErrorCode,DiscoveryMode not supported");
3726 return 0;
3727 }
3728#endif
3729 }
3730
3731 if (start_sta_mode(dut) != 0)
3732 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3733 return sta_set_60g_common(dut, conn, cmd);
3734}
3735
3736
3737static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
3738 struct sigma_cmd *cmd)
3739{
3740 const char *intf = get_param(cmd, "Interface");
3741 disconnect_station(dut);
3742 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
3743 * due to cached results. */
3744 wpa_command(intf, "SET ignore_old_scan_res 1");
3745 wpa_command(intf, "BSS_FLUSH");
3746 return 1;
3747}
3748
3749
3750static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
3751 struct sigma_cmd *cmd)
3752{
3753 const char *intf = get_param(cmd, "Interface");
3754 const char *bssid = get_param(cmd, "bssid");
3755 const char *val = get_param(cmd, "CHANNEL");
3756 struct wpa_ctrl *ctrl;
3757 char buf[100];
3758 int res;
3759 int chan = 0;
3760
3761 if (bssid == NULL) {
3762 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
3763 "argument");
3764 return 0;
3765 }
3766
3767 if (val)
3768 chan = atoi(val);
3769
3770 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
3771 /* The current network may be from sta_associate or
3772 * sta_hs2_associate
3773 */
3774 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
3775 0 ||
3776 set_network(intf, 0, "bssid", bssid) < 0)
3777 return -2;
3778 }
3779
3780 ctrl = open_wpa_mon(intf);
3781 if (ctrl == NULL) {
3782 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
3783 "wpa_supplicant monitor connection");
3784 return -1;
3785 }
3786
3787 if (wifi_chip_type == DRIVER_WCN) {
3788#ifdef ANDROID
3789 if (set_network(intf, dut->infra_network_id, "bssid", "any")
3790 < 0) {
3791 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
3792 "bssid to any during FASTREASSOC");
3793 return -2;
3794 }
3795 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
3796 bssid, chan);
3797 if (res > 0 && res < (int) sizeof(buf))
3798 res = wpa_command(intf, buf);
3799
3800 if (res < 0 || res >= (int) sizeof(buf)) {
3801 send_resp(dut, conn, SIGMA_ERROR,
3802 "errorCode,Failed to run DRIVER FASTREASSOC");
3803 wpa_ctrl_detach(ctrl);
3804 wpa_ctrl_close(ctrl);
3805 return 0;
3806 }
3807#else /* ANDROID */
3808 sigma_dut_print(dut, DUT_MSG_DEBUG,
3809 "Reassoc using iwpriv - skip chan=%d info",
3810 chan);
3811 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
3812 if (system(buf) != 0) {
3813 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
3814 wpa_ctrl_detach(ctrl);
3815 wpa_ctrl_close(ctrl);
3816 return 0;
3817 }
3818#endif /* ANDROID */
3819 sigma_dut_print(dut, DUT_MSG_INFO,
3820 "sta_reassoc: Run %s successful", buf);
3821 } else if (wpa_command(intf, "REASSOCIATE")) {
3822 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
3823 "request reassociation");
3824 wpa_ctrl_detach(ctrl);
3825 wpa_ctrl_close(ctrl);
3826 return 0;
3827 }
3828
3829 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
3830 buf, sizeof(buf));
3831
3832 wpa_ctrl_detach(ctrl);
3833 wpa_ctrl_close(ctrl);
3834
3835 if (res < 0) {
3836 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
3837 return -1;
3838 }
3839
3840 return 1;
3841}
3842
3843
3844static void hs2_clear_credentials(const char *intf)
3845{
3846 wpa_command(intf, "REMOVE_CRED all");
3847}
3848
3849
3850static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
3851 struct sigma_cmd *cmd)
3852{
3853 char buf[MAX_CMD_LEN];
3854 char bss_list[MAX_CMD_LEN];
3855 const char *parameter = get_param(cmd, "Parameter");
3856
3857 if (parameter == NULL)
3858 return -1;
3859
3860 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
3861 char *bss_line;
3862 char *bss_id = NULL;
3863 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303864 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003865
3866 if (ifname == NULL) {
3867 sigma_dut_print(dut, DUT_MSG_INFO,
3868 "For get DiscoveredDevList need Interface name.");
3869 return -1;
3870 }
3871
3872 /*
3873 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
3874 * of BSSIDs in "bssid=<BSSID>\n"
3875 */
3876 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
3877 bss_list,
3878 sizeof(bss_list)) < 0) {
3879 sigma_dut_print(dut, DUT_MSG_ERROR,
3880 "Failed to get bss list");
3881 return -1;
3882 }
3883
3884 sigma_dut_print(dut, DUT_MSG_DEBUG,
3885 "bss list for ifname:%s is:%s",
3886 ifname, bss_list);
3887
3888 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303889 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003890 while (bss_line) {
3891 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
3892 bss_id) {
3893 int len;
3894
3895 len = snprintf(buf + strlen(buf),
3896 sizeof(buf) - strlen(buf),
3897 ",%s", bss_id);
3898 free(bss_id);
3899 bss_id = NULL;
3900 if (len < 0) {
3901 sigma_dut_print(dut,
3902 DUT_MSG_ERROR,
3903 "Failed to read BSSID");
3904 send_resp(dut, conn, SIGMA_ERROR,
3905 "ErrorCode,Failed to read BSS ID");
3906 return 0;
3907 }
3908
3909 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
3910 sigma_dut_print(dut,
3911 DUT_MSG_ERROR,
3912 "Response buf too small for list");
3913 send_resp(dut, conn,
3914 SIGMA_ERROR,
3915 "ErrorCode,Response buf too small for list");
3916 return 0;
3917 }
3918 }
3919
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303920 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003921 }
3922
3923 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
3924 buf);
3925 send_resp(dut, conn, SIGMA_COMPLETE, buf);
3926 return 0;
3927 }
3928
3929 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
3930 return 0;
3931}
3932
3933
3934static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
3935 struct sigma_cmd *cmd)
3936{
3937 const char *program = get_param(cmd, "Program");
3938
3939 if (program == NULL)
3940 return -1;
3941
3942 if (strcasecmp(program, "P2PNFC") == 0)
3943 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
3944
3945 if (strcasecmp(program, "60ghz") == 0)
3946 return sta_get_parameter_60g(dut, conn, cmd);
3947
3948#ifdef ANDROID_NAN
3949 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07003950 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003951#endif /* ANDROID_NAN */
3952
3953 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
3954 return 0;
3955}
3956
3957
3958static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
3959 const char *type)
3960{
3961 char buf[100];
3962
3963 if (dut->program == PROGRAM_VHT) {
3964 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
3965 if (system(buf) != 0) {
3966 sigma_dut_print(dut, DUT_MSG_ERROR,
3967 "iwpriv %s chwidth failed", intf);
3968 }
3969
3970 snprintf(buf, sizeof(buf), "iwpriv %s mode 11ACVHT80", intf);
3971 if (system(buf) != 0) {
3972 sigma_dut_print(dut, DUT_MSG_ERROR,
3973 "iwpriv %s mode 11ACVHT80 failed",
3974 intf);
3975 }
3976
3977 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs -1", intf);
3978 if (system(buf) != 0) {
3979 sigma_dut_print(dut, DUT_MSG_ERROR,
3980 "iwpriv %s vhtmcs -1 failed", intf);
3981 }
3982 }
3983
3984 if (dut->program == PROGRAM_HT) {
3985 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3986 if (system(buf) != 0) {
3987 sigma_dut_print(dut, DUT_MSG_ERROR,
3988 "iwpriv %s chwidth failed", intf);
3989 }
3990
3991 snprintf(buf, sizeof(buf), "iwpriv %s mode 11naht40", intf);
3992 if (system(buf) != 0) {
3993 sigma_dut_print(dut, DUT_MSG_ERROR,
3994 "iwpriv %s mode 11naht40 failed",
3995 intf);
3996 }
3997
3998 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0", intf);
3999 if (system(buf) != 0) {
4000 sigma_dut_print(dut, DUT_MSG_ERROR,
4001 "iwpriv set11NRates failed");
4002 }
4003 }
4004
4005 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
4006 snprintf(buf, sizeof(buf), "iwpriv %s powersave 0", intf);
4007 if (system(buf) != 0) {
4008 sigma_dut_print(dut, DUT_MSG_ERROR,
4009 "disabling powersave failed");
4010 }
4011
4012 /* Reset CTS width */
4013 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
4014 intf);
4015 if (system(buf) != 0) {
4016 sigma_dut_print(dut, DUT_MSG_ERROR,
4017 "wifitool %s beeliner_fw_test 54 0 failed",
4018 intf);
4019 }
4020
4021 /* Enable Dynamic Bandwidth signalling by default */
4022 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", intf);
4023 if (system(buf) != 0) {
4024 sigma_dut_print(dut, DUT_MSG_ERROR,
4025 "iwpriv %s cwmenable 1 failed", intf);
4026 }
4027
4028 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
4029 if (system(buf) != 0) {
4030 sigma_dut_print(dut, DUT_MSG_ERROR,
4031 "iwpriv rts failed");
4032 }
4033 }
4034
4035 if (type && strcasecmp(type, "Testbed") == 0) {
4036 dut->testbed_flag_txsp = 1;
4037 dut->testbed_flag_rxsp = 1;
4038 /* STA has to set spatial stream to 2 per Appendix H */
4039 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0xfff0", intf);
4040 if (system(buf) != 0) {
4041 sigma_dut_print(dut, DUT_MSG_ERROR,
4042 "iwpriv vht_mcsmap failed");
4043 }
4044
4045 /* Disable LDPC per Appendix H */
4046 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", intf);
4047 if (system(buf) != 0) {
4048 sigma_dut_print(dut, DUT_MSG_ERROR,
4049 "iwpriv %s ldpc 0 failed", intf);
4050 }
4051
4052 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4053 if (system(buf) != 0) {
4054 sigma_dut_print(dut, DUT_MSG_ERROR,
4055 "iwpriv amsdu failed");
4056 }
4057
4058 /* TODO: Disable STBC 2x1 transmit and receive */
4059 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", intf);
4060 if (system(buf) != 0) {
4061 sigma_dut_print(dut, DUT_MSG_ERROR,
4062 "Disable tx_stbc 0 failed");
4063 }
4064
4065 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc 0", intf);
4066 if (system(buf) != 0) {
4067 sigma_dut_print(dut, DUT_MSG_ERROR,
4068 "Disable rx_stbc 0 failed");
4069 }
4070
4071 /* STA has to disable Short GI per Appendix H */
4072 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 0", intf);
4073 if (system(buf) != 0) {
4074 sigma_dut_print(dut, DUT_MSG_ERROR,
4075 "iwpriv %s shortgi 0 failed", intf);
4076 }
4077 }
4078
4079 if (type && strcasecmp(type, "DUT") == 0) {
4080 snprintf(buf, sizeof(buf), "iwpriv %s nss 3", intf);
4081 if (system(buf) != 0) {
4082 sigma_dut_print(dut, DUT_MSG_ERROR,
4083 "iwpriv %s nss 3 failed", intf);
4084 }
4085
4086 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 1", intf);
4087 if (system(buf) != 0) {
4088 sigma_dut_print(dut, DUT_MSG_ERROR,
4089 "iwpriv %s shortgi 1 failed", intf);
4090 }
4091 }
4092}
4093
4094
4095static int cmd_sta_reset_default(struct sigma_dut *dut,
4096 struct sigma_conn *conn,
4097 struct sigma_cmd *cmd)
4098{
4099 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
4100 struct sigma_cmd *cmd);
4101 const char *intf = get_param(cmd, "Interface");
4102 const char *type;
4103
4104 dut->program = sigma_program_to_enum(get_param(cmd, "prog"));
4105 dut->device_type = STA_unknown;
4106 type = get_param(cmd, "type");
4107 if (type && strcasecmp(type, "Testbed") == 0)
4108 dut->device_type = STA_testbed;
4109 if (type && strcasecmp(type, "DUT") == 0)
4110 dut->device_type = STA_dut;
4111
4112 if (dut->program == PROGRAM_TDLS) {
4113 /* Clear TDLS testing mode */
4114 wpa_command(intf, "SET tdls_disabled 0");
4115 wpa_command(intf, "SET tdls_testing 0");
4116 dut->no_tpk_expiration = 0;
4117 }
4118
4119 switch (get_driver_type()) {
4120 case DRIVER_ATHEROS:
4121 sta_reset_default_ath(dut, intf, type);
4122 break;
4123 default:
4124 break;
4125 }
4126
4127#ifdef ANDROID_NAN
4128 if (dut->program == PROGRAM_NAN)
4129 nan_cmd_sta_reset_default(dut, conn, cmd);
4130#endif /* ANDROID_NAN */
4131
4132 if (dut->program == PROGRAM_HS2_R2) {
4133 unlink("SP/wi-fi.org/pps.xml");
4134 if (system("rm -r SP/*") != 0) {
4135 }
4136 unlink("next-client-cert.pem");
4137 unlink("next-client-key.pem");
4138 }
4139
4140 if (dut->program == PROGRAM_60GHZ) {
4141 const char *dev_role = get_param(cmd, "DevRole");
4142
4143 if (!dev_role) {
4144 send_resp(dut, conn, SIGMA_ERROR,
4145 "errorCode,Missing DevRole argument");
4146 return 0;
4147 }
4148
4149 if (strcasecmp(dev_role, "STA") == 0)
4150 dut->dev_role = DEVROLE_STA;
4151 else if (strcasecmp(dev_role, "PCP") == 0)
4152 dut->dev_role = DEVROLE_PCP;
4153 else {
4154 send_resp(dut, conn, SIGMA_ERROR,
4155 "errorCode,Unknown DevRole");
4156 return 0;
4157 }
4158
4159 if (dut->device_type == STA_unknown) {
4160 sigma_dut_print(dut, DUT_MSG_ERROR,
4161 "Device type is not STA testbed or DUT");
4162 send_resp(dut, conn, SIGMA_ERROR,
4163 "errorCode,Unknown device type");
4164 return 0;
4165 }
4166 }
4167
4168 wpa_command(intf, "WPS_ER_STOP");
4169 wpa_command(intf, "FLUSH");
4170 wpa_command(intf, "SET radio_disabled 0");
4171
4172 if (dut->tmp_mac_addr && dut->set_macaddr) {
4173 dut->tmp_mac_addr = 0;
4174 if (system(dut->set_macaddr) != 0) {
4175 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
4176 "temporary MAC address");
4177 }
4178 }
4179
4180 set_ps(intf, dut, 0);
4181
4182 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2) {
4183 wpa_command(intf, "SET interworking 1");
4184 wpa_command(intf, "SET hs20 1");
4185 }
4186
4187 if (dut->program == PROGRAM_HS2_R2) {
4188 wpa_command(intf, "SET pmf 1");
4189 } else {
4190 wpa_command(intf, "SET pmf 0");
4191 }
4192
4193 hs2_clear_credentials(intf);
4194 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
4195 wpa_command(intf, "SET access_network_type 15");
4196
4197 static_ip_file(0, NULL, NULL, NULL);
4198 kill_dhcp_client(dut, intf);
4199 clear_ip_addr(dut, intf);
4200
4201 dut->er_oper_performed = 0;
4202 dut->er_oper_bssid[0] = '\0';
4203
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07004204 if (dut->program == PROGRAM_LOC) {
4205 /* Disable Interworking by default */
4206 wpa_command(get_station_ifname(), "SET interworking 0");
4207 }
4208
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08004209 if (dut->program != PROGRAM_VHT)
4210 return cmd_sta_p2p_reset(dut, conn, cmd);
4211 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004212}
4213
4214
4215static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
4216 struct sigma_cmd *cmd)
4217{
4218 const char *program = get_param(cmd, "Program");
4219
4220 if (program == NULL)
4221 return -1;
4222#ifdef ANDROID_NAN
4223 if (strcasecmp(program, "NAN") == 0)
4224 return nan_cmd_sta_get_events(dut, conn, cmd);
4225#endif /* ANDROID_NAN */
4226 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
4227 return 0;
4228}
4229
4230
4231static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
4232 struct sigma_cmd *cmd)
4233{
4234 const char *program = get_param(cmd, "Prog");
4235
4236 if (program == NULL)
4237 return -1;
4238#ifdef ANDROID_NAN
4239 if (strcasecmp(program, "NAN") == 0)
4240 return nan_cmd_sta_exec_action(dut, conn, cmd);
4241#endif /* ANDROID_NAN */
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004242 if (strcasecmp(program, "Loc") == 0)
4243 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004244 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
4245 return 0;
4246}
4247
4248
4249static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
4250 struct sigma_cmd *cmd)
4251{
4252 const char *intf = get_param(cmd, "Interface");
4253 const char *val, *mcs32, *rate;
4254
4255 val = get_param(cmd, "GREENFIELD");
4256 if (val) {
4257 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4258 /* Enable GD */
4259 send_resp(dut, conn, SIGMA_ERROR,
4260 "ErrorCode,GF not supported");
4261 return 0;
4262 }
4263 }
4264
4265 val = get_param(cmd, "SGI20");
4266 if (val) {
4267 switch (get_driver_type()) {
4268 case DRIVER_ATHEROS:
4269 ath_sta_set_sgi(dut, intf, val);
4270 break;
4271 default:
4272 send_resp(dut, conn, SIGMA_ERROR,
4273 "ErrorCode,SGI20 not supported");
4274 return 0;
4275 }
4276 }
4277
4278 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
4279 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
4280 if (mcs32 && rate) {
4281 /* TODO */
4282 send_resp(dut, conn, SIGMA_ERROR,
4283 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
4284 return 0;
4285 } else if (mcs32 && !rate) {
4286 /* TODO */
4287 send_resp(dut, conn, SIGMA_ERROR,
4288 "ErrorCode,MCS32 not supported");
4289 return 0;
4290 } else if (!mcs32 && rate) {
4291 switch (get_driver_type()) {
4292 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004293 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004294 ath_sta_set_11nrates(dut, intf, rate);
4295 break;
4296 default:
4297 send_resp(dut, conn, SIGMA_ERROR,
4298 "ErrorCode,MCS32_FIXEDRATE not supported");
4299 return 0;
4300 }
4301 }
4302
4303 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
4304}
4305
4306
4307static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
4308 struct sigma_conn *conn,
4309 struct sigma_cmd *cmd)
4310{
4311 const char *intf = get_param(cmd, "Interface");
4312 const char *val;
4313 char buf[30];
4314 int tkip = -1;
4315 int wep = -1;
4316
4317 val = get_param(cmd, "SGI80");
4318 if (val) {
4319 int sgi80;
4320
4321 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4322 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi80);
4323 if (system(buf) != 0) {
4324 sigma_dut_print(dut, DUT_MSG_ERROR,
4325 "iwpriv shortgi failed");
4326 }
4327 }
4328
4329 val = get_param(cmd, "TxBF");
4330 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
4331 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 1", intf);
4332 if (system(buf) != 0) {
4333 sigma_dut_print(dut, DUT_MSG_ERROR,
4334 "iwpriv vhtsubfee failed");
4335 }
4336 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 1", intf);
4337 if (system(buf) != 0) {
4338 sigma_dut_print(dut, DUT_MSG_ERROR,
4339 "iwpriv vhtsubfer failed");
4340 }
4341 }
4342
4343 val = get_param(cmd, "MU_TxBF");
4344 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
4345 switch (get_driver_type()) {
4346 case DRIVER_ATHEROS:
4347 ath_sta_set_txsp_stream(dut, intf, "1SS");
4348 ath_sta_set_rxsp_stream(dut, intf, "1SS");
4349 case DRIVER_WCN:
4350 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
4351 send_resp(dut, conn, SIGMA_ERROR,
4352 "ErrorCode,Failed to set RX/TXSP_STREAM");
4353 return 0;
4354 }
4355 default:
4356 sigma_dut_print(dut, DUT_MSG_ERROR,
4357 "Setting SP_STREAM not supported");
4358 break;
4359 }
4360 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 1", intf);
4361 if (system(buf) != 0) {
4362 sigma_dut_print(dut, DUT_MSG_ERROR,
4363 "iwpriv vhtmubfee failed");
4364 }
4365 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 1", intf);
4366 if (system(buf) != 0) {
4367 sigma_dut_print(dut, DUT_MSG_ERROR,
4368 "iwpriv vhtmubfer failed");
4369 }
4370 }
4371
4372 val = get_param(cmd, "LDPC");
4373 if (val) {
4374 int ldpc;
4375
4376 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4377 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, ldpc);
4378 if (system(buf) != 0) {
4379 sigma_dut_print(dut, DUT_MSG_ERROR,
4380 "iwpriv ldpc failed");
4381 }
4382 }
4383
4384 val = get_param(cmd, "opt_md_notif_ie");
4385 if (val) {
4386 char *result = NULL;
4387 char delim[] = ";";
4388 char token[30];
4389 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304390 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004391
4392 strncpy(token, val, sizeof(token));
4393 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304394 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004395
4396 /* Extract the NSS information */
4397 if (result) {
4398 value = atoi(result);
4399 switch (value) {
4400 case 1:
4401 config_val = 1;
4402 break;
4403 case 2:
4404 config_val = 3;
4405 break;
4406 case 3:
4407 config_val = 7;
4408 break;
4409 case 4:
4410 config_val = 15;
4411 break;
4412 default:
4413 config_val = 3;
4414 break;
4415 }
4416
4417 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
4418 intf, config_val);
4419 if (system(buf) != 0) {
4420 sigma_dut_print(dut, DUT_MSG_ERROR,
4421 "iwpriv rxchainmask failed");
4422 }
4423
4424 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
4425 intf, config_val);
4426 if (system(buf) != 0) {
4427 sigma_dut_print(dut, DUT_MSG_ERROR,
4428 "iwpriv txchainmask failed");
4429 }
4430 }
4431
4432 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304433 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004434 if (result) {
4435 value = atoi(result);
4436 switch (value) {
4437 case 20:
4438 config_val = 0;
4439 break;
4440 case 40:
4441 config_val = 1;
4442 break;
4443 case 80:
4444 config_val = 2;
4445 break;
4446 case 160:
4447 config_val = 3;
4448 break;
4449 default:
4450 config_val = 2;
4451 break;
4452 }
4453
4454 dut->chwidth = config_val;
4455
4456 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
4457 intf, config_val);
4458 if (system(buf) != 0) {
4459 sigma_dut_print(dut, DUT_MSG_ERROR,
4460 "iwpriv chwidth failed");
4461 }
4462 }
4463
4464 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", intf);
4465 if (system(buf) != 0) {
4466 sigma_dut_print(dut, DUT_MSG_ERROR,
4467 "iwpriv opmode_notify failed");
4468 }
4469 }
4470
4471 val = get_param(cmd, "nss_mcs_cap");
4472 if (val) {
4473 int nss, mcs;
4474 char token[20];
4475 char *result = NULL;
4476 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304477 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004478
4479 strncpy(token, val, sizeof(token));
4480 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304481 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05304482 if (!result) {
4483 sigma_dut_print(dut, DUT_MSG_ERROR,
4484 "VHT NSS not specified");
4485 return 0;
4486 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004487 nss = atoi(result);
4488
4489 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
4490 if (system(buf) != 0) {
4491 sigma_dut_print(dut, DUT_MSG_ERROR,
4492 "iwpriv nss failed");
4493 }
4494
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304495 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004496 if (result == NULL) {
4497 sigma_dut_print(dut, DUT_MSG_ERROR,
4498 "VHTMCS NOT SPECIFIED!");
4499 return 0;
4500 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304501 result = strtok_r(result, "-", &saveptr);
4502 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05304503 if (!result) {
4504 sigma_dut_print(dut, DUT_MSG_ERROR,
4505 "VHT MCS not specified");
4506 return 0;
4507 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004508 mcs = atoi(result);
4509
4510 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d", intf, mcs);
4511 if (system(buf) != 0) {
4512 sigma_dut_print(dut, DUT_MSG_ERROR,
4513 "iwpriv mcs failed");
4514 }
4515
4516 switch (nss) {
4517 case 1:
4518 switch (mcs) {
4519 case 7:
4520 vht_mcsmap = 0xfffc;
4521 break;
4522 case 8:
4523 vht_mcsmap = 0xfffd;
4524 break;
4525 case 9:
4526 vht_mcsmap = 0xfffe;
4527 break;
4528 default:
4529 vht_mcsmap = 0xfffe;
4530 break;
4531 }
4532 break;
4533 case 2:
4534 switch (mcs) {
4535 case 7:
4536 vht_mcsmap = 0xfff0;
4537 break;
4538 case 8:
4539 vht_mcsmap = 0xfff5;
4540 break;
4541 case 9:
4542 vht_mcsmap = 0xfffa;
4543 break;
4544 default:
4545 vht_mcsmap = 0xfffa;
4546 break;
4547 }
4548 break;
4549 case 3:
4550 switch (mcs) {
4551 case 7:
4552 vht_mcsmap = 0xffc0;
4553 break;
4554 case 8:
4555 vht_mcsmap = 0xffd5;
4556 break;
4557 case 9:
4558 vht_mcsmap = 0xffea;
4559 break;
4560 default:
4561 vht_mcsmap = 0xffea;
4562 break;
4563 }
4564 break;
4565 default:
4566 vht_mcsmap = 0xffea;
4567 break;
4568 }
4569 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4570 intf, vht_mcsmap);
4571 if (system(buf) != 0) {
4572 sigma_dut_print(dut, DUT_MSG_ERROR,
4573 "iwpriv vht_mcsmap failed");
4574 }
4575 }
4576
4577 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
4578
4579 val = get_param(cmd, "Vht_tkip");
4580 if (val)
4581 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4582
4583 val = get_param(cmd, "Vht_wep");
4584 if (val)
4585 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4586
4587 if (tkip != -1 || wep != -1) {
4588 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
4589 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1",
4590 intf);
4591 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
4592 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 0",
4593 intf);
4594 } else {
4595 sigma_dut_print(dut, DUT_MSG_ERROR,
4596 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
4597 return 0;
4598 }
4599
4600 if (system(buf) != 0) {
4601 sigma_dut_print(dut, DUT_MSG_ERROR,
4602 "iwpriv htweptkip failed");
4603 }
4604 }
4605
4606 val = get_param(cmd, "txBandwidth");
4607 if (val) {
4608 switch (get_driver_type()) {
4609 case DRIVER_ATHEROS:
4610 if (ath_set_width(dut, conn, intf, val) < 0) {
4611 send_resp(dut, conn, SIGMA_ERROR,
4612 "ErrorCode,Failed to set txBandwidth");
4613 return 0;
4614 }
4615 break;
4616 default:
4617 sigma_dut_print(dut, DUT_MSG_ERROR,
4618 "Setting txBandwidth not supported");
4619 break;
4620 }
4621 }
4622
4623 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
4624}
4625
4626
4627static int sta_set_wireless_60g(struct sigma_dut *dut,
4628 struct sigma_conn *conn,
4629 struct sigma_cmd *cmd)
4630{
4631 const char *dev_role = get_param(cmd, "DevRole");
4632
4633 if (!dev_role) {
4634 send_resp(dut, conn, SIGMA_INVALID,
4635 "ErrorCode,DevRole not specified");
4636 return 0;
4637 }
4638
4639 if (strcasecmp(dev_role, "PCP") == 0)
4640 return sta_set_60g_pcp(dut, conn, cmd);
4641 if (strcasecmp(dev_role, "STA") == 0)
4642 return sta_set_60g_sta(dut, conn, cmd);
4643 send_resp(dut, conn, SIGMA_INVALID,
4644 "ErrorCode,DevRole not supported");
4645 return 0;
4646}
4647
4648
4649static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
4650 struct sigma_cmd *cmd)
4651{
4652 const char *val;
4653
4654 val = get_param(cmd, "Program");
4655 if (val) {
4656 if (strcasecmp(val, "11n") == 0)
4657 return cmd_sta_set_11n(dut, conn, cmd);
4658 if (strcasecmp(val, "VHT") == 0)
4659 return cmd_sta_set_wireless_vht(dut, conn, cmd);
4660 if (strcasecmp(val, "60ghz") == 0)
4661 return sta_set_wireless_60g(dut, conn, cmd);
4662 send_resp(dut, conn, SIGMA_ERROR,
4663 "ErrorCode,Program value not supported");
4664 } else {
4665 send_resp(dut, conn, SIGMA_ERROR,
4666 "ErrorCode,Program argument not available");
4667 }
4668
4669 return 0;
4670}
4671
4672
4673static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
4674 int tid)
4675{
4676 char buf[100];
4677 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
4678
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05304679 if (tid < 0 ||
4680 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
4681 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
4682 return;
4683 }
4684
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004685 /*
4686 * Two ways to ensure that addba request with a
4687 * non zero TID could be sent out. EV 117296
4688 */
4689 snprintf(buf, sizeof(buf),
4690 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
4691 tid);
4692 if (system(buf) != 0) {
4693 sigma_dut_print(dut, DUT_MSG_ERROR,
4694 "Ping did not send out");
4695 }
4696
4697 snprintf(buf, sizeof(buf),
4698 "iwconfig %s | grep Access | awk '{print $6}' > %s",
4699 intf, VI_QOS_TMP_FILE);
4700 if (system(buf) != 0)
4701 return;
4702
4703 snprintf(buf, sizeof(buf),
4704 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
4705 intf, VI_QOS_TMP_FILE);
4706 if (system(buf) != 0)
4707 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
4708
4709 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
4710 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
4711 if (system(buf) != 0) {
4712 sigma_dut_print(dut, DUT_MSG_ERROR,
4713 "VI_QOS_TEMP_FILE generation error failed");
4714 }
4715 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
4716 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
4717 if (system(buf) != 0) {
4718 sigma_dut_print(dut, DUT_MSG_ERROR,
4719 "VI_QOS_FILE generation failed");
4720 }
4721
4722 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
4723 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
4724 if (system(buf) != 0) {
4725 sigma_dut_print(dut, DUT_MSG_ERROR,
4726 "VI_QOS_FILE generation failed");
4727 }
4728
4729 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
4730 if (system(buf) != 0) {
4731 }
4732}
4733
4734
4735static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
4736 struct sigma_cmd *cmd)
4737{
4738 const char *intf = get_param(cmd, "Interface");
4739 const char *val;
4740 int tid = 0;
4741 char buf[100];
4742
4743 val = get_param(cmd, "TID");
4744 if (val) {
4745 tid = atoi(val);
4746 if (tid)
4747 ath_sta_inject_frame(dut, intf, tid);
4748 }
4749
4750 /* Command sequence for ADDBA request on Peregrine based devices */
4751 snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", intf);
4752 if (system(buf) != 0) {
4753 sigma_dut_print(dut, DUT_MSG_ERROR,
4754 "iwpriv setaddbaoper failed");
4755 }
4756
4757 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
4758 if (system(buf) != 0) {
4759 sigma_dut_print(dut, DUT_MSG_ERROR,
4760 "wifitool senddelba failed");
4761 }
4762
4763 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
4764 if (system(buf) != 0) {
4765 sigma_dut_print(dut, DUT_MSG_ERROR,
4766 "wifitool sendaddba failed");
4767 }
4768
4769 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
4770
4771 return 1;
4772}
4773
4774
4775static int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
4776 struct sigma_cmd *cmd)
4777{
4778 const char *val;
4779 int tid = 0;
4780 char buf[100];
4781
4782 val = get_param(cmd, "TID");
4783 if (val) {
4784 tid = atoi(val);
4785 if (tid != 0) {
4786 sigma_dut_print(dut, DUT_MSG_ERROR,
4787 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
4788 tid);
4789 }
4790 }
4791
4792 val = get_param(cmd, "Dest_mac");
4793 if (!val) {
4794 sigma_dut_print(dut, DUT_MSG_ERROR,
4795 "Currently not supporting addba for 60G without Dest_mac");
4796 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4797 }
4798
4799 snprintf(buf, sizeof(buf), "wil6210_addba_req.py %s %d",
4800 val, dut->back_rcv_buf);
4801 sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
4802
4803 if (system(buf) != 0) {
4804 sigma_dut_print(dut, DUT_MSG_ERROR,
4805 "Failed to send addba");
4806 return -1;
4807 }
4808
4809 return 1;
4810}
4811
4812
4813static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
4814 struct sigma_cmd *cmd)
4815{
4816 switch (get_driver_type()) {
4817 case DRIVER_ATHEROS:
4818 return ath_sta_send_addba(dut, conn, cmd);
4819 case DRIVER_WIL6210:
4820 return send_addba_60g(dut, conn, cmd);
4821 default:
4822 /*
4823 * There is no driver specific implementation for other drivers.
4824 * Ignore the command and report COMPLETE since the following
4825 * throughput test operation will end up sending ADDBA anyway.
4826 */
4827 return 1;
4828 }
4829}
4830
4831
4832int inject_eth_frame(int s, const void *data, size_t len,
4833 unsigned short ethtype, char *dst, char *src)
4834{
4835 struct iovec iov[4] = {
4836 {
4837 .iov_base = dst,
4838 .iov_len = ETH_ALEN,
4839 },
4840 {
4841 .iov_base = src,
4842 .iov_len = ETH_ALEN,
4843 },
4844 {
4845 .iov_base = &ethtype,
4846 .iov_len = sizeof(unsigned short),
4847 },
4848 {
4849 .iov_base = (void *) data,
4850 .iov_len = len,
4851 }
4852 };
4853 struct msghdr msg = {
4854 .msg_name = NULL,
4855 .msg_namelen = 0,
4856 .msg_iov = iov,
4857 .msg_iovlen = 4,
4858 .msg_control = NULL,
4859 .msg_controllen = 0,
4860 .msg_flags = 0,
4861 };
4862
4863 return sendmsg(s, &msg, 0);
4864}
4865
4866#if defined(__linux__) || defined(__QNXNTO__)
4867
4868int inject_frame(int s, const void *data, size_t len, int encrypt)
4869{
4870#define IEEE80211_RADIOTAP_F_WEP 0x04
4871#define IEEE80211_RADIOTAP_F_FRAG 0x08
4872 unsigned char rtap_hdr[] = {
4873 0x00, 0x00, /* radiotap version */
4874 0x0e, 0x00, /* radiotap length */
4875 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
4876 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
4877 0x00, /* padding */
4878 0x00, 0x00, /* RX and TX flags to indicate that */
4879 0x00, 0x00, /* this is the injected frame directly */
4880 };
4881 struct iovec iov[2] = {
4882 {
4883 .iov_base = &rtap_hdr,
4884 .iov_len = sizeof(rtap_hdr),
4885 },
4886 {
4887 .iov_base = (void *) data,
4888 .iov_len = len,
4889 }
4890 };
4891 struct msghdr msg = {
4892 .msg_name = NULL,
4893 .msg_namelen = 0,
4894 .msg_iov = iov,
4895 .msg_iovlen = 2,
4896 .msg_control = NULL,
4897 .msg_controllen = 0,
4898 .msg_flags = 0,
4899 };
4900
4901 if (encrypt)
4902 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
4903
4904 return sendmsg(s, &msg, 0);
4905}
4906
4907
4908int open_monitor(const char *ifname)
4909{
4910#ifdef __QNXNTO__
4911 struct sockaddr_dl ll;
4912 int s;
4913
4914 memset(&ll, 0, sizeof(ll));
4915 ll.sdl_family = AF_LINK;
4916 ll.sdl_index = if_nametoindex(ifname);
4917 if (ll.sdl_index == 0) {
4918 perror("if_nametoindex");
4919 return -1;
4920 }
4921 s = socket(PF_INET, SOCK_RAW, 0);
4922#else /* __QNXNTO__ */
4923 struct sockaddr_ll ll;
4924 int s;
4925
4926 memset(&ll, 0, sizeof(ll));
4927 ll.sll_family = AF_PACKET;
4928 ll.sll_ifindex = if_nametoindex(ifname);
4929 if (ll.sll_ifindex == 0) {
4930 perror("if_nametoindex");
4931 return -1;
4932 }
4933 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
4934#endif /* __QNXNTO__ */
4935 if (s < 0) {
4936 perror("socket[PF_PACKET,SOCK_RAW]");
4937 return -1;
4938 }
4939
4940 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
4941 perror("monitor socket bind");
4942 close(s);
4943 return -1;
4944 }
4945
4946 return s;
4947}
4948
4949
4950static int hex2num(char c)
4951{
4952 if (c >= '0' && c <= '9')
4953 return c - '0';
4954 if (c >= 'a' && c <= 'f')
4955 return c - 'a' + 10;
4956 if (c >= 'A' && c <= 'F')
4957 return c - 'A' + 10;
4958 return -1;
4959}
4960
4961
4962int hwaddr_aton(const char *txt, unsigned char *addr)
4963{
4964 int i;
4965
4966 for (i = 0; i < 6; i++) {
4967 int a, b;
4968
4969 a = hex2num(*txt++);
4970 if (a < 0)
4971 return -1;
4972 b = hex2num(*txt++);
4973 if (b < 0)
4974 return -1;
4975 *addr++ = (a << 4) | b;
4976 if (i < 5 && *txt++ != ':')
4977 return -1;
4978 }
4979
4980 return 0;
4981}
4982
4983#endif /* defined(__linux__) || defined(__QNXNTO__) */
4984
4985enum send_frame_type {
4986 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
4987};
4988enum send_frame_protection {
4989 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
4990};
4991
4992
4993static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
4994 enum send_frame_type frame,
4995 enum send_frame_protection protected,
4996 const char *dest)
4997{
4998#ifdef __linux__
4999 unsigned char buf[1000], *pos;
5000 int s, res;
5001 char bssid[20], addr[20];
5002 char result[32], ssid[100];
5003 size_t ssid_len;
5004
5005 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
5006 sizeof(result)) < 0 ||
5007 strncmp(result, "COMPLETED", 9) != 0) {
5008 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
5009 return 0;
5010 }
5011
5012 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
5013 < 0) {
5014 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
5015 "current BSSID");
5016 return 0;
5017 }
5018
5019 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
5020 < 0) {
5021 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
5022 "own MAC address");
5023 return 0;
5024 }
5025
5026 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
5027 < 0) {
5028 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
5029 "current SSID");
5030 return 0;
5031 }
5032 ssid_len = strlen(ssid);
5033
5034 pos = buf;
5035
5036 /* Frame Control */
5037 switch (frame) {
5038 case DISASSOC:
5039 *pos++ = 0xa0;
5040 break;
5041 case DEAUTH:
5042 *pos++ = 0xc0;
5043 break;
5044 case SAQUERY:
5045 *pos++ = 0xd0;
5046 break;
5047 case AUTH:
5048 *pos++ = 0xb0;
5049 break;
5050 case ASSOCREQ:
5051 *pos++ = 0x00;
5052 break;
5053 case REASSOCREQ:
5054 *pos++ = 0x20;
5055 break;
5056 case DLS_REQ:
5057 *pos++ = 0xd0;
5058 break;
5059 }
5060
5061 if (protected == INCORRECT_KEY)
5062 *pos++ = 0x40; /* Set Protected field to 1 */
5063 else
5064 *pos++ = 0x00;
5065
5066 /* Duration */
5067 *pos++ = 0x00;
5068 *pos++ = 0x00;
5069
5070 /* addr1 = DA (current AP) */
5071 hwaddr_aton(bssid, pos);
5072 pos += 6;
5073 /* addr2 = SA (own address) */
5074 hwaddr_aton(addr, pos);
5075 pos += 6;
5076 /* addr3 = BSSID (current AP) */
5077 hwaddr_aton(bssid, pos);
5078 pos += 6;
5079
5080 /* Seq# (to be filled by driver/mac80211) */
5081 *pos++ = 0x00;
5082 *pos++ = 0x00;
5083
5084 if (protected == INCORRECT_KEY) {
5085 /* CCMP parameters */
5086 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
5087 pos += 8;
5088 }
5089
5090 if (protected == INCORRECT_KEY) {
5091 switch (frame) {
5092 case DEAUTH:
5093 /* Reason code (encrypted) */
5094 memcpy(pos, "\xa7\x39", 2);
5095 pos += 2;
5096 break;
5097 case DISASSOC:
5098 /* Reason code (encrypted) */
5099 memcpy(pos, "\xa7\x39", 2);
5100 pos += 2;
5101 break;
5102 case SAQUERY:
5103 /* Category|Action|TransID (encrypted) */
5104 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
5105 pos += 4;
5106 break;
5107 default:
5108 return -1;
5109 }
5110
5111 /* CCMP MIC */
5112 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
5113 pos += 8;
5114 } else {
5115 switch (frame) {
5116 case DEAUTH:
5117 /* reason code = 8 */
5118 *pos++ = 0x08;
5119 *pos++ = 0x00;
5120 break;
5121 case DISASSOC:
5122 /* reason code = 8 */
5123 *pos++ = 0x08;
5124 *pos++ = 0x00;
5125 break;
5126 case SAQUERY:
5127 /* Category - SA Query */
5128 *pos++ = 0x08;
5129 /* SA query Action - Request */
5130 *pos++ = 0x00;
5131 /* Transaction ID */
5132 *pos++ = 0x12;
5133 *pos++ = 0x34;
5134 break;
5135 case AUTH:
5136 /* Auth Alg (Open) */
5137 *pos++ = 0x00;
5138 *pos++ = 0x00;
5139 /* Seq# */
5140 *pos++ = 0x01;
5141 *pos++ = 0x00;
5142 /* Status code */
5143 *pos++ = 0x00;
5144 *pos++ = 0x00;
5145 break;
5146 case ASSOCREQ:
5147 /* Capability Information */
5148 *pos++ = 0x31;
5149 *pos++ = 0x04;
5150 /* Listen Interval */
5151 *pos++ = 0x0a;
5152 *pos++ = 0x00;
5153 /* SSID */
5154 *pos++ = 0x00;
5155 *pos++ = ssid_len;
5156 memcpy(pos, ssid, ssid_len);
5157 pos += ssid_len;
5158 /* Supported Rates */
5159 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
5160 10);
5161 pos += 10;
5162 /* Extended Supported Rates */
5163 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
5164 pos += 6;
5165 /* RSN */
5166 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
5167 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
5168 "\x00\x00\x00\x00\x0f\xac\x06", 28);
5169 pos += 28;
5170 break;
5171 case REASSOCREQ:
5172 /* Capability Information */
5173 *pos++ = 0x31;
5174 *pos++ = 0x04;
5175 /* Listen Interval */
5176 *pos++ = 0x0a;
5177 *pos++ = 0x00;
5178 /* Current AP */
5179 hwaddr_aton(bssid, pos);
5180 pos += 6;
5181 /* SSID */
5182 *pos++ = 0x00;
5183 *pos++ = ssid_len;
5184 memcpy(pos, ssid, ssid_len);
5185 pos += ssid_len;
5186 /* Supported Rates */
5187 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
5188 10);
5189 pos += 10;
5190 /* Extended Supported Rates */
5191 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
5192 pos += 6;
5193 /* RSN */
5194 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
5195 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
5196 "\x00\x00\x00\x00\x0f\xac\x06", 28);
5197 pos += 28;
5198 break;
5199 case DLS_REQ:
5200 /* Category - DLS */
5201 *pos++ = 0x02;
5202 /* DLS Action - Request */
5203 *pos++ = 0x00;
5204 /* Destination MACAddress */
5205 if (dest)
5206 hwaddr_aton(dest, pos);
5207 else
5208 memset(pos, 0, 6);
5209 pos += 6;
5210 /* Source MACAddress */
5211 hwaddr_aton(addr, pos);
5212 pos += 6;
5213 /* Capability Information */
5214 *pos++ = 0x10; /* Privacy */
5215 *pos++ = 0x06; /* QoS */
5216 /* DLS Timeout Value */
5217 *pos++ = 0x00;
5218 *pos++ = 0x01;
5219 /* Supported rates */
5220 *pos++ = 0x01;
5221 *pos++ = 0x08;
5222 *pos++ = 0x0c; /* 6 Mbps */
5223 *pos++ = 0x12; /* 9 Mbps */
5224 *pos++ = 0x18; /* 12 Mbps */
5225 *pos++ = 0x24; /* 18 Mbps */
5226 *pos++ = 0x30; /* 24 Mbps */
5227 *pos++ = 0x48; /* 36 Mbps */
5228 *pos++ = 0x60; /* 48 Mbps */
5229 *pos++ = 0x6c; /* 54 Mbps */
5230 /* TODO: Extended Supported Rates */
5231 /* TODO: HT Capabilities */
5232 break;
5233 }
5234 }
5235
5236 s = open_monitor("sigmadut");
5237 if (s < 0) {
5238 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
5239 "monitor socket");
5240 return 0;
5241 }
5242
5243 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
5244 if (res < 0) {
5245 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
5246 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05305247 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005248 return 0;
5249 }
5250 if (res < pos - buf) {
5251 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
5252 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05305253 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005254 return 0;
5255 }
5256
5257 close(s);
5258
5259 return 1;
5260#else /* __linux__ */
5261 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
5262 "yet supported");
5263 return 0;
5264#endif /* __linux__ */
5265}
5266
5267
5268static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
5269 struct sigma_conn *conn,
5270 struct sigma_cmd *cmd)
5271{
5272 const char *intf = get_param(cmd, "Interface");
5273 const char *sta, *val;
5274 unsigned char addr[ETH_ALEN];
5275 char buf[100];
5276
5277 sta = get_param(cmd, "peer");
5278 if (sta == NULL)
5279 sta = get_param(cmd, "station");
5280 if (sta == NULL) {
5281 send_resp(dut, conn, SIGMA_ERROR,
5282 "ErrorCode,Missing peer address");
5283 return 0;
5284 }
5285 if (hwaddr_aton(sta, addr) < 0) {
5286 send_resp(dut, conn, SIGMA_ERROR,
5287 "ErrorCode,Invalid peer address");
5288 return 0;
5289 }
5290
5291 val = get_param(cmd, "type");
5292 if (val == NULL)
5293 return -1;
5294
5295 if (strcasecmp(val, "DISCOVERY") == 0) {
5296 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
5297 if (wpa_command(intf, buf) < 0) {
5298 send_resp(dut, conn, SIGMA_ERROR,
5299 "ErrorCode,Failed to send TDLS discovery");
5300 return 0;
5301 }
5302 return 1;
5303 }
5304
5305 if (strcasecmp(val, "SETUP") == 0) {
5306 int status = 0, timeout = 0;
5307
5308 val = get_param(cmd, "Status");
5309 if (val)
5310 status = atoi(val);
5311
5312 val = get_param(cmd, "Timeout");
5313 if (val)
5314 timeout = atoi(val);
5315
5316 if (status != 0 && status != 37) {
5317 send_resp(dut, conn, SIGMA_ERROR,
5318 "ErrorCode,Unsupported status value");
5319 return 0;
5320 }
5321
5322 if (timeout != 0 && timeout != 301) {
5323 send_resp(dut, conn, SIGMA_ERROR,
5324 "ErrorCode,Unsupported timeout value");
5325 return 0;
5326 }
5327
5328 if (status && timeout) {
5329 send_resp(dut, conn, SIGMA_ERROR,
5330 "ErrorCode,Unsupported timeout+status "
5331 "combination");
5332 return 0;
5333 }
5334
5335 if (status == 37 &&
5336 wpa_command(intf, "SET tdls_testing 0x200")) {
5337 send_resp(dut, conn, SIGMA_ERROR,
5338 "ErrorCode,Failed to enable "
5339 "decline setup response test mode");
5340 return 0;
5341 }
5342
5343 if (timeout == 301) {
5344 int res;
5345 if (dut->no_tpk_expiration)
5346 res = wpa_command(intf,
5347 "SET tdls_testing 0x108");
5348 else
5349 res = wpa_command(intf,
5350 "SET tdls_testing 0x8");
5351 if (res) {
5352 send_resp(dut, conn, SIGMA_ERROR,
5353 "ErrorCode,Failed to set short TPK "
5354 "lifetime");
5355 return 0;
5356 }
5357 }
5358
5359 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
5360 if (wpa_command(intf, buf) < 0) {
5361 send_resp(dut, conn, SIGMA_ERROR,
5362 "ErrorCode,Failed to send TDLS setup");
5363 return 0;
5364 }
5365 return 1;
5366 }
5367
5368 if (strcasecmp(val, "TEARDOWN") == 0) {
5369 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
5370 if (wpa_command(intf, buf) < 0) {
5371 send_resp(dut, conn, SIGMA_ERROR,
5372 "ErrorCode,Failed to send TDLS teardown");
5373 return 0;
5374 }
5375 return 1;
5376 }
5377
5378 send_resp(dut, conn, SIGMA_ERROR,
5379 "ErrorCode,Unsupported TDLS frame");
5380 return 0;
5381}
5382
5383
5384static int sta_ap_known(const char *ifname, const char *bssid)
5385{
5386 char buf[4096];
5387
5388 snprintf(buf, sizeof(buf), "BSS %s", bssid);
5389 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
5390 return 0;
5391 if (strncmp(buf, "id=", 3) != 0)
5392 return 0;
5393 return 1;
5394}
5395
5396
5397static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
5398 const char *bssid)
5399{
5400 int res;
5401 struct wpa_ctrl *ctrl;
5402 char buf[256];
5403
5404 if (sta_ap_known(ifname, bssid))
5405 return 0;
5406 sigma_dut_print(dut, DUT_MSG_DEBUG,
5407 "AP not in BSS table - start scan");
5408
5409 ctrl = open_wpa_mon(ifname);
5410 if (ctrl == NULL) {
5411 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
5412 "wpa_supplicant monitor connection");
5413 return -1;
5414 }
5415
5416 if (wpa_command(ifname, "SCAN") < 0) {
5417 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
5418 wpa_ctrl_detach(ctrl);
5419 wpa_ctrl_close(ctrl);
5420 return -1;
5421 }
5422
5423 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
5424 buf, sizeof(buf));
5425
5426 wpa_ctrl_detach(ctrl);
5427 wpa_ctrl_close(ctrl);
5428
5429 if (res < 0) {
5430 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
5431 return -1;
5432 }
5433
5434 if (sta_ap_known(ifname, bssid))
5435 return 0;
5436 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
5437 return -1;
5438}
5439
5440
5441static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
5442 struct sigma_conn *conn,
5443 struct sigma_cmd *cmd,
5444 const char *intf)
5445{
5446 char buf[200];
5447
5448 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
5449 if (system(buf) != 0) {
5450 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
5451 "ndsend");
5452 return 0;
5453 }
5454
5455 return 1;
5456}
5457
5458
5459static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
5460 struct sigma_conn *conn,
5461 struct sigma_cmd *cmd,
5462 const char *intf)
5463{
5464 char buf[200];
5465 const char *ip = get_param(cmd, "SenderIP");
5466
5467 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
5468 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
5469 if (system(buf) == 0) {
5470 sigma_dut_print(dut, DUT_MSG_INFO,
5471 "Neighbor Solicitation got a response "
5472 "for %s@%s", ip, intf);
5473 }
5474
5475 return 1;
5476}
5477
5478
5479static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
5480 struct sigma_conn *conn,
5481 struct sigma_cmd *cmd,
5482 const char *ifname)
5483{
5484 char buf[200];
5485 const char *ip = get_param(cmd, "SenderIP");
5486
5487 if (ip == NULL) {
5488 send_resp(dut, conn, SIGMA_ERROR,
5489 "ErrorCode,Missing SenderIP parameter");
5490 return 0;
5491 }
5492 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
5493 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
5494 if (system(buf) != 0) {
5495 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
5496 "for %s@%s", ip, ifname);
5497 }
5498
5499 return 1;
5500}
5501
5502
5503static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
5504 struct sigma_conn *conn,
5505 struct sigma_cmd *cmd,
5506 const char *ifname)
5507{
5508 char buf[200];
5509 char ip[16];
5510 int s;
5511
5512 s = socket(PF_INET, SOCK_DGRAM, 0);
5513 if (s >= 0) {
5514 struct ifreq ifr;
5515 struct sockaddr_in saddr;
5516
5517 memset(&ifr, 0, sizeof(ifr));
5518 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
5519 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
5520 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
5521 "%s IP address: %s",
5522 ifname, strerror(errno));
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05305523 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005524 return -1;
5525 } else {
5526 memcpy(&saddr, &ifr.ifr_addr,
5527 sizeof(struct sockaddr_in));
5528 strncpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
5529 }
5530 close(s);
5531
5532 }
5533
5534 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
5535 ip);
5536 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
5537 if (system(buf) != 0) {
5538 }
5539
5540 return 1;
5541}
5542
5543
5544static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
5545 struct sigma_conn *conn,
5546 struct sigma_cmd *cmd,
5547 const char *ifname)
5548{
5549 char buf[200], addr[20];
5550 char dst[ETH_ALEN], src[ETH_ALEN];
5551 short ethtype = htons(ETH_P_ARP);
5552 char *pos;
5553 int s, res;
5554 const char *val;
5555 struct sockaddr_in taddr;
5556
5557 val = get_param(cmd, "dest");
5558 if (val)
5559 hwaddr_aton(val, (unsigned char *) dst);
5560
5561 val = get_param(cmd, "DestIP");
5562 if (val)
5563 inet_aton(val, &taddr.sin_addr);
5564
5565 if (get_wpa_status(get_station_ifname(), "address", addr,
5566 sizeof(addr)) < 0)
5567 return -2;
5568 hwaddr_aton(addr, (unsigned char *) src);
5569
5570 pos = buf;
5571 *pos++ = 0x00;
5572 *pos++ = 0x01;
5573 *pos++ = 0x08;
5574 *pos++ = 0x00;
5575 *pos++ = 0x06;
5576 *pos++ = 0x04;
5577 *pos++ = 0x00;
5578 *pos++ = 0x02;
5579 memcpy(pos, src, ETH_ALEN);
5580 pos += ETH_ALEN;
5581 memcpy(pos, &taddr.sin_addr, 4);
5582 pos += 4;
5583 memcpy(pos, dst, ETH_ALEN);
5584 pos += ETH_ALEN;
5585 memcpy(pos, &taddr.sin_addr, 4);
5586 pos += 4;
5587
5588 s = open_monitor(get_station_ifname());
5589 if (s < 0) {
5590 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
5591 "monitor socket");
5592 return 0;
5593 }
5594
5595 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
5596 if (res < 0) {
5597 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
5598 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05305599 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005600 return 0;
5601 }
5602
5603 close(s);
5604
5605 return 1;
5606}
5607
5608
5609static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
5610 struct sigma_conn *conn,
5611 struct sigma_cmd *cmd,
5612 const char *intf, const char *dest)
5613{
5614 char buf[100];
5615
5616 if (if_nametoindex("sigmadut") == 0) {
5617 snprintf(buf, sizeof(buf),
5618 "iw dev %s interface add sigmadut type monitor",
5619 get_station_ifname());
5620 if (system(buf) != 0 ||
5621 if_nametoindex("sigmadut") == 0) {
5622 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
5623 "monitor interface with '%s'", buf);
5624 return -2;
5625 }
5626 }
5627
5628 if (system("ifconfig sigmadut up") != 0) {
5629 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
5630 "monitor interface up");
5631 return -2;
5632 }
5633
5634 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
5635}
5636
5637
5638static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
5639 struct sigma_conn *conn,
5640 struct sigma_cmd *cmd)
5641{
5642 const char *intf = get_param(cmd, "Interface");
5643 const char *dest = get_param(cmd, "Dest");
5644 const char *type = get_param(cmd, "FrameName");
5645 const char *val;
5646 char buf[200], *pos, *end;
5647 int count, count2;
5648
5649 if (type == NULL)
5650 type = get_param(cmd, "Type");
5651
5652 if (intf == NULL || dest == NULL || type == NULL)
5653 return -1;
5654
5655 if (strcasecmp(type, "NeighAdv") == 0)
5656 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
5657
5658 if (strcasecmp(type, "NeighSolicitReq") == 0)
5659 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
5660
5661 if (strcasecmp(type, "ARPProbe") == 0)
5662 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
5663
5664 if (strcasecmp(type, "ARPAnnounce") == 0)
5665 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
5666
5667 if (strcasecmp(type, "ARPReply") == 0)
5668 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
5669
5670 if (strcasecmp(type, "DLS-request") == 0 ||
5671 strcasecmp(type, "DLSrequest") == 0)
5672 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
5673 dest);
5674
5675 if (strcasecmp(type, "ANQPQuery") != 0 &&
5676 strcasecmp(type, "Query") != 0) {
5677 send_resp(dut, conn, SIGMA_ERROR,
5678 "ErrorCode,Unsupported HS 2.0 send frame type");
5679 return 0;
5680 }
5681
5682 if (sta_scan_ap(dut, intf, dest) < 0) {
5683 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
5684 "the requested AP");
5685 return 0;
5686 }
5687
5688 pos = buf;
5689 end = buf + sizeof(buf);
5690 count = 0;
5691 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
5692
5693 val = get_param(cmd, "ANQP_CAP_LIST");
5694 if (val && atoi(val)) {
5695 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
5696 count++;
5697 }
5698
5699 val = get_param(cmd, "VENUE_NAME");
5700 if (val && atoi(val)) {
5701 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
5702 count++;
5703 }
5704
5705 val = get_param(cmd, "NETWORK_AUTH_TYPE");
5706 if (val && atoi(val)) {
5707 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
5708 count++;
5709 }
5710
5711 val = get_param(cmd, "ROAMING_CONS");
5712 if (val && atoi(val)) {
5713 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
5714 count++;
5715 }
5716
5717 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
5718 if (val && atoi(val)) {
5719 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
5720 count++;
5721 }
5722
5723 val = get_param(cmd, "NAI_REALM_LIST");
5724 if (val && atoi(val)) {
5725 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
5726 count++;
5727 }
5728
5729 val = get_param(cmd, "3GPP_INFO");
5730 if (val && atoi(val)) {
5731 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
5732 count++;
5733 }
5734
5735 val = get_param(cmd, "DOMAIN_LIST");
5736 if (val && atoi(val)) {
5737 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
5738 count++;
5739 }
5740
5741 if (count && wpa_command(intf, buf)) {
5742 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
5743 return 0;
5744 }
5745
5746 pos = buf;
5747 end = buf + sizeof(buf);
5748 count2 = 0;
5749 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
5750
5751 val = get_param(cmd, "HS_CAP_LIST");
5752 if (val && atoi(val)) {
5753 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
5754 count2++;
5755 }
5756
5757 val = get_param(cmd, "OPER_NAME");
5758 if (val && atoi(val)) {
5759 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
5760 count2++;
5761 }
5762
5763 val = get_param(cmd, "WAN_METRICS");
5764 if (!val)
5765 val = get_param(cmd, "WAN_MAT");
5766 if (!val)
5767 val = get_param(cmd, "WAN_MET");
5768 if (val && atoi(val)) {
5769 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
5770 count2++;
5771 }
5772
5773 val = get_param(cmd, "CONNECTION_CAPABILITY");
5774 if (val && atoi(val)) {
5775 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
5776 count2++;
5777 }
5778
5779 val = get_param(cmd, "OP_CLASS");
5780 if (val && atoi(val)) {
5781 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
5782 count2++;
5783 }
5784
5785 val = get_param(cmd, "OSU_PROVIDER_LIST");
5786 if (val && atoi(val)) {
5787 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
5788 count2++;
5789 }
5790
5791 if (count && count2) {
5792 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
5793 "second query");
5794 sleep(1);
5795 }
5796
5797 if (count2 && wpa_command(intf, buf)) {
5798 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
5799 "failed");
5800 return 0;
5801 }
5802
5803 val = get_param(cmd, "NAI_HOME_REALM_LIST");
5804 if (val) {
5805 if (count || count2) {
5806 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
5807 "sending out second query");
5808 sleep(1);
5809 }
5810
5811 if (strcmp(val, "1") == 0)
5812 val = "mail.example.com";
5813 snprintf(buf, end - pos,
5814 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
5815 dest, val);
5816 if (wpa_command(intf, buf)) {
5817 send_resp(dut, conn, SIGMA_ERROR,
5818 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
5819 "failed");
5820 return 0;
5821 }
5822 }
5823
5824 val = get_param(cmd, "ICON_REQUEST");
5825 if (val) {
5826 if (count || count2) {
5827 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
5828 "sending out second query");
5829 sleep(1);
5830 }
5831
5832 snprintf(buf, end - pos,
5833 "HS20_ICON_REQUEST %s %s", dest, val);
5834 if (wpa_command(intf, buf)) {
5835 send_resp(dut, conn, SIGMA_ERROR,
5836 "ErrorCode,HS20_ICON_REQUEST failed");
5837 return 0;
5838 }
5839 }
5840
5841 return 1;
5842}
5843
5844
5845static int ath_sta_send_frame_vht(struct sigma_dut *dut,
5846 struct sigma_conn *conn,
5847 struct sigma_cmd *cmd)
5848{
5849 const char *val;
5850 char *ifname;
5851 char buf[100];
5852 int chwidth, nss;
5853
5854 val = get_param(cmd, "framename");
5855 if (!val)
5856 return -1;
5857 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
5858
5859 /* Command sequence to generate Op mode notification */
5860 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
5861 ifname = get_station_ifname();
5862
5863 /* Disable STBC */
5864 snprintf(buf, sizeof(buf),
5865 "iwpriv %s tx_stbc 0", ifname);
5866 if (system(buf) != 0) {
5867 sigma_dut_print(dut, DUT_MSG_ERROR,
5868 "iwpriv tx_stbc 0 failed!");
5869 }
5870
5871 /* Extract Channel width */
5872 val = get_param(cmd, "Channel_width");
5873 if (val) {
5874 switch (atoi(val)) {
5875 case 20:
5876 chwidth = 0;
5877 break;
5878 case 40:
5879 chwidth = 1;
5880 break;
5881 case 80:
5882 chwidth = 2;
5883 break;
5884 case 160:
5885 chwidth = 3;
5886 break;
5887 default:
5888 chwidth = 2;
5889 break;
5890 }
5891
5892 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
5893 ifname, chwidth);
5894 if (system(buf) != 0) {
5895 sigma_dut_print(dut, DUT_MSG_ERROR,
5896 "iwpriv chwidth failed!");
5897 }
5898 }
5899
5900 /* Extract NSS */
5901 val = get_param(cmd, "NSS");
5902 if (val) {
5903 switch (atoi(val)) {
5904 case 1:
5905 nss = 1;
5906 break;
5907 case 2:
5908 nss = 3;
5909 break;
5910 case 3:
5911 nss = 7;
5912 break;
5913 default:
5914 /* We do not support NSS > 3 */
5915 nss = 3;
5916 break;
5917 }
5918 snprintf(buf, sizeof(buf),
5919 "iwpriv %s rxchainmask %d", ifname, nss);
5920 if (system(buf) != 0) {
5921 sigma_dut_print(dut, DUT_MSG_ERROR,
5922 "iwpriv rxchainmask failed!");
5923 }
5924 }
5925
5926 /* Opmode notify */
5927 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
5928 if (system(buf) != 0) {
5929 sigma_dut_print(dut, DUT_MSG_ERROR,
5930 "iwpriv opmode_notify failed!");
5931 } else {
5932 sigma_dut_print(dut, DUT_MSG_INFO,
5933 "Sent out the notify frame!");
5934 }
5935 }
5936
5937 return 1;
5938}
5939
5940
5941static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
5942 struct sigma_conn *conn,
5943 struct sigma_cmd *cmd)
5944{
5945 switch (get_driver_type()) {
5946 case DRIVER_ATHEROS:
5947 return ath_sta_send_frame_vht(dut, conn, cmd);
5948 default:
5949 send_resp(dut, conn, SIGMA_ERROR,
5950 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
5951 return 0;
5952 }
5953}
5954
5955
5956int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
5957 struct sigma_cmd *cmd)
5958{
5959 const char *intf = get_param(cmd, "Interface");
5960 const char *val;
5961 enum send_frame_type frame;
5962 enum send_frame_protection protected;
5963 char buf[100];
5964 unsigned char addr[ETH_ALEN];
5965 int res;
5966
5967 val = get_param(cmd, "program");
5968 if (val == NULL)
5969 val = get_param(cmd, "frame");
5970 if (val && strcasecmp(val, "TDLS") == 0)
5971 return cmd_sta_send_frame_tdls(dut, conn, cmd);
5972 if (val && (strcasecmp(val, "HS2") == 0 ||
5973 strcasecmp(val, "HS2-R2") == 0))
5974 return cmd_sta_send_frame_hs2(dut, conn, cmd);
5975 if (val && strcasecmp(val, "VHT") == 0)
5976 return cmd_sta_send_frame_vht(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005977 if (val && strcasecmp(val, "LOC") == 0)
5978 return loc_cmd_sta_send_frame(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005979
5980 val = get_param(cmd, "TD_DISC");
5981 if (val) {
5982 if (hwaddr_aton(val, addr) < 0)
5983 return -1;
5984 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
5985 if (wpa_command(intf, buf) < 0) {
5986 send_resp(dut, conn, SIGMA_ERROR,
5987 "ErrorCode,Failed to send TDLS discovery");
5988 return 0;
5989 }
5990 return 1;
5991 }
5992
5993 val = get_param(cmd, "TD_Setup");
5994 if (val) {
5995 if (hwaddr_aton(val, addr) < 0)
5996 return -1;
5997 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
5998 if (wpa_command(intf, buf) < 0) {
5999 send_resp(dut, conn, SIGMA_ERROR,
6000 "ErrorCode,Failed to start TDLS setup");
6001 return 0;
6002 }
6003 return 1;
6004 }
6005
6006 val = get_param(cmd, "TD_TearDown");
6007 if (val) {
6008 if (hwaddr_aton(val, addr) < 0)
6009 return -1;
6010 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
6011 if (wpa_command(intf, buf) < 0) {
6012 send_resp(dut, conn, SIGMA_ERROR,
6013 "ErrorCode,Failed to tear down TDLS link");
6014 return 0;
6015 }
6016 return 1;
6017 }
6018
6019 val = get_param(cmd, "TD_ChannelSwitch");
6020 if (val) {
6021 /* TODO */
6022 send_resp(dut, conn, SIGMA_ERROR,
6023 "ErrorCode,TD_ChannelSwitch not yet supported");
6024 return 0;
6025 }
6026
6027 val = get_param(cmd, "TD_NF");
6028 if (val) {
6029 /* TODO */
6030 send_resp(dut, conn, SIGMA_ERROR,
6031 "ErrorCode,TD_NF not yet supported");
6032 return 0;
6033 }
6034
6035 val = get_param(cmd, "PMFFrameType");
6036 if (val == NULL)
6037 val = get_param(cmd, "FrameName");
6038 if (val == NULL)
6039 val = get_param(cmd, "Type");
6040 if (val == NULL)
6041 return -1;
6042 if (strcasecmp(val, "disassoc") == 0)
6043 frame = DISASSOC;
6044 else if (strcasecmp(val, "deauth") == 0)
6045 frame = DEAUTH;
6046 else if (strcasecmp(val, "saquery") == 0)
6047 frame = SAQUERY;
6048 else if (strcasecmp(val, "auth") == 0)
6049 frame = AUTH;
6050 else if (strcasecmp(val, "assocreq") == 0)
6051 frame = ASSOCREQ;
6052 else if (strcasecmp(val, "reassocreq") == 0)
6053 frame = REASSOCREQ;
6054 else if (strcasecmp(val, "neigreq") == 0) {
6055 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
6056
6057 val = get_param(cmd, "ssid");
6058 if (val == NULL)
6059 return -1;
6060
6061 res = send_neighbor_request(dut, intf, val);
6062 if (res) {
6063 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
6064 "Failed to send neighbor report request");
6065 return 0;
6066 }
6067
6068 return 1;
6069 } else if (strcasecmp(val, "transmgmtquery") == 0) {
6070 sigma_dut_print(dut, DUT_MSG_DEBUG,
6071 "Got Transition Management Query");
6072
6073 val = get_param(cmd, "ssid");
6074 res = send_trans_mgmt_query(dut, intf, val);
6075 if (res) {
6076 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
6077 "Failed to send Transition Management Query");
6078 return 0;
6079 }
6080
6081 return 1;
6082 } else {
6083 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
6084 "PMFFrameType");
6085 return 0;
6086 }
6087
6088 val = get_param(cmd, "PMFProtected");
6089 if (val == NULL)
6090 val = get_param(cmd, "Protected");
6091 if (val == NULL)
6092 return -1;
6093 if (strcasecmp(val, "Correct-key") == 0 ||
6094 strcasecmp(val, "CorrectKey") == 0)
6095 protected = CORRECT_KEY;
6096 else if (strcasecmp(val, "IncorrectKey") == 0)
6097 protected = INCORRECT_KEY;
6098 else if (strcasecmp(val, "Unprotected") == 0)
6099 protected = UNPROTECTED;
6100 else {
6101 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
6102 "PMFProtected");
6103 return 0;
6104 }
6105
6106 if (protected != UNPROTECTED &&
6107 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
6108 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
6109 "PMFProtected for auth/assocreq/reassocreq");
6110 return 0;
6111 }
6112
6113 if (if_nametoindex("sigmadut") == 0) {
6114 snprintf(buf, sizeof(buf),
6115 "iw dev %s interface add sigmadut type monitor",
6116 get_station_ifname());
6117 if (system(buf) != 0 ||
6118 if_nametoindex("sigmadut") == 0) {
6119 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
6120 "monitor interface with '%s'", buf);
6121 return -2;
6122 }
6123 }
6124
6125 if (system("ifconfig sigmadut up") != 0) {
6126 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6127 "monitor interface up");
6128 return -2;
6129 }
6130
6131 return sta_inject_frame(dut, conn, frame, protected, NULL);
6132}
6133
6134
6135static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
6136 struct sigma_conn *conn,
6137 struct sigma_cmd *cmd,
6138 const char *ifname)
6139{
6140 char buf[200];
6141 const char *val;
6142
6143 val = get_param(cmd, "ClearARP");
6144 if (val && atoi(val) == 1) {
6145 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
6146 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6147 if (system(buf) != 0) {
6148 send_resp(dut, conn, SIGMA_ERROR,
6149 "errorCode,Failed to clear ARP cache");
6150 return 0;
6151 }
6152 }
6153
6154 return 1;
6155}
6156
6157
6158int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
6159 struct sigma_cmd *cmd)
6160{
6161 const char *intf = get_param(cmd, "Interface");
6162 const char *val;
6163
6164 if (intf == NULL)
6165 return -1;
6166
6167 val = get_param(cmd, "program");
6168 if (val && (strcasecmp(val, "HS2") == 0 ||
6169 strcasecmp(val, "HS2-R2") == 0))
6170 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
6171
6172 return -1;
6173}
6174
6175
6176static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
6177 struct sigma_cmd *cmd)
6178{
6179 const char *intf = get_param(cmd, "Interface");
6180 const char *mac = get_param(cmd, "MAC");
6181
6182 if (intf == NULL || mac == NULL)
6183 return -1;
6184
6185 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
6186 "interface %s to %s", intf, mac);
6187
6188 if (dut->set_macaddr) {
6189 char buf[128];
6190 int res;
6191 if (strcasecmp(mac, "default") == 0) {
6192 res = snprintf(buf, sizeof(buf), "%s",
6193 dut->set_macaddr);
6194 dut->tmp_mac_addr = 0;
6195 } else {
6196 res = snprintf(buf, sizeof(buf), "%s %s",
6197 dut->set_macaddr, mac);
6198 dut->tmp_mac_addr = 1;
6199 }
6200 if (res < 0 || res >= (int) sizeof(buf))
6201 return -1;
6202 if (system(buf) != 0) {
6203 send_resp(dut, conn, SIGMA_ERROR,
6204 "errorCode,Failed to set MAC "
6205 "address");
6206 return 0;
6207 }
6208 return 1;
6209 }
6210
6211 if (strcasecmp(mac, "default") == 0)
6212 return 1;
6213
6214 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
6215 "command");
6216 return 0;
6217}
6218
6219
6220static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
6221 struct sigma_conn *conn, const char *intf,
6222 int val)
6223{
6224 char buf[200];
6225 int res;
6226
6227 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
6228 intf, val);
6229 if (res < 0 || res >= (int) sizeof(buf))
6230 return -1;
6231 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6232 if (system(buf) != 0) {
6233 send_resp(dut, conn, SIGMA_ERROR,
6234 "errorCode,Failed to configure offchannel mode");
6235 return 0;
6236 }
6237
6238 return 1;
6239}
6240
6241
6242enum sec_ch_offset {
6243 SEC_CH_NO,
6244 SEC_CH_40ABOVE,
6245 SEC_CH_40BELOW
6246};
6247
6248
6249static int off_chan_val(enum sec_ch_offset off)
6250{
6251 switch (off) {
6252 case SEC_CH_NO:
6253 return 0;
6254 case SEC_CH_40ABOVE:
6255 return 40;
6256 case SEC_CH_40BELOW:
6257 return -40;
6258 }
6259
6260 return 0;
6261}
6262
6263
6264static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
6265 const char *intf, int off_ch_num,
6266 enum sec_ch_offset sec)
6267{
6268 char buf[200];
6269 int res;
6270
6271 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
6272 intf, off_ch_num);
6273 if (res < 0 || res >= (int) sizeof(buf))
6274 return -1;
6275 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6276 if (system(buf) != 0) {
6277 send_resp(dut, conn, SIGMA_ERROR,
6278 "errorCode,Failed to set offchan");
6279 return 0;
6280 }
6281
6282 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
6283 intf, off_chan_val(sec));
6284 if (res < 0 || res >= (int) sizeof(buf))
6285 return -1;
6286 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6287 if (system(buf) != 0) {
6288 send_resp(dut, conn, SIGMA_ERROR,
6289 "errorCode,Failed to set sec chan offset");
6290 return 0;
6291 }
6292
6293 return 1;
6294}
6295
6296
6297static int tdls_set_offchannel_offset(struct sigma_dut *dut,
6298 struct sigma_conn *conn,
6299 const char *intf, int off_ch_num,
6300 enum sec_ch_offset sec)
6301{
6302 char buf[200];
6303 int res;
6304
6305 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
6306 off_ch_num);
6307 if (res < 0 || res >= (int) sizeof(buf))
6308 return -1;
6309 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6310
6311 if (wpa_command(intf, buf) < 0) {
6312 send_resp(dut, conn, SIGMA_ERROR,
6313 "ErrorCode,Failed to set offchan");
6314 return 0;
6315 }
6316 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
6317 off_chan_val(sec));
6318 if (res < 0 || res >= (int) sizeof(buf))
6319 return -1;
6320
6321 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6322
6323 if (wpa_command(intf, buf) < 0) {
6324 send_resp(dut, conn, SIGMA_ERROR,
6325 "ErrorCode,Failed to set sec chan offset");
6326 return 0;
6327 }
6328
6329 return 1;
6330}
6331
6332
6333static int tdls_set_offchannel_mode(struct sigma_dut *dut,
6334 struct sigma_conn *conn,
6335 const char *intf, int val)
6336{
6337 char buf[200];
6338 int res;
6339
6340 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
6341 val);
6342 if (res < 0 || res >= (int) sizeof(buf))
6343 return -1;
6344 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6345
6346 if (wpa_command(intf, buf) < 0) {
6347 send_resp(dut, conn, SIGMA_ERROR,
6348 "ErrorCode,Failed to configure offchannel mode");
6349 return 0;
6350 }
6351
6352 return 1;
6353}
6354
6355
6356static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
6357 struct sigma_conn *conn,
6358 struct sigma_cmd *cmd)
6359{
6360 const char *val;
6361 enum {
6362 CHSM_NOT_SET,
6363 CHSM_ENABLE,
6364 CHSM_DISABLE,
6365 CHSM_REJREQ,
6366 CHSM_UNSOLRESP
6367 } chsm = CHSM_NOT_SET;
6368 int off_ch_num = -1;
6369 enum sec_ch_offset sec_ch = SEC_CH_NO;
6370 int res;
6371
6372 val = get_param(cmd, "Uapsd");
6373 if (val) {
6374 char buf[100];
6375 if (strcasecmp(val, "Enable") == 0)
6376 snprintf(buf, sizeof(buf), "SET ps 99");
6377 else if (strcasecmp(val, "Disable") == 0)
6378 snprintf(buf, sizeof(buf), "SET ps 98");
6379 else {
6380 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
6381 "Unsupported uapsd parameter value");
6382 return 0;
6383 }
6384 if (wpa_command(intf, buf)) {
6385 send_resp(dut, conn, SIGMA_ERROR,
6386 "ErrorCode,Failed to change U-APSD "
6387 "powersave mode");
6388 return 0;
6389 }
6390 }
6391
6392 val = get_param(cmd, "TPKTIMER");
6393 if (val && strcasecmp(val, "DISABLE") == 0) {
6394 if (wpa_command(intf, "SET tdls_testing 0x100")) {
6395 send_resp(dut, conn, SIGMA_ERROR,
6396 "ErrorCode,Failed to enable no TPK "
6397 "expiration test mode");
6398 return 0;
6399 }
6400 dut->no_tpk_expiration = 1;
6401 }
6402
6403 val = get_param(cmd, "ChSwitchMode");
6404 if (val) {
6405 if (strcasecmp(val, "Enable") == 0 ||
6406 strcasecmp(val, "Initiate") == 0)
6407 chsm = CHSM_ENABLE;
6408 else if (strcasecmp(val, "Disable") == 0 ||
6409 strcasecmp(val, "passive") == 0)
6410 chsm = CHSM_DISABLE;
6411 else if (strcasecmp(val, "RejReq") == 0)
6412 chsm = CHSM_REJREQ;
6413 else if (strcasecmp(val, "UnSolResp") == 0)
6414 chsm = CHSM_UNSOLRESP;
6415 else {
6416 send_resp(dut, conn, SIGMA_ERROR,
6417 "ErrorCode,Unknown ChSwitchMode value");
6418 return 0;
6419 }
6420 }
6421
6422 val = get_param(cmd, "OffChNum");
6423 if (val) {
6424 off_ch_num = atoi(val);
6425 if (off_ch_num == 0) {
6426 send_resp(dut, conn, SIGMA_ERROR,
6427 "ErrorCode,Invalid OffChNum");
6428 return 0;
6429 }
6430 }
6431
6432 val = get_param(cmd, "SecChOffset");
6433 if (val) {
6434 if (strcmp(val, "20") == 0)
6435 sec_ch = SEC_CH_NO;
6436 else if (strcasecmp(val, "40above") == 0)
6437 sec_ch = SEC_CH_40ABOVE;
6438 else if (strcasecmp(val, "40below") == 0)
6439 sec_ch = SEC_CH_40BELOW;
6440 else {
6441 send_resp(dut, conn, SIGMA_ERROR,
6442 "ErrorCode,Unknown SecChOffset value");
6443 return 0;
6444 }
6445 }
6446
6447 if (chsm == CHSM_NOT_SET) {
6448 /* no offchannel changes requested */
6449 return 1;
6450 }
6451
6452 if (strcmp(intf, get_main_ifname()) != 0 &&
6453 strcmp(intf, get_station_ifname()) != 0) {
6454 send_resp(dut, conn, SIGMA_ERROR,
6455 "ErrorCode,Unknown interface");
6456 return 0;
6457 }
6458
6459 switch (chsm) {
6460 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +03006461 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006462 break;
6463 case CHSM_ENABLE:
6464 if (off_ch_num < 0) {
6465 send_resp(dut, conn, SIGMA_ERROR,
6466 "ErrorCode,Missing OffChNum argument");
6467 return 0;
6468 }
6469 if (wifi_chip_type == DRIVER_WCN) {
6470 res = tdls_set_offchannel_offset(dut, conn, intf,
6471 off_ch_num, sec_ch);
6472 } else {
6473 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
6474 sec_ch);
6475 }
6476 if (res != 1)
6477 return res;
6478 if (wifi_chip_type == DRIVER_WCN)
6479 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
6480 else
6481 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
6482 break;
6483 case CHSM_DISABLE:
6484 if (wifi_chip_type == DRIVER_WCN)
6485 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
6486 else
6487 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
6488 break;
6489 case CHSM_REJREQ:
6490 if (wifi_chip_type == DRIVER_WCN)
6491 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
6492 else
6493 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
6494 break;
6495 case CHSM_UNSOLRESP:
6496 if (off_ch_num < 0) {
6497 send_resp(dut, conn, SIGMA_ERROR,
6498 "ErrorCode,Missing OffChNum argument");
6499 return 0;
6500 }
6501 if (wifi_chip_type == DRIVER_WCN) {
6502 res = tdls_set_offchannel_offset(dut, conn, intf,
6503 off_ch_num, sec_ch);
6504 } else {
6505 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
6506 sec_ch);
6507 }
6508 if (res != 1)
6509 return res;
6510 if (wifi_chip_type == DRIVER_WCN)
6511 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
6512 else
6513 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
6514 break;
6515 }
6516
6517 return res;
6518}
6519
6520
6521static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
6522 struct sigma_conn *conn,
6523 struct sigma_cmd *cmd)
6524{
6525 const char *val;
6526 char *token, *result;
6527
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08006528 novap_reset(dut, intf);
6529
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006530 val = get_param(cmd, "nss_mcs_opt");
6531 if (val) {
6532 /* String (nss_operating_mode; mcs_operating_mode) */
6533 int nss, mcs;
6534 char buf[50];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306535 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006536
6537 token = strdup(val);
6538 if (!token)
6539 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306540 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05306541 if (!result) {
6542 sigma_dut_print(dut, DUT_MSG_ERROR,
6543 "VHT NSS not specified");
6544 goto failed;
6545 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006546 if (strcasecmp(result, "def") != 0) {
6547 nss = atoi(result);
6548 if (nss == 4)
6549 ath_disable_txbf(dut, intf);
6550 snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
6551 intf, nss);
6552 if (system(buf) != 0) {
6553 sigma_dut_print(dut, DUT_MSG_ERROR,
6554 "iwpriv nss failed");
6555 goto failed;
6556 }
6557 }
6558
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306559 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05306560 if (!result) {
6561 sigma_dut_print(dut, DUT_MSG_ERROR,
6562 "VHT MCS not specified");
6563 goto failed;
6564 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006565 if (strcasecmp(result, "def") == 0) {
6566 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0",
6567 intf);
6568 if (system(buf) != 0) {
6569 sigma_dut_print(dut, DUT_MSG_ERROR,
6570 "iwpriv set11NRates failed");
6571 goto failed;
6572 }
6573
6574 } else {
6575 mcs = atoi(result);
6576 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
6577 intf, mcs);
6578 if (system(buf) != 0) {
6579 sigma_dut_print(dut, DUT_MSG_ERROR,
6580 "iwpriv vhtmcs failed");
6581 goto failed;
6582 }
6583 }
6584 /* Channel width gets messed up, fix this */
6585 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
6586 intf, dut->chwidth);
6587 if (system(buf) != 0) {
6588 sigma_dut_print(dut, DUT_MSG_ERROR,
6589 "iwpriv chwidth failed");
6590 }
6591 }
6592
6593 return 1;
6594failed:
6595 free(token);
6596 return 0;
6597}
6598
6599
6600static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
6601 struct sigma_conn *conn,
6602 struct sigma_cmd *cmd)
6603{
6604 switch (get_driver_type()) {
6605 case DRIVER_ATHEROS:
6606 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
6607 default:
6608 send_resp(dut, conn, SIGMA_ERROR,
6609 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
6610 return 0;
6611 }
6612}
6613
6614
6615static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
6616 struct sigma_cmd *cmd)
6617{
6618 const char *intf = get_param(cmd, "Interface");
6619 const char *prog = get_param(cmd, "Prog");
6620
6621 if (intf == NULL || prog == NULL)
6622 return -1;
6623
6624 if (strcasecmp(prog, "TDLS") == 0)
6625 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
6626
6627 if (strcasecmp(prog, "VHT") == 0)
6628 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
6629
6630 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
6631 return 0;
6632}
6633
6634
6635static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
6636 struct sigma_cmd *cmd)
6637{
6638 const char *intf = get_param(cmd, "Interface");
6639 const char *mode = get_param(cmd, "Mode");
6640 int res;
6641
6642 if (intf == NULL || mode == NULL)
6643 return -1;
6644
6645 if (strcasecmp(mode, "On") == 0)
6646 res = wpa_command(intf, "SET radio_disabled 0");
6647 else if (strcasecmp(mode, "Off") == 0)
6648 res = wpa_command(intf, "SET radio_disabled 1");
6649 else
6650 return -1;
6651
6652 if (res) {
6653 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
6654 "radio mode");
6655 return 0;
6656 }
6657
6658 return 1;
6659}
6660
6661
6662static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
6663 struct sigma_cmd *cmd)
6664{
6665 const char *intf = get_param(cmd, "Interface");
6666 const char *mode = get_param(cmd, "Mode");
6667 int res;
6668
6669 if (intf == NULL || mode == NULL)
6670 return -1;
6671
6672 if (strcasecmp(mode, "On") == 0)
6673 res = set_ps(intf, dut, 1);
6674 else if (strcasecmp(mode, "Off") == 0)
6675 res = set_ps(intf, dut, 0);
6676 else
6677 return -1;
6678
6679 if (res) {
6680 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
6681 "power save mode");
6682 return 0;
6683 }
6684
6685 return 1;
6686}
6687
6688
6689static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
6690 struct sigma_cmd *cmd)
6691{
6692 const char *intf = get_param(cmd, "Interface");
6693 const char *val, *bssid;
6694 int res;
6695 char *buf;
6696 size_t buf_len;
6697
6698 val = get_param(cmd, "BSSID_FILTER");
6699 if (val == NULL)
6700 return -1;
6701
6702 bssid = get_param(cmd, "BSSID_List");
6703 if (atoi(val) == 0 || bssid == NULL) {
6704 /* Disable BSSID filter */
6705 if (wpa_command(intf, "SET bssid_filter ")) {
6706 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
6707 "to disable BSSID filter");
6708 return 0;
6709 }
6710
6711 return 1;
6712 }
6713
6714 buf_len = 100 + strlen(bssid);
6715 buf = malloc(buf_len);
6716 if (buf == NULL)
6717 return -1;
6718
6719 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
6720 res = wpa_command(intf, buf);
6721 free(buf);
6722 if (res) {
6723 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
6724 "BSSID filter");
6725 return 0;
6726 }
6727
6728 return 1;
6729}
6730
6731
6732static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
6733 struct sigma_cmd *cmd)
6734{
6735 const char *intf = get_param(cmd, "Interface");
6736 const char *val;
6737
6738 /* TODO: ARP */
6739
6740 val = get_param(cmd, "HS2_CACHE_PROFILE");
6741 if (val && strcasecmp(val, "All") == 0)
6742 hs2_clear_credentials(intf);
6743
6744 return 1;
6745}
6746
6747
6748static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
6749 struct sigma_cmd *cmd)
6750{
6751 const char *intf = get_param(cmd, "Interface");
6752 const char *key_type = get_param(cmd, "KeyType");
6753 char buf[100], resp[200];
6754
6755 if (key_type == NULL)
6756 return -1;
6757
6758 if (strcasecmp(key_type, "GTK") == 0) {
6759 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
6760 strncmp(buf, "FAIL", 4) == 0) {
6761 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
6762 "not fetch current GTK");
6763 return 0;
6764 }
6765 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
6766 send_resp(dut, conn, SIGMA_COMPLETE, resp);
6767 return 0;
6768 } else {
6769 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
6770 "KeyType");
6771 return 0;
6772 }
6773
6774 return 1;
6775}
6776
6777
6778static int hs2_set_policy(struct sigma_dut *dut)
6779{
6780#ifdef ANDROID
6781 system("ip rule del prio 23000");
6782 if (system("ip rule add from all lookup main prio 23000") != 0) {
6783 sigma_dut_print(dut, DUT_MSG_ERROR,
6784 "Failed to run:ip rule add from all lookup main prio");
6785 return -1;
6786 }
6787 if (system("ip route flush cache") != 0) {
6788 sigma_dut_print(dut, DUT_MSG_ERROR,
6789 "Failed to run ip route flush cache");
6790 return -1;
6791 }
6792 return 1;
6793#else /* ANDROID */
6794 return 0;
6795#endif /* ANDROID */
6796}
6797
6798
6799static int cmd_sta_hs2_associate(struct sigma_dut *dut,
6800 struct sigma_conn *conn,
6801 struct sigma_cmd *cmd)
6802{
6803 const char *intf = get_param(cmd, "Interface");
6804 const char *val = get_param(cmd, "Ignore_blacklist");
6805 struct wpa_ctrl *ctrl;
6806 int res;
6807 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
6808 int tries = 0;
6809 int ignore_blacklist = 0;
6810 const char *events[] = {
6811 "CTRL-EVENT-CONNECTED",
6812 "INTERWORKING-BLACKLISTED",
6813 "INTERWORKING-NO-MATCH",
6814 NULL
6815 };
6816
6817 start_sta_mode(dut);
6818
6819 blacklisted[0] = '\0';
6820 if (val && atoi(val))
6821 ignore_blacklist = 1;
6822
6823try_again:
6824 ctrl = open_wpa_mon(intf);
6825 if (ctrl == NULL) {
6826 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6827 "wpa_supplicant monitor connection");
6828 return -2;
6829 }
6830
6831 tries++;
6832 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
6833 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
6834 "Interworking connection");
6835 wpa_ctrl_detach(ctrl);
6836 wpa_ctrl_close(ctrl);
6837 return 0;
6838 }
6839
6840 buf[0] = '\0';
6841 while (1) {
6842 char *pos;
6843 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
6844 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
6845 if (!pos)
6846 break;
6847 pos += 25;
6848 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
6849 pos);
6850 if (!blacklisted[0])
6851 memcpy(blacklisted, pos, strlen(pos) + 1);
6852 }
6853
6854 if (ignore_blacklist && blacklisted[0]) {
6855 char *end;
6856 end = strchr(blacklisted, ' ');
6857 if (end)
6858 *end = '\0';
6859 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
6860 blacklisted);
6861 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
6862 blacklisted);
6863 if (wpa_command(intf, buf)) {
6864 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
6865 wpa_ctrl_detach(ctrl);
6866 wpa_ctrl_close(ctrl);
6867 return 0;
6868 }
6869 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6870 buf, sizeof(buf));
6871 }
6872
6873 wpa_ctrl_detach(ctrl);
6874 wpa_ctrl_close(ctrl);
6875
6876 if (res < 0) {
6877 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
6878 "connect");
6879 return 0;
6880 }
6881
6882 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
6883 strstr(buf, "INTERWORKING-BLACKLISTED")) {
6884 if (tries < 2) {
6885 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
6886 goto try_again;
6887 }
6888 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
6889 "matching credentials found");
6890 return 0;
6891 }
6892
6893 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
6894 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
6895 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
6896 "get current BSSID/SSID");
6897 return 0;
6898 }
6899
6900 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
6901 send_resp(dut, conn, SIGMA_COMPLETE, resp);
6902 hs2_set_policy(dut);
6903 return 0;
6904}
6905
6906
6907static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
6908 struct sigma_conn *conn,
6909 const char *ifname,
6910 struct sigma_cmd *cmd)
6911{
6912 const char *val;
6913 int id;
6914
6915 id = add_cred(ifname);
6916 if (id < 0)
6917 return -2;
6918 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
6919
6920 val = get_param(cmd, "prefer");
6921 if (val && atoi(val) > 0)
6922 set_cred(ifname, id, "priority", "1");
6923
6924 val = get_param(cmd, "REALM");
6925 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
6926 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
6927 "realm");
6928 return 0;
6929 }
6930
6931 val = get_param(cmd, "HOME_FQDN");
6932 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
6933 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
6934 "home_fqdn");
6935 return 0;
6936 }
6937
6938 val = get_param(cmd, "Username");
6939 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
6940 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
6941 "username");
6942 return 0;
6943 }
6944
6945 val = get_param(cmd, "Password");
6946 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
6947 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
6948 "password");
6949 return 0;
6950 }
6951
6952 val = get_param(cmd, "ROOT_CA");
6953 if (val) {
6954 char fname[200];
6955 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
6956#ifdef __linux__
6957 if (!file_exists(fname)) {
6958 char msg[300];
6959 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
6960 "file (%s) not found", fname);
6961 send_resp(dut, conn, SIGMA_ERROR, msg);
6962 return 0;
6963 }
6964#endif /* __linux__ */
6965 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
6966 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
6967 "not set root CA");
6968 return 0;
6969 }
6970 }
6971
6972 return 1;
6973}
6974
6975
6976static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
6977{
6978 FILE *in, *out;
6979 char buf[500];
6980 int found = 0;
6981
6982 in = fopen("devdetail.xml", "r");
6983 if (in == NULL)
6984 return -1;
6985 out = fopen("devdetail.xml.tmp", "w");
6986 if (out == NULL) {
6987 fclose(in);
6988 return -1;
6989 }
6990
6991 while (fgets(buf, sizeof(buf), in)) {
6992 char *pos = strstr(buf, "<IMSI>");
6993 if (pos) {
6994 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
6995 imsi);
6996 pos += 6;
6997 *pos = '\0';
6998 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
6999 found++;
7000 } else {
7001 fprintf(out, "%s", buf);
7002 }
7003 }
7004
7005 fclose(out);
7006 fclose(in);
7007 if (found)
7008 rename("devdetail.xml.tmp", "devdetail.xml");
7009 else
7010 unlink("devdetail.xml.tmp");
7011
7012 return 0;
7013}
7014
7015
7016static int sta_add_credential_sim(struct sigma_dut *dut,
7017 struct sigma_conn *conn,
7018 const char *ifname, struct sigma_cmd *cmd)
7019{
7020 const char *val, *imsi = NULL;
7021 int id;
7022 char buf[200];
7023 int res;
7024 const char *pos;
7025 size_t mnc_len;
7026 char plmn_mcc[4];
7027 char plmn_mnc[4];
7028
7029 id = add_cred(ifname);
7030 if (id < 0)
7031 return -2;
7032 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
7033
7034 val = get_param(cmd, "prefer");
7035 if (val && atoi(val) > 0)
7036 set_cred(ifname, id, "priority", "1");
7037
7038 val = get_param(cmd, "PLMN_MCC");
7039 if (val == NULL) {
7040 send_resp(dut, conn, SIGMA_ERROR,
7041 "errorCode,Missing PLMN_MCC");
7042 return 0;
7043 }
7044 if (strlen(val) != 3) {
7045 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
7046 return 0;
7047 }
7048 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
7049
7050 val = get_param(cmd, "PLMN_MNC");
7051 if (val == NULL) {
7052 send_resp(dut, conn, SIGMA_ERROR,
7053 "errorCode,Missing PLMN_MNC");
7054 return 0;
7055 }
7056 if (strlen(val) != 2 && strlen(val) != 3) {
7057 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
7058 return 0;
7059 }
7060 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
7061
7062 val = get_param(cmd, "IMSI");
7063 if (val == NULL) {
7064 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
7065 "IMSI");
7066 return 0;
7067 }
7068
7069 imsi = pos = val;
7070
7071 if (strncmp(plmn_mcc, pos, 3) != 0) {
7072 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
7073 return 0;
7074 }
7075 pos += 3;
7076
7077 mnc_len = strlen(plmn_mnc);
7078 if (mnc_len < 2) {
7079 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
7080 return 0;
7081 }
7082
7083 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
7084 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
7085 return 0;
7086 }
7087 pos += mnc_len;
7088
7089 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
7090 if (res < 0 || res >= (int) sizeof(buf))
7091 return -1;
7092 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
7093 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7094 "not set IMSI");
7095 return 0;
7096 }
7097
7098 val = get_param(cmd, "Password");
7099 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
7100 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7101 "not set password");
7102 return 0;
7103 }
7104
7105 if (dut->program == PROGRAM_HS2_R2) {
7106 /*
7107 * Set provisioning_sp for the test cases where SIM/USIM
7108 * provisioning is used.
7109 */
7110 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
7111 "wi-fi.org") < 0) {
7112 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7113 "not set provisioning_sp");
7114 return 0;
7115 }
7116
7117 update_devdetail_imsi(dut, imsi);
7118 }
7119
7120 return 1;
7121}
7122
7123
7124static int sta_add_credential_cert(struct sigma_dut *dut,
7125 struct sigma_conn *conn,
7126 const char *ifname,
7127 struct sigma_cmd *cmd)
7128{
7129 const char *val;
7130 int id;
7131
7132 id = add_cred(ifname);
7133 if (id < 0)
7134 return -2;
7135 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
7136
7137 val = get_param(cmd, "prefer");
7138 if (val && atoi(val) > 0)
7139 set_cred(ifname, id, "priority", "1");
7140
7141 val = get_param(cmd, "REALM");
7142 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
7143 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
7144 "realm");
7145 return 0;
7146 }
7147
7148 val = get_param(cmd, "HOME_FQDN");
7149 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
7150 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
7151 "home_fqdn");
7152 return 0;
7153 }
7154
7155 val = get_param(cmd, "Username");
7156 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
7157 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
7158 "username");
7159 return 0;
7160 }
7161
7162 val = get_param(cmd, "clientCertificate");
7163 if (val) {
7164 char fname[200];
7165 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
7166#ifdef __linux__
7167 if (!file_exists(fname)) {
7168 char msg[300];
7169 snprintf(msg, sizeof(msg),
7170 "ErrorCode,clientCertificate "
7171 "file (%s) not found", fname);
7172 send_resp(dut, conn, SIGMA_ERROR, msg);
7173 return 0;
7174 }
7175#endif /* __linux__ */
7176 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
7177 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7178 "not set client_cert");
7179 return 0;
7180 }
7181 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
7182 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7183 "not set private_key");
7184 return 0;
7185 }
7186 }
7187
7188 val = get_param(cmd, "ROOT_CA");
7189 if (val) {
7190 char fname[200];
7191 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
7192#ifdef __linux__
7193 if (!file_exists(fname)) {
7194 char msg[300];
7195 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
7196 "file (%s) not found", fname);
7197 send_resp(dut, conn, SIGMA_ERROR, msg);
7198 return 0;
7199 }
7200#endif /* __linux__ */
7201 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
7202 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7203 "not set root CA");
7204 return 0;
7205 }
7206 }
7207
7208 return 1;
7209}
7210
7211
7212static int cmd_sta_add_credential(struct sigma_dut *dut,
7213 struct sigma_conn *conn,
7214 struct sigma_cmd *cmd)
7215{
7216 const char *intf = get_param(cmd, "Interface");
7217 const char *type;
7218
7219 start_sta_mode(dut);
7220
7221 type = get_param(cmd, "Type");
7222 if (!type)
7223 return -1;
7224
7225 if (strcasecmp(type, "uname_pwd") == 0)
7226 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
7227
7228 if (strcasecmp(type, "sim") == 0)
7229 return sta_add_credential_sim(dut, conn, intf, cmd);
7230
7231 if (strcasecmp(type, "cert") == 0)
7232 return sta_add_credential_cert(dut, conn, intf, cmd);
7233
7234 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
7235 "type");
7236 return 0;
7237}
7238
7239
7240static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
7241 struct sigma_cmd *cmd)
7242{
7243 const char *intf = get_param(cmd, "Interface");
7244 const char *val;
7245 char buf[100];
7246 int res;
7247
7248 val = get_param(cmd, "HESSID");
7249 if (val) {
7250 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
7251 if (res < 0 || res >= (int) sizeof(buf))
7252 return -1;
7253 wpa_command(intf, buf);
7254 }
7255
7256 val = get_param(cmd, "ACCS_NET_TYPE");
7257 if (val) {
7258 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
7259 val);
7260 if (res < 0 || res >= (int) sizeof(buf))
7261 return -1;
7262 wpa_command(intf, buf);
7263 }
7264
7265 if (wpa_command(intf, "SCAN")) {
7266 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
7267 "scan");
7268 return 0;
7269 }
7270
7271 return 1;
7272}
7273
7274
7275static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
7276 struct sigma_cmd *cmd)
7277{
7278#ifdef __linux__
7279 struct timeval tv;
7280 struct tm tm;
7281 time_t t;
7282 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +05307283 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007284
7285 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
7286
7287 memset(&tm, 0, sizeof(tm));
7288 val = get_param(cmd, "seconds");
7289 if (val)
7290 tm.tm_sec = atoi(val);
7291 val = get_param(cmd, "minutes");
7292 if (val)
7293 tm.tm_min = atoi(val);
7294 val = get_param(cmd, "hours");
7295 if (val)
7296 tm.tm_hour = atoi(val);
7297 val = get_param(cmd, "date");
7298 if (val)
7299 tm.tm_mday = atoi(val);
7300 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +05307301 if (val) {
7302 v = atoi(val);
7303 if (v < 1 || v > 12) {
7304 send_resp(dut, conn, SIGMA_INVALID,
7305 "errorCode,Invalid month");
7306 return 0;
7307 }
7308 tm.tm_mon = v - 1;
7309 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007310 val = get_param(cmd, "year");
7311 if (val) {
7312 int year = atoi(val);
7313#ifdef ANDROID
7314 if (year > 2035)
7315 year = 2035; /* years beyond 2035 not supported */
7316#endif /* ANDROID */
7317 tm.tm_year = year - 1900;
7318 }
7319 t = mktime(&tm);
7320 if (t == (time_t) -1) {
7321 send_resp(dut, conn, SIGMA_ERROR,
7322 "errorCode,Invalid date or time");
7323 return 0;
7324 }
7325
7326 memset(&tv, 0, sizeof(tv));
7327 tv.tv_sec = t;
7328
7329 if (settimeofday(&tv, NULL) < 0) {
7330 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
7331 strerror(errno));
7332 send_resp(dut, conn, SIGMA_ERROR,
7333 "errorCode,Failed to set time");
7334 return 0;
7335 }
7336
7337 return 1;
7338#endif /* __linux__ */
7339
7340 return -1;
7341}
7342
7343
7344static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
7345 struct sigma_cmd *cmd)
7346{
7347 const char *intf = get_param(cmd, "Interface");
7348 const char *name, *val;
7349 int prod_ess_assoc = 1;
7350 char buf[200], bssid[100], ssid[100];
7351 int res;
7352 struct wpa_ctrl *ctrl;
7353
7354 name = get_param(cmd, "osuFriendlyName");
7355
7356 val = get_param(cmd, "ProdESSAssoc");
7357 if (val)
7358 prod_ess_assoc = atoi(val);
7359
7360 kill_dhcp_client(dut, intf);
7361 if (start_dhcp_client(dut, intf) < 0)
7362 return -2;
7363
7364 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
7365 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
7366 res = snprintf(buf, sizeof(buf),
7367 "%s %s%s%s signup osu-ca.pem",
7368 prod_ess_assoc ? "" : "-N",
7369 name ? "-O'" : "", name ? name : "",
7370 name ? "'" : "");
7371
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +05307372 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007373 if (run_hs20_osu(dut, buf) < 0) {
7374 FILE *f;
7375
7376 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
7377
7378 f = fopen("hs20-osu-client.res", "r");
7379 if (f) {
7380 char resp[400], res[300], *pos;
7381 if (!fgets(res, sizeof(res), f))
7382 res[0] = '\0';
7383 pos = strchr(res, '\n');
7384 if (pos)
7385 *pos = '\0';
7386 fclose(f);
7387 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
7388 res);
7389 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
7390 if (system(resp) != 0) {
7391 }
7392 snprintf(resp, sizeof(resp),
7393 "SSID,,BSSID,,failureReason,%s", res);
7394 send_resp(dut, conn, SIGMA_COMPLETE, resp);
7395 return 0;
7396 }
7397
7398 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
7399 return 0;
7400 }
7401
7402 if (!prod_ess_assoc)
7403 goto report;
7404
7405 ctrl = open_wpa_mon(intf);
7406 if (ctrl == NULL) {
7407 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7408 "wpa_supplicant monitor connection");
7409 return -1;
7410 }
7411
7412 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
7413 buf, sizeof(buf));
7414
7415 wpa_ctrl_detach(ctrl);
7416 wpa_ctrl_close(ctrl);
7417
7418 if (res < 0) {
7419 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
7420 "network after OSU");
7421 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
7422 return 0;
7423 }
7424
7425report:
7426 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
7427 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
7428 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
7429 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
7430 return 0;
7431 }
7432
7433 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
7434 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007435 return 0;
7436}
7437
7438
7439static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
7440 struct sigma_cmd *cmd)
7441{
7442 const char *val;
7443 int timeout = 120;
7444
7445 val = get_param(cmd, "PolicyUpdate");
7446 if (val == NULL || atoi(val) == 0)
7447 return 1; /* No operation requested */
7448
7449 val = get_param(cmd, "Timeout");
7450 if (val)
7451 timeout = atoi(val);
7452
7453 if (timeout) {
7454 /* TODO: time out the command and return
7455 * PolicyUpdateStatus,TIMEOUT if needed. */
7456 }
7457
7458 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
7459 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
7460 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
7461 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
7462 return 0;
7463 }
7464
7465 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
7466 return 0;
7467}
7468
7469
7470static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
7471 struct sigma_cmd *cmd)
7472{
7473 struct wpa_ctrl *ctrl;
7474 const char *intf = get_param(cmd, "Interface");
7475 const char *bssid = get_param(cmd, "Bssid");
7476 const char *ssid = get_param(cmd, "SSID");
7477 const char *security = get_param(cmd, "Security");
7478 const char *passphrase = get_param(cmd, "Passphrase");
7479 const char *pin = get_param(cmd, "PIN");
7480 char buf[1000];
7481 char ssid_hex[200], passphrase_hex[200];
7482 const char *keymgmt, *cipher;
7483
7484 if (intf == NULL)
7485 intf = get_main_ifname();
7486
7487 if (!bssid) {
7488 send_resp(dut, conn, SIGMA_ERROR,
7489 "ErrorCode,Missing Bssid argument");
7490 return 0;
7491 }
7492
7493 if (!ssid) {
7494 send_resp(dut, conn, SIGMA_ERROR,
7495 "ErrorCode,Missing SSID argument");
7496 return 0;
7497 }
7498
7499 if (!security) {
7500 send_resp(dut, conn, SIGMA_ERROR,
7501 "ErrorCode,Missing Security argument");
7502 return 0;
7503 }
7504
7505 if (!passphrase) {
7506 send_resp(dut, conn, SIGMA_ERROR,
7507 "ErrorCode,Missing Passphrase argument");
7508 return 0;
7509 }
7510
7511 if (!pin) {
7512 send_resp(dut, conn, SIGMA_ERROR,
7513 "ErrorCode,Missing PIN argument");
7514 return 0;
7515 }
7516
7517 if (strlen(ssid) >= 2 * sizeof(ssid_hex) ||
7518 strlen(passphrase) >= 2 * sizeof(passphrase_hex)) {
7519 send_resp(dut, conn, SIGMA_ERROR,
7520 "ErrorCode,Too long SSID/passphrase");
7521 return 0;
7522 }
7523
7524 ctrl = open_wpa_mon(intf);
7525 if (ctrl == NULL) {
7526 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7527 "wpa_supplicant monitor connection");
7528 return -2;
7529 }
7530
7531 if (strcasecmp(security, "wpa2-psk") == 0) {
7532 keymgmt = "WPA2PSK";
7533 cipher = "CCMP";
7534 } else {
7535 wpa_ctrl_detach(ctrl);
7536 wpa_ctrl_close(ctrl);
7537 send_resp(dut, conn, SIGMA_ERROR,
7538 "ErrorCode,Unsupported Security value");
7539 return 0;
7540 }
7541
7542 ascii2hexstr(ssid, ssid_hex);
7543 ascii2hexstr(passphrase, passphrase_hex);
7544 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
7545 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
7546
7547 if (wpa_command(intf, buf) < 0) {
7548 wpa_ctrl_detach(ctrl);
7549 wpa_ctrl_close(ctrl);
7550 send_resp(dut, conn, SIGMA_ERROR,
7551 "ErrorCode,Failed to start registrar");
7552 return 0;
7553 }
7554
7555 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
7556 dut->er_oper_performed = 1;
7557
7558 return wps_connection_event(dut, conn, ctrl, intf, 0);
7559}
7560
7561
7562static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
7563 struct sigma_conn *conn,
7564 struct sigma_cmd *cmd)
7565{
7566 struct wpa_ctrl *ctrl;
7567 const char *intf = get_param(cmd, "Interface");
7568 const char *bssid = get_param(cmd, "Bssid");
7569 char buf[100];
7570
7571 if (!bssid) {
7572 send_resp(dut, conn, SIGMA_ERROR,
7573 "ErrorCode,Missing Bssid argument");
7574 return 0;
7575 }
7576
7577 ctrl = open_wpa_mon(intf);
7578 if (ctrl == NULL) {
7579 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7580 "wpa_supplicant monitor connection");
7581 return -2;
7582 }
7583
7584 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
7585
7586 if (wpa_command(intf, buf) < 0) {
7587 wpa_ctrl_detach(ctrl);
7588 wpa_ctrl_close(ctrl);
7589 send_resp(dut, conn, SIGMA_ERROR,
7590 "ErrorCode,Failed to start registrar");
7591 return 0;
7592 }
7593
7594 return wps_connection_event(dut, conn, ctrl, intf, 0);
7595}
7596
7597
7598static int req_intf(struct sigma_cmd *cmd)
7599{
7600 return get_param(cmd, "interface") == NULL ? -1 : 0;
7601}
7602
7603
7604void sta_register_cmds(void)
7605{
7606 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
7607 cmd_sta_get_ip_config);
7608 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
7609 cmd_sta_set_ip_config);
7610 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
7611 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
7612 cmd_sta_get_mac_address);
7613 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
7614 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
7615 cmd_sta_verify_ip_connection);
7616 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
7617 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
7618 cmd_sta_set_encryption);
7619 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
7620 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
7621 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
7622 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
7623 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
7624 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
7625 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
7626 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
7627 cmd_sta_set_eapakaprime);
7628 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
7629 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
7630 /* TODO: sta_set_ibss */
7631 /* TODO: sta_set_mode */
7632 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
7633 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
7634 /* TODO: sta_up_load */
7635 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
7636 cmd_sta_preset_testparameters);
7637 /* TODO: sta_set_system */
7638 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
7639 /* TODO: sta_set_rifs_test */
7640 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
7641 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
7642 /* TODO: sta_send_coexist_mgmt */
7643 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
7644 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
7645 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
7646 sigma_dut_reg_cmd("sta_reset_default", req_intf,
7647 cmd_sta_reset_default);
7648 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
7649 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
7650 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
7651 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
7652 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
7653 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
7654 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
7655 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
7656 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
7657 cmd_sta_hs2_associate);
7658 sigma_dut_reg_cmd("sta_add_credential", req_intf,
7659 cmd_sta_add_credential);
7660 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
7661 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
7662 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
7663 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
7664 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
7665 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
7666 cmd_sta_wps_connect_pw_token);
7667 sigma_dut_reg_cmd("sta_exec_action", req_intf, cmd_sta_exec_action);
7668 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
7669 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
7670}