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