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