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