blob: 8cb5a79ab3178131ba21b37492b98648f2505e2b [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
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05302688static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
2689 const char *val)
2690{
2691 char buf[60];
2692
2693 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
2694 if (system(buf) != 0)
2695 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
2696
2697 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
2698 if (system(buf) != 0)
2699 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
2700}
2701
2702
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002703static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
2704 struct sigma_conn *conn,
2705 struct sigma_cmd *cmd)
2706{
2707 const char *intf = get_param(cmd, "Interface");
2708 const char *val;
2709
2710 val = get_param(cmd, "Program");
2711 if (val && strcasecmp(val, "HS2-R2") == 0) {
2712 if (intf == NULL)
2713 return -1;
2714 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
2715 cmd);
2716 }
2717
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07002718 if (val && strcasecmp(val, "LOC") == 0)
2719 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
2720
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002721#ifdef ANDROID_NAN
2722 if (val && strcasecmp(val, "NAN") == 0)
2723 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
2724#endif /* ANDROID_NAN */
2725
2726#if 0
2727 val = get_param(cmd, "Supplicant");
2728 if (val && strcasecmp(val, "Default") != 0) {
2729 send_resp(dut, conn, SIGMA_ERROR,
2730 "ErrorCode,Only default(Vendor) supplicant "
2731 "supported");
2732 return 0;
2733 }
2734#endif
2735
2736 val = get_param(cmd, "RTS");
2737 if (val) {
2738 switch (get_driver_type()) {
2739 case DRIVER_ATHEROS:
2740 ath_sta_set_rts(dut, intf, val);
2741 break;
2742 default:
2743#if 0
2744 send_resp(dut, conn, SIGMA_ERROR,
2745 "ErrorCode,Setting RTS not supported");
2746 return 0;
2747#else
2748 sigma_dut_print(dut, DUT_MSG_DEBUG,
2749 "Setting RTS not supported");
2750 break;
2751#endif
2752 }
2753 }
2754
2755#if 0
2756 val = get_param(cmd, "FRGMNT");
2757 if (val) {
2758 /* TODO */
2759 send_resp(dut, conn, SIGMA_ERROR,
2760 "ErrorCode,Setting FRGMNT not supported");
2761 return 0;
2762 }
2763#endif
2764
2765#if 0
2766 val = get_param(cmd, "Preamble");
2767 if (val) {
2768 /* TODO: Long/Short */
2769 send_resp(dut, conn, SIGMA_ERROR,
2770 "ErrorCode,Setting Preamble not supported");
2771 return 0;
2772 }
2773#endif
2774
2775 val = get_param(cmd, "Mode");
2776 if (val) {
2777 if (strcmp(val, "11b") == 0 ||
2778 strcmp(val, "11g") == 0 ||
2779 strcmp(val, "11a") == 0 ||
2780 strcmp(val, "11n") == 0 ||
2781 strcmp(val, "11ng") == 0 ||
2782 strcmp(val, "11nl") == 0 ||
2783 strcmp(val, "11nl(nabg)") == 0 ||
2784 strcmp(val, "AC") == 0 ||
2785 strcmp(val, "11AC") == 0 ||
2786 strcmp(val, "11ac") == 0 ||
2787 strcmp(val, "11na") == 0 ||
2788 strcmp(val, "11an") == 0) {
2789 /* STA supports all modes by default */
2790 } else {
2791 send_resp(dut, conn, SIGMA_ERROR,
2792 "ErrorCode,Setting Mode not supported");
2793 return 0;
2794 }
2795 }
2796
2797 val = get_param(cmd, "wmm");
2798 if (val) {
2799 switch (get_driver_type()) {
2800 case DRIVER_ATHEROS:
2801 ath_sta_set_wmm(dut, intf, val);
2802 break;
2803 default:
2804 sigma_dut_print(dut, DUT_MSG_DEBUG,
2805 "Setting wmm not supported");
2806 break;
2807 }
2808 }
2809
2810 val = get_param(cmd, "Powersave");
2811 if (val) {
2812 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
2813 if (wpa_command(get_station_ifname(),
2814 "P2P_SET ps 0") < 0)
2815 return -2;
2816 /* Make sure test modes are disabled */
2817 wpa_command(get_station_ifname(), "P2P_SET ps 98");
2818 wpa_command(get_station_ifname(), "P2P_SET ps 96");
2819 } else if (strcmp(val, "1") == 0 ||
2820 strcasecmp(val, "PSPoll") == 0 ||
2821 strcasecmp(val, "on") == 0) {
2822 /* Disable default power save mode */
2823 wpa_command(get_station_ifname(), "P2P_SET ps 0");
2824 /* Enable PS-Poll test mode */
2825 if (wpa_command(get_station_ifname(),
2826 "P2P_SET ps 97") < 0 ||
2827 wpa_command(get_station_ifname(),
2828 "P2P_SET ps 99") < 0)
2829 return -2;
2830 } else if (strcmp(val, "2") == 0 ||
2831 strcasecmp(val, "Fast") == 0) {
2832 /* TODO */
2833 send_resp(dut, conn, SIGMA_ERROR,
2834 "ErrorCode,Powersave=Fast not supported");
2835 return 0;
2836 } else if (strcmp(val, "3") == 0 ||
2837 strcasecmp(val, "PSNonPoll") == 0) {
2838 /* Make sure test modes are disabled */
2839 wpa_command(get_station_ifname(), "P2P_SET ps 98");
2840 wpa_command(get_station_ifname(), "P2P_SET ps 96");
2841
2842 /* Enable default power save mode */
2843 if (wpa_command(get_station_ifname(),
2844 "P2P_SET ps 1") < 0)
2845 return -2;
2846 } else
2847 return -1;
2848 }
2849
2850 val = get_param(cmd, "NoAck");
2851 if (val) {
2852 switch (get_driver_type()) {
2853 case DRIVER_ATHEROS:
2854 ath_sta_set_noack(dut, intf, val);
2855 break;
2856 default:
2857 send_resp(dut, conn, SIGMA_ERROR,
2858 "ErrorCode,Setting NoAck not supported");
2859 return 0;
2860 }
2861 }
2862
2863 val = get_param(cmd, "IgnoreChswitchProhibit");
2864 if (val) {
2865 /* TODO: Enabled/disabled */
2866 if (strcasecmp(val, "Enabled") == 0) {
2867 send_resp(dut, conn, SIGMA_ERROR,
2868 "ErrorCode,Enabling IgnoreChswitchProhibit "
2869 "not supported");
2870 return 0;
2871 }
2872 }
2873
2874 val = get_param(cmd, "TDLS");
2875 if (val) {
2876 if (strcasecmp(val, "Disabled") == 0) {
2877 if (wpa_command(intf, "SET tdls_disabled 1")) {
2878 send_resp(dut, conn, SIGMA_ERROR,
2879 "ErrorCode,Failed to disable TDLS");
2880 return 0;
2881 }
2882 } else if (strcasecmp(val, "Enabled") == 0) {
2883 if (wpa_command(intf, "SET tdls_disabled 0")) {
2884 send_resp(dut, conn, SIGMA_ERROR,
2885 "ErrorCode,Failed to enable TDLS");
2886 return 0;
2887 }
2888 } else {
2889 send_resp(dut, conn, SIGMA_ERROR,
2890 "ErrorCode,Unsupported TDLS value");
2891 return 0;
2892 }
2893 }
2894
2895 val = get_param(cmd, "TDLSmode");
2896 if (val) {
2897 if (strcasecmp(val, "Default") == 0) {
2898 wpa_command(intf, "SET tdls_testing 0");
2899 } else if (strcasecmp(val, "APProhibit") == 0) {
2900 if (wpa_command(intf, "SET tdls_testing 0x400")) {
2901 send_resp(dut, conn, SIGMA_ERROR,
2902 "ErrorCode,Failed to enable ignore "
2903 "APProhibit TDLS mode");
2904 return 0;
2905 }
2906 } else if (strcasecmp(val, "HiLoMac") == 0) {
2907 /* STA should respond with TDLS setup req for a TDLS
2908 * setup req */
2909 if (wpa_command(intf, "SET tdls_testing 0x80")) {
2910 send_resp(dut, conn, SIGMA_ERROR,
2911 "ErrorCode,Failed to enable HiLoMac "
2912 "TDLS mode");
2913 return 0;
2914 }
2915 } else if (strcasecmp(val, "WeakSecurity") == 0) {
2916 /*
2917 * Since all security modes are enabled by default when
2918 * Sigma control is used, there is no need to do
2919 * anything here.
2920 */
2921 } else if (strcasecmp(val, "ExistLink") == 0) {
2922 /*
2923 * Since we allow new TDLS Setup Request even if there
2924 * is an existing link, nothing needs to be done for
2925 * this.
2926 */
2927 } else {
2928 /* TODO:
2929 * ExistLink: STA should send TDLS setup req even if
2930 * direct link already exists
2931 */
2932 send_resp(dut, conn, SIGMA_ERROR,
2933 "ErrorCode,Unsupported TDLSmode value");
2934 return 0;
2935 }
2936 }
2937
2938 val = get_param(cmd, "FakePubKey");
2939 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
2940 send_resp(dut, conn, SIGMA_ERROR,
2941 "ErrorCode,Failed to enable FakePubKey");
2942 return 0;
2943 }
2944
2945 return 1;
2946}
2947
2948
2949static const char * ath_get_radio_name(const char *radio_name)
2950{
2951 if (radio_name == NULL)
2952 return "wifi0";
2953 if (strcmp(radio_name, "wifi1") == 0)
2954 return "wifi1";
2955 if (strcmp(radio_name, "wifi2") == 0)
2956 return "wifi2";
2957 return "wifi0";
2958}
2959
2960
2961static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
2962 const char *val)
2963{
2964 char buf[60];
2965 unsigned int vht_mcsmap = 0;
2966 int txchainmask = 0;
2967 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
2968
2969 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
2970 if (dut->testbed_flag_txsp == 1) {
2971 vht_mcsmap = 0xfffc;
2972 dut->testbed_flag_txsp = 0;
2973 } else {
2974 vht_mcsmap = 0xfffe;
2975 }
2976 txchainmask = 1;
2977 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
2978 if (dut->testbed_flag_txsp == 1) {
2979 vht_mcsmap = 0xfff0;
2980 dut->testbed_flag_txsp = 0;
2981 } else {
2982 vht_mcsmap = 0xfffa;
2983 }
2984 txchainmask = 3;
2985 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
2986 if (dut->testbed_flag_txsp == 1) {
2987 vht_mcsmap = 0xffc0;
2988 dut->testbed_flag_txsp = 0;
2989 } else {
2990 vht_mcsmap = 0xffea;
2991 }
2992 txchainmask = 7;
2993 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
2994 if (dut->testbed_flag_txsp == 1) {
2995 vht_mcsmap = 0xff00;
2996 dut->testbed_flag_txsp = 0;
2997 } else {
2998 vht_mcsmap = 0xffaa;
2999 }
3000 txchainmask = 15;
3001 } else {
3002 if (dut->testbed_flag_txsp == 1) {
3003 vht_mcsmap = 0xffc0;
3004 dut->testbed_flag_txsp = 0;
3005 } else {
3006 vht_mcsmap = 0xffea;
3007 }
3008 }
3009
3010 if (txchainmask) {
3011 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
3012 basedev, txchainmask);
3013 if (system(buf) != 0) {
3014 sigma_dut_print(dut, DUT_MSG_ERROR,
3015 "iwpriv txchainmask failed");
3016 }
3017 }
3018
3019 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
3020 intf, vht_mcsmap);
3021 if (system(buf) != 0) {
3022 sigma_dut_print(dut, DUT_MSG_ERROR,
3023 "iwpriv %s vht_mcsmap 0x%04x failed",
3024 intf, vht_mcsmap);
3025 }
3026}
3027
3028
3029static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
3030 const char *val)
3031{
3032 char buf[60];
3033 unsigned int vht_mcsmap = 0;
3034 int rxchainmask = 0;
3035 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
3036
3037 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
3038 if (dut->testbed_flag_rxsp == 1) {
3039 vht_mcsmap = 0xfffc;
3040 dut->testbed_flag_rxsp = 0;
3041 } else {
3042 vht_mcsmap = 0xfffe;
3043 }
3044 rxchainmask = 1;
3045 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
3046 if (dut->testbed_flag_rxsp == 1) {
3047 vht_mcsmap = 0xfff0;
3048 dut->testbed_flag_rxsp = 0;
3049 } else {
3050 vht_mcsmap = 0xfffa;
3051 }
3052 rxchainmask = 3;
3053 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
3054 if (dut->testbed_flag_rxsp == 1) {
3055 vht_mcsmap = 0xffc0;
3056 dut->testbed_flag_rxsp = 0;
3057 } else {
3058 vht_mcsmap = 0xffea;
3059 }
3060 rxchainmask = 7;
3061 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
3062 if (dut->testbed_flag_rxsp == 1) {
3063 vht_mcsmap = 0xff00;
3064 dut->testbed_flag_rxsp = 0;
3065 } else {
3066 vht_mcsmap = 0xffaa;
3067 }
3068 rxchainmask = 15;
3069 } else {
3070 if (dut->testbed_flag_rxsp == 1) {
3071 vht_mcsmap = 0xffc0;
3072 dut->testbed_flag_rxsp = 0;
3073 } else {
3074 vht_mcsmap = 0xffea;
3075 }
3076 }
3077
3078 if (rxchainmask) {
3079 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
3080 basedev, rxchainmask);
3081 if (system(buf) != 0) {
3082 sigma_dut_print(dut, DUT_MSG_ERROR,
3083 "iwpriv rxchainmask failed");
3084 }
3085 }
3086
3087 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
3088 intf, vht_mcsmap);
3089 if (system(buf) != 0) {
3090 sigma_dut_print(dut, DUT_MSG_ERROR,
3091 "iwpriv %s vht_mcsmap 0x%04x",
3092 intf, vht_mcsmap);
3093 }
3094}
3095
3096
3097void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
3098{
3099 if (strcasecmp(val, "enable") == 0) {
3100 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
3101 != 0) {
3102 sigma_dut_print(dut, DUT_MSG_ERROR,
3103 "Disable BB_VHTSIGB_CRC_CALC failed");
3104 }
3105
3106 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
3107 != 0) {
3108 sigma_dut_print(dut, DUT_MSG_ERROR,
3109 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
3110 }
3111 } else {
3112 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
3113 != 0) {
3114 sigma_dut_print(dut, DUT_MSG_ERROR,
3115 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
3116 }
3117
3118 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
3119 != 0) {
3120 sigma_dut_print(dut, DUT_MSG_ERROR,
3121 "Enable BB_VHTSIGB_CRC_CALC failed");
3122 }
3123 }
3124}
3125
3126
3127static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
3128 struct sigma_conn *conn,
3129 struct sigma_cmd *cmd)
3130{
3131 const char *val;
3132 int ampdu = -1;
3133 char buf[30];
3134
3135 val = get_param(cmd, "40_INTOLERANT");
3136 if (val) {
3137 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
3138 /* TODO: iwpriv ht40intol through wpa_supplicant */
3139 send_resp(dut, conn, SIGMA_ERROR,
3140 "ErrorCode,40_INTOLERANT not supported");
3141 return 0;
3142 }
3143 }
3144
3145 val = get_param(cmd, "ADDBA_REJECT");
3146 if (val) {
3147 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
3148 /* reject any ADDBA with status "decline" */
3149 ampdu = 0;
3150 } else {
3151 /* accept ADDBA */
3152 ampdu = 1;
3153 }
3154 }
3155
3156 val = get_param(cmd, "AMPDU");
3157 if (val) {
3158 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
3159 /* enable AMPDU Aggregation */
3160 if (ampdu == 0) {
3161 send_resp(dut, conn, SIGMA_ERROR,
3162 "ErrorCode,Mismatch in "
3163 "addba_reject/ampdu - "
3164 "not supported");
3165 return 0;
3166 }
3167 ampdu = 1;
3168 } else {
3169 /* disable AMPDU Aggregation */
3170 if (ampdu == 1) {
3171 send_resp(dut, conn, SIGMA_ERROR,
3172 "ErrorCode,Mismatch in "
3173 "addba_reject/ampdu - "
3174 "not supported");
3175 return 0;
3176 }
3177 ampdu = 0;
3178 }
3179 }
3180
3181 if (ampdu >= 0) {
3182 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
3183 ampdu ? "Enabling" : "Disabling");
3184 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003185 if (wpa_command(intf, buf) < 0 &&
3186 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003187 send_resp(dut, conn, SIGMA_ERROR,
3188 "ErrorCode,set aggr failed");
3189 return 0;
3190 }
3191 }
3192
3193 val = get_param(cmd, "AMSDU");
3194 if (val) {
3195 switch (get_driver_type()) {
3196 case DRIVER_ATHEROS:
3197 ath_sta_set_amsdu(dut, intf, val);
3198 break;
3199 default:
3200 if (strcmp(val, "1") == 0 ||
3201 strcasecmp(val, "Enable") == 0) {
3202 /* Enable AMSDU Aggregation */
3203 send_resp(dut, conn, SIGMA_ERROR,
3204 "ErrorCode,AMSDU aggregation not supported");
3205 return 0;
3206 }
3207 break;
3208 }
3209 }
3210
3211 val = get_param(cmd, "STBC_RX");
3212 if (val) {
3213 switch (get_driver_type()) {
3214 case DRIVER_ATHEROS:
3215 ath_sta_set_stbc(dut, intf, val);
3216 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303217 case DRIVER_WCN:
3218 wcn_sta_set_stbc(dut, intf, val);
3219 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003220 default:
3221 send_resp(dut, conn, SIGMA_ERROR,
3222 "ErrorCode,STBC_RX not supported");
3223 return 0;
3224 }
3225 }
3226
3227 val = get_param(cmd, "WIDTH");
3228 if (val) {
3229 switch (get_driver_type()) {
3230 case DRIVER_WCN:
3231 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
3232 send_resp(dut, conn, SIGMA_ERROR,
3233 "ErrorCode,Failed to set WIDTH");
3234 return 0;
3235 }
3236 break;
3237 case DRIVER_ATHEROS:
3238 if (ath_set_width(dut, conn, intf, val) < 0)
3239 return 0;
3240 break;
3241 default:
3242 sigma_dut_print(dut, DUT_MSG_ERROR,
3243 "Setting WIDTH not supported");
3244 break;
3245 }
3246 }
3247
3248 val = get_param(cmd, "SMPS");
3249 if (val) {
3250 /* TODO: Dynamic/0, Static/1, No Limit/2 */
3251 send_resp(dut, conn, SIGMA_ERROR,
3252 "ErrorCode,SMPS not supported");
3253 return 0;
3254 }
3255
3256 val = get_param(cmd, "TXSP_STREAM");
3257 if (val) {
3258 switch (get_driver_type()) {
3259 case DRIVER_WCN:
3260 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
3261 send_resp(dut, conn, SIGMA_ERROR,
3262 "ErrorCode,Failed to set TXSP_STREAM");
3263 return 0;
3264 }
3265 break;
3266 case DRIVER_ATHEROS:
3267 ath_sta_set_txsp_stream(dut, intf, val);
3268 break;
3269 default:
3270 sigma_dut_print(dut, DUT_MSG_ERROR,
3271 "Setting TXSP_STREAM not supported");
3272 break;
3273 }
3274 }
3275
3276 val = get_param(cmd, "RXSP_STREAM");
3277 if (val) {
3278 switch (get_driver_type()) {
3279 case DRIVER_WCN:
3280 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
3281 send_resp(dut, conn, SIGMA_ERROR,
3282 "ErrorCode,Failed to set RXSP_STREAM");
3283 return 0;
3284 }
3285 break;
3286 case DRIVER_ATHEROS:
3287 ath_sta_set_rxsp_stream(dut, intf, val);
3288 break;
3289 default:
3290 sigma_dut_print(dut, DUT_MSG_ERROR,
3291 "Setting RXSP_STREAM not supported");
3292 break;
3293 }
3294 }
3295
3296 val = get_param(cmd, "DYN_BW_SGNL");
3297 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08003298 switch (get_driver_type()) {
3299 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08003300 if (strcasecmp(val, "enable") == 0) {
3301 snprintf(buf, sizeof(buf),
3302 "iwpriv %s cwmenable 1", intf);
3303 if (system(buf) != 0) {
3304 sigma_dut_print(dut, DUT_MSG_ERROR,
3305 "iwpriv cwmenable 1 failed");
3306 return 0;
3307 }
3308 } else if (strcasecmp(val, "disable") == 0) {
3309 snprintf(buf, sizeof(buf),
3310 "iwpriv %s cwmenable 0", intf);
3311 if (system(buf) != 0) {
3312 sigma_dut_print(dut, DUT_MSG_ERROR,
3313 "iwpriv cwmenable 0 failed");
3314 return 0;
3315 }
3316 } else {
3317 sigma_dut_print(dut, DUT_MSG_ERROR,
3318 "Unsupported DYN_BW_SGL");
3319 }
3320
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003321 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3322 if (system(buf) != 0) {
3323 sigma_dut_print(dut, DUT_MSG_ERROR,
3324 "Failed to set cts_cbw in DYN_BW_SGNL");
3325 return 0;
3326 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08003327 break;
3328 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08003329 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08003330 ath_config_dyn_bw_sig(dut, intf, val);
3331 break;
3332 default:
3333 sigma_dut_print(dut, DUT_MSG_ERROR,
3334 "Failed to set DYN_BW_SGNL");
3335 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003336 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003337 }
3338
3339 val = get_param(cmd, "RTS_FORCE");
3340 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08003341 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003342 if (strcasecmp(val, "Enable") == 0) {
3343 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02003344 if (system(buf) != 0) {
3345 sigma_dut_print(dut, DUT_MSG_ERROR,
3346 "Failed to set RTS_FORCE 64");
3347 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08003348 snprintf(buf, sizeof(buf),
3349 "wifitool %s beeliner_fw_test 100 1", intf);
3350 if (system(buf) != 0) {
3351 sigma_dut_print(dut, DUT_MSG_ERROR,
3352 "wifitool beeliner_fw_test 100 1 failed");
3353 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003354 } else if (strcasecmp(val, "Disable") == 0) {
3355 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
3356 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02003357 if (system(buf) != 0) {
3358 sigma_dut_print(dut, DUT_MSG_ERROR,
3359 "Failed to set RTS_FORCE 2347");
3360 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003361 } else {
3362 send_resp(dut, conn, SIGMA_ERROR,
3363 "ErrorCode,RTS_FORCE value not supported");
3364 return 0;
3365 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003366 }
3367
3368 val = get_param(cmd, "CTS_WIDTH");
3369 if (val) {
3370 switch (get_driver_type()) {
3371 case DRIVER_WCN:
3372 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
3373 send_resp(dut, conn, SIGMA_ERROR,
3374 "ErrorCode,Failed to set CTS_WIDTH");
3375 return 0;
3376 }
3377 break;
3378 case DRIVER_ATHEROS:
3379 ath_set_cts_width(dut, intf, val);
3380 break;
3381 default:
3382 sigma_dut_print(dut, DUT_MSG_ERROR,
3383 "Setting CTS_WIDTH not supported");
3384 break;
3385 }
3386 }
3387
3388 val = get_param(cmd, "BW_SGNL");
3389 if (val) {
3390 if (strcasecmp(val, "Enable") == 0) {
3391 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1",
3392 intf);
3393 } else if (strcasecmp(val, "Disable") == 0) {
3394 /* TODO: Disable */
3395 buf[0] = '\0';
3396 } else {
3397 send_resp(dut, conn, SIGMA_ERROR,
3398 "ErrorCode,BW_SGNL value not supported");
3399 return 0;
3400 }
3401
3402 if (buf[0] != '\0' && system(buf) != 0) {
3403 sigma_dut_print(dut, DUT_MSG_ERROR,
3404 "Failed to set BW_SGNL");
3405 }
3406 }
3407
3408 val = get_param(cmd, "Band");
3409 if (val) {
3410 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
3411 /* STA supports all bands by default */
3412 } else {
3413 send_resp(dut, conn, SIGMA_ERROR,
3414 "ErrorCode,Unsupported Band");
3415 return 0;
3416 }
3417 }
3418
3419 val = get_param(cmd, "zero_crc");
3420 if (val) {
3421 switch (get_driver_type()) {
3422 case DRIVER_ATHEROS:
3423 ath_set_zero_crc(dut, val);
3424 break;
3425 default:
3426 break;
3427 }
3428 }
3429
3430 return 1;
3431}
3432
3433
3434static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
3435 struct sigma_cmd *cmd)
3436{
3437 const char *val;
3438 char buf[100];
3439
3440 val = get_param(cmd, "MSDUSize");
3441 if (val) {
3442 int mtu;
3443
3444 dut->amsdu_size = atoi(val);
3445 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
3446 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
3447 sigma_dut_print(dut, DUT_MSG_ERROR,
3448 "MSDUSize %d is above max %d or below min %d",
3449 dut->amsdu_size,
3450 IEEE80211_MAX_DATA_LEN_DMG,
3451 IEEE80211_SNAP_LEN_DMG);
3452 dut->amsdu_size = 0;
3453 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3454 }
3455
3456 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
3457 sigma_dut_print(dut, DUT_MSG_DEBUG,
3458 "Setting amsdu_size to %d", mtu);
3459 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
3460 get_station_ifname(), mtu);
3461
3462 if (system(buf) != 0) {
3463 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
3464 buf);
3465 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3466 }
3467 }
3468
3469 val = get_param(cmd, "BAckRcvBuf");
3470 if (val) {
3471 dut->back_rcv_buf = atoi(val);
3472 if (dut->back_rcv_buf == 0) {
3473 sigma_dut_print(dut, DUT_MSG_ERROR,
3474 "Failed to convert %s or value is 0",
3475 val);
3476 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3477 }
3478
3479 sigma_dut_print(dut, DUT_MSG_DEBUG,
3480 "Setting BAckRcvBuf to %s", val);
3481 }
3482
3483 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
3484}
3485
3486
3487static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
3488 struct sigma_cmd *cmd)
3489{
3490 int net_id;
3491 char *ifname;
3492 const char *val;
3493 char buf[100];
3494
3495 dut->mode = SIGMA_MODE_STATION;
3496 ifname = get_main_ifname();
3497 if (wpa_command(ifname, "PING") != 0) {
3498 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
3499 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3500 }
3501
3502 wpa_command(ifname, "FLUSH");
3503 net_id = add_network_common(dut, conn, ifname, cmd);
3504 if (net_id < 0) {
3505 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
3506 return net_id;
3507 }
3508
3509 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
3510 if (set_network(ifname, net_id, "mode", "2") < 0) {
3511 sigma_dut_print(dut, DUT_MSG_ERROR,
3512 "Failed to set supplicant network mode");
3513 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3514 }
3515
3516 sigma_dut_print(dut, DUT_MSG_DEBUG,
3517 "Supplicant set network with mode 2");
3518
3519 val = get_param(cmd, "Security");
3520 if (val && strcasecmp(val, "OPEN") == 0) {
3521 dut->ap_key_mgmt = AP_OPEN;
3522 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
3523 sigma_dut_print(dut, DUT_MSG_ERROR,
3524 "Failed to set supplicant to %s security",
3525 val);
3526 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3527 }
3528 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
3529 dut->ap_key_mgmt = AP_WPA2_PSK;
3530 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
3531 sigma_dut_print(dut, DUT_MSG_ERROR,
3532 "Failed to set supplicant to %s security",
3533 val);
3534 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3535 }
3536
3537 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
3538 sigma_dut_print(dut, DUT_MSG_ERROR,
3539 "Failed to set supplicant to proto RSN");
3540 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3541 }
3542 } else if (val) {
3543 sigma_dut_print(dut, DUT_MSG_ERROR,
3544 "Requested Security %s is not supported on 60GHz",
3545 val);
3546 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
3547 }
3548
3549 val = get_param(cmd, "Encrypt");
3550 if (val && strcasecmp(val, "AES-GCMP") == 0) {
3551 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
3552 sigma_dut_print(dut, DUT_MSG_ERROR,
3553 "Failed to set supplicant to pairwise GCMP");
3554 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3555 }
3556 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
3557 sigma_dut_print(dut, DUT_MSG_ERROR,
3558 "Failed to set supplicant to group GCMP");
3559 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3560 }
3561 } else if (val) {
3562 sigma_dut_print(dut, DUT_MSG_ERROR,
3563 "Requested Encrypt %s is not supported on 60 GHz",
3564 val);
3565 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
3566 }
3567
3568 val = get_param(cmd, "PSK");
3569 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
3570 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
3571 val);
3572 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3573 }
3574
3575 /* Convert 60G channel to freq */
3576 switch (dut->ap_channel) {
3577 case 1:
3578 val = "58320";
3579 break;
3580 case 2:
3581 val = "60480";
3582 break;
3583 case 3:
3584 val = "62640";
3585 break;
3586 default:
3587 sigma_dut_print(dut, DUT_MSG_ERROR,
3588 "Failed to configure channel %d. Not supported",
3589 dut->ap_channel);
3590 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3591 }
3592
3593 if (set_network(ifname, net_id, "frequency", val) < 0) {
3594 sigma_dut_print(dut, DUT_MSG_ERROR,
3595 "Failed to set supplicant network frequency");
3596 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3597 }
3598
3599 sigma_dut_print(dut, DUT_MSG_DEBUG,
3600 "Supplicant set network with frequency");
3601
3602 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
3603 if (wpa_command(ifname, buf) < 0) {
3604 sigma_dut_print(dut, DUT_MSG_INFO,
3605 "Failed to select network id %d on %s",
3606 net_id, ifname);
3607 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3608 }
3609
3610 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
3611
3612 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
3613}
3614
3615
3616static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
3617 struct sigma_cmd *cmd)
3618{
3619 const char *val;
3620
3621 if (dut->dev_role != DEVROLE_PCP) {
3622 send_resp(dut, conn, SIGMA_INVALID,
3623 "ErrorCode,Invalid DevRole");
3624 return 0;
3625 }
3626
3627 val = get_param(cmd, "SSID");
3628 if (val) {
3629 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
3630 send_resp(dut, conn, SIGMA_INVALID,
3631 "ErrorCode,Invalid SSID");
3632 return -1;
3633 }
3634
3635 strncpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
3636 }
3637
3638 val = get_param(cmd, "CHANNEL");
3639 if (val) {
3640 const char *pos;
3641
3642 dut->ap_channel = atoi(val);
3643 pos = strchr(val, ';');
3644 if (pos) {
3645 pos++;
3646 dut->ap_channel_1 = atoi(pos);
3647 }
3648 }
3649
3650 switch (dut->ap_channel) {
3651 case 1:
3652 case 2:
3653 case 3:
3654 break;
3655 default:
3656 sigma_dut_print(dut, DUT_MSG_ERROR,
3657 "Channel %d is not supported", dut->ap_channel);
3658 send_resp(dut, conn, SIGMA_ERROR,
3659 "Requested channel is not supported");
3660 return -1;
3661 }
3662
3663 val = get_param(cmd, "BCNINT");
3664 if (val)
3665 dut->ap_bcnint = atoi(val);
3666
3667
3668 val = get_param(cmd, "ExtSchIE");
3669 if (val) {
3670 send_resp(dut, conn, SIGMA_ERROR,
3671 "ErrorCode,ExtSchIE is not supported yet");
3672 return -1;
3673 }
3674
3675 val = get_param(cmd, "AllocType");
3676 if (val) {
3677 send_resp(dut, conn, SIGMA_ERROR,
3678 "ErrorCode,AllocType is not supported yet");
3679 return -1;
3680 }
3681
3682 val = get_param(cmd, "PercentBI");
3683 if (val) {
3684 send_resp(dut, conn, SIGMA_ERROR,
3685 "ErrorCode,PercentBI is not supported yet");
3686 return -1;
3687 }
3688
3689 val = get_param(cmd, "CBAPOnly");
3690 if (val) {
3691 send_resp(dut, conn, SIGMA_ERROR,
3692 "ErrorCode,CBAPOnly is not supported yet");
3693 return -1;
3694 }
3695
3696 val = get_param(cmd, "AMPDU");
3697 if (val) {
3698 if (strcasecmp(val, "Enable") == 0)
3699 dut->ap_ampdu = 1;
3700 else if (strcasecmp(val, "Disable") == 0)
3701 dut->ap_ampdu = 2;
3702 else {
3703 send_resp(dut, conn, SIGMA_ERROR,
3704 "ErrorCode,AMPDU value is not Enable nor Disabled");
3705 return -1;
3706 }
3707 }
3708
3709 val = get_param(cmd, "AMSDU");
3710 if (val) {
3711 if (strcasecmp(val, "Enable") == 0)
3712 dut->ap_amsdu = 1;
3713 else if (strcasecmp(val, "Disable") == 0)
3714 dut->ap_amsdu = 2;
3715 }
3716
3717 val = get_param(cmd, "NumMSDU");
3718 if (val) {
3719 send_resp(dut, conn, SIGMA_ERROR,
3720 "ErrorCode, NumMSDU is not supported yet");
3721 return -1;
3722 }
3723
3724 val = get_param(cmd, "ABFTLRang");
3725 if (val) {
3726 sigma_dut_print(dut, DUT_MSG_DEBUG,
3727 "Ignoring ABFTLRang parameter since FW default is greater than 1");
3728 }
3729
3730 if (sta_pcp_start(dut, conn, cmd) < 0) {
3731 send_resp(dut, conn, SIGMA_ERROR,
3732 "ErrorCode, Can't start PCP role");
3733 return -1;
3734 }
3735
3736 return sta_set_60g_common(dut, conn, cmd);
3737}
3738
3739
3740static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
3741 struct sigma_cmd *cmd)
3742{
3743 const char *val = get_param(cmd, "DiscoveryMode");
3744
3745 if (dut->dev_role != DEVROLE_STA) {
3746 send_resp(dut, conn, SIGMA_INVALID,
3747 "ErrorCode,Invalid DevRole");
3748 return 0;
3749 }
3750
3751 if (val) {
3752 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
3753 /* Ignore Discovery mode till Driver expose API. */
3754#if 0
3755 if (strcasecmp(val, "1") == 0) {
3756 send_resp(dut, conn, SIGMA_INVALID,
3757 "ErrorCode,DiscoveryMode 1 not supported");
3758 return 0;
3759 }
3760
3761 if (strcasecmp(val, "0") == 0) {
3762 /* OK */
3763 } else {
3764 send_resp(dut, conn, SIGMA_INVALID,
3765 "ErrorCode,DiscoveryMode not supported");
3766 return 0;
3767 }
3768#endif
3769 }
3770
3771 if (start_sta_mode(dut) != 0)
3772 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
3773 return sta_set_60g_common(dut, conn, cmd);
3774}
3775
3776
3777static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
3778 struct sigma_cmd *cmd)
3779{
3780 const char *intf = get_param(cmd, "Interface");
3781 disconnect_station(dut);
3782 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
3783 * due to cached results. */
3784 wpa_command(intf, "SET ignore_old_scan_res 1");
3785 wpa_command(intf, "BSS_FLUSH");
3786 return 1;
3787}
3788
3789
3790static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
3791 struct sigma_cmd *cmd)
3792{
3793 const char *intf = get_param(cmd, "Interface");
3794 const char *bssid = get_param(cmd, "bssid");
3795 const char *val = get_param(cmd, "CHANNEL");
3796 struct wpa_ctrl *ctrl;
3797 char buf[100];
3798 int res;
3799 int chan = 0;
3800
3801 if (bssid == NULL) {
3802 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
3803 "argument");
3804 return 0;
3805 }
3806
3807 if (val)
3808 chan = atoi(val);
3809
3810 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
3811 /* The current network may be from sta_associate or
3812 * sta_hs2_associate
3813 */
3814 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
3815 0 ||
3816 set_network(intf, 0, "bssid", bssid) < 0)
3817 return -2;
3818 }
3819
3820 ctrl = open_wpa_mon(intf);
3821 if (ctrl == NULL) {
3822 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
3823 "wpa_supplicant monitor connection");
3824 return -1;
3825 }
3826
3827 if (wifi_chip_type == DRIVER_WCN) {
3828#ifdef ANDROID
3829 if (set_network(intf, dut->infra_network_id, "bssid", "any")
3830 < 0) {
3831 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
3832 "bssid to any during FASTREASSOC");
3833 return -2;
3834 }
3835 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
3836 bssid, chan);
3837 if (res > 0 && res < (int) sizeof(buf))
3838 res = wpa_command(intf, buf);
3839
3840 if (res < 0 || res >= (int) sizeof(buf)) {
3841 send_resp(dut, conn, SIGMA_ERROR,
3842 "errorCode,Failed to run DRIVER FASTREASSOC");
3843 wpa_ctrl_detach(ctrl);
3844 wpa_ctrl_close(ctrl);
3845 return 0;
3846 }
3847#else /* ANDROID */
3848 sigma_dut_print(dut, DUT_MSG_DEBUG,
3849 "Reassoc using iwpriv - skip chan=%d info",
3850 chan);
3851 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
3852 if (system(buf) != 0) {
3853 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
3854 wpa_ctrl_detach(ctrl);
3855 wpa_ctrl_close(ctrl);
3856 return 0;
3857 }
3858#endif /* ANDROID */
3859 sigma_dut_print(dut, DUT_MSG_INFO,
3860 "sta_reassoc: Run %s successful", buf);
3861 } else if (wpa_command(intf, "REASSOCIATE")) {
3862 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
3863 "request reassociation");
3864 wpa_ctrl_detach(ctrl);
3865 wpa_ctrl_close(ctrl);
3866 return 0;
3867 }
3868
3869 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
3870 buf, sizeof(buf));
3871
3872 wpa_ctrl_detach(ctrl);
3873 wpa_ctrl_close(ctrl);
3874
3875 if (res < 0) {
3876 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
3877 return -1;
3878 }
3879
3880 return 1;
3881}
3882
3883
3884static void hs2_clear_credentials(const char *intf)
3885{
3886 wpa_command(intf, "REMOVE_CRED all");
3887}
3888
3889
3890static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
3891 struct sigma_cmd *cmd)
3892{
3893 char buf[MAX_CMD_LEN];
3894 char bss_list[MAX_CMD_LEN];
3895 const char *parameter = get_param(cmd, "Parameter");
3896
3897 if (parameter == NULL)
3898 return -1;
3899
3900 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
3901 char *bss_line;
3902 char *bss_id = NULL;
3903 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303904 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003905
3906 if (ifname == NULL) {
3907 sigma_dut_print(dut, DUT_MSG_INFO,
3908 "For get DiscoveredDevList need Interface name.");
3909 return -1;
3910 }
3911
3912 /*
3913 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
3914 * of BSSIDs in "bssid=<BSSID>\n"
3915 */
3916 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
3917 bss_list,
3918 sizeof(bss_list)) < 0) {
3919 sigma_dut_print(dut, DUT_MSG_ERROR,
3920 "Failed to get bss list");
3921 return -1;
3922 }
3923
3924 sigma_dut_print(dut, DUT_MSG_DEBUG,
3925 "bss list for ifname:%s is:%s",
3926 ifname, bss_list);
3927
3928 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303929 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003930 while (bss_line) {
3931 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
3932 bss_id) {
3933 int len;
3934
3935 len = snprintf(buf + strlen(buf),
3936 sizeof(buf) - strlen(buf),
3937 ",%s", bss_id);
3938 free(bss_id);
3939 bss_id = NULL;
3940 if (len < 0) {
3941 sigma_dut_print(dut,
3942 DUT_MSG_ERROR,
3943 "Failed to read BSSID");
3944 send_resp(dut, conn, SIGMA_ERROR,
3945 "ErrorCode,Failed to read BSS ID");
3946 return 0;
3947 }
3948
3949 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
3950 sigma_dut_print(dut,
3951 DUT_MSG_ERROR,
3952 "Response buf too small for list");
3953 send_resp(dut, conn,
3954 SIGMA_ERROR,
3955 "ErrorCode,Response buf too small for list");
3956 return 0;
3957 }
3958 }
3959
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303960 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003961 }
3962
3963 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
3964 buf);
3965 send_resp(dut, conn, SIGMA_COMPLETE, buf);
3966 return 0;
3967 }
3968
3969 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
3970 return 0;
3971}
3972
3973
3974static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
3975 struct sigma_cmd *cmd)
3976{
3977 const char *program = get_param(cmd, "Program");
3978
3979 if (program == NULL)
3980 return -1;
3981
3982 if (strcasecmp(program, "P2PNFC") == 0)
3983 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
3984
3985 if (strcasecmp(program, "60ghz") == 0)
3986 return sta_get_parameter_60g(dut, conn, cmd);
3987
3988#ifdef ANDROID_NAN
3989 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07003990 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003991#endif /* ANDROID_NAN */
3992
3993 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
3994 return 0;
3995}
3996
3997
3998static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
3999 const char *type)
4000{
4001 char buf[100];
4002
4003 if (dut->program == PROGRAM_VHT) {
4004 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
4005 if (system(buf) != 0) {
4006 sigma_dut_print(dut, DUT_MSG_ERROR,
4007 "iwpriv %s chwidth failed", intf);
4008 }
4009
4010 snprintf(buf, sizeof(buf), "iwpriv %s mode 11ACVHT80", intf);
4011 if (system(buf) != 0) {
4012 sigma_dut_print(dut, DUT_MSG_ERROR,
4013 "iwpriv %s mode 11ACVHT80 failed",
4014 intf);
4015 }
4016
4017 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs -1", intf);
4018 if (system(buf) != 0) {
4019 sigma_dut_print(dut, DUT_MSG_ERROR,
4020 "iwpriv %s vhtmcs -1 failed", intf);
4021 }
4022 }
4023
4024 if (dut->program == PROGRAM_HT) {
4025 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
4026 if (system(buf) != 0) {
4027 sigma_dut_print(dut, DUT_MSG_ERROR,
4028 "iwpriv %s chwidth failed", intf);
4029 }
4030
4031 snprintf(buf, sizeof(buf), "iwpriv %s mode 11naht40", intf);
4032 if (system(buf) != 0) {
4033 sigma_dut_print(dut, DUT_MSG_ERROR,
4034 "iwpriv %s mode 11naht40 failed",
4035 intf);
4036 }
4037
4038 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0", intf);
4039 if (system(buf) != 0) {
4040 sigma_dut_print(dut, DUT_MSG_ERROR,
4041 "iwpriv set11NRates failed");
4042 }
4043 }
4044
4045 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
4046 snprintf(buf, sizeof(buf), "iwpriv %s powersave 0", intf);
4047 if (system(buf) != 0) {
4048 sigma_dut_print(dut, DUT_MSG_ERROR,
4049 "disabling powersave failed");
4050 }
4051
4052 /* Reset CTS width */
4053 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
4054 intf);
4055 if (system(buf) != 0) {
4056 sigma_dut_print(dut, DUT_MSG_ERROR,
4057 "wifitool %s beeliner_fw_test 54 0 failed",
4058 intf);
4059 }
4060
4061 /* Enable Dynamic Bandwidth signalling by default */
4062 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", intf);
4063 if (system(buf) != 0) {
4064 sigma_dut_print(dut, DUT_MSG_ERROR,
4065 "iwpriv %s cwmenable 1 failed", intf);
4066 }
4067
4068 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
4069 if (system(buf) != 0) {
4070 sigma_dut_print(dut, DUT_MSG_ERROR,
4071 "iwpriv rts failed");
4072 }
4073 }
4074
4075 if (type && strcasecmp(type, "Testbed") == 0) {
4076 dut->testbed_flag_txsp = 1;
4077 dut->testbed_flag_rxsp = 1;
4078 /* STA has to set spatial stream to 2 per Appendix H */
4079 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0xfff0", intf);
4080 if (system(buf) != 0) {
4081 sigma_dut_print(dut, DUT_MSG_ERROR,
4082 "iwpriv vht_mcsmap failed");
4083 }
4084
4085 /* Disable LDPC per Appendix H */
4086 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", intf);
4087 if (system(buf) != 0) {
4088 sigma_dut_print(dut, DUT_MSG_ERROR,
4089 "iwpriv %s ldpc 0 failed", intf);
4090 }
4091
4092 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4093 if (system(buf) != 0) {
4094 sigma_dut_print(dut, DUT_MSG_ERROR,
4095 "iwpriv amsdu failed");
4096 }
4097
4098 /* TODO: Disable STBC 2x1 transmit and receive */
4099 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", intf);
4100 if (system(buf) != 0) {
4101 sigma_dut_print(dut, DUT_MSG_ERROR,
4102 "Disable tx_stbc 0 failed");
4103 }
4104
4105 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc 0", intf);
4106 if (system(buf) != 0) {
4107 sigma_dut_print(dut, DUT_MSG_ERROR,
4108 "Disable rx_stbc 0 failed");
4109 }
4110
4111 /* STA has to disable Short GI per Appendix H */
4112 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 0", intf);
4113 if (system(buf) != 0) {
4114 sigma_dut_print(dut, DUT_MSG_ERROR,
4115 "iwpriv %s shortgi 0 failed", intf);
4116 }
4117 }
4118
4119 if (type && strcasecmp(type, "DUT") == 0) {
4120 snprintf(buf, sizeof(buf), "iwpriv %s nss 3", intf);
4121 if (system(buf) != 0) {
4122 sigma_dut_print(dut, DUT_MSG_ERROR,
4123 "iwpriv %s nss 3 failed", intf);
4124 }
4125
4126 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 1", intf);
4127 if (system(buf) != 0) {
4128 sigma_dut_print(dut, DUT_MSG_ERROR,
4129 "iwpriv %s shortgi 1 failed", intf);
4130 }
4131 }
4132}
4133
4134
4135static int cmd_sta_reset_default(struct sigma_dut *dut,
4136 struct sigma_conn *conn,
4137 struct sigma_cmd *cmd)
4138{
4139 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
4140 struct sigma_cmd *cmd);
4141 const char *intf = get_param(cmd, "Interface");
4142 const char *type;
4143
4144 dut->program = sigma_program_to_enum(get_param(cmd, "prog"));
4145 dut->device_type = STA_unknown;
4146 type = get_param(cmd, "type");
4147 if (type && strcasecmp(type, "Testbed") == 0)
4148 dut->device_type = STA_testbed;
4149 if (type && strcasecmp(type, "DUT") == 0)
4150 dut->device_type = STA_dut;
4151
4152 if (dut->program == PROGRAM_TDLS) {
4153 /* Clear TDLS testing mode */
4154 wpa_command(intf, "SET tdls_disabled 0");
4155 wpa_command(intf, "SET tdls_testing 0");
4156 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05304157 if (get_driver_type() == DRIVER_WCN) {
4158 /* Enable the WCN driver in TDLS Explicit trigger mode
4159 */
4160 wpa_command(intf, "SET tdls_external_control 0");
4161 wpa_command(intf, "SET tdls_trigger_control 0");
4162 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004163 }
4164
4165 switch (get_driver_type()) {
4166 case DRIVER_ATHEROS:
4167 sta_reset_default_ath(dut, intf, type);
4168 break;
4169 default:
4170 break;
4171 }
4172
4173#ifdef ANDROID_NAN
4174 if (dut->program == PROGRAM_NAN)
4175 nan_cmd_sta_reset_default(dut, conn, cmd);
4176#endif /* ANDROID_NAN */
4177
4178 if (dut->program == PROGRAM_HS2_R2) {
4179 unlink("SP/wi-fi.org/pps.xml");
4180 if (system("rm -r SP/*") != 0) {
4181 }
4182 unlink("next-client-cert.pem");
4183 unlink("next-client-key.pem");
4184 }
4185
4186 if (dut->program == PROGRAM_60GHZ) {
4187 const char *dev_role = get_param(cmd, "DevRole");
4188
4189 if (!dev_role) {
4190 send_resp(dut, conn, SIGMA_ERROR,
4191 "errorCode,Missing DevRole argument");
4192 return 0;
4193 }
4194
4195 if (strcasecmp(dev_role, "STA") == 0)
4196 dut->dev_role = DEVROLE_STA;
4197 else if (strcasecmp(dev_role, "PCP") == 0)
4198 dut->dev_role = DEVROLE_PCP;
4199 else {
4200 send_resp(dut, conn, SIGMA_ERROR,
4201 "errorCode,Unknown DevRole");
4202 return 0;
4203 }
4204
4205 if (dut->device_type == STA_unknown) {
4206 sigma_dut_print(dut, DUT_MSG_ERROR,
4207 "Device type is not STA testbed or DUT");
4208 send_resp(dut, conn, SIGMA_ERROR,
4209 "errorCode,Unknown device type");
4210 return 0;
4211 }
4212 }
4213
4214 wpa_command(intf, "WPS_ER_STOP");
4215 wpa_command(intf, "FLUSH");
4216 wpa_command(intf, "SET radio_disabled 0");
4217
4218 if (dut->tmp_mac_addr && dut->set_macaddr) {
4219 dut->tmp_mac_addr = 0;
4220 if (system(dut->set_macaddr) != 0) {
4221 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
4222 "temporary MAC address");
4223 }
4224 }
4225
4226 set_ps(intf, dut, 0);
4227
4228 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2) {
4229 wpa_command(intf, "SET interworking 1");
4230 wpa_command(intf, "SET hs20 1");
4231 }
4232
4233 if (dut->program == PROGRAM_HS2_R2) {
4234 wpa_command(intf, "SET pmf 1");
4235 } else {
4236 wpa_command(intf, "SET pmf 0");
4237 }
4238
4239 hs2_clear_credentials(intf);
4240 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
4241 wpa_command(intf, "SET access_network_type 15");
4242
4243 static_ip_file(0, NULL, NULL, NULL);
4244 kill_dhcp_client(dut, intf);
4245 clear_ip_addr(dut, intf);
4246
4247 dut->er_oper_performed = 0;
4248 dut->er_oper_bssid[0] = '\0';
4249
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07004250 if (dut->program == PROGRAM_LOC) {
4251 /* Disable Interworking by default */
4252 wpa_command(get_station_ifname(), "SET interworking 0");
4253 }
4254
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08004255 if (dut->program != PROGRAM_VHT)
4256 return cmd_sta_p2p_reset(dut, conn, cmd);
4257 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004258}
4259
4260
4261static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
4262 struct sigma_cmd *cmd)
4263{
4264 const char *program = get_param(cmd, "Program");
4265
4266 if (program == NULL)
4267 return -1;
4268#ifdef ANDROID_NAN
4269 if (strcasecmp(program, "NAN") == 0)
4270 return nan_cmd_sta_get_events(dut, conn, cmd);
4271#endif /* ANDROID_NAN */
4272 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
4273 return 0;
4274}
4275
4276
4277static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
4278 struct sigma_cmd *cmd)
4279{
4280 const char *program = get_param(cmd, "Prog");
4281
4282 if (program == NULL)
4283 return -1;
4284#ifdef ANDROID_NAN
4285 if (strcasecmp(program, "NAN") == 0)
4286 return nan_cmd_sta_exec_action(dut, conn, cmd);
4287#endif /* ANDROID_NAN */
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004288 if (strcasecmp(program, "Loc") == 0)
4289 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004290 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
4291 return 0;
4292}
4293
4294
4295static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
4296 struct sigma_cmd *cmd)
4297{
4298 const char *intf = get_param(cmd, "Interface");
4299 const char *val, *mcs32, *rate;
4300
4301 val = get_param(cmd, "GREENFIELD");
4302 if (val) {
4303 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4304 /* Enable GD */
4305 send_resp(dut, conn, SIGMA_ERROR,
4306 "ErrorCode,GF not supported");
4307 return 0;
4308 }
4309 }
4310
4311 val = get_param(cmd, "SGI20");
4312 if (val) {
4313 switch (get_driver_type()) {
4314 case DRIVER_ATHEROS:
4315 ath_sta_set_sgi(dut, intf, val);
4316 break;
4317 default:
4318 send_resp(dut, conn, SIGMA_ERROR,
4319 "ErrorCode,SGI20 not supported");
4320 return 0;
4321 }
4322 }
4323
4324 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
4325 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
4326 if (mcs32 && rate) {
4327 /* TODO */
4328 send_resp(dut, conn, SIGMA_ERROR,
4329 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
4330 return 0;
4331 } else if (mcs32 && !rate) {
4332 /* TODO */
4333 send_resp(dut, conn, SIGMA_ERROR,
4334 "ErrorCode,MCS32 not supported");
4335 return 0;
4336 } else if (!mcs32 && rate) {
4337 switch (get_driver_type()) {
4338 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004339 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004340 ath_sta_set_11nrates(dut, intf, rate);
4341 break;
4342 default:
4343 send_resp(dut, conn, SIGMA_ERROR,
4344 "ErrorCode,MCS32_FIXEDRATE not supported");
4345 return 0;
4346 }
4347 }
4348
4349 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
4350}
4351
4352
4353static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
4354 struct sigma_conn *conn,
4355 struct sigma_cmd *cmd)
4356{
4357 const char *intf = get_param(cmd, "Interface");
4358 const char *val;
4359 char buf[30];
4360 int tkip = -1;
4361 int wep = -1;
4362
4363 val = get_param(cmd, "SGI80");
4364 if (val) {
4365 int sgi80;
4366
4367 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4368 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi80);
4369 if (system(buf) != 0) {
4370 sigma_dut_print(dut, DUT_MSG_ERROR,
4371 "iwpriv shortgi failed");
4372 }
4373 }
4374
4375 val = get_param(cmd, "TxBF");
4376 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
4377 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 1", intf);
4378 if (system(buf) != 0) {
4379 sigma_dut_print(dut, DUT_MSG_ERROR,
4380 "iwpriv vhtsubfee failed");
4381 }
4382 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 1", intf);
4383 if (system(buf) != 0) {
4384 sigma_dut_print(dut, DUT_MSG_ERROR,
4385 "iwpriv vhtsubfer failed");
4386 }
4387 }
4388
4389 val = get_param(cmd, "MU_TxBF");
4390 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
4391 switch (get_driver_type()) {
4392 case DRIVER_ATHEROS:
4393 ath_sta_set_txsp_stream(dut, intf, "1SS");
4394 ath_sta_set_rxsp_stream(dut, intf, "1SS");
4395 case DRIVER_WCN:
4396 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
4397 send_resp(dut, conn, SIGMA_ERROR,
4398 "ErrorCode,Failed to set RX/TXSP_STREAM");
4399 return 0;
4400 }
4401 default:
4402 sigma_dut_print(dut, DUT_MSG_ERROR,
4403 "Setting SP_STREAM not supported");
4404 break;
4405 }
4406 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 1", intf);
4407 if (system(buf) != 0) {
4408 sigma_dut_print(dut, DUT_MSG_ERROR,
4409 "iwpriv vhtmubfee failed");
4410 }
4411 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 1", intf);
4412 if (system(buf) != 0) {
4413 sigma_dut_print(dut, DUT_MSG_ERROR,
4414 "iwpriv vhtmubfer failed");
4415 }
4416 }
4417
4418 val = get_param(cmd, "LDPC");
4419 if (val) {
4420 int ldpc;
4421
4422 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4423 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, ldpc);
4424 if (system(buf) != 0) {
4425 sigma_dut_print(dut, DUT_MSG_ERROR,
4426 "iwpriv ldpc failed");
4427 }
4428 }
4429
4430 val = get_param(cmd, "opt_md_notif_ie");
4431 if (val) {
4432 char *result = NULL;
4433 char delim[] = ";";
4434 char token[30];
4435 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304436 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004437
4438 strncpy(token, val, sizeof(token));
4439 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304440 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004441
4442 /* Extract the NSS information */
4443 if (result) {
4444 value = atoi(result);
4445 switch (value) {
4446 case 1:
4447 config_val = 1;
4448 break;
4449 case 2:
4450 config_val = 3;
4451 break;
4452 case 3:
4453 config_val = 7;
4454 break;
4455 case 4:
4456 config_val = 15;
4457 break;
4458 default:
4459 config_val = 3;
4460 break;
4461 }
4462
4463 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
4464 intf, config_val);
4465 if (system(buf) != 0) {
4466 sigma_dut_print(dut, DUT_MSG_ERROR,
4467 "iwpriv rxchainmask failed");
4468 }
4469
4470 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
4471 intf, config_val);
4472 if (system(buf) != 0) {
4473 sigma_dut_print(dut, DUT_MSG_ERROR,
4474 "iwpriv txchainmask failed");
4475 }
4476 }
4477
4478 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304479 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004480 if (result) {
4481 value = atoi(result);
4482 switch (value) {
4483 case 20:
4484 config_val = 0;
4485 break;
4486 case 40:
4487 config_val = 1;
4488 break;
4489 case 80:
4490 config_val = 2;
4491 break;
4492 case 160:
4493 config_val = 3;
4494 break;
4495 default:
4496 config_val = 2;
4497 break;
4498 }
4499
4500 dut->chwidth = config_val;
4501
4502 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
4503 intf, config_val);
4504 if (system(buf) != 0) {
4505 sigma_dut_print(dut, DUT_MSG_ERROR,
4506 "iwpriv chwidth failed");
4507 }
4508 }
4509
4510 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", intf);
4511 if (system(buf) != 0) {
4512 sigma_dut_print(dut, DUT_MSG_ERROR,
4513 "iwpriv opmode_notify failed");
4514 }
4515 }
4516
4517 val = get_param(cmd, "nss_mcs_cap");
4518 if (val) {
4519 int nss, mcs;
4520 char token[20];
4521 char *result = NULL;
4522 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304523 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004524
4525 strncpy(token, val, sizeof(token));
4526 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304527 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05304528 if (!result) {
4529 sigma_dut_print(dut, DUT_MSG_ERROR,
4530 "VHT NSS not specified");
4531 return 0;
4532 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004533 nss = atoi(result);
4534
4535 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
4536 if (system(buf) != 0) {
4537 sigma_dut_print(dut, DUT_MSG_ERROR,
4538 "iwpriv nss failed");
4539 }
4540
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304541 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004542 if (result == NULL) {
4543 sigma_dut_print(dut, DUT_MSG_ERROR,
4544 "VHTMCS NOT SPECIFIED!");
4545 return 0;
4546 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304547 result = strtok_r(result, "-", &saveptr);
4548 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05304549 if (!result) {
4550 sigma_dut_print(dut, DUT_MSG_ERROR,
4551 "VHT MCS not specified");
4552 return 0;
4553 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004554 mcs = atoi(result);
4555
4556 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d", intf, mcs);
4557 if (system(buf) != 0) {
4558 sigma_dut_print(dut, DUT_MSG_ERROR,
4559 "iwpriv mcs failed");
4560 }
4561
4562 switch (nss) {
4563 case 1:
4564 switch (mcs) {
4565 case 7:
4566 vht_mcsmap = 0xfffc;
4567 break;
4568 case 8:
4569 vht_mcsmap = 0xfffd;
4570 break;
4571 case 9:
4572 vht_mcsmap = 0xfffe;
4573 break;
4574 default:
4575 vht_mcsmap = 0xfffe;
4576 break;
4577 }
4578 break;
4579 case 2:
4580 switch (mcs) {
4581 case 7:
4582 vht_mcsmap = 0xfff0;
4583 break;
4584 case 8:
4585 vht_mcsmap = 0xfff5;
4586 break;
4587 case 9:
4588 vht_mcsmap = 0xfffa;
4589 break;
4590 default:
4591 vht_mcsmap = 0xfffa;
4592 break;
4593 }
4594 break;
4595 case 3:
4596 switch (mcs) {
4597 case 7:
4598 vht_mcsmap = 0xffc0;
4599 break;
4600 case 8:
4601 vht_mcsmap = 0xffd5;
4602 break;
4603 case 9:
4604 vht_mcsmap = 0xffea;
4605 break;
4606 default:
4607 vht_mcsmap = 0xffea;
4608 break;
4609 }
4610 break;
4611 default:
4612 vht_mcsmap = 0xffea;
4613 break;
4614 }
4615 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4616 intf, vht_mcsmap);
4617 if (system(buf) != 0) {
4618 sigma_dut_print(dut, DUT_MSG_ERROR,
4619 "iwpriv vht_mcsmap failed");
4620 }
4621 }
4622
4623 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
4624
4625 val = get_param(cmd, "Vht_tkip");
4626 if (val)
4627 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4628
4629 val = get_param(cmd, "Vht_wep");
4630 if (val)
4631 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4632
4633 if (tkip != -1 || wep != -1) {
4634 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
4635 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1",
4636 intf);
4637 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
4638 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 0",
4639 intf);
4640 } else {
4641 sigma_dut_print(dut, DUT_MSG_ERROR,
4642 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
4643 return 0;
4644 }
4645
4646 if (system(buf) != 0) {
4647 sigma_dut_print(dut, DUT_MSG_ERROR,
4648 "iwpriv htweptkip failed");
4649 }
4650 }
4651
4652 val = get_param(cmd, "txBandwidth");
4653 if (val) {
4654 switch (get_driver_type()) {
4655 case DRIVER_ATHEROS:
4656 if (ath_set_width(dut, conn, intf, val) < 0) {
4657 send_resp(dut, conn, SIGMA_ERROR,
4658 "ErrorCode,Failed to set txBandwidth");
4659 return 0;
4660 }
4661 break;
4662 default:
4663 sigma_dut_print(dut, DUT_MSG_ERROR,
4664 "Setting txBandwidth not supported");
4665 break;
4666 }
4667 }
4668
4669 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
4670}
4671
4672
4673static int sta_set_wireless_60g(struct sigma_dut *dut,
4674 struct sigma_conn *conn,
4675 struct sigma_cmd *cmd)
4676{
4677 const char *dev_role = get_param(cmd, "DevRole");
4678
4679 if (!dev_role) {
4680 send_resp(dut, conn, SIGMA_INVALID,
4681 "ErrorCode,DevRole not specified");
4682 return 0;
4683 }
4684
4685 if (strcasecmp(dev_role, "PCP") == 0)
4686 return sta_set_60g_pcp(dut, conn, cmd);
4687 if (strcasecmp(dev_role, "STA") == 0)
4688 return sta_set_60g_sta(dut, conn, cmd);
4689 send_resp(dut, conn, SIGMA_INVALID,
4690 "ErrorCode,DevRole not supported");
4691 return 0;
4692}
4693
4694
4695static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
4696 struct sigma_cmd *cmd)
4697{
4698 const char *val;
4699
4700 val = get_param(cmd, "Program");
4701 if (val) {
4702 if (strcasecmp(val, "11n") == 0)
4703 return cmd_sta_set_11n(dut, conn, cmd);
4704 if (strcasecmp(val, "VHT") == 0)
4705 return cmd_sta_set_wireless_vht(dut, conn, cmd);
4706 if (strcasecmp(val, "60ghz") == 0)
4707 return sta_set_wireless_60g(dut, conn, cmd);
4708 send_resp(dut, conn, SIGMA_ERROR,
4709 "ErrorCode,Program value not supported");
4710 } else {
4711 send_resp(dut, conn, SIGMA_ERROR,
4712 "ErrorCode,Program argument not available");
4713 }
4714
4715 return 0;
4716}
4717
4718
4719static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
4720 int tid)
4721{
4722 char buf[100];
4723 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
4724
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05304725 if (tid < 0 ||
4726 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
4727 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
4728 return;
4729 }
4730
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004731 /*
4732 * Two ways to ensure that addba request with a
4733 * non zero TID could be sent out. EV 117296
4734 */
4735 snprintf(buf, sizeof(buf),
4736 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
4737 tid);
4738 if (system(buf) != 0) {
4739 sigma_dut_print(dut, DUT_MSG_ERROR,
4740 "Ping did not send out");
4741 }
4742
4743 snprintf(buf, sizeof(buf),
4744 "iwconfig %s | grep Access | awk '{print $6}' > %s",
4745 intf, VI_QOS_TMP_FILE);
4746 if (system(buf) != 0)
4747 return;
4748
4749 snprintf(buf, sizeof(buf),
4750 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
4751 intf, VI_QOS_TMP_FILE);
4752 if (system(buf) != 0)
4753 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
4754
4755 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
4756 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
4757 if (system(buf) != 0) {
4758 sigma_dut_print(dut, DUT_MSG_ERROR,
4759 "VI_QOS_TEMP_FILE generation error failed");
4760 }
4761 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
4762 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
4763 if (system(buf) != 0) {
4764 sigma_dut_print(dut, DUT_MSG_ERROR,
4765 "VI_QOS_FILE generation failed");
4766 }
4767
4768 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
4769 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
4770 if (system(buf) != 0) {
4771 sigma_dut_print(dut, DUT_MSG_ERROR,
4772 "VI_QOS_FILE generation failed");
4773 }
4774
4775 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
4776 if (system(buf) != 0) {
4777 }
4778}
4779
4780
4781static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
4782 struct sigma_cmd *cmd)
4783{
4784 const char *intf = get_param(cmd, "Interface");
4785 const char *val;
4786 int tid = 0;
4787 char buf[100];
4788
4789 val = get_param(cmd, "TID");
4790 if (val) {
4791 tid = atoi(val);
4792 if (tid)
4793 ath_sta_inject_frame(dut, intf, tid);
4794 }
4795
4796 /* Command sequence for ADDBA request on Peregrine based devices */
4797 snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", intf);
4798 if (system(buf) != 0) {
4799 sigma_dut_print(dut, DUT_MSG_ERROR,
4800 "iwpriv setaddbaoper failed");
4801 }
4802
4803 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
4804 if (system(buf) != 0) {
4805 sigma_dut_print(dut, DUT_MSG_ERROR,
4806 "wifitool senddelba failed");
4807 }
4808
4809 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
4810 if (system(buf) != 0) {
4811 sigma_dut_print(dut, DUT_MSG_ERROR,
4812 "wifitool sendaddba failed");
4813 }
4814
4815 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
4816
4817 return 1;
4818}
4819
4820
4821static int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
4822 struct sigma_cmd *cmd)
4823{
4824 const char *val;
4825 int tid = 0;
4826 char buf[100];
4827
4828 val = get_param(cmd, "TID");
4829 if (val) {
4830 tid = atoi(val);
4831 if (tid != 0) {
4832 sigma_dut_print(dut, DUT_MSG_ERROR,
4833 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
4834 tid);
4835 }
4836 }
4837
4838 val = get_param(cmd, "Dest_mac");
4839 if (!val) {
4840 sigma_dut_print(dut, DUT_MSG_ERROR,
4841 "Currently not supporting addba for 60G without Dest_mac");
4842 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4843 }
4844
4845 snprintf(buf, sizeof(buf), "wil6210_addba_req.py %s %d",
4846 val, dut->back_rcv_buf);
4847 sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
4848
4849 if (system(buf) != 0) {
4850 sigma_dut_print(dut, DUT_MSG_ERROR,
4851 "Failed to send addba");
4852 return -1;
4853 }
4854
4855 return 1;
4856}
4857
4858
4859static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
4860 struct sigma_cmd *cmd)
4861{
4862 switch (get_driver_type()) {
4863 case DRIVER_ATHEROS:
4864 return ath_sta_send_addba(dut, conn, cmd);
4865 case DRIVER_WIL6210:
4866 return send_addba_60g(dut, conn, cmd);
4867 default:
4868 /*
4869 * There is no driver specific implementation for other drivers.
4870 * Ignore the command and report COMPLETE since the following
4871 * throughput test operation will end up sending ADDBA anyway.
4872 */
4873 return 1;
4874 }
4875}
4876
4877
4878int inject_eth_frame(int s, const void *data, size_t len,
4879 unsigned short ethtype, char *dst, char *src)
4880{
4881 struct iovec iov[4] = {
4882 {
4883 .iov_base = dst,
4884 .iov_len = ETH_ALEN,
4885 },
4886 {
4887 .iov_base = src,
4888 .iov_len = ETH_ALEN,
4889 },
4890 {
4891 .iov_base = &ethtype,
4892 .iov_len = sizeof(unsigned short),
4893 },
4894 {
4895 .iov_base = (void *) data,
4896 .iov_len = len,
4897 }
4898 };
4899 struct msghdr msg = {
4900 .msg_name = NULL,
4901 .msg_namelen = 0,
4902 .msg_iov = iov,
4903 .msg_iovlen = 4,
4904 .msg_control = NULL,
4905 .msg_controllen = 0,
4906 .msg_flags = 0,
4907 };
4908
4909 return sendmsg(s, &msg, 0);
4910}
4911
4912#if defined(__linux__) || defined(__QNXNTO__)
4913
4914int inject_frame(int s, const void *data, size_t len, int encrypt)
4915{
4916#define IEEE80211_RADIOTAP_F_WEP 0x04
4917#define IEEE80211_RADIOTAP_F_FRAG 0x08
4918 unsigned char rtap_hdr[] = {
4919 0x00, 0x00, /* radiotap version */
4920 0x0e, 0x00, /* radiotap length */
4921 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
4922 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
4923 0x00, /* padding */
4924 0x00, 0x00, /* RX and TX flags to indicate that */
4925 0x00, 0x00, /* this is the injected frame directly */
4926 };
4927 struct iovec iov[2] = {
4928 {
4929 .iov_base = &rtap_hdr,
4930 .iov_len = sizeof(rtap_hdr),
4931 },
4932 {
4933 .iov_base = (void *) data,
4934 .iov_len = len,
4935 }
4936 };
4937 struct msghdr msg = {
4938 .msg_name = NULL,
4939 .msg_namelen = 0,
4940 .msg_iov = iov,
4941 .msg_iovlen = 2,
4942 .msg_control = NULL,
4943 .msg_controllen = 0,
4944 .msg_flags = 0,
4945 };
4946
4947 if (encrypt)
4948 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
4949
4950 return sendmsg(s, &msg, 0);
4951}
4952
4953
4954int open_monitor(const char *ifname)
4955{
4956#ifdef __QNXNTO__
4957 struct sockaddr_dl ll;
4958 int s;
4959
4960 memset(&ll, 0, sizeof(ll));
4961 ll.sdl_family = AF_LINK;
4962 ll.sdl_index = if_nametoindex(ifname);
4963 if (ll.sdl_index == 0) {
4964 perror("if_nametoindex");
4965 return -1;
4966 }
4967 s = socket(PF_INET, SOCK_RAW, 0);
4968#else /* __QNXNTO__ */
4969 struct sockaddr_ll ll;
4970 int s;
4971
4972 memset(&ll, 0, sizeof(ll));
4973 ll.sll_family = AF_PACKET;
4974 ll.sll_ifindex = if_nametoindex(ifname);
4975 if (ll.sll_ifindex == 0) {
4976 perror("if_nametoindex");
4977 return -1;
4978 }
4979 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
4980#endif /* __QNXNTO__ */
4981 if (s < 0) {
4982 perror("socket[PF_PACKET,SOCK_RAW]");
4983 return -1;
4984 }
4985
4986 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
4987 perror("monitor socket bind");
4988 close(s);
4989 return -1;
4990 }
4991
4992 return s;
4993}
4994
4995
4996static int hex2num(char c)
4997{
4998 if (c >= '0' && c <= '9')
4999 return c - '0';
5000 if (c >= 'a' && c <= 'f')
5001 return c - 'a' + 10;
5002 if (c >= 'A' && c <= 'F')
5003 return c - 'A' + 10;
5004 return -1;
5005}
5006
5007
5008int hwaddr_aton(const char *txt, unsigned char *addr)
5009{
5010 int i;
5011
5012 for (i = 0; i < 6; i++) {
5013 int a, b;
5014
5015 a = hex2num(*txt++);
5016 if (a < 0)
5017 return -1;
5018 b = hex2num(*txt++);
5019 if (b < 0)
5020 return -1;
5021 *addr++ = (a << 4) | b;
5022 if (i < 5 && *txt++ != ':')
5023 return -1;
5024 }
5025
5026 return 0;
5027}
5028
5029#endif /* defined(__linux__) || defined(__QNXNTO__) */
5030
5031enum send_frame_type {
5032 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
5033};
5034enum send_frame_protection {
5035 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
5036};
5037
5038
5039static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
5040 enum send_frame_type frame,
5041 enum send_frame_protection protected,
5042 const char *dest)
5043{
5044#ifdef __linux__
5045 unsigned char buf[1000], *pos;
5046 int s, res;
5047 char bssid[20], addr[20];
5048 char result[32], ssid[100];
5049 size_t ssid_len;
5050
5051 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
5052 sizeof(result)) < 0 ||
5053 strncmp(result, "COMPLETED", 9) != 0) {
5054 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
5055 return 0;
5056 }
5057
5058 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
5059 < 0) {
5060 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
5061 "current BSSID");
5062 return 0;
5063 }
5064
5065 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
5066 < 0) {
5067 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
5068 "own MAC address");
5069 return 0;
5070 }
5071
5072 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
5073 < 0) {
5074 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
5075 "current SSID");
5076 return 0;
5077 }
5078 ssid_len = strlen(ssid);
5079
5080 pos = buf;
5081
5082 /* Frame Control */
5083 switch (frame) {
5084 case DISASSOC:
5085 *pos++ = 0xa0;
5086 break;
5087 case DEAUTH:
5088 *pos++ = 0xc0;
5089 break;
5090 case SAQUERY:
5091 *pos++ = 0xd0;
5092 break;
5093 case AUTH:
5094 *pos++ = 0xb0;
5095 break;
5096 case ASSOCREQ:
5097 *pos++ = 0x00;
5098 break;
5099 case REASSOCREQ:
5100 *pos++ = 0x20;
5101 break;
5102 case DLS_REQ:
5103 *pos++ = 0xd0;
5104 break;
5105 }
5106
5107 if (protected == INCORRECT_KEY)
5108 *pos++ = 0x40; /* Set Protected field to 1 */
5109 else
5110 *pos++ = 0x00;
5111
5112 /* Duration */
5113 *pos++ = 0x00;
5114 *pos++ = 0x00;
5115
5116 /* addr1 = DA (current AP) */
5117 hwaddr_aton(bssid, pos);
5118 pos += 6;
5119 /* addr2 = SA (own address) */
5120 hwaddr_aton(addr, pos);
5121 pos += 6;
5122 /* addr3 = BSSID (current AP) */
5123 hwaddr_aton(bssid, pos);
5124 pos += 6;
5125
5126 /* Seq# (to be filled by driver/mac80211) */
5127 *pos++ = 0x00;
5128 *pos++ = 0x00;
5129
5130 if (protected == INCORRECT_KEY) {
5131 /* CCMP parameters */
5132 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
5133 pos += 8;
5134 }
5135
5136 if (protected == INCORRECT_KEY) {
5137 switch (frame) {
5138 case DEAUTH:
5139 /* Reason code (encrypted) */
5140 memcpy(pos, "\xa7\x39", 2);
5141 pos += 2;
5142 break;
5143 case DISASSOC:
5144 /* Reason code (encrypted) */
5145 memcpy(pos, "\xa7\x39", 2);
5146 pos += 2;
5147 break;
5148 case SAQUERY:
5149 /* Category|Action|TransID (encrypted) */
5150 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
5151 pos += 4;
5152 break;
5153 default:
5154 return -1;
5155 }
5156
5157 /* CCMP MIC */
5158 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
5159 pos += 8;
5160 } else {
5161 switch (frame) {
5162 case DEAUTH:
5163 /* reason code = 8 */
5164 *pos++ = 0x08;
5165 *pos++ = 0x00;
5166 break;
5167 case DISASSOC:
5168 /* reason code = 8 */
5169 *pos++ = 0x08;
5170 *pos++ = 0x00;
5171 break;
5172 case SAQUERY:
5173 /* Category - SA Query */
5174 *pos++ = 0x08;
5175 /* SA query Action - Request */
5176 *pos++ = 0x00;
5177 /* Transaction ID */
5178 *pos++ = 0x12;
5179 *pos++ = 0x34;
5180 break;
5181 case AUTH:
5182 /* Auth Alg (Open) */
5183 *pos++ = 0x00;
5184 *pos++ = 0x00;
5185 /* Seq# */
5186 *pos++ = 0x01;
5187 *pos++ = 0x00;
5188 /* Status code */
5189 *pos++ = 0x00;
5190 *pos++ = 0x00;
5191 break;
5192 case ASSOCREQ:
5193 /* Capability Information */
5194 *pos++ = 0x31;
5195 *pos++ = 0x04;
5196 /* Listen Interval */
5197 *pos++ = 0x0a;
5198 *pos++ = 0x00;
5199 /* SSID */
5200 *pos++ = 0x00;
5201 *pos++ = ssid_len;
5202 memcpy(pos, ssid, ssid_len);
5203 pos += ssid_len;
5204 /* Supported Rates */
5205 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
5206 10);
5207 pos += 10;
5208 /* Extended Supported Rates */
5209 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
5210 pos += 6;
5211 /* RSN */
5212 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
5213 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
5214 "\x00\x00\x00\x00\x0f\xac\x06", 28);
5215 pos += 28;
5216 break;
5217 case REASSOCREQ:
5218 /* Capability Information */
5219 *pos++ = 0x31;
5220 *pos++ = 0x04;
5221 /* Listen Interval */
5222 *pos++ = 0x0a;
5223 *pos++ = 0x00;
5224 /* Current AP */
5225 hwaddr_aton(bssid, pos);
5226 pos += 6;
5227 /* SSID */
5228 *pos++ = 0x00;
5229 *pos++ = ssid_len;
5230 memcpy(pos, ssid, ssid_len);
5231 pos += ssid_len;
5232 /* Supported Rates */
5233 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
5234 10);
5235 pos += 10;
5236 /* Extended Supported Rates */
5237 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
5238 pos += 6;
5239 /* RSN */
5240 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
5241 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
5242 "\x00\x00\x00\x00\x0f\xac\x06", 28);
5243 pos += 28;
5244 break;
5245 case DLS_REQ:
5246 /* Category - DLS */
5247 *pos++ = 0x02;
5248 /* DLS Action - Request */
5249 *pos++ = 0x00;
5250 /* Destination MACAddress */
5251 if (dest)
5252 hwaddr_aton(dest, pos);
5253 else
5254 memset(pos, 0, 6);
5255 pos += 6;
5256 /* Source MACAddress */
5257 hwaddr_aton(addr, pos);
5258 pos += 6;
5259 /* Capability Information */
5260 *pos++ = 0x10; /* Privacy */
5261 *pos++ = 0x06; /* QoS */
5262 /* DLS Timeout Value */
5263 *pos++ = 0x00;
5264 *pos++ = 0x01;
5265 /* Supported rates */
5266 *pos++ = 0x01;
5267 *pos++ = 0x08;
5268 *pos++ = 0x0c; /* 6 Mbps */
5269 *pos++ = 0x12; /* 9 Mbps */
5270 *pos++ = 0x18; /* 12 Mbps */
5271 *pos++ = 0x24; /* 18 Mbps */
5272 *pos++ = 0x30; /* 24 Mbps */
5273 *pos++ = 0x48; /* 36 Mbps */
5274 *pos++ = 0x60; /* 48 Mbps */
5275 *pos++ = 0x6c; /* 54 Mbps */
5276 /* TODO: Extended Supported Rates */
5277 /* TODO: HT Capabilities */
5278 break;
5279 }
5280 }
5281
5282 s = open_monitor("sigmadut");
5283 if (s < 0) {
5284 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
5285 "monitor socket");
5286 return 0;
5287 }
5288
5289 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
5290 if (res < 0) {
5291 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
5292 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05305293 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005294 return 0;
5295 }
5296 if (res < pos - buf) {
5297 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
5298 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05305299 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005300 return 0;
5301 }
5302
5303 close(s);
5304
5305 return 1;
5306#else /* __linux__ */
5307 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
5308 "yet supported");
5309 return 0;
5310#endif /* __linux__ */
5311}
5312
5313
5314static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
5315 struct sigma_conn *conn,
5316 struct sigma_cmd *cmd)
5317{
5318 const char *intf = get_param(cmd, "Interface");
5319 const char *sta, *val;
5320 unsigned char addr[ETH_ALEN];
5321 char buf[100];
5322
5323 sta = get_param(cmd, "peer");
5324 if (sta == NULL)
5325 sta = get_param(cmd, "station");
5326 if (sta == NULL) {
5327 send_resp(dut, conn, SIGMA_ERROR,
5328 "ErrorCode,Missing peer address");
5329 return 0;
5330 }
5331 if (hwaddr_aton(sta, addr) < 0) {
5332 send_resp(dut, conn, SIGMA_ERROR,
5333 "ErrorCode,Invalid peer address");
5334 return 0;
5335 }
5336
5337 val = get_param(cmd, "type");
5338 if (val == NULL)
5339 return -1;
5340
5341 if (strcasecmp(val, "DISCOVERY") == 0) {
5342 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
5343 if (wpa_command(intf, buf) < 0) {
5344 send_resp(dut, conn, SIGMA_ERROR,
5345 "ErrorCode,Failed to send TDLS discovery");
5346 return 0;
5347 }
5348 return 1;
5349 }
5350
5351 if (strcasecmp(val, "SETUP") == 0) {
5352 int status = 0, timeout = 0;
5353
5354 val = get_param(cmd, "Status");
5355 if (val)
5356 status = atoi(val);
5357
5358 val = get_param(cmd, "Timeout");
5359 if (val)
5360 timeout = atoi(val);
5361
5362 if (status != 0 && status != 37) {
5363 send_resp(dut, conn, SIGMA_ERROR,
5364 "ErrorCode,Unsupported status value");
5365 return 0;
5366 }
5367
5368 if (timeout != 0 && timeout != 301) {
5369 send_resp(dut, conn, SIGMA_ERROR,
5370 "ErrorCode,Unsupported timeout value");
5371 return 0;
5372 }
5373
5374 if (status && timeout) {
5375 send_resp(dut, conn, SIGMA_ERROR,
5376 "ErrorCode,Unsupported timeout+status "
5377 "combination");
5378 return 0;
5379 }
5380
5381 if (status == 37 &&
5382 wpa_command(intf, "SET tdls_testing 0x200")) {
5383 send_resp(dut, conn, SIGMA_ERROR,
5384 "ErrorCode,Failed to enable "
5385 "decline setup response test mode");
5386 return 0;
5387 }
5388
5389 if (timeout == 301) {
5390 int res;
5391 if (dut->no_tpk_expiration)
5392 res = wpa_command(intf,
5393 "SET tdls_testing 0x108");
5394 else
5395 res = wpa_command(intf,
5396 "SET tdls_testing 0x8");
5397 if (res) {
5398 send_resp(dut, conn, SIGMA_ERROR,
5399 "ErrorCode,Failed to set short TPK "
5400 "lifetime");
5401 return 0;
5402 }
5403 }
5404
5405 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
5406 if (wpa_command(intf, buf) < 0) {
5407 send_resp(dut, conn, SIGMA_ERROR,
5408 "ErrorCode,Failed to send TDLS setup");
5409 return 0;
5410 }
5411 return 1;
5412 }
5413
5414 if (strcasecmp(val, "TEARDOWN") == 0) {
5415 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
5416 if (wpa_command(intf, buf) < 0) {
5417 send_resp(dut, conn, SIGMA_ERROR,
5418 "ErrorCode,Failed to send TDLS teardown");
5419 return 0;
5420 }
5421 return 1;
5422 }
5423
5424 send_resp(dut, conn, SIGMA_ERROR,
5425 "ErrorCode,Unsupported TDLS frame");
5426 return 0;
5427}
5428
5429
5430static int sta_ap_known(const char *ifname, const char *bssid)
5431{
5432 char buf[4096];
5433
5434 snprintf(buf, sizeof(buf), "BSS %s", bssid);
5435 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
5436 return 0;
5437 if (strncmp(buf, "id=", 3) != 0)
5438 return 0;
5439 return 1;
5440}
5441
5442
5443static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
5444 const char *bssid)
5445{
5446 int res;
5447 struct wpa_ctrl *ctrl;
5448 char buf[256];
5449
5450 if (sta_ap_known(ifname, bssid))
5451 return 0;
5452 sigma_dut_print(dut, DUT_MSG_DEBUG,
5453 "AP not in BSS table - start scan");
5454
5455 ctrl = open_wpa_mon(ifname);
5456 if (ctrl == NULL) {
5457 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
5458 "wpa_supplicant monitor connection");
5459 return -1;
5460 }
5461
5462 if (wpa_command(ifname, "SCAN") < 0) {
5463 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
5464 wpa_ctrl_detach(ctrl);
5465 wpa_ctrl_close(ctrl);
5466 return -1;
5467 }
5468
5469 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
5470 buf, sizeof(buf));
5471
5472 wpa_ctrl_detach(ctrl);
5473 wpa_ctrl_close(ctrl);
5474
5475 if (res < 0) {
5476 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
5477 return -1;
5478 }
5479
5480 if (sta_ap_known(ifname, bssid))
5481 return 0;
5482 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
5483 return -1;
5484}
5485
5486
5487static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
5488 struct sigma_conn *conn,
5489 struct sigma_cmd *cmd,
5490 const char *intf)
5491{
5492 char buf[200];
5493
5494 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
5495 if (system(buf) != 0) {
5496 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
5497 "ndsend");
5498 return 0;
5499 }
5500
5501 return 1;
5502}
5503
5504
5505static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
5506 struct sigma_conn *conn,
5507 struct sigma_cmd *cmd,
5508 const char *intf)
5509{
5510 char buf[200];
5511 const char *ip = get_param(cmd, "SenderIP");
5512
5513 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
5514 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
5515 if (system(buf) == 0) {
5516 sigma_dut_print(dut, DUT_MSG_INFO,
5517 "Neighbor Solicitation got a response "
5518 "for %s@%s", ip, intf);
5519 }
5520
5521 return 1;
5522}
5523
5524
5525static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
5526 struct sigma_conn *conn,
5527 struct sigma_cmd *cmd,
5528 const char *ifname)
5529{
5530 char buf[200];
5531 const char *ip = get_param(cmd, "SenderIP");
5532
5533 if (ip == NULL) {
5534 send_resp(dut, conn, SIGMA_ERROR,
5535 "ErrorCode,Missing SenderIP parameter");
5536 return 0;
5537 }
5538 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
5539 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
5540 if (system(buf) != 0) {
5541 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
5542 "for %s@%s", ip, ifname);
5543 }
5544
5545 return 1;
5546}
5547
5548
5549static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
5550 struct sigma_conn *conn,
5551 struct sigma_cmd *cmd,
5552 const char *ifname)
5553{
5554 char buf[200];
5555 char ip[16];
5556 int s;
5557
5558 s = socket(PF_INET, SOCK_DGRAM, 0);
5559 if (s >= 0) {
5560 struct ifreq ifr;
5561 struct sockaddr_in saddr;
5562
5563 memset(&ifr, 0, sizeof(ifr));
5564 strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
5565 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
5566 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
5567 "%s IP address: %s",
5568 ifname, strerror(errno));
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05305569 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005570 return -1;
5571 } else {
5572 memcpy(&saddr, &ifr.ifr_addr,
5573 sizeof(struct sockaddr_in));
5574 strncpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
5575 }
5576 close(s);
5577
5578 }
5579
5580 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
5581 ip);
5582 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
5583 if (system(buf) != 0) {
5584 }
5585
5586 return 1;
5587}
5588
5589
5590static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
5591 struct sigma_conn *conn,
5592 struct sigma_cmd *cmd,
5593 const char *ifname)
5594{
5595 char buf[200], addr[20];
5596 char dst[ETH_ALEN], src[ETH_ALEN];
5597 short ethtype = htons(ETH_P_ARP);
5598 char *pos;
5599 int s, res;
5600 const char *val;
5601 struct sockaddr_in taddr;
5602
5603 val = get_param(cmd, "dest");
5604 if (val)
5605 hwaddr_aton(val, (unsigned char *) dst);
5606
5607 val = get_param(cmd, "DestIP");
5608 if (val)
5609 inet_aton(val, &taddr.sin_addr);
5610
5611 if (get_wpa_status(get_station_ifname(), "address", addr,
5612 sizeof(addr)) < 0)
5613 return -2;
5614 hwaddr_aton(addr, (unsigned char *) src);
5615
5616 pos = buf;
5617 *pos++ = 0x00;
5618 *pos++ = 0x01;
5619 *pos++ = 0x08;
5620 *pos++ = 0x00;
5621 *pos++ = 0x06;
5622 *pos++ = 0x04;
5623 *pos++ = 0x00;
5624 *pos++ = 0x02;
5625 memcpy(pos, src, ETH_ALEN);
5626 pos += ETH_ALEN;
5627 memcpy(pos, &taddr.sin_addr, 4);
5628 pos += 4;
5629 memcpy(pos, dst, ETH_ALEN);
5630 pos += ETH_ALEN;
5631 memcpy(pos, &taddr.sin_addr, 4);
5632 pos += 4;
5633
5634 s = open_monitor(get_station_ifname());
5635 if (s < 0) {
5636 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
5637 "monitor socket");
5638 return 0;
5639 }
5640
5641 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
5642 if (res < 0) {
5643 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
5644 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05305645 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005646 return 0;
5647 }
5648
5649 close(s);
5650
5651 return 1;
5652}
5653
5654
5655static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
5656 struct sigma_conn *conn,
5657 struct sigma_cmd *cmd,
5658 const char *intf, const char *dest)
5659{
5660 char buf[100];
5661
5662 if (if_nametoindex("sigmadut") == 0) {
5663 snprintf(buf, sizeof(buf),
5664 "iw dev %s interface add sigmadut type monitor",
5665 get_station_ifname());
5666 if (system(buf) != 0 ||
5667 if_nametoindex("sigmadut") == 0) {
5668 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
5669 "monitor interface with '%s'", buf);
5670 return -2;
5671 }
5672 }
5673
5674 if (system("ifconfig sigmadut up") != 0) {
5675 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
5676 "monitor interface up");
5677 return -2;
5678 }
5679
5680 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
5681}
5682
5683
5684static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
5685 struct sigma_conn *conn,
5686 struct sigma_cmd *cmd)
5687{
5688 const char *intf = get_param(cmd, "Interface");
5689 const char *dest = get_param(cmd, "Dest");
5690 const char *type = get_param(cmd, "FrameName");
5691 const char *val;
5692 char buf[200], *pos, *end;
5693 int count, count2;
5694
5695 if (type == NULL)
5696 type = get_param(cmd, "Type");
5697
5698 if (intf == NULL || dest == NULL || type == NULL)
5699 return -1;
5700
5701 if (strcasecmp(type, "NeighAdv") == 0)
5702 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
5703
5704 if (strcasecmp(type, "NeighSolicitReq") == 0)
5705 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
5706
5707 if (strcasecmp(type, "ARPProbe") == 0)
5708 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
5709
5710 if (strcasecmp(type, "ARPAnnounce") == 0)
5711 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
5712
5713 if (strcasecmp(type, "ARPReply") == 0)
5714 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
5715
5716 if (strcasecmp(type, "DLS-request") == 0 ||
5717 strcasecmp(type, "DLSrequest") == 0)
5718 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
5719 dest);
5720
5721 if (strcasecmp(type, "ANQPQuery") != 0 &&
5722 strcasecmp(type, "Query") != 0) {
5723 send_resp(dut, conn, SIGMA_ERROR,
5724 "ErrorCode,Unsupported HS 2.0 send frame type");
5725 return 0;
5726 }
5727
5728 if (sta_scan_ap(dut, intf, dest) < 0) {
5729 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
5730 "the requested AP");
5731 return 0;
5732 }
5733
5734 pos = buf;
5735 end = buf + sizeof(buf);
5736 count = 0;
5737 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
5738
5739 val = get_param(cmd, "ANQP_CAP_LIST");
5740 if (val && atoi(val)) {
5741 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
5742 count++;
5743 }
5744
5745 val = get_param(cmd, "VENUE_NAME");
5746 if (val && atoi(val)) {
5747 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
5748 count++;
5749 }
5750
5751 val = get_param(cmd, "NETWORK_AUTH_TYPE");
5752 if (val && atoi(val)) {
5753 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
5754 count++;
5755 }
5756
5757 val = get_param(cmd, "ROAMING_CONS");
5758 if (val && atoi(val)) {
5759 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
5760 count++;
5761 }
5762
5763 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
5764 if (val && atoi(val)) {
5765 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
5766 count++;
5767 }
5768
5769 val = get_param(cmd, "NAI_REALM_LIST");
5770 if (val && atoi(val)) {
5771 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
5772 count++;
5773 }
5774
5775 val = get_param(cmd, "3GPP_INFO");
5776 if (val && atoi(val)) {
5777 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
5778 count++;
5779 }
5780
5781 val = get_param(cmd, "DOMAIN_LIST");
5782 if (val && atoi(val)) {
5783 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
5784 count++;
5785 }
5786
5787 if (count && wpa_command(intf, buf)) {
5788 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
5789 return 0;
5790 }
5791
5792 pos = buf;
5793 end = buf + sizeof(buf);
5794 count2 = 0;
5795 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
5796
5797 val = get_param(cmd, "HS_CAP_LIST");
5798 if (val && atoi(val)) {
5799 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
5800 count2++;
5801 }
5802
5803 val = get_param(cmd, "OPER_NAME");
5804 if (val && atoi(val)) {
5805 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
5806 count2++;
5807 }
5808
5809 val = get_param(cmd, "WAN_METRICS");
5810 if (!val)
5811 val = get_param(cmd, "WAN_MAT");
5812 if (!val)
5813 val = get_param(cmd, "WAN_MET");
5814 if (val && atoi(val)) {
5815 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
5816 count2++;
5817 }
5818
5819 val = get_param(cmd, "CONNECTION_CAPABILITY");
5820 if (val && atoi(val)) {
5821 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
5822 count2++;
5823 }
5824
5825 val = get_param(cmd, "OP_CLASS");
5826 if (val && atoi(val)) {
5827 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
5828 count2++;
5829 }
5830
5831 val = get_param(cmd, "OSU_PROVIDER_LIST");
5832 if (val && atoi(val)) {
5833 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
5834 count2++;
5835 }
5836
5837 if (count && count2) {
5838 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
5839 "second query");
5840 sleep(1);
5841 }
5842
5843 if (count2 && wpa_command(intf, buf)) {
5844 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
5845 "failed");
5846 return 0;
5847 }
5848
5849 val = get_param(cmd, "NAI_HOME_REALM_LIST");
5850 if (val) {
5851 if (count || count2) {
5852 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
5853 "sending out second query");
5854 sleep(1);
5855 }
5856
5857 if (strcmp(val, "1") == 0)
5858 val = "mail.example.com";
5859 snprintf(buf, end - pos,
5860 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
5861 dest, val);
5862 if (wpa_command(intf, buf)) {
5863 send_resp(dut, conn, SIGMA_ERROR,
5864 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
5865 "failed");
5866 return 0;
5867 }
5868 }
5869
5870 val = get_param(cmd, "ICON_REQUEST");
5871 if (val) {
5872 if (count || count2) {
5873 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
5874 "sending out second query");
5875 sleep(1);
5876 }
5877
5878 snprintf(buf, end - pos,
5879 "HS20_ICON_REQUEST %s %s", dest, val);
5880 if (wpa_command(intf, buf)) {
5881 send_resp(dut, conn, SIGMA_ERROR,
5882 "ErrorCode,HS20_ICON_REQUEST failed");
5883 return 0;
5884 }
5885 }
5886
5887 return 1;
5888}
5889
5890
5891static int ath_sta_send_frame_vht(struct sigma_dut *dut,
5892 struct sigma_conn *conn,
5893 struct sigma_cmd *cmd)
5894{
5895 const char *val;
5896 char *ifname;
5897 char buf[100];
5898 int chwidth, nss;
5899
5900 val = get_param(cmd, "framename");
5901 if (!val)
5902 return -1;
5903 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
5904
5905 /* Command sequence to generate Op mode notification */
5906 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
5907 ifname = get_station_ifname();
5908
5909 /* Disable STBC */
5910 snprintf(buf, sizeof(buf),
5911 "iwpriv %s tx_stbc 0", ifname);
5912 if (system(buf) != 0) {
5913 sigma_dut_print(dut, DUT_MSG_ERROR,
5914 "iwpriv tx_stbc 0 failed!");
5915 }
5916
5917 /* Extract Channel width */
5918 val = get_param(cmd, "Channel_width");
5919 if (val) {
5920 switch (atoi(val)) {
5921 case 20:
5922 chwidth = 0;
5923 break;
5924 case 40:
5925 chwidth = 1;
5926 break;
5927 case 80:
5928 chwidth = 2;
5929 break;
5930 case 160:
5931 chwidth = 3;
5932 break;
5933 default:
5934 chwidth = 2;
5935 break;
5936 }
5937
5938 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
5939 ifname, chwidth);
5940 if (system(buf) != 0) {
5941 sigma_dut_print(dut, DUT_MSG_ERROR,
5942 "iwpriv chwidth failed!");
5943 }
5944 }
5945
5946 /* Extract NSS */
5947 val = get_param(cmd, "NSS");
5948 if (val) {
5949 switch (atoi(val)) {
5950 case 1:
5951 nss = 1;
5952 break;
5953 case 2:
5954 nss = 3;
5955 break;
5956 case 3:
5957 nss = 7;
5958 break;
5959 default:
5960 /* We do not support NSS > 3 */
5961 nss = 3;
5962 break;
5963 }
5964 snprintf(buf, sizeof(buf),
5965 "iwpriv %s rxchainmask %d", ifname, nss);
5966 if (system(buf) != 0) {
5967 sigma_dut_print(dut, DUT_MSG_ERROR,
5968 "iwpriv rxchainmask failed!");
5969 }
5970 }
5971
5972 /* Opmode notify */
5973 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
5974 if (system(buf) != 0) {
5975 sigma_dut_print(dut, DUT_MSG_ERROR,
5976 "iwpriv opmode_notify failed!");
5977 } else {
5978 sigma_dut_print(dut, DUT_MSG_INFO,
5979 "Sent out the notify frame!");
5980 }
5981 }
5982
5983 return 1;
5984}
5985
5986
5987static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
5988 struct sigma_conn *conn,
5989 struct sigma_cmd *cmd)
5990{
5991 switch (get_driver_type()) {
5992 case DRIVER_ATHEROS:
5993 return ath_sta_send_frame_vht(dut, conn, cmd);
5994 default:
5995 send_resp(dut, conn, SIGMA_ERROR,
5996 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
5997 return 0;
5998 }
5999}
6000
6001
6002int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
6003 struct sigma_cmd *cmd)
6004{
6005 const char *intf = get_param(cmd, "Interface");
6006 const char *val;
6007 enum send_frame_type frame;
6008 enum send_frame_protection protected;
6009 char buf[100];
6010 unsigned char addr[ETH_ALEN];
6011 int res;
6012
6013 val = get_param(cmd, "program");
6014 if (val == NULL)
6015 val = get_param(cmd, "frame");
6016 if (val && strcasecmp(val, "TDLS") == 0)
6017 return cmd_sta_send_frame_tdls(dut, conn, cmd);
6018 if (val && (strcasecmp(val, "HS2") == 0 ||
6019 strcasecmp(val, "HS2-R2") == 0))
6020 return cmd_sta_send_frame_hs2(dut, conn, cmd);
6021 if (val && strcasecmp(val, "VHT") == 0)
6022 return cmd_sta_send_frame_vht(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07006023 if (val && strcasecmp(val, "LOC") == 0)
6024 return loc_cmd_sta_send_frame(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006025
6026 val = get_param(cmd, "TD_DISC");
6027 if (val) {
6028 if (hwaddr_aton(val, addr) < 0)
6029 return -1;
6030 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
6031 if (wpa_command(intf, buf) < 0) {
6032 send_resp(dut, conn, SIGMA_ERROR,
6033 "ErrorCode,Failed to send TDLS discovery");
6034 return 0;
6035 }
6036 return 1;
6037 }
6038
6039 val = get_param(cmd, "TD_Setup");
6040 if (val) {
6041 if (hwaddr_aton(val, addr) < 0)
6042 return -1;
6043 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
6044 if (wpa_command(intf, buf) < 0) {
6045 send_resp(dut, conn, SIGMA_ERROR,
6046 "ErrorCode,Failed to start TDLS setup");
6047 return 0;
6048 }
6049 return 1;
6050 }
6051
6052 val = get_param(cmd, "TD_TearDown");
6053 if (val) {
6054 if (hwaddr_aton(val, addr) < 0)
6055 return -1;
6056 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
6057 if (wpa_command(intf, buf) < 0) {
6058 send_resp(dut, conn, SIGMA_ERROR,
6059 "ErrorCode,Failed to tear down TDLS link");
6060 return 0;
6061 }
6062 return 1;
6063 }
6064
6065 val = get_param(cmd, "TD_ChannelSwitch");
6066 if (val) {
6067 /* TODO */
6068 send_resp(dut, conn, SIGMA_ERROR,
6069 "ErrorCode,TD_ChannelSwitch not yet supported");
6070 return 0;
6071 }
6072
6073 val = get_param(cmd, "TD_NF");
6074 if (val) {
6075 /* TODO */
6076 send_resp(dut, conn, SIGMA_ERROR,
6077 "ErrorCode,TD_NF not yet supported");
6078 return 0;
6079 }
6080
6081 val = get_param(cmd, "PMFFrameType");
6082 if (val == NULL)
6083 val = get_param(cmd, "FrameName");
6084 if (val == NULL)
6085 val = get_param(cmd, "Type");
6086 if (val == NULL)
6087 return -1;
6088 if (strcasecmp(val, "disassoc") == 0)
6089 frame = DISASSOC;
6090 else if (strcasecmp(val, "deauth") == 0)
6091 frame = DEAUTH;
6092 else if (strcasecmp(val, "saquery") == 0)
6093 frame = SAQUERY;
6094 else if (strcasecmp(val, "auth") == 0)
6095 frame = AUTH;
6096 else if (strcasecmp(val, "assocreq") == 0)
6097 frame = ASSOCREQ;
6098 else if (strcasecmp(val, "reassocreq") == 0)
6099 frame = REASSOCREQ;
6100 else if (strcasecmp(val, "neigreq") == 0) {
6101 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
6102
6103 val = get_param(cmd, "ssid");
6104 if (val == NULL)
6105 return -1;
6106
6107 res = send_neighbor_request(dut, intf, val);
6108 if (res) {
6109 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
6110 "Failed to send neighbor report request");
6111 return 0;
6112 }
6113
6114 return 1;
6115 } else if (strcasecmp(val, "transmgmtquery") == 0) {
6116 sigma_dut_print(dut, DUT_MSG_DEBUG,
6117 "Got Transition Management Query");
6118
6119 val = get_param(cmd, "ssid");
6120 res = send_trans_mgmt_query(dut, intf, val);
6121 if (res) {
6122 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
6123 "Failed to send Transition Management Query");
6124 return 0;
6125 }
6126
6127 return 1;
6128 } else {
6129 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
6130 "PMFFrameType");
6131 return 0;
6132 }
6133
6134 val = get_param(cmd, "PMFProtected");
6135 if (val == NULL)
6136 val = get_param(cmd, "Protected");
6137 if (val == NULL)
6138 return -1;
6139 if (strcasecmp(val, "Correct-key") == 0 ||
6140 strcasecmp(val, "CorrectKey") == 0)
6141 protected = CORRECT_KEY;
6142 else if (strcasecmp(val, "IncorrectKey") == 0)
6143 protected = INCORRECT_KEY;
6144 else if (strcasecmp(val, "Unprotected") == 0)
6145 protected = UNPROTECTED;
6146 else {
6147 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
6148 "PMFProtected");
6149 return 0;
6150 }
6151
6152 if (protected != UNPROTECTED &&
6153 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
6154 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
6155 "PMFProtected for auth/assocreq/reassocreq");
6156 return 0;
6157 }
6158
6159 if (if_nametoindex("sigmadut") == 0) {
6160 snprintf(buf, sizeof(buf),
6161 "iw dev %s interface add sigmadut type monitor",
6162 get_station_ifname());
6163 if (system(buf) != 0 ||
6164 if_nametoindex("sigmadut") == 0) {
6165 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
6166 "monitor interface with '%s'", buf);
6167 return -2;
6168 }
6169 }
6170
6171 if (system("ifconfig sigmadut up") != 0) {
6172 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6173 "monitor interface up");
6174 return -2;
6175 }
6176
6177 return sta_inject_frame(dut, conn, frame, protected, NULL);
6178}
6179
6180
6181static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
6182 struct sigma_conn *conn,
6183 struct sigma_cmd *cmd,
6184 const char *ifname)
6185{
6186 char buf[200];
6187 const char *val;
6188
6189 val = get_param(cmd, "ClearARP");
6190 if (val && atoi(val) == 1) {
6191 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
6192 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6193 if (system(buf) != 0) {
6194 send_resp(dut, conn, SIGMA_ERROR,
6195 "errorCode,Failed to clear ARP cache");
6196 return 0;
6197 }
6198 }
6199
6200 return 1;
6201}
6202
6203
6204int cmd_sta_set_parameter(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 *val;
6209
6210 if (intf == NULL)
6211 return -1;
6212
6213 val = get_param(cmd, "program");
6214 if (val && (strcasecmp(val, "HS2") == 0 ||
6215 strcasecmp(val, "HS2-R2") == 0))
6216 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
6217
6218 return -1;
6219}
6220
6221
6222static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
6223 struct sigma_cmd *cmd)
6224{
6225 const char *intf = get_param(cmd, "Interface");
6226 const char *mac = get_param(cmd, "MAC");
6227
6228 if (intf == NULL || mac == NULL)
6229 return -1;
6230
6231 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
6232 "interface %s to %s", intf, mac);
6233
6234 if (dut->set_macaddr) {
6235 char buf[128];
6236 int res;
6237 if (strcasecmp(mac, "default") == 0) {
6238 res = snprintf(buf, sizeof(buf), "%s",
6239 dut->set_macaddr);
6240 dut->tmp_mac_addr = 0;
6241 } else {
6242 res = snprintf(buf, sizeof(buf), "%s %s",
6243 dut->set_macaddr, mac);
6244 dut->tmp_mac_addr = 1;
6245 }
6246 if (res < 0 || res >= (int) sizeof(buf))
6247 return -1;
6248 if (system(buf) != 0) {
6249 send_resp(dut, conn, SIGMA_ERROR,
6250 "errorCode,Failed to set MAC "
6251 "address");
6252 return 0;
6253 }
6254 return 1;
6255 }
6256
6257 if (strcasecmp(mac, "default") == 0)
6258 return 1;
6259
6260 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
6261 "command");
6262 return 0;
6263}
6264
6265
6266static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
6267 struct sigma_conn *conn, const char *intf,
6268 int val)
6269{
6270 char buf[200];
6271 int res;
6272
6273 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
6274 intf, val);
6275 if (res < 0 || res >= (int) sizeof(buf))
6276 return -1;
6277 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6278 if (system(buf) != 0) {
6279 send_resp(dut, conn, SIGMA_ERROR,
6280 "errorCode,Failed to configure offchannel mode");
6281 return 0;
6282 }
6283
6284 return 1;
6285}
6286
6287
6288enum sec_ch_offset {
6289 SEC_CH_NO,
6290 SEC_CH_40ABOVE,
6291 SEC_CH_40BELOW
6292};
6293
6294
6295static int off_chan_val(enum sec_ch_offset off)
6296{
6297 switch (off) {
6298 case SEC_CH_NO:
6299 return 0;
6300 case SEC_CH_40ABOVE:
6301 return 40;
6302 case SEC_CH_40BELOW:
6303 return -40;
6304 }
6305
6306 return 0;
6307}
6308
6309
6310static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
6311 const char *intf, int off_ch_num,
6312 enum sec_ch_offset sec)
6313{
6314 char buf[200];
6315 int res;
6316
6317 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
6318 intf, off_ch_num);
6319 if (res < 0 || res >= (int) sizeof(buf))
6320 return -1;
6321 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6322 if (system(buf) != 0) {
6323 send_resp(dut, conn, SIGMA_ERROR,
6324 "errorCode,Failed to set offchan");
6325 return 0;
6326 }
6327
6328 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
6329 intf, off_chan_val(sec));
6330 if (res < 0 || res >= (int) sizeof(buf))
6331 return -1;
6332 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6333 if (system(buf) != 0) {
6334 send_resp(dut, conn, SIGMA_ERROR,
6335 "errorCode,Failed to set sec chan offset");
6336 return 0;
6337 }
6338
6339 return 1;
6340}
6341
6342
6343static int tdls_set_offchannel_offset(struct sigma_dut *dut,
6344 struct sigma_conn *conn,
6345 const char *intf, int off_ch_num,
6346 enum sec_ch_offset sec)
6347{
6348 char buf[200];
6349 int res;
6350
6351 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
6352 off_ch_num);
6353 if (res < 0 || res >= (int) sizeof(buf))
6354 return -1;
6355 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6356
6357 if (wpa_command(intf, buf) < 0) {
6358 send_resp(dut, conn, SIGMA_ERROR,
6359 "ErrorCode,Failed to set offchan");
6360 return 0;
6361 }
6362 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
6363 off_chan_val(sec));
6364 if (res < 0 || res >= (int) sizeof(buf))
6365 return -1;
6366
6367 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6368
6369 if (wpa_command(intf, buf) < 0) {
6370 send_resp(dut, conn, SIGMA_ERROR,
6371 "ErrorCode,Failed to set sec chan offset");
6372 return 0;
6373 }
6374
6375 return 1;
6376}
6377
6378
6379static int tdls_set_offchannel_mode(struct sigma_dut *dut,
6380 struct sigma_conn *conn,
6381 const char *intf, int val)
6382{
6383 char buf[200];
6384 int res;
6385
6386 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
6387 val);
6388 if (res < 0 || res >= (int) sizeof(buf))
6389 return -1;
6390 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6391
6392 if (wpa_command(intf, buf) < 0) {
6393 send_resp(dut, conn, SIGMA_ERROR,
6394 "ErrorCode,Failed to configure offchannel mode");
6395 return 0;
6396 }
6397
6398 return 1;
6399}
6400
6401
6402static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
6403 struct sigma_conn *conn,
6404 struct sigma_cmd *cmd)
6405{
6406 const char *val;
6407 enum {
6408 CHSM_NOT_SET,
6409 CHSM_ENABLE,
6410 CHSM_DISABLE,
6411 CHSM_REJREQ,
6412 CHSM_UNSOLRESP
6413 } chsm = CHSM_NOT_SET;
6414 int off_ch_num = -1;
6415 enum sec_ch_offset sec_ch = SEC_CH_NO;
6416 int res;
6417
6418 val = get_param(cmd, "Uapsd");
6419 if (val) {
6420 char buf[100];
6421 if (strcasecmp(val, "Enable") == 0)
6422 snprintf(buf, sizeof(buf), "SET ps 99");
6423 else if (strcasecmp(val, "Disable") == 0)
6424 snprintf(buf, sizeof(buf), "SET ps 98");
6425 else {
6426 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
6427 "Unsupported uapsd parameter value");
6428 return 0;
6429 }
6430 if (wpa_command(intf, buf)) {
6431 send_resp(dut, conn, SIGMA_ERROR,
6432 "ErrorCode,Failed to change U-APSD "
6433 "powersave mode");
6434 return 0;
6435 }
6436 }
6437
6438 val = get_param(cmd, "TPKTIMER");
6439 if (val && strcasecmp(val, "DISABLE") == 0) {
6440 if (wpa_command(intf, "SET tdls_testing 0x100")) {
6441 send_resp(dut, conn, SIGMA_ERROR,
6442 "ErrorCode,Failed to enable no TPK "
6443 "expiration test mode");
6444 return 0;
6445 }
6446 dut->no_tpk_expiration = 1;
6447 }
6448
6449 val = get_param(cmd, "ChSwitchMode");
6450 if (val) {
6451 if (strcasecmp(val, "Enable") == 0 ||
6452 strcasecmp(val, "Initiate") == 0)
6453 chsm = CHSM_ENABLE;
6454 else if (strcasecmp(val, "Disable") == 0 ||
6455 strcasecmp(val, "passive") == 0)
6456 chsm = CHSM_DISABLE;
6457 else if (strcasecmp(val, "RejReq") == 0)
6458 chsm = CHSM_REJREQ;
6459 else if (strcasecmp(val, "UnSolResp") == 0)
6460 chsm = CHSM_UNSOLRESP;
6461 else {
6462 send_resp(dut, conn, SIGMA_ERROR,
6463 "ErrorCode,Unknown ChSwitchMode value");
6464 return 0;
6465 }
6466 }
6467
6468 val = get_param(cmd, "OffChNum");
6469 if (val) {
6470 off_ch_num = atoi(val);
6471 if (off_ch_num == 0) {
6472 send_resp(dut, conn, SIGMA_ERROR,
6473 "ErrorCode,Invalid OffChNum");
6474 return 0;
6475 }
6476 }
6477
6478 val = get_param(cmd, "SecChOffset");
6479 if (val) {
6480 if (strcmp(val, "20") == 0)
6481 sec_ch = SEC_CH_NO;
6482 else if (strcasecmp(val, "40above") == 0)
6483 sec_ch = SEC_CH_40ABOVE;
6484 else if (strcasecmp(val, "40below") == 0)
6485 sec_ch = SEC_CH_40BELOW;
6486 else {
6487 send_resp(dut, conn, SIGMA_ERROR,
6488 "ErrorCode,Unknown SecChOffset value");
6489 return 0;
6490 }
6491 }
6492
6493 if (chsm == CHSM_NOT_SET) {
6494 /* no offchannel changes requested */
6495 return 1;
6496 }
6497
6498 if (strcmp(intf, get_main_ifname()) != 0 &&
6499 strcmp(intf, get_station_ifname()) != 0) {
6500 send_resp(dut, conn, SIGMA_ERROR,
6501 "ErrorCode,Unknown interface");
6502 return 0;
6503 }
6504
6505 switch (chsm) {
6506 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +03006507 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006508 break;
6509 case CHSM_ENABLE:
6510 if (off_ch_num < 0) {
6511 send_resp(dut, conn, SIGMA_ERROR,
6512 "ErrorCode,Missing OffChNum argument");
6513 return 0;
6514 }
6515 if (wifi_chip_type == DRIVER_WCN) {
6516 res = tdls_set_offchannel_offset(dut, conn, intf,
6517 off_ch_num, sec_ch);
6518 } else {
6519 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
6520 sec_ch);
6521 }
6522 if (res != 1)
6523 return res;
6524 if (wifi_chip_type == DRIVER_WCN)
6525 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
6526 else
6527 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
6528 break;
6529 case CHSM_DISABLE:
6530 if (wifi_chip_type == DRIVER_WCN)
6531 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
6532 else
6533 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
6534 break;
6535 case CHSM_REJREQ:
6536 if (wifi_chip_type == DRIVER_WCN)
6537 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
6538 else
6539 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
6540 break;
6541 case CHSM_UNSOLRESP:
6542 if (off_ch_num < 0) {
6543 send_resp(dut, conn, SIGMA_ERROR,
6544 "ErrorCode,Missing OffChNum argument");
6545 return 0;
6546 }
6547 if (wifi_chip_type == DRIVER_WCN) {
6548 res = tdls_set_offchannel_offset(dut, conn, intf,
6549 off_ch_num, sec_ch);
6550 } else {
6551 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
6552 sec_ch);
6553 }
6554 if (res != 1)
6555 return res;
6556 if (wifi_chip_type == DRIVER_WCN)
6557 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
6558 else
6559 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
6560 break;
6561 }
6562
6563 return res;
6564}
6565
6566
6567static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
6568 struct sigma_conn *conn,
6569 struct sigma_cmd *cmd)
6570{
6571 const char *val;
6572 char *token, *result;
6573
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08006574 novap_reset(dut, intf);
6575
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006576 val = get_param(cmd, "nss_mcs_opt");
6577 if (val) {
6578 /* String (nss_operating_mode; mcs_operating_mode) */
6579 int nss, mcs;
6580 char buf[50];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306581 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006582
6583 token = strdup(val);
6584 if (!token)
6585 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306586 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05306587 if (!result) {
6588 sigma_dut_print(dut, DUT_MSG_ERROR,
6589 "VHT NSS not specified");
6590 goto failed;
6591 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006592 if (strcasecmp(result, "def") != 0) {
6593 nss = atoi(result);
6594 if (nss == 4)
6595 ath_disable_txbf(dut, intf);
6596 snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
6597 intf, nss);
6598 if (system(buf) != 0) {
6599 sigma_dut_print(dut, DUT_MSG_ERROR,
6600 "iwpriv nss failed");
6601 goto failed;
6602 }
6603 }
6604
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306605 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05306606 if (!result) {
6607 sigma_dut_print(dut, DUT_MSG_ERROR,
6608 "VHT MCS not specified");
6609 goto failed;
6610 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006611 if (strcasecmp(result, "def") == 0) {
6612 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0",
6613 intf);
6614 if (system(buf) != 0) {
6615 sigma_dut_print(dut, DUT_MSG_ERROR,
6616 "iwpriv set11NRates failed");
6617 goto failed;
6618 }
6619
6620 } else {
6621 mcs = atoi(result);
6622 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
6623 intf, mcs);
6624 if (system(buf) != 0) {
6625 sigma_dut_print(dut, DUT_MSG_ERROR,
6626 "iwpriv vhtmcs failed");
6627 goto failed;
6628 }
6629 }
6630 /* Channel width gets messed up, fix this */
6631 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
6632 intf, dut->chwidth);
6633 if (system(buf) != 0) {
6634 sigma_dut_print(dut, DUT_MSG_ERROR,
6635 "iwpriv chwidth failed");
6636 }
6637 }
6638
6639 return 1;
6640failed:
6641 free(token);
6642 return 0;
6643}
6644
6645
6646static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
6647 struct sigma_conn *conn,
6648 struct sigma_cmd *cmd)
6649{
6650 switch (get_driver_type()) {
6651 case DRIVER_ATHEROS:
6652 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
6653 default:
6654 send_resp(dut, conn, SIGMA_ERROR,
6655 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
6656 return 0;
6657 }
6658}
6659
6660
6661static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
6662 struct sigma_cmd *cmd)
6663{
6664 const char *intf = get_param(cmd, "Interface");
6665 const char *prog = get_param(cmd, "Prog");
6666
6667 if (intf == NULL || prog == NULL)
6668 return -1;
6669
6670 if (strcasecmp(prog, "TDLS") == 0)
6671 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
6672
6673 if (strcasecmp(prog, "VHT") == 0)
6674 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
6675
6676 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
6677 return 0;
6678}
6679
6680
6681static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
6682 struct sigma_cmd *cmd)
6683{
6684 const char *intf = get_param(cmd, "Interface");
6685 const char *mode = get_param(cmd, "Mode");
6686 int res;
6687
6688 if (intf == NULL || mode == NULL)
6689 return -1;
6690
6691 if (strcasecmp(mode, "On") == 0)
6692 res = wpa_command(intf, "SET radio_disabled 0");
6693 else if (strcasecmp(mode, "Off") == 0)
6694 res = wpa_command(intf, "SET radio_disabled 1");
6695 else
6696 return -1;
6697
6698 if (res) {
6699 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
6700 "radio mode");
6701 return 0;
6702 }
6703
6704 return 1;
6705}
6706
6707
6708static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
6709 struct sigma_cmd *cmd)
6710{
6711 const char *intf = get_param(cmd, "Interface");
6712 const char *mode = get_param(cmd, "Mode");
6713 int res;
6714
6715 if (intf == NULL || mode == NULL)
6716 return -1;
6717
6718 if (strcasecmp(mode, "On") == 0)
6719 res = set_ps(intf, dut, 1);
6720 else if (strcasecmp(mode, "Off") == 0)
6721 res = set_ps(intf, dut, 0);
6722 else
6723 return -1;
6724
6725 if (res) {
6726 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
6727 "power save mode");
6728 return 0;
6729 }
6730
6731 return 1;
6732}
6733
6734
6735static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
6736 struct sigma_cmd *cmd)
6737{
6738 const char *intf = get_param(cmd, "Interface");
6739 const char *val, *bssid;
6740 int res;
6741 char *buf;
6742 size_t buf_len;
6743
6744 val = get_param(cmd, "BSSID_FILTER");
6745 if (val == NULL)
6746 return -1;
6747
6748 bssid = get_param(cmd, "BSSID_List");
6749 if (atoi(val) == 0 || bssid == NULL) {
6750 /* Disable BSSID filter */
6751 if (wpa_command(intf, "SET bssid_filter ")) {
6752 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
6753 "to disable BSSID filter");
6754 return 0;
6755 }
6756
6757 return 1;
6758 }
6759
6760 buf_len = 100 + strlen(bssid);
6761 buf = malloc(buf_len);
6762 if (buf == NULL)
6763 return -1;
6764
6765 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
6766 res = wpa_command(intf, buf);
6767 free(buf);
6768 if (res) {
6769 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
6770 "BSSID filter");
6771 return 0;
6772 }
6773
6774 return 1;
6775}
6776
6777
6778static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
6779 struct sigma_cmd *cmd)
6780{
6781 const char *intf = get_param(cmd, "Interface");
6782 const char *val;
6783
6784 /* TODO: ARP */
6785
6786 val = get_param(cmd, "HS2_CACHE_PROFILE");
6787 if (val && strcasecmp(val, "All") == 0)
6788 hs2_clear_credentials(intf);
6789
6790 return 1;
6791}
6792
6793
6794static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
6795 struct sigma_cmd *cmd)
6796{
6797 const char *intf = get_param(cmd, "Interface");
6798 const char *key_type = get_param(cmd, "KeyType");
6799 char buf[100], resp[200];
6800
6801 if (key_type == NULL)
6802 return -1;
6803
6804 if (strcasecmp(key_type, "GTK") == 0) {
6805 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
6806 strncmp(buf, "FAIL", 4) == 0) {
6807 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
6808 "not fetch current GTK");
6809 return 0;
6810 }
6811 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
6812 send_resp(dut, conn, SIGMA_COMPLETE, resp);
6813 return 0;
6814 } else {
6815 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
6816 "KeyType");
6817 return 0;
6818 }
6819
6820 return 1;
6821}
6822
6823
6824static int hs2_set_policy(struct sigma_dut *dut)
6825{
6826#ifdef ANDROID
6827 system("ip rule del prio 23000");
6828 if (system("ip rule add from all lookup main prio 23000") != 0) {
6829 sigma_dut_print(dut, DUT_MSG_ERROR,
6830 "Failed to run:ip rule add from all lookup main prio");
6831 return -1;
6832 }
6833 if (system("ip route flush cache") != 0) {
6834 sigma_dut_print(dut, DUT_MSG_ERROR,
6835 "Failed to run ip route flush cache");
6836 return -1;
6837 }
6838 return 1;
6839#else /* ANDROID */
6840 return 0;
6841#endif /* ANDROID */
6842}
6843
6844
6845static int cmd_sta_hs2_associate(struct sigma_dut *dut,
6846 struct sigma_conn *conn,
6847 struct sigma_cmd *cmd)
6848{
6849 const char *intf = get_param(cmd, "Interface");
6850 const char *val = get_param(cmd, "Ignore_blacklist");
6851 struct wpa_ctrl *ctrl;
6852 int res;
6853 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
6854 int tries = 0;
6855 int ignore_blacklist = 0;
6856 const char *events[] = {
6857 "CTRL-EVENT-CONNECTED",
6858 "INTERWORKING-BLACKLISTED",
6859 "INTERWORKING-NO-MATCH",
6860 NULL
6861 };
6862
6863 start_sta_mode(dut);
6864
6865 blacklisted[0] = '\0';
6866 if (val && atoi(val))
6867 ignore_blacklist = 1;
6868
6869try_again:
6870 ctrl = open_wpa_mon(intf);
6871 if (ctrl == NULL) {
6872 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6873 "wpa_supplicant monitor connection");
6874 return -2;
6875 }
6876
6877 tries++;
6878 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
6879 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
6880 "Interworking connection");
6881 wpa_ctrl_detach(ctrl);
6882 wpa_ctrl_close(ctrl);
6883 return 0;
6884 }
6885
6886 buf[0] = '\0';
6887 while (1) {
6888 char *pos;
6889 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
6890 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
6891 if (!pos)
6892 break;
6893 pos += 25;
6894 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
6895 pos);
6896 if (!blacklisted[0])
6897 memcpy(blacklisted, pos, strlen(pos) + 1);
6898 }
6899
6900 if (ignore_blacklist && blacklisted[0]) {
6901 char *end;
6902 end = strchr(blacklisted, ' ');
6903 if (end)
6904 *end = '\0';
6905 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
6906 blacklisted);
6907 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
6908 blacklisted);
6909 if (wpa_command(intf, buf)) {
6910 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
6911 wpa_ctrl_detach(ctrl);
6912 wpa_ctrl_close(ctrl);
6913 return 0;
6914 }
6915 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6916 buf, sizeof(buf));
6917 }
6918
6919 wpa_ctrl_detach(ctrl);
6920 wpa_ctrl_close(ctrl);
6921
6922 if (res < 0) {
6923 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
6924 "connect");
6925 return 0;
6926 }
6927
6928 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
6929 strstr(buf, "INTERWORKING-BLACKLISTED")) {
6930 if (tries < 2) {
6931 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
6932 goto try_again;
6933 }
6934 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
6935 "matching credentials found");
6936 return 0;
6937 }
6938
6939 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
6940 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
6941 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
6942 "get current BSSID/SSID");
6943 return 0;
6944 }
6945
6946 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
6947 send_resp(dut, conn, SIGMA_COMPLETE, resp);
6948 hs2_set_policy(dut);
6949 return 0;
6950}
6951
6952
6953static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
6954 struct sigma_conn *conn,
6955 const char *ifname,
6956 struct sigma_cmd *cmd)
6957{
6958 const char *val;
6959 int id;
6960
6961 id = add_cred(ifname);
6962 if (id < 0)
6963 return -2;
6964 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
6965
6966 val = get_param(cmd, "prefer");
6967 if (val && atoi(val) > 0)
6968 set_cred(ifname, id, "priority", "1");
6969
6970 val = get_param(cmd, "REALM");
6971 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
6972 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
6973 "realm");
6974 return 0;
6975 }
6976
6977 val = get_param(cmd, "HOME_FQDN");
6978 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
6979 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
6980 "home_fqdn");
6981 return 0;
6982 }
6983
6984 val = get_param(cmd, "Username");
6985 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
6986 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
6987 "username");
6988 return 0;
6989 }
6990
6991 val = get_param(cmd, "Password");
6992 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
6993 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
6994 "password");
6995 return 0;
6996 }
6997
6998 val = get_param(cmd, "ROOT_CA");
6999 if (val) {
7000 char fname[200];
7001 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
7002#ifdef __linux__
7003 if (!file_exists(fname)) {
7004 char msg[300];
7005 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
7006 "file (%s) not found", fname);
7007 send_resp(dut, conn, SIGMA_ERROR, msg);
7008 return 0;
7009 }
7010#endif /* __linux__ */
7011 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
7012 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7013 "not set root CA");
7014 return 0;
7015 }
7016 }
7017
7018 return 1;
7019}
7020
7021
7022static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
7023{
7024 FILE *in, *out;
7025 char buf[500];
7026 int found = 0;
7027
7028 in = fopen("devdetail.xml", "r");
7029 if (in == NULL)
7030 return -1;
7031 out = fopen("devdetail.xml.tmp", "w");
7032 if (out == NULL) {
7033 fclose(in);
7034 return -1;
7035 }
7036
7037 while (fgets(buf, sizeof(buf), in)) {
7038 char *pos = strstr(buf, "<IMSI>");
7039 if (pos) {
7040 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
7041 imsi);
7042 pos += 6;
7043 *pos = '\0';
7044 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
7045 found++;
7046 } else {
7047 fprintf(out, "%s", buf);
7048 }
7049 }
7050
7051 fclose(out);
7052 fclose(in);
7053 if (found)
7054 rename("devdetail.xml.tmp", "devdetail.xml");
7055 else
7056 unlink("devdetail.xml.tmp");
7057
7058 return 0;
7059}
7060
7061
7062static int sta_add_credential_sim(struct sigma_dut *dut,
7063 struct sigma_conn *conn,
7064 const char *ifname, struct sigma_cmd *cmd)
7065{
7066 const char *val, *imsi = NULL;
7067 int id;
7068 char buf[200];
7069 int res;
7070 const char *pos;
7071 size_t mnc_len;
7072 char plmn_mcc[4];
7073 char plmn_mnc[4];
7074
7075 id = add_cred(ifname);
7076 if (id < 0)
7077 return -2;
7078 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
7079
7080 val = get_param(cmd, "prefer");
7081 if (val && atoi(val) > 0)
7082 set_cred(ifname, id, "priority", "1");
7083
7084 val = get_param(cmd, "PLMN_MCC");
7085 if (val == NULL) {
7086 send_resp(dut, conn, SIGMA_ERROR,
7087 "errorCode,Missing PLMN_MCC");
7088 return 0;
7089 }
7090 if (strlen(val) != 3) {
7091 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
7092 return 0;
7093 }
7094 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
7095
7096 val = get_param(cmd, "PLMN_MNC");
7097 if (val == NULL) {
7098 send_resp(dut, conn, SIGMA_ERROR,
7099 "errorCode,Missing PLMN_MNC");
7100 return 0;
7101 }
7102 if (strlen(val) != 2 && strlen(val) != 3) {
7103 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
7104 return 0;
7105 }
7106 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
7107
7108 val = get_param(cmd, "IMSI");
7109 if (val == NULL) {
7110 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
7111 "IMSI");
7112 return 0;
7113 }
7114
7115 imsi = pos = val;
7116
7117 if (strncmp(plmn_mcc, pos, 3) != 0) {
7118 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
7119 return 0;
7120 }
7121 pos += 3;
7122
7123 mnc_len = strlen(plmn_mnc);
7124 if (mnc_len < 2) {
7125 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
7126 return 0;
7127 }
7128
7129 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
7130 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
7131 return 0;
7132 }
7133 pos += mnc_len;
7134
7135 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
7136 if (res < 0 || res >= (int) sizeof(buf))
7137 return -1;
7138 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
7139 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7140 "not set IMSI");
7141 return 0;
7142 }
7143
7144 val = get_param(cmd, "Password");
7145 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
7146 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7147 "not set password");
7148 return 0;
7149 }
7150
7151 if (dut->program == PROGRAM_HS2_R2) {
7152 /*
7153 * Set provisioning_sp for the test cases where SIM/USIM
7154 * provisioning is used.
7155 */
7156 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
7157 "wi-fi.org") < 0) {
7158 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7159 "not set provisioning_sp");
7160 return 0;
7161 }
7162
7163 update_devdetail_imsi(dut, imsi);
7164 }
7165
7166 return 1;
7167}
7168
7169
7170static int sta_add_credential_cert(struct sigma_dut *dut,
7171 struct sigma_conn *conn,
7172 const char *ifname,
7173 struct sigma_cmd *cmd)
7174{
7175 const char *val;
7176 int id;
7177
7178 id = add_cred(ifname);
7179 if (id < 0)
7180 return -2;
7181 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
7182
7183 val = get_param(cmd, "prefer");
7184 if (val && atoi(val) > 0)
7185 set_cred(ifname, id, "priority", "1");
7186
7187 val = get_param(cmd, "REALM");
7188 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
7189 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
7190 "realm");
7191 return 0;
7192 }
7193
7194 val = get_param(cmd, "HOME_FQDN");
7195 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
7196 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
7197 "home_fqdn");
7198 return 0;
7199 }
7200
7201 val = get_param(cmd, "Username");
7202 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
7203 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
7204 "username");
7205 return 0;
7206 }
7207
7208 val = get_param(cmd, "clientCertificate");
7209 if (val) {
7210 char fname[200];
7211 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
7212#ifdef __linux__
7213 if (!file_exists(fname)) {
7214 char msg[300];
7215 snprintf(msg, sizeof(msg),
7216 "ErrorCode,clientCertificate "
7217 "file (%s) not found", fname);
7218 send_resp(dut, conn, SIGMA_ERROR, msg);
7219 return 0;
7220 }
7221#endif /* __linux__ */
7222 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
7223 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7224 "not set client_cert");
7225 return 0;
7226 }
7227 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
7228 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7229 "not set private_key");
7230 return 0;
7231 }
7232 }
7233
7234 val = get_param(cmd, "ROOT_CA");
7235 if (val) {
7236 char fname[200];
7237 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
7238#ifdef __linux__
7239 if (!file_exists(fname)) {
7240 char msg[300];
7241 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
7242 "file (%s) not found", fname);
7243 send_resp(dut, conn, SIGMA_ERROR, msg);
7244 return 0;
7245 }
7246#endif /* __linux__ */
7247 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
7248 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
7249 "not set root CA");
7250 return 0;
7251 }
7252 }
7253
7254 return 1;
7255}
7256
7257
7258static int cmd_sta_add_credential(struct sigma_dut *dut,
7259 struct sigma_conn *conn,
7260 struct sigma_cmd *cmd)
7261{
7262 const char *intf = get_param(cmd, "Interface");
7263 const char *type;
7264
7265 start_sta_mode(dut);
7266
7267 type = get_param(cmd, "Type");
7268 if (!type)
7269 return -1;
7270
7271 if (strcasecmp(type, "uname_pwd") == 0)
7272 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
7273
7274 if (strcasecmp(type, "sim") == 0)
7275 return sta_add_credential_sim(dut, conn, intf, cmd);
7276
7277 if (strcasecmp(type, "cert") == 0)
7278 return sta_add_credential_cert(dut, conn, intf, cmd);
7279
7280 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
7281 "type");
7282 return 0;
7283}
7284
7285
7286static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
7287 struct sigma_cmd *cmd)
7288{
7289 const char *intf = get_param(cmd, "Interface");
7290 const char *val;
7291 char buf[100];
7292 int res;
7293
7294 val = get_param(cmd, "HESSID");
7295 if (val) {
7296 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
7297 if (res < 0 || res >= (int) sizeof(buf))
7298 return -1;
7299 wpa_command(intf, buf);
7300 }
7301
7302 val = get_param(cmd, "ACCS_NET_TYPE");
7303 if (val) {
7304 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
7305 val);
7306 if (res < 0 || res >= (int) sizeof(buf))
7307 return -1;
7308 wpa_command(intf, buf);
7309 }
7310
7311 if (wpa_command(intf, "SCAN")) {
7312 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
7313 "scan");
7314 return 0;
7315 }
7316
7317 return 1;
7318}
7319
7320
7321static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
7322 struct sigma_cmd *cmd)
7323{
7324#ifdef __linux__
7325 struct timeval tv;
7326 struct tm tm;
7327 time_t t;
7328 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +05307329 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007330
7331 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
7332
7333 memset(&tm, 0, sizeof(tm));
7334 val = get_param(cmd, "seconds");
7335 if (val)
7336 tm.tm_sec = atoi(val);
7337 val = get_param(cmd, "minutes");
7338 if (val)
7339 tm.tm_min = atoi(val);
7340 val = get_param(cmd, "hours");
7341 if (val)
7342 tm.tm_hour = atoi(val);
7343 val = get_param(cmd, "date");
7344 if (val)
7345 tm.tm_mday = atoi(val);
7346 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +05307347 if (val) {
7348 v = atoi(val);
7349 if (v < 1 || v > 12) {
7350 send_resp(dut, conn, SIGMA_INVALID,
7351 "errorCode,Invalid month");
7352 return 0;
7353 }
7354 tm.tm_mon = v - 1;
7355 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007356 val = get_param(cmd, "year");
7357 if (val) {
7358 int year = atoi(val);
7359#ifdef ANDROID
7360 if (year > 2035)
7361 year = 2035; /* years beyond 2035 not supported */
7362#endif /* ANDROID */
7363 tm.tm_year = year - 1900;
7364 }
7365 t = mktime(&tm);
7366 if (t == (time_t) -1) {
7367 send_resp(dut, conn, SIGMA_ERROR,
7368 "errorCode,Invalid date or time");
7369 return 0;
7370 }
7371
7372 memset(&tv, 0, sizeof(tv));
7373 tv.tv_sec = t;
7374
7375 if (settimeofday(&tv, NULL) < 0) {
7376 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
7377 strerror(errno));
7378 send_resp(dut, conn, SIGMA_ERROR,
7379 "errorCode,Failed to set time");
7380 return 0;
7381 }
7382
7383 return 1;
7384#endif /* __linux__ */
7385
7386 return -1;
7387}
7388
7389
7390static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
7391 struct sigma_cmd *cmd)
7392{
7393 const char *intf = get_param(cmd, "Interface");
7394 const char *name, *val;
7395 int prod_ess_assoc = 1;
7396 char buf[200], bssid[100], ssid[100];
7397 int res;
7398 struct wpa_ctrl *ctrl;
7399
7400 name = get_param(cmd, "osuFriendlyName");
7401
7402 val = get_param(cmd, "ProdESSAssoc");
7403 if (val)
7404 prod_ess_assoc = atoi(val);
7405
7406 kill_dhcp_client(dut, intf);
7407 if (start_dhcp_client(dut, intf) < 0)
7408 return -2;
7409
7410 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
7411 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
7412 res = snprintf(buf, sizeof(buf),
7413 "%s %s%s%s signup osu-ca.pem",
7414 prod_ess_assoc ? "" : "-N",
7415 name ? "-O'" : "", name ? name : "",
7416 name ? "'" : "");
7417
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +05307418 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007419 if (run_hs20_osu(dut, buf) < 0) {
7420 FILE *f;
7421
7422 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
7423
7424 f = fopen("hs20-osu-client.res", "r");
7425 if (f) {
7426 char resp[400], res[300], *pos;
7427 if (!fgets(res, sizeof(res), f))
7428 res[0] = '\0';
7429 pos = strchr(res, '\n');
7430 if (pos)
7431 *pos = '\0';
7432 fclose(f);
7433 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
7434 res);
7435 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
7436 if (system(resp) != 0) {
7437 }
7438 snprintf(resp, sizeof(resp),
7439 "SSID,,BSSID,,failureReason,%s", res);
7440 send_resp(dut, conn, SIGMA_COMPLETE, resp);
7441 return 0;
7442 }
7443
7444 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
7445 return 0;
7446 }
7447
7448 if (!prod_ess_assoc)
7449 goto report;
7450
7451 ctrl = open_wpa_mon(intf);
7452 if (ctrl == NULL) {
7453 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7454 "wpa_supplicant monitor connection");
7455 return -1;
7456 }
7457
7458 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
7459 buf, sizeof(buf));
7460
7461 wpa_ctrl_detach(ctrl);
7462 wpa_ctrl_close(ctrl);
7463
7464 if (res < 0) {
7465 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
7466 "network after OSU");
7467 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
7468 return 0;
7469 }
7470
7471report:
7472 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
7473 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
7474 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
7475 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
7476 return 0;
7477 }
7478
7479 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
7480 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007481 return 0;
7482}
7483
7484
7485static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
7486 struct sigma_cmd *cmd)
7487{
7488 const char *val;
7489 int timeout = 120;
7490
7491 val = get_param(cmd, "PolicyUpdate");
7492 if (val == NULL || atoi(val) == 0)
7493 return 1; /* No operation requested */
7494
7495 val = get_param(cmd, "Timeout");
7496 if (val)
7497 timeout = atoi(val);
7498
7499 if (timeout) {
7500 /* TODO: time out the command and return
7501 * PolicyUpdateStatus,TIMEOUT if needed. */
7502 }
7503
7504 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
7505 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
7506 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
7507 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
7508 return 0;
7509 }
7510
7511 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
7512 return 0;
7513}
7514
7515
7516static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
7517 struct sigma_cmd *cmd)
7518{
7519 struct wpa_ctrl *ctrl;
7520 const char *intf = get_param(cmd, "Interface");
7521 const char *bssid = get_param(cmd, "Bssid");
7522 const char *ssid = get_param(cmd, "SSID");
7523 const char *security = get_param(cmd, "Security");
7524 const char *passphrase = get_param(cmd, "Passphrase");
7525 const char *pin = get_param(cmd, "PIN");
7526 char buf[1000];
7527 char ssid_hex[200], passphrase_hex[200];
7528 const char *keymgmt, *cipher;
7529
7530 if (intf == NULL)
7531 intf = get_main_ifname();
7532
7533 if (!bssid) {
7534 send_resp(dut, conn, SIGMA_ERROR,
7535 "ErrorCode,Missing Bssid argument");
7536 return 0;
7537 }
7538
7539 if (!ssid) {
7540 send_resp(dut, conn, SIGMA_ERROR,
7541 "ErrorCode,Missing SSID argument");
7542 return 0;
7543 }
7544
7545 if (!security) {
7546 send_resp(dut, conn, SIGMA_ERROR,
7547 "ErrorCode,Missing Security argument");
7548 return 0;
7549 }
7550
7551 if (!passphrase) {
7552 send_resp(dut, conn, SIGMA_ERROR,
7553 "ErrorCode,Missing Passphrase argument");
7554 return 0;
7555 }
7556
7557 if (!pin) {
7558 send_resp(dut, conn, SIGMA_ERROR,
7559 "ErrorCode,Missing PIN argument");
7560 return 0;
7561 }
7562
7563 if (strlen(ssid) >= 2 * sizeof(ssid_hex) ||
7564 strlen(passphrase) >= 2 * sizeof(passphrase_hex)) {
7565 send_resp(dut, conn, SIGMA_ERROR,
7566 "ErrorCode,Too long SSID/passphrase");
7567 return 0;
7568 }
7569
7570 ctrl = open_wpa_mon(intf);
7571 if (ctrl == NULL) {
7572 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7573 "wpa_supplicant monitor connection");
7574 return -2;
7575 }
7576
7577 if (strcasecmp(security, "wpa2-psk") == 0) {
7578 keymgmt = "WPA2PSK";
7579 cipher = "CCMP";
7580 } else {
7581 wpa_ctrl_detach(ctrl);
7582 wpa_ctrl_close(ctrl);
7583 send_resp(dut, conn, SIGMA_ERROR,
7584 "ErrorCode,Unsupported Security value");
7585 return 0;
7586 }
7587
7588 ascii2hexstr(ssid, ssid_hex);
7589 ascii2hexstr(passphrase, passphrase_hex);
7590 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
7591 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
7592
7593 if (wpa_command(intf, buf) < 0) {
7594 wpa_ctrl_detach(ctrl);
7595 wpa_ctrl_close(ctrl);
7596 send_resp(dut, conn, SIGMA_ERROR,
7597 "ErrorCode,Failed to start registrar");
7598 return 0;
7599 }
7600
7601 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
7602 dut->er_oper_performed = 1;
7603
7604 return wps_connection_event(dut, conn, ctrl, intf, 0);
7605}
7606
7607
7608static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
7609 struct sigma_conn *conn,
7610 struct sigma_cmd *cmd)
7611{
7612 struct wpa_ctrl *ctrl;
7613 const char *intf = get_param(cmd, "Interface");
7614 const char *bssid = get_param(cmd, "Bssid");
7615 char buf[100];
7616
7617 if (!bssid) {
7618 send_resp(dut, conn, SIGMA_ERROR,
7619 "ErrorCode,Missing Bssid argument");
7620 return 0;
7621 }
7622
7623 ctrl = open_wpa_mon(intf);
7624 if (ctrl == NULL) {
7625 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7626 "wpa_supplicant monitor connection");
7627 return -2;
7628 }
7629
7630 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
7631
7632 if (wpa_command(intf, buf) < 0) {
7633 wpa_ctrl_detach(ctrl);
7634 wpa_ctrl_close(ctrl);
7635 send_resp(dut, conn, SIGMA_ERROR,
7636 "ErrorCode,Failed to start registrar");
7637 return 0;
7638 }
7639
7640 return wps_connection_event(dut, conn, ctrl, intf, 0);
7641}
7642
7643
7644static int req_intf(struct sigma_cmd *cmd)
7645{
7646 return get_param(cmd, "interface") == NULL ? -1 : 0;
7647}
7648
7649
7650void sta_register_cmds(void)
7651{
7652 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
7653 cmd_sta_get_ip_config);
7654 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
7655 cmd_sta_set_ip_config);
7656 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
7657 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
7658 cmd_sta_get_mac_address);
7659 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
7660 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
7661 cmd_sta_verify_ip_connection);
7662 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
7663 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
7664 cmd_sta_set_encryption);
7665 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
7666 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
7667 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
7668 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
7669 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
7670 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
7671 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
7672 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
7673 cmd_sta_set_eapakaprime);
7674 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
7675 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
7676 /* TODO: sta_set_ibss */
7677 /* TODO: sta_set_mode */
7678 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
7679 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
7680 /* TODO: sta_up_load */
7681 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
7682 cmd_sta_preset_testparameters);
7683 /* TODO: sta_set_system */
7684 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
7685 /* TODO: sta_set_rifs_test */
7686 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
7687 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
7688 /* TODO: sta_send_coexist_mgmt */
7689 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
7690 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
7691 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
7692 sigma_dut_reg_cmd("sta_reset_default", req_intf,
7693 cmd_sta_reset_default);
7694 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
7695 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
7696 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
7697 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
7698 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
7699 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
7700 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
7701 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
7702 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
7703 cmd_sta_hs2_associate);
7704 sigma_dut_reg_cmd("sta_add_credential", req_intf,
7705 cmd_sta_add_credential);
7706 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
7707 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
7708 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
7709 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
7710 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
7711 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
7712 cmd_sta_wps_connect_pw_token);
7713 sigma_dut_reg_cmd("sta_exec_action", req_intf, cmd_sta_exec_action);
7714 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
7715 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
7716}