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