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