blob: 2407ab1e402bdf41885121f928911e3262ef2005 [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.
Jouni Malinen9d7e31d2017-12-22 18:55:04 +02004 * Copyright (c) 2011-2017, Qualcomm Atheros, Inc.
Jouni Malinenc12ea4a2018-01-05 21:07:10 +02005 * Copyright (c) 2018, The Linux Foundation
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006 * All Rights Reserved.
7 * Licensed under the Clear BSD license. See README for more details.
8 */
9
10#include "sigma_dut.h"
11#include <sys/ioctl.h>
12#include <sys/stat.h>
13#ifdef __linux__
Lior Davidcc88b562017-01-03 18:52:09 +020014#include <regex.h>
15#include <dirent.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016#include <sys/time.h>
17#include <netpacket/packet.h>
18#include <linux/if_ether.h>
19#ifdef ANDROID
20#include <cutils/properties.h>
21#include <android/log.h>
22#include "keystore_get.h"
23#else /* ANDROID */
24#include <ifaddrs.h>
25#endif /* ANDROID */
26#include <netdb.h>
27#endif /* __linux__ */
28#ifdef __QNXNTO__
29#include <net/if_dl.h>
30#endif /* __QNXNTO__ */
31#include "wpa_ctrl.h"
32#include "wpa_helpers.h"
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070033#include "miracast.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020034
35/* Temporary files for sta_send_addba */
36#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
37#define VI_QOS_FILE "/tmp/vi-qos.txt"
38#define VI_QOS_REFFILE "/etc/vi-qos.txt"
39
40/*
41 * MTU for Ethernet need to take into account 8-byte SNAP header
42 * to be added when encapsulating Ethernet frame into 802.11
43 */
44#ifndef IEEE80211_MAX_DATA_LEN_DMG
45#define IEEE80211_MAX_DATA_LEN_DMG 7920
46#endif
47#ifndef IEEE80211_SNAP_LEN_DMG
48#define IEEE80211_SNAP_LEN_DMG 8
49#endif
50
Ashwini Patil00402582017-04-13 12:29:39 +053051#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053052#define NEIGHBOR_REPORT_SIZE 1000
53#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
54#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053055
Jouni Malinencd4e3c32015-10-29 12:39:56 +020056extern char *sigma_wpas_ctrl;
57extern char *sigma_cert_path;
58extern enum driver_type wifi_chip_type;
59extern char *sigma_radio_ifname[];
60
Lior David0fe101e2017-03-09 16:09:50 +020061#ifdef __linux__
62#define WIL_WMI_MAX_PAYLOAD 248
63#define WIL_WMI_BF_TRIG_CMDID 0x83a
64
65struct wil_wmi_header {
66 uint8_t mid;
67 uint8_t reserved;
68 uint16_t cmd;
69 uint32_t ts;
70} __attribute__((packed));
71
72enum wil_wmi_bf_trig_type {
73 WIL_WMI_SLS,
74 WIL_WMI_BRP_RX,
75 WIL_WMI_BRP_TX,
76};
77
78struct wil_wmi_bf_trig_cmd {
79 /* enum wil_wmi_bf_trig_type */
80 uint32_t bf_type;
81 /* cid when type == WMI_BRP_RX */
82 uint32_t sta_id;
83 uint32_t reserved;
84 /* mac address when type = WIL_WMI_SLS */
85 uint8_t dest_mac[6];
86} __attribute__((packed));
87#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020088
89#ifdef ANDROID
90
91static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
92
93#define ANDROID_KEYSTORE_GET 'g'
94#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
95
96static int android_keystore_get(char cmd, const char *key, unsigned char *val)
97{
Jouni Malinencd4e3c32015-10-29 12:39:56 +020098 /* Android 4.3 changed keystore design, so need to use keystore_get() */
99#ifndef KEYSTORE_MESSAGE_SIZE
100#define KEYSTORE_MESSAGE_SIZE 65535
101#endif /* KEYSTORE_MESSAGE_SIZE */
102
103 ssize_t len;
104 uint8_t *value = NULL;
105
106 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
107 "keystore command '%c' key '%s' --> keystore_get",
108 cmd, key);
109
110 len = keystore_get(key, strlen(key), &value);
111 if (len < 0) {
112 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
113 "keystore_get() failed");
114 return -1;
115 }
116
117 if (len > KEYSTORE_MESSAGE_SIZE)
118 len = KEYSTORE_MESSAGE_SIZE;
119 memcpy(val, value, len);
120 free(value);
121 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200122}
123#endif /* ANDROID */
124
125
126int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
127{
128#ifdef __linux__
129 char buf[100];
130
131 if (wifi_chip_type == DRIVER_WCN) {
132 if (enabled) {
133 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 906");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530134 if (system(buf) != 0)
135 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200136 } else {
137 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 905");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530138 if (system(buf) != 0)
139 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200140 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 912");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530141 if (system(buf) != 0)
142 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200143 }
144
145 return 0;
146 }
147
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530148set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200149 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
150 intf, enabled ? "on" : "off");
151 if (system(buf) != 0) {
152 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
153 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530154 if (system(buf) != 0) {
155 sigma_dut_print(dut, DUT_MSG_ERROR,
156 "Failed to set power save %s",
157 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200158 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530159 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200160 }
161
162 return 0;
163#else /* __linux__ */
164 return -1;
165#endif /* __linux__ */
166}
167
168
Lior Davidcc88b562017-01-03 18:52:09 +0200169#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200170
Lior Davidcc88b562017-01-03 18:52:09 +0200171static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
172 size_t len)
173{
174 DIR *dir, *wil_dir;
175 struct dirent *entry;
176 int ret = -1;
177 const char *root_path = "/sys/kernel/debug/ieee80211";
178
179 dir = opendir(root_path);
180 if (!dir)
181 return -2;
182
183 while ((entry = readdir(dir))) {
184 if (strcmp(entry->d_name, ".") == 0 ||
185 strcmp(entry->d_name, "..") == 0)
186 continue;
187
188 if (snprintf(path, len, "%s/%s/wil6210",
189 root_path, entry->d_name) >= (int) len) {
190 ret = -3;
191 break;
192 }
193
194 wil_dir = opendir(path);
195 if (wil_dir) {
196 closedir(wil_dir);
197 ret = 0;
198 break;
199 }
200 }
201
202 closedir(dir);
203 return ret;
204}
Lior David0fe101e2017-03-09 16:09:50 +0200205
206
207static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
208 void *payload, uint16_t length)
209{
210 struct {
211 struct wil_wmi_header hdr;
212 char payload[WIL_WMI_MAX_PAYLOAD];
213 } __attribute__((packed)) cmd;
214 char buf[128], fname[128];
215 size_t towrite, written;
216 FILE *f;
217
218 if (length > WIL_WMI_MAX_PAYLOAD) {
219 sigma_dut_print(dut, DUT_MSG_ERROR,
220 "payload too large(%u, max %u)",
221 length, WIL_WMI_MAX_PAYLOAD);
222 return -1;
223 }
224
225 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
226 cmd.hdr.cmd = command;
227 memcpy(cmd.payload, payload, length);
228
229 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
230 sigma_dut_print(dut, DUT_MSG_ERROR,
231 "failed to get wil6210 debugfs dir");
232 return -1;
233 }
234
235 snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
236 f = fopen(fname, "wb");
237 if (!f) {
238 sigma_dut_print(dut, DUT_MSG_ERROR,
239 "failed to open: %s", fname);
240 return -1;
241 }
242
243 towrite = sizeof(cmd.hdr) + length;
244 written = fwrite(&cmd, 1, towrite, f);
245 fclose(f);
246 if (written != towrite) {
247 sigma_dut_print(dut, DUT_MSG_ERROR,
248 "failed to send wmi %u", command);
249 return -1;
250 }
251
252 return 0;
253}
254
255
256static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
257 const char *pattern, unsigned int *field)
258{
259 char buf[128], fname[128];
260 FILE *f;
261 regex_t re;
262 regmatch_t m[2];
263 int rc, ret = -1;
264
265 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
266 sigma_dut_print(dut, DUT_MSG_ERROR,
267 "failed to get wil6210 debugfs dir");
268 return -1;
269 }
270
271 snprintf(fname, sizeof(fname), "%s/stations", buf);
272 f = fopen(fname, "r");
273 if (!f) {
274 sigma_dut_print(dut, DUT_MSG_ERROR,
275 "failed to open: %s", fname);
276 return -1;
277 }
278
279 if (regcomp(&re, pattern, REG_EXTENDED)) {
280 sigma_dut_print(dut, DUT_MSG_ERROR,
281 "regcomp failed: %s", pattern);
282 goto out;
283 }
284
285 /*
286 * find the entry for the mac address
287 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
288 */
289 while (fgets(buf, sizeof(buf), f)) {
290 if (strcasestr(buf, bssid)) {
291 /* extract the field (CID/AID/state) */
292 rc = regexec(&re, buf, 2, m, 0);
293 if (!rc && (m[1].rm_so >= 0)) {
294 buf[m[1].rm_eo] = 0;
295 *field = atoi(&buf[m[1].rm_so]);
296 ret = 0;
297 break;
298 }
299 }
300 }
301
302 regfree(&re);
303 if (ret)
304 sigma_dut_print(dut, DUT_MSG_ERROR,
305 "could not extract field");
306
307out:
308 fclose(f);
309
310 return ret;
311}
312
313
314static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
315 unsigned int *cid)
316{
317 const char *pattern = "\\[([0-9]+)\\]";
318
319 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
320}
321
322
323static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
324 int l_rx)
325{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700326 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200327 unsigned int cid;
328
Rakesh Sunki556237d2017-03-30 14:49:31 -0700329 memset(&cmd, 0, sizeof(cmd));
330
Lior David0fe101e2017-03-09 16:09:50 +0200331 if (wil6210_get_cid(dut, mac, &cid))
332 return -1;
333
334 cmd.bf_type = WIL_WMI_BRP_RX;
335 cmd.sta_id = cid;
336 /* training length (l_rx) is ignored, FW always uses length 16 */
337 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
338 &cmd, sizeof(cmd));
339}
340
341
342static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
343{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700344 struct wil_wmi_bf_trig_cmd cmd;
345
346 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200347
348 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
349 return -1;
350
351 cmd.bf_type = WIL_WMI_SLS;
352 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
353 &cmd, sizeof(cmd));
354}
355
Lior Davidcc88b562017-01-03 18:52:09 +0200356#endif /* __linux__ */
357
358
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200359static void static_ip_file(int proto, const char *addr, const char *mask,
360 const char *gw)
361{
362 if (proto) {
363 FILE *f = fopen("static-ip", "w");
364 if (f) {
365 fprintf(f, "%d %s %s %s\n", proto, addr,
366 mask ? mask : "N/A",
367 gw ? gw : "N/A");
368 fclose(f);
369 }
370 } else {
371 unlink("static-ip");
372 }
373}
374
375
376static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
377 const char *ssid)
378{
379#ifdef __linux__
380 char buf[100];
381
382 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
383 intf, ssid);
384 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
385
386 if (system(buf) != 0) {
387 sigma_dut_print(dut, DUT_MSG_ERROR,
388 "iwpriv neighbor request failed");
389 return -1;
390 }
391
392 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
393
394 return 0;
395#else /* __linux__ */
396 return -1;
397#endif /* __linux__ */
398}
399
400
401static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530402 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200403{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530404 const char *val;
405 int reason_code = 0;
406 char buf[1024];
407
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200408 /*
409 * In the earlier builds we used WNM_QUERY and in later
410 * builds used WNM_BSS_QUERY.
411 */
412
Ashwini Patil5acd7382017-04-13 15:55:04 +0530413 val = get_param(cmd, "BTMQuery_Reason_Code");
414 if (val)
415 reason_code = atoi(val);
416
417 val = get_param(cmd, "Cand_List");
418 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
419 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
420 dut->btm_query_cand_list);
421 free(dut->btm_query_cand_list);
422 dut->btm_query_cand_list = NULL;
423 } else {
424 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
425 }
426
427 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200428 sigma_dut_print(dut, DUT_MSG_ERROR,
429 "transition management query failed");
430 return -1;
431 }
432
433 sigma_dut_print(dut, DUT_MSG_DEBUG,
434 "transition management query sent");
435
436 return 0;
437}
438
439
440int is_ip_addr(const char *str)
441{
442 const char *pos = str;
443 struct in_addr addr;
444
445 while (*pos) {
446 if (*pos != '.' && (*pos < '0' || *pos > '9'))
447 return 0;
448 pos++;
449 }
450
451 return inet_aton(str, &addr);
452}
453
454
455int is_ipv6_addr(const char *str)
456{
457 struct sockaddr_in6 addr;
458
459 return inet_pton(AF_INET6, str, &(addr.sin6_addr));
460}
461
462
463int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
464 size_t buf_len)
465{
466 char tmp[256], *pos, *pos2;
467 FILE *f;
468 char ip[16], mask[15], dns[16], sec_dns[16];
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530469 const char *str_ps;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200470 int is_dhcp = 0;
471 int s;
472#ifdef ANDROID
473 char prop[PROPERTY_VALUE_MAX];
474#endif /* ANDROID */
475
476 ip[0] = '\0';
477 mask[0] = '\0';
478 dns[0] = '\0';
479 sec_dns[0] = '\0';
480
481 s = socket(PF_INET, SOCK_DGRAM, 0);
482 if (s >= 0) {
483 struct ifreq ifr;
484 struct sockaddr_in saddr;
485
486 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700487 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200488 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
489 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
490 "%s IP address: %s",
491 ifname, strerror(errno));
492 } else {
493 memcpy(&saddr, &ifr.ifr_addr,
494 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700495 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200496 }
497
498 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
499 memcpy(&saddr, &ifr.ifr_addr,
500 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700501 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200502 }
503 close(s);
504 }
505
506#ifdef ANDROID
507 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
508 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
509 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
510 if (property_get(tmp, prop, NULL) != 0 &&
511 strcmp(prop, "ok") == 0) {
512 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
513 ifname);
514 if (property_get(tmp, prop, NULL) != 0 &&
515 strcmp(ip, prop) == 0)
516 is_dhcp = 1;
517 }
518 }
519
520 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700521 if (property_get(tmp, prop, NULL) != 0)
522 strlcpy(dns, prop, sizeof(dns));
523 else if (property_get("net.dns1", prop, NULL) != 0)
524 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200525
526 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700527 if (property_get(tmp, prop, NULL) != 0)
528 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200529#else /* ANDROID */
530#ifdef __linux__
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530531 if (get_driver_type() == DRIVER_OPENWRT)
532 str_ps = "ps -w";
533 else
534 str_ps = "ps ax";
535 snprintf(tmp, sizeof(tmp),
536 "%s | grep dhclient | grep -v grep | grep -q %s",
537 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200538 if (system(tmp) == 0)
539 is_dhcp = 1;
540 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530541 snprintf(tmp, sizeof(tmp),
542 "%s | grep udhcpc | grep -v grep | grep -q %s",
543 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200544 if (system(tmp) == 0)
545 is_dhcp = 1;
546 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530547 snprintf(tmp, sizeof(tmp),
548 "%s | grep dhcpcd | grep -v grep | grep -q %s",
549 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200550 if (system(tmp) == 0)
551 is_dhcp = 1;
552 }
553 }
554#endif /* __linux__ */
555
556 f = fopen("/etc/resolv.conf", "r");
557 if (f) {
558 while (fgets(tmp, sizeof(tmp), f)) {
559 if (strncmp(tmp, "nameserver", 10) != 0)
560 continue;
561 pos = tmp + 10;
562 while (*pos == ' ' || *pos == '\t')
563 pos++;
564 pos2 = pos;
565 while (*pos2) {
566 if (*pos2 == '\n' || *pos2 == '\r') {
567 *pos2 = '\0';
568 break;
569 }
570 pos2++;
571 }
Peng Xub8fc5cc2017-05-10 17:27:28 -0700572 if (!dns[0])
573 strlcpy(dns, pos, sizeof(dns));
574 else if (!sec_dns[0])
575 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200576 }
577 fclose(f);
578 }
579#endif /* ANDROID */
580
581 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
582 is_dhcp, ip, mask, dns);
583 buf[buf_len - 1] = '\0';
584
585 return 0;
586}
587
588
589
590
591int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
592 size_t buf_len)
593{
594#ifdef __linux__
595#ifdef ANDROID
596 char cmd[200], result[1000], *pos, *end;
597 FILE *f;
598 size_t len;
599
600 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
601 f = popen(cmd, "r");
602 if (f == NULL)
603 return -1;
604 len = fread(result, 1, sizeof(result) - 1, f);
605 pclose(f);
606 if (len == 0)
607 return -1;
608 result[len] = '\0';
609 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
610
611 pos = strstr(result, "inet6 ");
612 if (pos == NULL)
613 return -1;
614 pos += 6;
615 end = strchr(pos, ' ');
616 if (end)
617 *end = '\0';
618 end = strchr(pos, '/');
619 if (end)
620 *end = '\0';
621 snprintf(buf, buf_len, "ip,%s", pos);
622 buf[buf_len - 1] = '\0';
623 return 0;
624#else /* ANDROID */
625 struct ifaddrs *ifaddr, *ifa;
626 int res, found = 0;
627 char host[NI_MAXHOST];
628
629 if (getifaddrs(&ifaddr) < 0) {
630 perror("getifaddrs");
631 return -1;
632 }
633
634 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
635 if (strcasecmp(ifname, ifa->ifa_name) != 0)
636 continue;
637 if (ifa->ifa_addr == NULL ||
638 ifa->ifa_addr->sa_family != AF_INET6)
639 continue;
640
641 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
642 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
643 if (res != 0) {
644 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
645 gai_strerror(res));
646 continue;
647 }
648 if (strncmp(host, "fe80::", 6) == 0)
649 continue; /* skip link-local */
650
651 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
652 found = 1;
653 break;
654 }
655
656 freeifaddrs(ifaddr);
657
658 if (found) {
659 char *pos;
660 pos = strchr(host, '%');
661 if (pos)
662 *pos = '\0';
663 snprintf(buf, buf_len, "ip,%s", host);
664 buf[buf_len - 1] = '\0';
665 return 0;
666 }
667
668#endif /* ANDROID */
669#endif /* __linux__ */
670 return -1;
671}
672
673
674static int cmd_sta_get_ip_config(struct sigma_dut *dut,
675 struct sigma_conn *conn,
676 struct sigma_cmd *cmd)
677{
678 const char *intf = get_param(cmd, "Interface");
679 const char *ifname;
680 char buf[200];
681 const char *val;
682 int type = 1;
683
684 if (intf == NULL)
685 return -1;
686
687 if (strcmp(intf, get_main_ifname()) == 0)
688 ifname = get_station_ifname();
689 else
690 ifname = intf;
691
692 /*
693 * UCC may assume the IP address to be available immediately after
694 * association without trying to run sta_get_ip_config multiple times.
695 * Sigma CAPI does not specify this command as a block command that
696 * would wait for the address to become available, but to pass tests
697 * more reliably, it looks like such a wait may be needed here.
698 */
699 if (wait_ip_addr(dut, ifname, 15) < 0) {
700 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
701 "for sta_get_ip_config");
702 /*
703 * Try to continue anyway since many UCC tests do not really
704 * care about the return value from here..
705 */
706 }
707
708 val = get_param(cmd, "Type");
709 if (val)
710 type = atoi(val);
711 if (type == 2 || dut->last_set_ip_config_ipv6) {
712 int i;
713
714 /*
715 * Since we do not have proper wait for IPv6 addresses, use a
716 * fixed two second delay here as a workaround for UCC script
717 * assuming IPv6 address is available when this command returns.
718 * Some scripts did not use Type,2 properly for IPv6, so include
719 * also the cases where the previous sta_set_ip_config indicated
720 * use of IPv6.
721 */
722 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
723 for (i = 0; i < 10; i++) {
724 sleep(1);
725 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
726 {
727 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
728 send_resp(dut, conn, SIGMA_COMPLETE, buf);
729#ifdef ANDROID
730 sigma_dut_print(dut, DUT_MSG_INFO,
731 "Adding IPv6 rule on Android");
732 add_ipv6_rule(dut, intf);
733#endif /* ANDROID */
734
735 return 0;
736 }
737 }
738 }
739 if (type == 1) {
740 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
741 return -2;
742 } else if (type == 2) {
743 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
744 return -2;
745 } else {
746 send_resp(dut, conn, SIGMA_ERROR,
747 "errorCode,Unsupported address type");
748 return 0;
749 }
750
751 send_resp(dut, conn, SIGMA_COMPLETE, buf);
752 return 0;
753}
754
755
756static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
757{
758#ifdef __linux__
759 char buf[200];
760 char path[128];
761 struct stat s;
762
763#ifdef ANDROID
764 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
765#else /* ANDROID */
766 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
767#endif /* ANDROID */
768 if (stat(path, &s) == 0) {
769 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
770 sigma_dut_print(dut, DUT_MSG_INFO,
771 "Kill previous DHCP client: %s", buf);
772 if (system(buf) != 0)
773 sigma_dut_print(dut, DUT_MSG_INFO,
774 "Failed to kill DHCP client");
775 unlink(path);
776 sleep(1);
777 } else {
778 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
779
780 if (stat(path, &s) == 0) {
781 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
782 sigma_dut_print(dut, DUT_MSG_INFO,
783 "Kill previous DHCP client: %s", buf);
784 if (system(buf) != 0)
785 sigma_dut_print(dut, DUT_MSG_INFO,
786 "Failed to kill DHCP client");
787 unlink(path);
788 sleep(1);
789 }
790 }
791#endif /* __linux__ */
792}
793
794
795static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
796{
797#ifdef __linux__
798 char buf[200];
799
800#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +0530801 if (access("/system/bin/dhcpcd", F_OK) != -1) {
802 snprintf(buf, sizeof(buf),
803 "/system/bin/dhcpcd -b %s", ifname);
804 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
805 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
806 } else {
807 sigma_dut_print(dut, DUT_MSG_ERROR,
808 "DHCP client program missing");
809 return 0;
810 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200811#else /* ANDROID */
812 snprintf(buf, sizeof(buf),
813 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
814 ifname, ifname);
815#endif /* ANDROID */
816 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
817 if (system(buf) != 0) {
818 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
819 if (system(buf) != 0) {
820 sigma_dut_print(dut, DUT_MSG_INFO,
821 "Failed to start DHCP client");
822#ifndef ANDROID
823 return -1;
824#endif /* ANDROID */
825 }
826 }
827#endif /* __linux__ */
828
829 return 0;
830}
831
832
833static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
834{
835#ifdef __linux__
836 char buf[200];
837
838 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
839 if (system(buf) != 0) {
840 sigma_dut_print(dut, DUT_MSG_INFO,
841 "Failed to clear IP addresses");
842 return -1;
843 }
844#endif /* __linux__ */
845
846 return 0;
847}
848
849
850#ifdef ANDROID
851static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
852{
853 char cmd[200], *result, *pos;
854 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530855 int tableid;
856 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200857
858 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
859 ifname);
860 fp = popen(cmd, "r");
861 if (fp == NULL)
862 return -1;
863
864 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530865 if (result == NULL) {
866 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200867 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530868 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200869
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530870 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200871 fclose(fp);
872
873 if (len == 0) {
874 free(result);
875 return -1;
876 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530877 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200878
879 pos = strstr(result, "table ");
880 if (pos == NULL) {
881 free(result);
882 return -1;
883 }
884
885 pos += strlen("table ");
886 tableid = atoi(pos);
887 if (tableid != 0) {
888 if (system("ip -6 rule del prio 22000") != 0) {
889 /* ignore any error */
890 }
891 snprintf(cmd, sizeof(cmd),
892 "ip -6 rule add from all lookup %d prio 22000",
893 tableid);
894 if (system(cmd) != 0) {
895 sigma_dut_print(dut, DUT_MSG_INFO,
896 "Failed to run %s", cmd);
897 free(result);
898 return -1;
899 }
900 } else {
901 sigma_dut_print(dut, DUT_MSG_INFO,
902 "No Valid Table Id found %s", pos);
903 free(result);
904 return -1;
905 }
906 free(result);
907
908 return 0;
909}
910#endif /* ANDROID */
911
912
Ankita Bajaj1bde7942018-01-09 19:15:01 +0530913int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
914 const char *ip, const char *mask)
915{
916 char buf[200];
917
918 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
919 ifname, ip, mask);
920 return system(buf) == 0;
921}
922
923
924int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
925{
926 char buf[200];
927
928 if (!is_ip_addr(gw)) {
929 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
930 return -1;
931 }
932
933 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
934 if (!dut->no_ip_addr_set && system(buf) != 0) {
935 snprintf(buf, sizeof(buf), "ip ro re default via %s",
936 gw);
937 if (system(buf) != 0)
938 return 0;
939 }
940
941 return 1;
942}
943
944
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200945static int cmd_sta_set_ip_config(struct sigma_dut *dut,
946 struct sigma_conn *conn,
947 struct sigma_cmd *cmd)
948{
949 const char *intf = get_param(cmd, "Interface");
950 const char *ifname;
951 char buf[200];
952 const char *val, *ip, *mask, *gw;
953 int type = 1;
954
955 if (intf == NULL)
956 return -1;
957
958 if (strcmp(intf, get_main_ifname()) == 0)
959 ifname = get_station_ifname();
960 else
961 ifname = intf;
962
963 if (if_nametoindex(ifname) == 0) {
964 send_resp(dut, conn, SIGMA_ERROR,
965 "ErrorCode,Unknown interface");
966 return 0;
967 }
968
969 val = get_param(cmd, "Type");
970 if (val) {
971 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +0530972 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200973 send_resp(dut, conn, SIGMA_ERROR,
974 "ErrorCode,Unsupported address type");
975 return 0;
976 }
977 }
978
979 dut->last_set_ip_config_ipv6 = 0;
980
981 val = get_param(cmd, "dhcp");
982 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
983 static_ip_file(0, NULL, NULL, NULL);
984#ifdef __linux__
985 if (type == 2) {
986 dut->last_set_ip_config_ipv6 = 1;
987 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
988 "stateless address autoconfiguration");
989#ifdef ANDROID
990 /*
991 * This sleep is required as the assignment in case of
992 * Android is taking time and is done by the kernel.
993 * The subsequent ping for IPv6 is impacting HS20 test
994 * case.
995 */
996 sleep(2);
997 add_ipv6_rule(dut, intf);
998#endif /* ANDROID */
999 /* Assume this happens by default */
1000 return 1;
1001 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301002 if (type != 3) {
1003 kill_dhcp_client(dut, ifname);
1004 if (start_dhcp_client(dut, ifname) < 0)
1005 return -2;
1006 } else {
1007 sigma_dut_print(dut, DUT_MSG_DEBUG,
1008 "Using FILS HLP DHCPv4 Rapid Commit");
1009 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001010
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001011 return 1;
1012#endif /* __linux__ */
1013 return -2;
1014 }
1015
1016 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301017 if (!ip) {
1018 send_resp(dut, conn, SIGMA_INVALID,
1019 "ErrorCode,Missing IP address");
1020 return 0;
1021 }
1022
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001023 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301024 if (!mask) {
1025 send_resp(dut, conn, SIGMA_INVALID,
1026 "ErrorCode,Missing subnet mask");
1027 return 0;
1028 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001029
1030 if (type == 2) {
1031 int net = atoi(mask);
1032
1033 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1034 return -1;
1035
1036 if (dut->no_ip_addr_set) {
1037 snprintf(buf, sizeof(buf),
1038 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1039 ifname);
1040 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1041 if (system(buf) != 0) {
1042 sigma_dut_print(dut, DUT_MSG_DEBUG,
1043 "Failed to disable IPv6 address before association");
1044 }
1045 } else {
1046 snprintf(buf, sizeof(buf),
1047 "ip -6 addr del %s/%s dev %s",
1048 ip, mask, ifname);
1049 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1050 if (system(buf) != 0) {
1051 /*
1052 * This command may fail if the address being
1053 * deleted does not exist. Inaction here is
1054 * intentional.
1055 */
1056 }
1057
1058 snprintf(buf, sizeof(buf),
1059 "ip -6 addr add %s/%s dev %s",
1060 ip, mask, ifname);
1061 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1062 if (system(buf) != 0) {
1063 send_resp(dut, conn, SIGMA_ERROR,
1064 "ErrorCode,Failed to set IPv6 address");
1065 return 0;
1066 }
1067 }
1068
1069 dut->last_set_ip_config_ipv6 = 1;
1070 static_ip_file(6, ip, mask, NULL);
1071 return 1;
1072 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301073 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001074 return -1;
1075 }
1076
1077 kill_dhcp_client(dut, ifname);
1078
1079 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301080 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001081 send_resp(dut, conn, SIGMA_ERROR,
1082 "ErrorCode,Failed to set IP address");
1083 return 0;
1084 }
1085 }
1086
1087 gw = get_param(cmd, "defaultGateway");
1088 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301089 if (set_ipv4_gw(dut, gw) < 1) {
1090 send_resp(dut, conn, SIGMA_ERROR,
1091 "ErrorCode,Failed to set default gateway");
1092 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001093 }
1094 }
1095
1096 val = get_param(cmd, "primary-dns");
1097 if (val) {
1098 /* TODO */
1099 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1100 "setting", val);
1101 }
1102
1103 val = get_param(cmd, "secondary-dns");
1104 if (val) {
1105 /* TODO */
1106 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1107 "setting", val);
1108 }
1109
1110 static_ip_file(4, ip, mask, gw);
1111
1112 return 1;
1113}
1114
1115
1116static int cmd_sta_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
1117 struct sigma_cmd *cmd)
1118{
1119 /* const char *intf = get_param(cmd, "Interface"); */
1120 /* TODO: could report more details here */
1121 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1122 return 0;
1123}
1124
1125
1126static int cmd_sta_get_mac_address(struct sigma_dut *dut,
1127 struct sigma_conn *conn,
1128 struct sigma_cmd *cmd)
1129{
1130 /* const char *intf = get_param(cmd, "Interface"); */
1131 char addr[20], resp[50];
1132
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301133 if (dut->dev_role == DEVROLE_STA_CFON)
1134 return sta_cfon_get_mac_address(dut, conn, cmd);
1135
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001136 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
1137 < 0)
1138 return -2;
1139
1140 snprintf(resp, sizeof(resp), "mac,%s", addr);
1141 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1142 return 0;
1143}
1144
1145
1146static int cmd_sta_is_connected(struct sigma_dut *dut, struct sigma_conn *conn,
1147 struct sigma_cmd *cmd)
1148{
1149 /* const char *intf = get_param(cmd, "Interface"); */
1150 int connected = 0;
1151 char result[32];
1152 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
1153 sizeof(result)) < 0) {
1154 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get interface "
1155 "%s status", get_station_ifname());
1156 return -2;
1157 }
1158
1159 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1160 if (strncmp(result, "COMPLETED", 9) == 0)
1161 connected = 1;
1162
1163 if (connected)
1164 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1165 else
1166 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1167
1168 return 0;
1169}
1170
1171
1172static int cmd_sta_verify_ip_connection(struct sigma_dut *dut,
1173 struct sigma_conn *conn,
1174 struct sigma_cmd *cmd)
1175{
1176 /* const char *intf = get_param(cmd, "Interface"); */
1177 const char *dst, *timeout;
1178 int wait_time = 90;
1179 char buf[100];
1180 int res;
1181
1182 dst = get_param(cmd, "destination");
1183 if (dst == NULL || !is_ip_addr(dst))
1184 return -1;
1185
1186 timeout = get_param(cmd, "timeout");
1187 if (timeout) {
1188 wait_time = atoi(timeout);
1189 if (wait_time < 1)
1190 wait_time = 1;
1191 }
1192
1193 /* TODO: force renewal of IP lease if DHCP is enabled */
1194
1195 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1196 res = system(buf);
1197 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1198 if (res == 0)
1199 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1200 else if (res == 256)
1201 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1202 else
1203 return -2;
1204
1205 return 0;
1206}
1207
1208
1209static int cmd_sta_get_bssid(struct sigma_dut *dut, struct sigma_conn *conn,
1210 struct sigma_cmd *cmd)
1211{
1212 /* const char *intf = get_param(cmd, "Interface"); */
1213 char bssid[20], resp[50];
1214
1215 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
1216 < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001217 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001218
1219 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1220 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1221 return 0;
1222}
1223
1224
1225#ifdef __SAMSUNG__
1226static int add_use_network(const char *ifname)
1227{
1228 char buf[100];
1229
1230 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1231 wpa_command(ifname, buf);
1232 return 0;
1233}
1234#endif /* __SAMSUNG__ */
1235
1236
1237static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1238 const char *ifname, struct sigma_cmd *cmd)
1239{
1240 const char *ssid = get_param(cmd, "ssid");
1241 int id;
1242 const char *val;
1243
1244 if (ssid == NULL)
1245 return -1;
1246
1247 start_sta_mode(dut);
1248
1249#ifdef __SAMSUNG__
1250 add_use_network(ifname);
1251#endif /* __SAMSUNG__ */
1252
1253 id = add_network(ifname);
1254 if (id < 0)
1255 return -2;
1256 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1257
1258 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1259 return -2;
1260
1261 dut->infra_network_id = id;
1262 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1263
1264 val = get_param(cmd, "program");
1265 if (!val)
1266 val = get_param(cmd, "prog");
1267 if (val && strcasecmp(val, "hs2") == 0) {
1268 char buf[100];
1269 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1270 wpa_command(ifname, buf);
1271
1272 val = get_param(cmd, "prefer");
1273 if (val && atoi(val) > 0)
1274 set_network(ifname, id, "priority", "1");
1275 }
1276
1277 return id;
1278}
1279
1280
1281static int cmd_sta_set_encryption(struct sigma_dut *dut,
1282 struct sigma_conn *conn,
1283 struct sigma_cmd *cmd)
1284{
1285 const char *intf = get_param(cmd, "Interface");
1286 const char *ssid = get_param(cmd, "ssid");
1287 const char *type = get_param(cmd, "encpType");
1288 const char *ifname;
1289 char buf[200];
1290 int id;
1291
1292 if (intf == NULL || ssid == NULL)
1293 return -1;
1294
1295 if (strcmp(intf, get_main_ifname()) == 0)
1296 ifname = get_station_ifname();
1297 else
1298 ifname = intf;
1299
1300 id = add_network_common(dut, conn, ifname, cmd);
1301 if (id < 0)
1302 return id;
1303
1304 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1305 return -2;
1306
1307 if (type && strcasecmp(type, "wep") == 0) {
1308 const char *val;
1309 int i;
1310
1311 val = get_param(cmd, "activeKey");
1312 if (val) {
1313 int keyid;
1314 keyid = atoi(val);
1315 if (keyid < 1 || keyid > 4)
1316 return -1;
1317 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1318 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1319 return -2;
1320 }
1321
1322 for (i = 0; i < 4; i++) {
1323 snprintf(buf, sizeof(buf), "key%d", i + 1);
1324 val = get_param(cmd, buf);
1325 if (val == NULL)
1326 continue;
1327 snprintf(buf, sizeof(buf), "wep_key%d", i);
1328 if (set_network(ifname, id, buf, val) < 0)
1329 return -2;
1330 }
1331 }
1332
1333 return 1;
1334}
1335
1336
1337static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1338 const char *ifname, struct sigma_cmd *cmd)
1339{
1340 const char *val;
1341 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001342 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001343 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301344 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001345
1346 id = add_network_common(dut, conn, ifname, cmd);
1347 if (id < 0)
1348 return id;
1349
Jouni Malinen47dcc952017-10-09 16:43:24 +03001350 val = get_param(cmd, "Type");
1351 owe = val && strcasecmp(val, "OWE") == 0;
1352
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001353 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001354 if (!val && owe)
1355 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001356 if (val == NULL) {
1357 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Missing keyMgmtType");
1358 return 0;
1359 }
1360 if (strcasecmp(val, "wpa") == 0 ||
1361 strcasecmp(val, "wpa-psk") == 0) {
1362 if (set_network(ifname, id, "proto", "WPA") < 0)
1363 return -2;
1364 } else if (strcasecmp(val, "wpa2") == 0 ||
1365 strcasecmp(val, "wpa2-psk") == 0 ||
1366 strcasecmp(val, "wpa2-ft") == 0 ||
1367 strcasecmp(val, "wpa2-sha256") == 0) {
1368 if (set_network(ifname, id, "proto", "WPA2") < 0)
1369 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301370 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1371 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001372 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1373 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001374 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301375 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001376 if (set_network(ifname, id, "proto", "WPA2") < 0)
1377 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001378 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001379 } else {
1380 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1381 return 0;
1382 }
1383
1384 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001385 if (val) {
1386 cipher_set = 1;
1387 if (strcasecmp(val, "tkip") == 0) {
1388 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1389 return -2;
1390 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1391 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1392 return -2;
1393 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1394 if (set_network(ifname, id, "pairwise",
1395 "CCMP TKIP") < 0)
1396 return -2;
1397 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1398 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1399 return -2;
1400 if (set_network(ifname, id, "group", "GCMP") < 0)
1401 return -2;
1402 } else {
1403 send_resp(dut, conn, SIGMA_ERROR,
1404 "errorCode,Unrecognized encpType value");
1405 return 0;
1406 }
1407 }
1408
1409 val = get_param(cmd, "PairwiseCipher");
1410 if (val) {
1411 cipher_set = 1;
1412 /* TODO: Support space separated list */
1413 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1414 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1415 return -2;
1416 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1417 if (set_network(ifname, id, "pairwise",
1418 "CCMP-256") < 0)
1419 return -2;
1420 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1421 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1422 return -2;
1423 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1424 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1425 return -2;
1426 } else {
1427 send_resp(dut, conn, SIGMA_ERROR,
1428 "errorCode,Unrecognized PairwiseCipher value");
1429 return 0;
1430 }
1431 }
1432
Jouni Malinen47dcc952017-10-09 16:43:24 +03001433 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001434 send_resp(dut, conn, SIGMA_ERROR,
1435 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001436 return 0;
1437 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001438
1439 val = get_param(cmd, "GroupCipher");
1440 if (val) {
1441 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1442 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1443 return -2;
1444 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1445 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1446 return -2;
1447 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1448 if (set_network(ifname, id, "group", "GCMP") < 0)
1449 return -2;
1450 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1451 if (set_network(ifname, id, "group", "CCMP") < 0)
1452 return -2;
1453 } else {
1454 send_resp(dut, conn, SIGMA_ERROR,
1455 "errorCode,Unrecognized GroupCipher value");
1456 return 0;
1457 }
1458 }
1459
Jouni Malinen7b239522017-09-14 21:37:18 +03001460 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001461 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001462 const char *cipher;
1463
1464 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1465 cipher = "BIP-GMAC-256";
1466 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1467 cipher = "BIP-CMAC-256";
1468 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1469 cipher = "BIP-GMAC-128";
1470 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1471 cipher = "AES-128-CMAC";
1472 } else {
1473 send_resp(dut, conn, SIGMA_INVALID,
1474 "errorCode,Unsupported GroupMgntCipher");
1475 return 0;
1476 }
1477 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1478 send_resp(dut, conn, SIGMA_INVALID,
1479 "errorCode,Failed to set GroupMgntCipher");
1480 return 0;
1481 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001482 }
1483
1484 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301485
1486 if (dut->program == PROGRAM_OCE) {
1487 dut->sta_pmf = STA_PMF_OPTIONAL;
1488 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1489 return -2;
1490 }
1491
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001492 val = get_param(cmd, "PMF");
1493 if (val) {
1494 if (strcasecmp(val, "Required") == 0 ||
1495 strcasecmp(val, "Forced_Required") == 0) {
1496 dut->sta_pmf = STA_PMF_REQUIRED;
1497 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1498 return -2;
1499 } else if (strcasecmp(val, "Optional") == 0) {
1500 dut->sta_pmf = STA_PMF_OPTIONAL;
1501 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1502 return -2;
1503 } else if (strcasecmp(val, "Disabled") == 0 ||
1504 strcasecmp(val, "Forced_Disabled") == 0) {
1505 dut->sta_pmf = STA_PMF_DISABLED;
1506 } else {
1507 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
1508 return 0;
1509 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05301510 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02001511 dut->sta_pmf = STA_PMF_REQUIRED;
1512 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1513 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001514 }
1515
1516 return id;
1517}
1518
1519
1520static int cmd_sta_set_psk(struct sigma_dut *dut, struct sigma_conn *conn,
1521 struct sigma_cmd *cmd)
1522{
1523 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03001524 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02001525 const char *pmf = get_param(cmd, "PMF");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001526 const char *ifname, *val, *alg;
1527 int id;
1528
1529 if (intf == NULL)
1530 return -1;
1531
1532 if (strcmp(intf, get_main_ifname()) == 0)
1533 ifname = get_station_ifname();
1534 else
1535 ifname = intf;
1536
1537 id = set_wpa_common(dut, conn, ifname, cmd);
1538 if (id < 0)
1539 return id;
1540
1541 val = get_param(cmd, "keyMgmtType");
1542 alg = get_param(cmd, "micAlg");
1543
Jouni Malinen992a81e2017-08-22 13:57:47 +03001544 if (type && strcasecmp(type, "SAE") == 0) {
1545 if (val && strcasecmp(val, "wpa2-ft") == 0) {
1546 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
1547 return -2;
1548 } else {
1549 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
1550 return -2;
1551 }
1552 if (wpa_command(ifname, "SET sae_groups ") != 0) {
1553 sigma_dut_print(dut, DUT_MSG_ERROR,
1554 "Failed to clear sae_groups to default");
1555 return -2;
1556 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02001557 if (!pmf) {
1558 dut->sta_pmf = STA_PMF_REQUIRED;
1559 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1560 return -2;
1561 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03001562 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
1563 if (val && strcasecmp(val, "wpa2-ft") == 0) {
1564 if (set_network(ifname, id, "key_mgmt",
1565 "FT-SAE FT-PSK") < 0)
1566 return -2;
1567 } else {
1568 if (set_network(ifname, id, "key_mgmt",
1569 "SAE WPA-PSK") < 0)
1570 return -2;
1571 }
1572 if (wpa_command(ifname, "SET sae_groups ") != 0) {
1573 sigma_dut_print(dut, DUT_MSG_ERROR,
1574 "Failed to clear sae_groups to default");
1575 return -2;
1576 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02001577 if (!pmf) {
1578 dut->sta_pmf = STA_PMF_OPTIONAL;
1579 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1580 return -2;
1581 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03001582 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001583 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
1584 return -2;
1585 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1586 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1587 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05301588 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1589 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
1590 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001591 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1592 dut->sta_pmf == STA_PMF_REQUIRED) {
1593 if (set_network(ifname, id, "key_mgmt",
1594 "WPA-PSK WPA-PSK-SHA256") < 0)
1595 return -2;
1596 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1597 if (set_network(ifname, id, "key_mgmt",
1598 "WPA-PSK WPA-PSK-SHA256") < 0)
1599 return -2;
1600 } else {
1601 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1602 return -2;
1603 }
1604
1605 val = get_param(cmd, "passPhrase");
1606 if (val == NULL)
1607 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03001608 if (type && strcasecmp(type, "SAE") == 0) {
1609 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
1610 return -2;
1611 } else {
1612 if (set_network_quoted(ifname, id, "psk", val) < 0)
1613 return -2;
1614 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001615
Jouni Malinen992a81e2017-08-22 13:57:47 +03001616 val = get_param(cmd, "ECGroupID");
1617 if (val) {
1618 char buf[50];
1619
1620 snprintf(buf, sizeof(buf), "SET sae_groups %u", atoi(val));
1621 if (wpa_command(ifname, buf) != 0) {
1622 sigma_dut_print(dut, DUT_MSG_ERROR,
1623 "Failed to clear sae_groups");
1624 return -2;
1625 }
1626 }
1627
Jouni Malinen68143132017-09-02 02:34:08 +03001628 val = get_param(cmd, "InvalidSAEElement");
1629 if (val) {
1630 free(dut->sae_commit_override);
1631 dut->sae_commit_override = strdup(val);
1632 }
1633
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001634 return 1;
1635}
1636
1637
1638static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301639 const char *ifname, int username_identity,
1640 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001641{
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301642 const char *val, *alg, *akm;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001643 int id;
1644 char buf[200];
1645#ifdef ANDROID
1646 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1647 int length;
1648#endif /* ANDROID */
1649
1650 id = set_wpa_common(dut, conn, ifname, cmd);
1651 if (id < 0)
1652 return id;
1653
1654 val = get_param(cmd, "keyMgmtType");
1655 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301656 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001657
Jouni Malinenad395a22017-09-01 21:13:46 +03001658 if (val && strcasecmp(val, "SuiteB") == 0) {
1659 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
1660 0)
1661 return -2;
1662 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001663 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
1664 return -2;
1665 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1666 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1667 return -2;
1668 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1669 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
1670 return -2;
1671 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1672 dut->sta_pmf == STA_PMF_REQUIRED) {
1673 if (set_network(ifname, id, "key_mgmt",
1674 "WPA-EAP WPA-EAP-SHA256") < 0)
1675 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301676 } else if (akm && atoi(akm) == 14) {
1677 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
1678 dut->sta_pmf == STA_PMF_REQUIRED) {
1679 if (set_network(ifname, id, "key_mgmt",
1680 "WPA-EAP-SHA256 FILS-SHA256") < 0)
1681 return -2;
1682 } else {
1683 if (set_network(ifname, id, "key_mgmt",
1684 "WPA-EAP FILS-SHA256") < 0)
1685 return -2;
1686 }
1687
1688 if (set_network(ifname, id, "erp", "1") < 0)
1689 return -2;
1690 } else if (akm && atoi(akm) == 15) {
1691 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
1692 dut->sta_pmf == STA_PMF_REQUIRED) {
1693 if (set_network(ifname, id, "key_mgmt",
1694 "WPA-EAP-SHA256 FILS-SHA384") < 0)
1695 return -2;
1696 } else {
1697 if (set_network(ifname, id, "key_mgmt",
1698 "WPA-EAP FILS-SHA384") < 0)
1699 return -2;
1700 }
1701
1702 if (set_network(ifname, id, "erp", "1") < 0)
1703 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001704 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1705 if (set_network(ifname, id, "key_mgmt",
1706 "WPA-EAP WPA-EAP-SHA256") < 0)
1707 return -2;
1708 } else {
1709 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1710 return -2;
1711 }
1712
1713 val = get_param(cmd, "trustedRootCA");
1714 if (val) {
1715#ifdef ANDROID
1716 snprintf(buf, sizeof(buf), "CACERT_%s", val);
1717 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf,
1718 kvalue);
1719 if (length > 0) {
1720 sigma_dut_print(dut, DUT_MSG_INFO,
1721 "Use Android keystore [%s]", buf);
1722 snprintf(buf, sizeof(buf), "keystore://CACERT_%s",
1723 val);
1724 goto ca_cert_selected;
1725 }
1726#endif /* ANDROID */
1727
1728 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1729#ifdef __linux__
1730 if (!file_exists(buf)) {
1731 char msg[300];
1732 snprintf(msg, sizeof(msg), "ErrorCode,trustedRootCA "
1733 "file (%s) not found", buf);
1734 send_resp(dut, conn, SIGMA_ERROR, msg);
1735 return -3;
1736 }
1737#endif /* __linux__ */
1738#ifdef ANDROID
1739ca_cert_selected:
1740#endif /* ANDROID */
1741 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
1742 return -2;
1743 }
1744
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301745 if (username_identity) {
1746 val = get_param(cmd, "username");
1747 if (val) {
1748 if (set_network_quoted(ifname, id, "identity", val) < 0)
1749 return -2;
1750 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001751
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301752 val = get_param(cmd, "password");
1753 if (val) {
1754 if (set_network_quoted(ifname, id, "password", val) < 0)
1755 return -2;
1756 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001757 }
1758
1759 return id;
1760}
1761
1762
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03001763static int set_tls_cipher(const char *ifname, int id, const char *cipher)
1764{
1765 const char *val;
1766
1767 if (!cipher)
1768 return 0;
1769
1770 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
1771 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
1772 else if (strcasecmp(cipher,
1773 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
1774 val = "ECDHE-RSA-AES256-GCM-SHA384";
1775 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
1776 val = "DHE-RSA-AES256-GCM-SHA384";
1777 else if (strcasecmp(cipher,
1778 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
1779 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
1780 else
1781 return -1;
1782
1783 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
1784 set_network_quoted(ifname, id, "phase1", "");
1785
1786 return set_network_quoted(ifname, id, "openssl_ciphers", val);
1787}
1788
1789
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001790static int cmd_sta_set_eaptls(struct sigma_dut *dut, struct sigma_conn *conn,
1791 struct sigma_cmd *cmd)
1792{
1793 const char *intf = get_param(cmd, "Interface");
1794 const char *ifname, *val;
1795 int id;
1796 char buf[200];
1797#ifdef ANDROID
1798 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1799 int length;
1800 int jb_or_newer = 0;
1801 char prop[PROPERTY_VALUE_MAX];
1802#endif /* ANDROID */
1803
1804 if (intf == NULL)
1805 return -1;
1806
1807 if (strcmp(intf, get_main_ifname()) == 0)
1808 ifname = get_station_ifname();
1809 else
1810 ifname = intf;
1811
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301812 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001813 if (id < 0)
1814 return id;
1815
1816 if (set_network(ifname, id, "eap", "TLS") < 0)
1817 return -2;
1818
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05301819 if (!get_param(cmd, "username") &&
1820 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001821 "wifi-user@wifilabs.local") < 0)
1822 return -2;
1823
1824 val = get_param(cmd, "clientCertificate");
1825 if (val == NULL)
1826 return -1;
1827#ifdef ANDROID
1828 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1829 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
1830 if (length < 0) {
1831 /*
1832 * JB started reporting keystore type mismatches, so retry with
1833 * the GET_PUBKEY command if the generic GET fails.
1834 */
1835 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
1836 buf, kvalue);
1837 }
1838
1839 if (property_get("ro.build.version.release", prop, NULL) != 0) {
1840 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
1841 if (strncmp(prop, "4.0", 3) != 0)
1842 jb_or_newer = 1;
1843 } else
1844 jb_or_newer = 1; /* assume newer */
1845
1846 if (jb_or_newer && length > 0) {
1847 sigma_dut_print(dut, DUT_MSG_INFO,
1848 "Use Android keystore [%s]", buf);
1849 if (set_network(ifname, id, "engine", "1") < 0)
1850 return -2;
1851 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
1852 return -2;
1853 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1854 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
1855 return -2;
1856 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
1857 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1858 return -2;
1859 return 1;
1860 } else if (length > 0) {
1861 sigma_dut_print(dut, DUT_MSG_INFO,
1862 "Use Android keystore [%s]", buf);
1863 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
1864 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
1865 return -2;
1866 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
1867 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1868 return -2;
1869 return 1;
1870 }
1871#endif /* ANDROID */
1872
1873 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1874#ifdef __linux__
1875 if (!file_exists(buf)) {
1876 char msg[300];
1877 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
1878 "(%s) not found", buf);
1879 send_resp(dut, conn, SIGMA_ERROR, msg);
1880 return -3;
1881 }
1882#endif /* __linux__ */
1883 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
1884 return -2;
1885 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1886 return -2;
1887
1888 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
1889 return -2;
1890
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03001891 val = get_param(cmd, "keyMgmtType");
1892 if (val && strcasecmp(val, "SuiteB") == 0) {
1893 val = get_param(cmd, "CertType");
1894 if (val && strcasecmp(val, "RSA") == 0) {
1895 if (set_network_quoted(ifname, id, "phase1",
1896 "tls_suiteb=1") < 0)
1897 return -2;
1898 } else {
1899 if (set_network_quoted(ifname, id, "openssl_ciphers",
1900 "SUITEB192") < 0)
1901 return -2;
1902 }
1903
1904 val = get_param(cmd, "TLSCipher");
1905 if (set_tls_cipher(ifname, id, val) < 0) {
1906 send_resp(dut, conn, SIGMA_ERROR,
1907 "ErrorCode,Unsupported TLSCipher value");
1908 return -3;
1909 }
1910 }
1911
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001912 return 1;
1913}
1914
1915
1916static int cmd_sta_set_eapttls(struct sigma_dut *dut, struct sigma_conn *conn,
1917 struct sigma_cmd *cmd)
1918{
1919 const char *intf = get_param(cmd, "Interface");
1920 const char *ifname;
1921 int id;
1922
1923 if (intf == NULL)
1924 return -1;
1925
1926 if (strcmp(intf, get_main_ifname()) == 0)
1927 ifname = get_station_ifname();
1928 else
1929 ifname = intf;
1930
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301931 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001932 if (id < 0)
1933 return id;
1934
1935 if (set_network(ifname, id, "eap", "TTLS") < 0) {
1936 send_resp(dut, conn, SIGMA_ERROR,
1937 "errorCode,Failed to set TTLS method");
1938 return 0;
1939 }
1940
1941 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
1942 send_resp(dut, conn, SIGMA_ERROR,
1943 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
1944 return 0;
1945 }
1946
1947 return 1;
1948}
1949
1950
1951static int cmd_sta_set_eapsim(struct sigma_dut *dut, struct sigma_conn *conn,
1952 struct sigma_cmd *cmd)
1953{
1954 const char *intf = get_param(cmd, "Interface");
1955 const char *ifname;
1956 int id;
1957
1958 if (intf == NULL)
1959 return -1;
1960
1961 if (strcmp(intf, get_main_ifname()) == 0)
1962 ifname = get_station_ifname();
1963 else
1964 ifname = intf;
1965
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301966 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001967 if (id < 0)
1968 return id;
1969
1970 if (set_network(ifname, id, "eap", "SIM") < 0)
1971 return -2;
1972
1973 return 1;
1974}
1975
1976
1977static int cmd_sta_set_peap(struct sigma_dut *dut, struct sigma_conn *conn,
1978 struct sigma_cmd *cmd)
1979{
1980 const char *intf = get_param(cmd, "Interface");
1981 const char *ifname, *val;
1982 int id;
1983 char buf[100];
1984
1985 if (intf == NULL)
1986 return -1;
1987
1988 if (strcmp(intf, get_main_ifname()) == 0)
1989 ifname = get_station_ifname();
1990 else
1991 ifname = intf;
1992
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301993 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001994 if (id < 0)
1995 return id;
1996
1997 if (set_network(ifname, id, "eap", "PEAP") < 0)
1998 return -2;
1999
2000 val = get_param(cmd, "innerEAP");
2001 if (val) {
2002 if (strcasecmp(val, "MSCHAPv2") == 0) {
2003 if (set_network_quoted(ifname, id, "phase2",
2004 "auth=MSCHAPV2") < 0)
2005 return -2;
2006 } else if (strcasecmp(val, "GTC") == 0) {
2007 if (set_network_quoted(ifname, id, "phase2",
2008 "auth=GTC") < 0)
2009 return -2;
2010 } else
2011 return -1;
2012 }
2013
2014 val = get_param(cmd, "peapVersion");
2015 if (val) {
2016 int ver = atoi(val);
2017 if (ver < 0 || ver > 1)
2018 return -1;
2019 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2020 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2021 return -2;
2022 }
2023
2024 return 1;
2025}
2026
2027
2028static int cmd_sta_set_eapfast(struct sigma_dut *dut, struct sigma_conn *conn,
2029 struct sigma_cmd *cmd)
2030{
2031 const char *intf = get_param(cmd, "Interface");
2032 const char *ifname, *val;
2033 int id;
2034 char buf[100];
2035
2036 if (intf == NULL)
2037 return -1;
2038
2039 if (strcmp(intf, get_main_ifname()) == 0)
2040 ifname = get_station_ifname();
2041 else
2042 ifname = intf;
2043
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302044 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002045 if (id < 0)
2046 return id;
2047
2048 if (set_network(ifname, id, "eap", "FAST") < 0)
2049 return -2;
2050
2051 val = get_param(cmd, "innerEAP");
2052 if (val) {
2053 if (strcasecmp(val, "MSCHAPV2") == 0) {
2054 if (set_network_quoted(ifname, id, "phase2",
2055 "auth=MSCHAPV2") < 0)
2056 return -2;
2057 } else if (strcasecmp(val, "GTC") == 0) {
2058 if (set_network_quoted(ifname, id, "phase2",
2059 "auth=GTC") < 0)
2060 return -2;
2061 } else
2062 return -1;
2063 }
2064
2065 val = get_param(cmd, "validateServer");
2066 if (val) {
2067 /* TODO */
2068 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2069 "validateServer=%s", val);
2070 }
2071
2072 val = get_param(cmd, "pacFile");
2073 if (val) {
2074 snprintf(buf, sizeof(buf), "blob://%s", val);
2075 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2076 return -2;
2077 }
2078
2079 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2080 0)
2081 return -2;
2082
2083 return 1;
2084}
2085
2086
2087static int cmd_sta_set_eapaka(struct sigma_dut *dut, struct sigma_conn *conn,
2088 struct sigma_cmd *cmd)
2089{
2090 const char *intf = get_param(cmd, "Interface");
2091 const char *ifname;
2092 int id;
2093
2094 if (intf == NULL)
2095 return -1;
2096
2097 if (strcmp(intf, get_main_ifname()) == 0)
2098 ifname = get_station_ifname();
2099 else
2100 ifname = intf;
2101
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302102 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002103 if (id < 0)
2104 return id;
2105
2106 if (set_network(ifname, id, "eap", "AKA") < 0)
2107 return -2;
2108
2109 return 1;
2110}
2111
2112
2113static int cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2114 struct sigma_conn *conn,
2115 struct sigma_cmd *cmd)
2116{
2117 const char *intf = get_param(cmd, "Interface");
2118 const char *ifname;
2119 int id;
2120
2121 if (intf == NULL)
2122 return -1;
2123
2124 if (strcmp(intf, get_main_ifname()) == 0)
2125 ifname = get_station_ifname();
2126 else
2127 ifname = intf;
2128
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302129 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002130 if (id < 0)
2131 return id;
2132
2133 if (set_network(ifname, id, "eap", "AKA'") < 0)
2134 return -2;
2135
2136 return 1;
2137}
2138
2139
2140static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2141 struct sigma_cmd *cmd)
2142{
2143 const char *intf = get_param(cmd, "Interface");
2144 const char *ifname;
2145 int id;
2146
2147 if (strcmp(intf, get_main_ifname()) == 0)
2148 ifname = get_station_ifname();
2149 else
2150 ifname = intf;
2151
2152 id = add_network_common(dut, conn, ifname, cmd);
2153 if (id < 0)
2154 return id;
2155
2156 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2157 return -2;
2158
2159 return 1;
2160}
2161
2162
Jouni Malinen47dcc952017-10-09 16:43:24 +03002163static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2164 struct sigma_cmd *cmd)
2165{
2166 const char *intf = get_param(cmd, "Interface");
2167 const char *ifname, *val;
2168 int id;
2169
2170 if (intf == NULL)
2171 return -1;
2172
2173 if (strcmp(intf, get_main_ifname()) == 0)
2174 ifname = get_station_ifname();
2175 else
2176 ifname = intf;
2177
2178 id = set_wpa_common(dut, conn, ifname, cmd);
2179 if (id < 0)
2180 return id;
2181
2182 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2183 return -2;
2184
2185 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002186 if (val && strcmp(val, "0") == 0) {
2187 if (wpa_command(ifname,
2188 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2189 sigma_dut_print(dut, DUT_MSG_ERROR,
2190 "Failed to set OWE DH Param element override");
2191 return -2;
2192 }
2193 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002194 sigma_dut_print(dut, DUT_MSG_ERROR,
2195 "Failed to clear owe_group");
2196 return -2;
2197 }
2198
2199 return 1;
2200}
2201
2202
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002203static int cmd_sta_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
2204 struct sigma_cmd *cmd)
2205{
2206 const char *type = get_param(cmd, "Type");
2207
2208 if (type == NULL) {
2209 send_resp(dut, conn, SIGMA_ERROR,
2210 "ErrorCode,Missing Type argument");
2211 return 0;
2212 }
2213
2214 if (strcasecmp(type, "OPEN") == 0)
2215 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002216 if (strcasecmp(type, "OWE") == 0)
2217 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002218 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002219 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002220 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002221 return cmd_sta_set_psk(dut, conn, cmd);
2222 if (strcasecmp(type, "EAPTLS") == 0)
2223 return cmd_sta_set_eaptls(dut, conn, cmd);
2224 if (strcasecmp(type, "EAPTTLS") == 0)
2225 return cmd_sta_set_eapttls(dut, conn, cmd);
2226 if (strcasecmp(type, "EAPPEAP") == 0)
2227 return cmd_sta_set_peap(dut, conn, cmd);
2228 if (strcasecmp(type, "EAPSIM") == 0)
2229 return cmd_sta_set_eapsim(dut, conn, cmd);
2230 if (strcasecmp(type, "EAPFAST") == 0)
2231 return cmd_sta_set_eapfast(dut, conn, cmd);
2232 if (strcasecmp(type, "EAPAKA") == 0)
2233 return cmd_sta_set_eapaka(dut, conn, cmd);
2234 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2235 return cmd_sta_set_eapakaprime(dut, conn, cmd);
2236
2237 send_resp(dut, conn, SIGMA_ERROR,
2238 "ErrorCode,Unsupported Type value");
2239 return 0;
2240}
2241
2242
2243int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2244{
2245#ifdef __linux__
2246 /* special handling for ath6kl */
2247 char path[128], fname[128], *pos;
2248 ssize_t res;
2249 FILE *f;
2250
2251 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", intf);
2252 res = readlink(path, path, sizeof(path));
2253 if (res < 0)
2254 return 0; /* not ath6kl */
2255
2256 if (res >= (int) sizeof(path))
2257 res = sizeof(path) - 1;
2258 path[res] = '\0';
2259 pos = strrchr(path, '/');
2260 if (pos == NULL)
2261 pos = path;
2262 else
2263 pos++;
2264 snprintf(fname, sizeof(fname),
2265 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2266 "create_qos", pos);
2267 if (!file_exists(fname))
2268 return 0; /* not ath6kl */
2269
2270 if (uapsd) {
2271 f = fopen(fname, "w");
2272 if (f == NULL)
2273 return -1;
2274
2275 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2276 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2277 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2278 "20000 0\n");
2279 fclose(f);
2280 } else {
2281 snprintf(fname, sizeof(fname),
2282 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2283 "delete_qos", pos);
2284
2285 f = fopen(fname, "w");
2286 if (f == NULL)
2287 return -1;
2288
2289 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2290 fprintf(f, "2 4\n");
2291 fclose(f);
2292 }
2293#endif /* __linux__ */
2294
2295 return 0;
2296}
2297
2298
2299static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
2300 struct sigma_cmd *cmd)
2301{
2302 const char *intf = get_param(cmd, "Interface");
2303 /* const char *ssid = get_param(cmd, "ssid"); */
2304 const char *val;
2305 int max_sp_len = 4;
2306 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2307 char buf[100];
2308 int ret1, ret2;
2309
2310 val = get_param(cmd, "maxSPLength");
2311 if (val) {
2312 max_sp_len = atoi(val);
2313 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2314 max_sp_len != 4)
2315 return -1;
2316 }
2317
2318 val = get_param(cmd, "acBE");
2319 if (val)
2320 ac_be = atoi(val);
2321
2322 val = get_param(cmd, "acBK");
2323 if (val)
2324 ac_bk = atoi(val);
2325
2326 val = get_param(cmd, "acVI");
2327 if (val)
2328 ac_vi = atoi(val);
2329
2330 val = get_param(cmd, "acVO");
2331 if (val)
2332 ac_vo = atoi(val);
2333
2334 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2335
2336 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2337 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2338 ret1 = wpa_command(intf, buf);
2339
2340 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2341 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2342 ret2 = wpa_command(intf, buf);
2343
2344 if (ret1 && ret2) {
2345 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2346 "UAPSD parameters.");
2347 return -2;
2348 }
2349
2350 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2351 send_resp(dut, conn, SIGMA_ERROR,
2352 "ErrorCode,Failed to set ath6kl QoS parameters");
2353 return 0;
2354 }
2355
2356 return 1;
2357}
2358
2359
2360static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
2361 struct sigma_cmd *cmd)
2362{
2363 char buf[1000];
2364 const char *intf = get_param(cmd, "Interface");
2365 const char *grp = get_param(cmd, "Group");
2366 const char *act = get_param(cmd, "Action");
2367 const char *tid = get_param(cmd, "Tid");
2368 const char *dir = get_param(cmd, "Direction");
2369 const char *psb = get_param(cmd, "Psb");
2370 const char *up = get_param(cmd, "Up");
2371 const char *fixed = get_param(cmd, "Fixed");
2372 const char *size = get_param(cmd, "Size");
2373 const char *msize = get_param(cmd, "Maxsize");
2374 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2375 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2376 const char *inact = get_param(cmd, "Inactivity");
2377 const char *sus = get_param(cmd, "Suspension");
2378 const char *mindr = get_param(cmd, "Mindatarate");
2379 const char *meandr = get_param(cmd, "Meandatarate");
2380 const char *peakdr = get_param(cmd, "Peakdatarate");
2381 const char *phyrate = get_param(cmd, "Phyrate");
2382 const char *burstsize = get_param(cmd, "Burstsize");
2383 const char *sba = get_param(cmd, "Sba");
2384 int direction;
2385 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002386 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002387 int fixed_int;
2388 int psb_ts;
2389
2390 if (intf == NULL || grp == NULL || act == NULL )
2391 return -1;
2392
2393 if (strcasecmp(act, "addts") == 0) {
2394 if (tid == NULL || dir == NULL || psb == NULL ||
2395 up == NULL || fixed == NULL || size == NULL)
2396 return -1;
2397
2398 /*
2399 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
2400 * possible values, but WMM-AC and V-E test scripts use "UP,
2401 * "DOWN", and "BIDI".
2402 */
2403 if (strcasecmp(dir, "uplink") == 0 ||
2404 strcasecmp(dir, "up") == 0) {
2405 direction = 0;
2406 } else if (strcasecmp(dir, "downlink") == 0 ||
2407 strcasecmp(dir, "down") == 0) {
2408 direction = 1;
2409 } else if (strcasecmp(dir, "bidi") == 0) {
2410 direction = 2;
2411 } else {
2412 sigma_dut_print(dut, DUT_MSG_ERROR,
2413 "Direction %s not supported", dir);
2414 return -1;
2415 }
2416
2417 if (strcasecmp(psb, "legacy") == 0) {
2418 psb_ts = 0;
2419 } else if (strcasecmp(psb, "uapsd") == 0) {
2420 psb_ts = 1;
2421 } else {
2422 sigma_dut_print(dut, DUT_MSG_ERROR,
2423 "PSB %s not supported", psb);
2424 return -1;
2425 }
2426
2427 if (atoi(tid) < 0 || atoi(tid) > 7) {
2428 sigma_dut_print(dut, DUT_MSG_ERROR,
2429 "TID %s not supported", tid);
2430 return -1;
2431 }
2432
2433 if (strcasecmp(fixed, "true") == 0) {
2434 fixed_int = 1;
2435 } else {
2436 fixed_int = 0;
2437 }
2438
Peng Xu93319622017-10-04 17:58:16 -07002439 if (sba)
2440 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002441
2442 dut->dialog_token++;
2443 handle = 7000 + dut->dialog_token;
2444
2445 /*
2446 * size: convert to hex
2447 * maxsi: convert to hex
2448 * mindr: convert to hex
2449 * meandr: convert to hex
2450 * peakdr: convert to hex
2451 * burstsize: convert to hex
2452 * phyrate: convert to hex
2453 * sba: convert to hex with modification
2454 * minsi: convert to integer
2455 * sus: convert to integer
2456 * inact: convert to integer
2457 * maxsi: convert to integer
2458 */
2459
2460 /*
2461 * The Nominal MSDU Size field is 2 octets long and contains an
2462 * unsigned integer that specifies the nominal size, in octets,
2463 * of MSDUs belonging to the traffic under this traffic
2464 * specification and is defined in Figure 16. If the Fixed
2465 * subfield is set to 1, then the size of the MSDU is fixed and
2466 * is indicated by the Size Subfield. If the Fixed subfield is
2467 * set to 0, then the size of the MSDU might not be fixed and
2468 * the Size indicates the nominal MSDU size.
2469 *
2470 * The Surplus Bandwidth Allowance Factor field is 2 octets long
2471 * and specifies the excess allocation of time (and bandwidth)
2472 * over and above the stated rates required to transport an MSDU
2473 * belonging to the traffic in this TSPEC. This field is
2474 * represented as an unsigned binary number with an implicit
2475 * binary point after the leftmost 3 bits. For example, an SBA
2476 * of 1.75 is represented as 0x3800. This field is included to
2477 * account for retransmissions. As such, the value of this field
2478 * must be greater than unity.
2479 */
2480
2481 snprintf(buf, sizeof(buf),
2482 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
2483 " 0x%X 0x%X 0x%X"
2484 " 0x%X 0x%X 0x%X"
2485 " 0x%X %d %d %d %d"
2486 " %d %d",
2487 intf, handle, tid, direction, psb_ts, up,
2488 (unsigned int) ((fixed_int << 15) | atoi(size)),
2489 msize ? atoi(msize) : 0,
2490 mindr ? atoi(mindr) : 0,
2491 meandr ? atoi(meandr) : 0,
2492 peakdr ? atoi(peakdr) : 0,
2493 burstsize ? atoi(burstsize) : 0,
2494 phyrate ? atoi(phyrate) : 0,
2495 sba ? ((unsigned int) (((int) sba_fv << 13) |
2496 (int)((sba_fv - (int) sba_fv) *
2497 8192))) : 0,
2498 minsi ? atoi(minsi) : 0,
2499 sus ? atoi(sus) : 0,
2500 0, 0,
2501 inact ? atoi(inact) : 0,
2502 maxsi ? atoi(maxsi) : 0);
2503
2504 if (system(buf) != 0) {
2505 sigma_dut_print(dut, DUT_MSG_ERROR,
2506 "iwpriv addtspec request failed");
2507 send_resp(dut, conn, SIGMA_ERROR,
2508 "errorCode,Failed to execute addTspec command");
2509 return 0;
2510 }
2511
2512 sigma_dut_print(dut, DUT_MSG_INFO,
2513 "iwpriv addtspec request send");
2514
2515 /* Mapping handle to a TID */
2516 dut->tid_to_handle[atoi(tid)] = handle;
2517 } else if (strcasecmp(act, "delts") == 0) {
2518 if (tid == NULL)
2519 return -1;
2520
2521 if (atoi(tid) < 0 || atoi(tid) > 7) {
2522 sigma_dut_print(dut, DUT_MSG_ERROR,
2523 "TID %s not supported", tid);
2524 send_resp(dut, conn, SIGMA_ERROR,
2525 "errorCode,Unsupported TID");
2526 return 0;
2527 }
2528
2529 handle = dut->tid_to_handle[atoi(tid)];
2530
2531 if (handle < 7000 || handle > 7255) {
2532 /* Invalid handle ie no mapping for that TID */
2533 sigma_dut_print(dut, DUT_MSG_ERROR,
2534 "handle-> %d not found", handle);
2535 }
2536
2537 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
2538 intf, handle);
2539
2540 if (system(buf) != 0) {
2541 sigma_dut_print(dut, DUT_MSG_ERROR,
2542 "iwpriv deltspec request failed");
2543 send_resp(dut, conn, SIGMA_ERROR,
2544 "errorCode,Failed to execute delTspec command");
2545 return 0;
2546 }
2547
2548 sigma_dut_print(dut, DUT_MSG_INFO,
2549 "iwpriv deltspec request send");
2550
2551 dut->tid_to_handle[atoi(tid)] = 0;
2552 } else {
2553 sigma_dut_print(dut, DUT_MSG_ERROR,
2554 "Action type %s not supported", act);
2555 send_resp(dut, conn, SIGMA_ERROR,
2556 "errorCode,Unsupported Action");
2557 return 0;
2558 }
2559
2560 return 1;
2561}
2562
2563
vamsi krishna52e16f92017-08-29 12:37:34 +05302564static int find_network(struct sigma_dut *dut, const char *ssid)
2565{
2566 char list[4096];
2567 char *pos;
2568
2569 sigma_dut_print(dut, DUT_MSG_DEBUG,
2570 "Search for profile based on SSID: '%s'", ssid);
2571 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
2572 list, sizeof(list)) < 0)
2573 return -1;
2574 pos = strstr(list, ssid);
2575 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
2576 return -1;
2577
2578 while (pos > list && pos[-1] != '\n')
2579 pos--;
2580 dut->infra_network_id = atoi(pos);
2581 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
2582 return 0;
2583}
2584
2585
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002586static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
2587 struct sigma_cmd *cmd)
2588{
2589 /* const char *intf = get_param(cmd, "Interface"); */
2590 const char *ssid = get_param(cmd, "ssid");
2591 const char *wps_param = get_param(cmd, "WPS");
2592 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03002593 const char *chan = get_param(cmd, "channel");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002594 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03002595 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002596
2597 if (ssid == NULL)
2598 return -1;
2599
Jouni Malinen3c367e82017-06-23 17:01:47 +03002600 if (dut->rsne_override) {
2601 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
2602 dut->rsne_override);
2603 if (wpa_command(get_station_ifname(), buf) < 0) {
2604 send_resp(dut, conn, SIGMA_ERROR,
2605 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
2606 return 0;
2607 }
2608 }
2609
Jouni Malinen68143132017-09-02 02:34:08 +03002610 if (dut->sae_commit_override) {
2611 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
2612 dut->sae_commit_override);
2613 if (wpa_command(get_station_ifname(), buf) < 0) {
2614 send_resp(dut, conn, SIGMA_ERROR,
2615 "ErrorCode,Failed to set SAE commit override");
2616 return 0;
2617 }
2618 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05302619#ifdef ANDROID
2620 if (dut->fils_hlp)
2621 process_fils_hlp(dut);
2622#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03002623
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002624 if (wps_param &&
2625 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
2626 wps = 1;
2627
2628 if (wps) {
2629 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
2630 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
2631 "parameters not yet set");
2632 return 0;
2633 }
2634 if (dut->wps_method == WFA_CS_WPS_PBC) {
2635 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
2636 return -2;
2637 } else {
2638 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
2639 dut->wps_pin);
2640 if (wpa_command(get_station_ifname(), buf) < 0)
2641 return -2;
2642 }
2643 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05302644 if (strcmp(ssid, dut->infra_ssid) == 0) {
2645 sigma_dut_print(dut, DUT_MSG_DEBUG,
2646 "sta_associate for the most recently added network");
2647 } else if (find_network(dut, ssid) < 0) {
2648 sigma_dut_print(dut, DUT_MSG_DEBUG,
2649 "sta_associate for a previously stored network profile");
2650 send_resp(dut, conn, SIGMA_ERROR,
2651 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002652 return 0;
2653 }
2654
2655 if (bssid &&
2656 set_network(get_station_ifname(), dut->infra_network_id,
2657 "bssid", bssid) < 0) {
2658 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2659 "Invalid bssid argument");
2660 return 0;
2661 }
2662
Jouni Malinen46a19b62017-06-23 14:31:27 +03002663 extra[0] = '\0';
2664 if (chan)
2665 snprintf(extra, sizeof(extra), " freq=%u",
2666 channel_to_freq(atoi(chan)));
2667 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
2668 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002669 if (wpa_command(get_station_ifname(), buf) < 0) {
2670 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
2671 "network id %d on %s",
2672 dut->infra_network_id,
2673 get_station_ifname());
2674 return -2;
2675 }
2676 }
2677
2678 return 1;
2679}
2680
2681
2682static int run_hs20_osu(struct sigma_dut *dut, const char *params)
2683{
2684 char buf[500], cmd[200];
2685 int res;
2686
2687 /* Use hs20-osu-client file at the current dir, if found; otherwise use
2688 * default path */
2689 res = snprintf(cmd, sizeof(cmd),
2690 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
2691 file_exists("./hs20-osu-client") ?
2692 "./hs20-osu-client" : "hs20-osu-client",
2693 sigma_wpas_ctrl,
2694 dut->summary_log ? "-s " : "",
2695 dut->summary_log ? dut->summary_log : "");
2696 if (res < 0 || res >= (int) sizeof(cmd))
2697 return -1;
2698
2699 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
2700 if (res < 0 || res >= (int) sizeof(buf))
2701 return -1;
2702 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
2703
2704 if (system(buf) != 0) {
2705 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
2706 return -1;
2707 }
2708 sigma_dut_print(dut, DUT_MSG_DEBUG,
2709 "Completed hs20-osu-client operation");
2710
2711 return 0;
2712}
2713
2714
2715static int download_ppsmo(struct sigma_dut *dut,
2716 struct sigma_conn *conn,
2717 const char *intf,
2718 struct sigma_cmd *cmd)
2719{
2720 const char *name, *path, *val;
2721 char url[500], buf[600], fbuf[100];
2722 char *fqdn = NULL;
2723
2724 name = get_param(cmd, "FileName");
2725 path = get_param(cmd, "FilePath");
2726 if (name == NULL || path == NULL)
2727 return -1;
2728
2729 if (strcasecmp(path, "VendorSpecific") == 0) {
2730 snprintf(url, sizeof(url), "PPS/%s", name);
2731 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
2732 "from the device (%s)", url);
2733 if (!file_exists(url)) {
2734 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2735 "PPS MO file does not exist");
2736 return 0;
2737 }
2738 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
2739 if (system(buf) != 0) {
2740 send_resp(dut, conn, SIGMA_ERROR,
2741 "errorCode,Failed to copy PPS MO");
2742 return 0;
2743 }
2744 } else if (strncasecmp(path, "http:", 5) != 0 &&
2745 strncasecmp(path, "https:", 6) != 0) {
2746 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2747 "Unsupported FilePath value");
2748 return 0;
2749 } else {
2750 snprintf(url, sizeof(url), "%s/%s", path, name);
2751 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
2752 url);
2753 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
2754 remove("pps-tnds.xml");
2755 if (system(buf) != 0) {
2756 send_resp(dut, conn, SIGMA_ERROR,
2757 "errorCode,Failed to download PPS MO");
2758 return 0;
2759 }
2760 }
2761
2762 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
2763 send_resp(dut, conn, SIGMA_ERROR,
2764 "errorCode,Failed to parse downloaded PPSMO");
2765 return 0;
2766 }
2767 unlink("pps-tnds.xml");
2768
2769 val = get_param(cmd, "managementTreeURI");
2770 if (val) {
2771 const char *pos, *end;
2772 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
2773 val);
2774 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
2775 send_resp(dut, conn, SIGMA_ERROR,
2776 "errorCode,Invalid managementTreeURI prefix");
2777 return 0;
2778 }
2779 pos = val + 8;
2780 end = strchr(pos, '/');
2781 if (end == NULL ||
2782 strcmp(end, "/PerProviderSubscription") != 0) {
2783 send_resp(dut, conn, SIGMA_ERROR,
2784 "errorCode,Invalid managementTreeURI postfix");
2785 return 0;
2786 }
2787 if (end - pos >= (int) sizeof(fbuf)) {
2788 send_resp(dut, conn, SIGMA_ERROR,
2789 "errorCode,Too long FQDN in managementTreeURI");
2790 return 0;
2791 }
2792 memcpy(fbuf, pos, end - pos);
2793 fbuf[end - pos] = '\0';
2794 fqdn = fbuf;
2795 sigma_dut_print(dut, DUT_MSG_INFO,
2796 "FQDN from managementTreeURI: %s", fqdn);
2797 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
2798 FILE *f = fopen("pps-fqdn", "r");
2799 if (f) {
2800 if (fgets(fbuf, sizeof(fbuf), f)) {
2801 fbuf[sizeof(fbuf) - 1] = '\0';
2802 fqdn = fbuf;
2803 sigma_dut_print(dut, DUT_MSG_DEBUG,
2804 "Use FQDN %s", fqdn);
2805 }
2806 fclose(f);
2807 }
2808 }
2809
2810 if (fqdn == NULL) {
2811 send_resp(dut, conn, SIGMA_ERROR,
2812 "errorCode,No FQDN specified");
2813 return 0;
2814 }
2815
2816 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2817 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
2818 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2819
2820 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
2821 if (rename("pps.xml", buf) < 0) {
2822 send_resp(dut, conn, SIGMA_ERROR,
2823 "errorCode,Could not move PPS MO");
2824 return 0;
2825 }
2826
2827 if (strcasecmp(path, "VendorSpecific") == 0) {
2828 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
2829 fqdn);
2830 if (system(buf)) {
2831 send_resp(dut, conn, SIGMA_ERROR,
2832 "errorCode,Failed to copy OSU CA cert");
2833 return 0;
2834 }
2835
2836 snprintf(buf, sizeof(buf),
2837 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
2838 fqdn);
2839 if (system(buf)) {
2840 send_resp(dut, conn, SIGMA_ERROR,
2841 "errorCode,Failed to copy AAA CA cert");
2842 return 0;
2843 }
2844 } else {
2845 snprintf(buf, sizeof(buf),
2846 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
2847 fqdn, fqdn);
2848 if (run_hs20_osu(dut, buf) < 0) {
2849 send_resp(dut, conn, SIGMA_ERROR,
2850 "errorCode,Failed to download OSU CA cert");
2851 return 0;
2852 }
2853
2854 snprintf(buf, sizeof(buf),
2855 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
2856 fqdn, fqdn);
2857 if (run_hs20_osu(dut, buf) < 0) {
2858 sigma_dut_print(dut, DUT_MSG_INFO,
2859 "Failed to download AAA CA cert");
2860 }
2861 }
2862
2863 if (file_exists("next-client-cert.pem")) {
2864 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
2865 if (rename("next-client-cert.pem", buf) < 0) {
2866 send_resp(dut, conn, SIGMA_ERROR,
2867 "errorCode,Could not move client certificate");
2868 return 0;
2869 }
2870 }
2871
2872 if (file_exists("next-client-key.pem")) {
2873 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
2874 if (rename("next-client-key.pem", buf) < 0) {
2875 send_resp(dut, conn, SIGMA_ERROR,
2876 "errorCode,Could not move client key");
2877 return 0;
2878 }
2879 }
2880
2881 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
2882 if (run_hs20_osu(dut, buf) < 0) {
2883 send_resp(dut, conn, SIGMA_ERROR,
2884 "errorCode,Failed to configure credential from "
2885 "PPSMO");
2886 return 0;
2887 }
2888
2889 return 1;
2890}
2891
2892
2893static int download_cert(struct sigma_dut *dut,
2894 struct sigma_conn *conn,
2895 const char *intf,
2896 struct sigma_cmd *cmd)
2897{
2898 const char *name, *path;
2899 char url[500], buf[600];
2900
2901 name = get_param(cmd, "FileName");
2902 path = get_param(cmd, "FilePath");
2903 if (name == NULL || path == NULL)
2904 return -1;
2905
2906 if (strcasecmp(path, "VendorSpecific") == 0) {
2907 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
2908 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2909 "certificate from the device (%s)", url);
2910 if (!file_exists(url)) {
2911 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2912 "certificate file does not exist");
2913 return 0;
2914 }
2915 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
2916 if (system(buf) != 0) {
2917 send_resp(dut, conn, SIGMA_ERROR,
2918 "errorCode,Failed to copy client "
2919 "certificate");
2920 return 0;
2921 }
2922
2923 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
2924 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2925 "private key from the device (%s)", url);
2926 if (!file_exists(url)) {
2927 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2928 "private key file does not exist");
2929 return 0;
2930 }
2931 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
2932 if (system(buf) != 0) {
2933 send_resp(dut, conn, SIGMA_ERROR,
2934 "errorCode,Failed to copy client key");
2935 return 0;
2936 }
2937 } else if (strncasecmp(path, "http:", 5) != 0 &&
2938 strncasecmp(path, "https:", 6) != 0) {
2939 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2940 "Unsupported FilePath value");
2941 return 0;
2942 } else {
2943 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
2944 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
2945 "certificate/key from %s", url);
2946 snprintf(buf, sizeof(buf),
2947 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
2948 if (system(buf) != 0) {
2949 send_resp(dut, conn, SIGMA_ERROR,
2950 "errorCode,Failed to download client "
2951 "certificate");
2952 return 0;
2953 }
2954
2955 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
2956 {
2957 send_resp(dut, conn, SIGMA_ERROR,
2958 "errorCode,Failed to copy client key");
2959 return 0;
2960 }
2961 }
2962
2963 return 1;
2964}
2965
2966
2967static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
2968 struct sigma_conn *conn,
2969 const char *intf,
2970 struct sigma_cmd *cmd)
2971{
2972 const char *val;
2973
2974 val = get_param(cmd, "FileType");
2975 if (val && strcasecmp(val, "PPSMO") == 0)
2976 return download_ppsmo(dut, conn, intf, cmd);
2977 if (val && strcasecmp(val, "CERT") == 0)
2978 return download_cert(dut, conn, intf, cmd);
2979 if (val) {
2980 send_resp(dut, conn, SIGMA_ERROR,
2981 "ErrorCode,Unsupported FileType");
2982 return 0;
2983 }
2984
2985 return 1;
2986}
2987
2988
Ankita Bajaja2cb5672017-10-25 16:08:28 +05302989static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
2990 struct sigma_conn *conn,
2991 const char *intf,
2992 struct sigma_cmd *cmd)
2993{
2994 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05302995 char buf[1000];
2996 char text[20];
2997 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05302998
2999 val = get_param(cmd, "OCESupport");
3000 if (val && strcasecmp(val, "Disable") == 0) {
3001 if (wpa_command(intf, "SET oce 0") < 0) {
3002 send_resp(dut, conn, SIGMA_ERROR,
3003 "ErrorCode,Failed to disable OCE");
3004 return 0;
3005 }
3006 } else if (val && strcasecmp(val, "Enable") == 0) {
3007 if (wpa_command(intf, "SET oce 1") < 0) {
3008 send_resp(dut, conn, SIGMA_ERROR,
3009 "ErrorCode,Failed to enable OCE");
3010 return 0;
3011 }
3012 }
3013
vamsi krishnaa2799492017-12-05 14:28:01 +05303014 val = get_param(cmd, "FILScap");
3015 if (val && (atoi(val) == 1)) {
3016 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3017 send_resp(dut, conn, SIGMA_ERROR,
3018 "ErrorCode,Failed to enable FILS");
3019 return 0;
3020 }
3021 } else if (val && (atoi(val) == 0)) {
3022 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3023 send_resp(dut, conn, SIGMA_ERROR,
3024 "ErrorCode,Failed to disable FILS");
3025 return 0;
3026 }
3027 }
3028
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303029 val = get_param(cmd, "FILSHLP");
3030 if (val && strcasecmp(val, "Enable") == 0) {
3031 if (get_wpa_status(get_station_ifname(), "address", text,
3032 sizeof(text)) < 0)
3033 return -2;
3034 hwaddr_aton(text, addr);
3035 snprintf(buf, sizeof(buf),
3036 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3037 "080045100140000040004011399e00000000ffffffff00440043"
3038 "012cb30001010600fd4f46410000000000000000000000000000"
3039 "000000000000"
3040 "%02x%02x%02x%02x%02x%02x"
3041 "0000000000000000000000000000000000000000000000000000"
3042 "0000000000000000000000000000000000000000000000000000"
3043 "0000000000000000000000000000000000000000000000000000"
3044 "0000000000000000000000000000000000000000000000000000"
3045 "0000000000000000000000000000000000000000000000000000"
3046 "0000000000000000000000000000000000000000000000000000"
3047 "0000000000000000000000000000000000000000000000000000"
3048 "0000000000000000000000000000000000000000638253633501"
3049 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3050 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3051 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3052 if (wpa_command(intf, buf)) {
3053 send_resp(dut, conn, SIGMA_ERROR,
3054 "ErrorCode,Failed to add HLP");
3055 return 0;
3056 }
3057 dut->fils_hlp = 1;
3058 }
3059
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303060 return 1;
3061}
3062
3063
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003064static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3065 const char *val)
3066{
3067 int counter = 0;
3068 char token[50];
3069 char *result;
3070 char buf[100];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303071 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003072
Peng Xub8fc5cc2017-05-10 17:27:28 -07003073 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003074 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303075 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003076 while (result) {
3077 if (strcmp(result, "disable") == 0) {
3078 snprintf(buf, sizeof(buf),
3079 "iwpriv %s noackpolicy %d 1 0",
3080 intf, counter);
3081 } else {
3082 snprintf(buf, sizeof(buf),
3083 "iwpriv %s noackpolicy %d 1 1",
3084 intf, counter);
3085 }
3086 if (system(buf) != 0) {
3087 sigma_dut_print(dut, DUT_MSG_ERROR,
3088 "iwpriv noackpolicy failed");
3089 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303090 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003091 counter++;
3092 }
3093}
3094
3095
3096static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3097 const char *val)
3098{
3099 char buf[100];
3100
3101 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3102 if (system(buf) != 0) {
3103 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3104 }
3105}
3106
3107
3108static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3109 const char *val)
3110{
3111 char buf[100];
3112
3113 if (strcasecmp(val, "off") == 0) {
3114 snprintf(buf, sizeof(buf), "iwpriv %s wmm 0", intf);
3115 if (system(buf) != 0) {
3116 sigma_dut_print(dut, DUT_MSG_ERROR,
3117 "Failed to turn off WMM");
3118 }
3119 }
3120}
3121
3122
3123static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3124 const char *val)
3125{
3126 char buf[100];
3127 int sgi20;
3128
3129 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3130
3131 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi20);
3132 if (system(buf) != 0)
3133 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv shortgi failed");
3134}
3135
3136
3137static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3138 const char *val)
3139{
3140 char buf[100];
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303141 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003142
3143 /* Disable Tx Beam forming when using a fixed rate */
3144 ath_disable_txbf(dut, intf);
3145
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303146 v = atoi(val);
3147 if (v < 0 || v > 32) {
3148 sigma_dut_print(dut, DUT_MSG_ERROR,
3149 "Invalid Fixed MCS rate: %d", v);
3150 return;
3151 }
3152 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003153
3154 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0x%x",
3155 intf, rate_code);
3156 if (system(buf) != 0) {
3157 sigma_dut_print(dut, DUT_MSG_ERROR,
3158 "iwpriv set11NRates failed");
3159 }
3160
3161 /* Channel width gets messed up, fix this */
3162 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d", intf, dut->chwidth);
3163 if (system(buf) != 0)
3164 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
3165}
3166
3167
3168static void ath_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3169 const char *val)
3170{
3171 char buf[60];
3172
3173 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3174 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3175 else
3176 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3177
3178 if (system(buf) != 0)
3179 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3180}
3181
3182
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003183static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3184 int ampdu)
3185{
3186 char buf[60];
3187
3188 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3189 if (system(buf) != 0) {
3190 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3191 return -1;
3192 }
3193
3194 return 0;
3195}
3196
3197
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003198static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3199 const char *val)
3200{
3201 char buf[60];
3202
3203 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3204 if (system(buf) != 0) {
3205 sigma_dut_print(dut, DUT_MSG_ERROR,
3206 "iwpriv tx_stbc failed");
3207 }
3208
3209 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3210 if (system(buf) != 0) {
3211 sigma_dut_print(dut, DUT_MSG_ERROR,
3212 "iwpriv rx_stbc failed");
3213 }
3214}
3215
3216
3217static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3218 const char *val)
3219{
3220 char buf[60];
3221
Peng Xucc317ed2017-05-18 16:44:37 -07003222 if (strcmp(val, "160") == 0) {
3223 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3224 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003225 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3226 } else if (strcmp(val, "40") == 0) {
3227 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3228 } else if (strcmp(val, "20") == 0) {
3229 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3230 } else if (strcasecmp(val, "Auto") == 0) {
3231 buf[0] = '\0';
3232 } else {
3233 sigma_dut_print(dut, DUT_MSG_ERROR,
3234 "WIDTH/CTS_WIDTH value not supported");
3235 return -1;
3236 }
3237
3238 if (buf[0] != '\0' && system(buf) != 0) {
3239 sigma_dut_print(dut, DUT_MSG_ERROR,
3240 "Failed to set WIDTH/CTS_WIDTH");
3241 return -1;
3242 }
3243
3244 return 0;
3245}
3246
3247
3248int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3249 const char *intf, const char *val)
3250{
3251 char buf[60];
3252
3253 if (strcasecmp(val, "Auto") == 0) {
3254 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3255 dut->chwidth = 0;
3256 } else if (strcasecmp(val, "20") == 0) {
3257 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3258 dut->chwidth = 0;
3259 } else if (strcasecmp(val, "40") == 0) {
3260 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
3261 dut->chwidth = 1;
3262 } else if (strcasecmp(val, "80") == 0) {
3263 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
3264 dut->chwidth = 2;
3265 } else if (strcasecmp(val, "160") == 0) {
3266 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 3", intf);
3267 dut->chwidth = 3;
3268 } else {
3269 send_resp(dut, conn, SIGMA_ERROR,
3270 "ErrorCode,WIDTH not supported");
3271 return -1;
3272 }
3273
3274 if (system(buf) != 0) {
3275 sigma_dut_print(dut, DUT_MSG_ERROR,
3276 "iwpriv chwidth failed");
3277 }
3278
3279 return 0;
3280}
3281
3282
3283static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3284 const char *val)
3285{
3286 char buf[60];
3287
3288 if (strcmp(val, "1SS") == 0) {
3289 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
3290 } else if (strcmp(val, "2SS") == 0) {
3291 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
3292 } else {
3293 sigma_dut_print(dut, DUT_MSG_ERROR,
3294 "SP_STREAM value not supported");
3295 return -1;
3296 }
3297
3298 if (system(buf) != 0) {
3299 sigma_dut_print(dut, DUT_MSG_ERROR,
3300 "Failed to set SP_STREAM");
3301 return -1;
3302 }
3303
3304 return 0;
3305}
3306
3307
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303308static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3309 const char *val)
3310{
3311 char buf[60];
3312
3313 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3314 if (system(buf) != 0)
3315 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
3316
3317 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3318 if (system(buf) != 0)
3319 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
3320}
3321
3322
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303323static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
3324 struct sigma_conn *conn,
3325 const char *intf, int capa)
3326{
3327 char buf[32];
3328
3329 if (capa > 0 && capa < 4) {
3330 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
3331 if (wpa_command(intf, buf) < 0) {
3332 send_resp(dut, conn, SIGMA_ERROR,
3333 "ErrorCode, Failed to set cellular data capability");
3334 return 0;
3335 }
3336 return 1;
3337 }
3338
3339 sigma_dut_print(dut, DUT_MSG_ERROR,
3340 "Invalid Cellular data capability: %d", capa);
3341 send_resp(dut, conn, SIGMA_INVALID,
3342 "ErrorCode,Invalid cellular data capability");
3343 return 0;
3344}
3345
3346
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303347static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
3348 const char *intf, const char *val)
3349{
3350 if (strcasecmp(val, "Disable") == 0) {
3351 if (wpa_command(intf, "SET roaming 0") < 0) {
3352 send_resp(dut, conn, SIGMA_ERROR,
3353 "ErrorCode,Failed to disable roaming");
3354 return 0;
3355 }
3356 return 1;
3357 }
3358
3359 if (strcasecmp(val, "Enable") == 0) {
3360 if (wpa_command(intf, "SET roaming 1") < 0) {
3361 send_resp(dut, conn, SIGMA_ERROR,
3362 "ErrorCode,Failed to enable roaming");
3363 return 0;
3364 }
3365 return 1;
3366 }
3367
3368 sigma_dut_print(dut, DUT_MSG_ERROR,
3369 "Invalid value provided for roaming: %s", val);
3370 send_resp(dut, conn, SIGMA_INVALID,
3371 "ErrorCode,Unknown value provided for Roaming");
3372 return 0;
3373}
3374
3375
Ashwini Patila75de5a2017-04-13 16:35:05 +05303376static int mbo_set_assoc_disallow(struct sigma_dut *dut,
3377 struct sigma_conn *conn,
3378 const char *intf, const char *val)
3379{
3380 if (strcasecmp(val, "Disable") == 0) {
3381 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
3382 send_resp(dut, conn, SIGMA_ERROR,
3383 "ErrorCode,Failed to disable Assoc_disallow");
3384 return 0;
3385 }
3386 return 1;
3387 }
3388
3389 if (strcasecmp(val, "Enable") == 0) {
3390 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
3391 send_resp(dut, conn, SIGMA_ERROR,
3392 "ErrorCode,Failed to enable Assoc_disallow");
3393 return 0;
3394 }
3395 return 1;
3396 }
3397
3398 sigma_dut_print(dut, DUT_MSG_ERROR,
3399 "Invalid value provided for Assoc_disallow: %s", val);
3400 send_resp(dut, conn, SIGMA_INVALID,
3401 "ErrorCode,Unknown value provided for Assoc_disallow");
3402 return 0;
3403}
3404
3405
Ashwini Patilc63161e2017-04-13 16:30:23 +05303406static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
3407 const char *intf, const char *val)
3408{
3409 if (strcasecmp(val, "Reject") == 0) {
3410 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
3411 send_resp(dut, conn, SIGMA_ERROR,
3412 "ErrorCode,Failed to Reject BTM Request");
3413 return 0;
3414 }
3415 return 1;
3416 }
3417
3418 if (strcasecmp(val, "Accept") == 0) {
3419 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
3420 send_resp(dut, conn, SIGMA_ERROR,
3421 "ErrorCode,Failed to Accept BTM Request");
3422 return 0;
3423 }
3424 return 1;
3425 }
3426
3427 sigma_dut_print(dut, DUT_MSG_ERROR,
3428 "Invalid value provided for BSS_Transition: %s", val);
3429 send_resp(dut, conn, SIGMA_INVALID,
3430 "ErrorCode,Unknown value provided for BSS_Transition");
3431 return 0;
3432}
3433
3434
Ashwini Patil00402582017-04-13 12:29:39 +05303435static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
3436 struct sigma_conn *conn,
3437 const char *intf,
3438 struct sigma_cmd *cmd)
3439{
3440 const char *ch, *pref, *op_class, *reason;
3441 char buf[120];
3442 int len, ret;
3443
3444 pref = get_param(cmd, "Ch_Pref");
3445 if (!pref)
3446 return 1;
3447
3448 if (strcasecmp(pref, "clear") == 0) {
3449 free(dut->non_pref_ch_list);
3450 dut->non_pref_ch_list = NULL;
3451 } else {
3452 op_class = get_param(cmd, "Ch_Op_Class");
3453 if (!op_class) {
3454 send_resp(dut, conn, SIGMA_INVALID,
3455 "ErrorCode,Ch_Op_Class not provided");
3456 return 0;
3457 }
3458
3459 ch = get_param(cmd, "Ch_Pref_Num");
3460 if (!ch) {
3461 send_resp(dut, conn, SIGMA_INVALID,
3462 "ErrorCode,Ch_Pref_Num not provided");
3463 return 0;
3464 }
3465
3466 reason = get_param(cmd, "Ch_Reason_Code");
3467 if (!reason) {
3468 send_resp(dut, conn, SIGMA_INVALID,
3469 "ErrorCode,Ch_Reason_Code not provided");
3470 return 0;
3471 }
3472
3473 if (!dut->non_pref_ch_list) {
3474 dut->non_pref_ch_list =
3475 calloc(1, NON_PREF_CH_LIST_SIZE);
3476 if (!dut->non_pref_ch_list) {
3477 send_resp(dut, conn, SIGMA_ERROR,
3478 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
3479 return 0;
3480 }
3481 }
3482 len = strlen(dut->non_pref_ch_list);
3483 ret = snprintf(dut->non_pref_ch_list + len,
3484 NON_PREF_CH_LIST_SIZE - len,
3485 " %s:%s:%s:%s", op_class, ch, pref, reason);
3486 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
3487 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
3488 dut->non_pref_ch_list);
3489 } else {
3490 sigma_dut_print(dut, DUT_MSG_ERROR,
3491 "snprintf failed for non_pref_list, ret = %d",
3492 ret);
3493 send_resp(dut, conn, SIGMA_ERROR,
3494 "ErrorCode,snprintf failed");
3495 free(dut->non_pref_ch_list);
3496 dut->non_pref_ch_list = NULL;
3497 return 0;
3498 }
3499 }
3500
3501 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
3502 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
3503 if (ret < 0 || ret >= (int) sizeof(buf)) {
3504 sigma_dut_print(dut, DUT_MSG_DEBUG,
3505 "snprintf failed for set non_pref_chan, ret: %d",
3506 ret);
3507 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
3508 return 0;
3509 }
3510
3511 if (wpa_command(intf, buf) < 0) {
3512 send_resp(dut, conn, SIGMA_ERROR,
3513 "ErrorCode,Failed to set non-preferred channel list");
3514 return 0;
3515 }
3516
3517 return 1;
3518}
3519
3520
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003521static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
3522 struct sigma_conn *conn,
3523 struct sigma_cmd *cmd)
3524{
3525 const char *intf = get_param(cmd, "Interface");
3526 const char *val;
3527
3528 val = get_param(cmd, "Program");
Peng Xue9fa7952017-05-09 15:59:49 -07003529 if (val && strcasecmp(val, "HS2-R2") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003530 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
3531 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003532
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07003533 if (val && strcasecmp(val, "LOC") == 0)
3534 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
3535
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003536#ifdef ANDROID_NAN
3537 if (val && strcasecmp(val, "NAN") == 0)
3538 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
3539#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07003540#ifdef MIRACAST
3541 if (val && (strcasecmp(val, "WFD") == 0 ||
3542 strcasecmp(val, "DisplayR2") == 0))
3543 return miracast_preset_testparameters(dut, conn, cmd);
3544#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003545
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303546 if (val && strcasecmp(val, "MBO") == 0) {
3547 val = get_param(cmd, "Cellular_Data_Cap");
3548 if (val &&
3549 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
3550 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05303551
3552 val = get_param(cmd, "Ch_Pref");
3553 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
3554 return 0;
3555
Ashwini Patilc63161e2017-04-13 16:30:23 +05303556 val = get_param(cmd, "BSS_Transition");
3557 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
3558 return 0;
3559
Ashwini Patila75de5a2017-04-13 16:35:05 +05303560 val = get_param(cmd, "Assoc_Disallow");
3561 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
3562 return 0;
3563
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303564 val = get_param(cmd, "Roaming");
3565 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
3566 return 0;
3567
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303568 return 1;
3569 }
3570
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303571 if (val && strcasecmp(val, "OCE") == 0)
3572 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
3573
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003574#if 0
3575 val = get_param(cmd, "Supplicant");
3576 if (val && strcasecmp(val, "Default") != 0) {
3577 send_resp(dut, conn, SIGMA_ERROR,
3578 "ErrorCode,Only default(Vendor) supplicant "
3579 "supported");
3580 return 0;
3581 }
3582#endif
3583
3584 val = get_param(cmd, "RTS");
3585 if (val) {
3586 switch (get_driver_type()) {
3587 case DRIVER_ATHEROS:
3588 ath_sta_set_rts(dut, intf, val);
3589 break;
3590 default:
3591#if 0
3592 send_resp(dut, conn, SIGMA_ERROR,
3593 "ErrorCode,Setting RTS not supported");
3594 return 0;
3595#else
3596 sigma_dut_print(dut, DUT_MSG_DEBUG,
3597 "Setting RTS not supported");
3598 break;
3599#endif
3600 }
3601 }
3602
3603#if 0
3604 val = get_param(cmd, "FRGMNT");
3605 if (val) {
3606 /* TODO */
3607 send_resp(dut, conn, SIGMA_ERROR,
3608 "ErrorCode,Setting FRGMNT not supported");
3609 return 0;
3610 }
3611#endif
3612
3613#if 0
3614 val = get_param(cmd, "Preamble");
3615 if (val) {
3616 /* TODO: Long/Short */
3617 send_resp(dut, conn, SIGMA_ERROR,
3618 "ErrorCode,Setting Preamble not supported");
3619 return 0;
3620 }
3621#endif
3622
3623 val = get_param(cmd, "Mode");
3624 if (val) {
3625 if (strcmp(val, "11b") == 0 ||
3626 strcmp(val, "11g") == 0 ||
3627 strcmp(val, "11a") == 0 ||
3628 strcmp(val, "11n") == 0 ||
3629 strcmp(val, "11ng") == 0 ||
3630 strcmp(val, "11nl") == 0 ||
3631 strcmp(val, "11nl(nabg)") == 0 ||
3632 strcmp(val, "AC") == 0 ||
3633 strcmp(val, "11AC") == 0 ||
3634 strcmp(val, "11ac") == 0 ||
3635 strcmp(val, "11na") == 0 ||
3636 strcmp(val, "11an") == 0) {
3637 /* STA supports all modes by default */
3638 } else {
3639 send_resp(dut, conn, SIGMA_ERROR,
3640 "ErrorCode,Setting Mode not supported");
3641 return 0;
3642 }
3643 }
3644
3645 val = get_param(cmd, "wmm");
3646 if (val) {
3647 switch (get_driver_type()) {
3648 case DRIVER_ATHEROS:
3649 ath_sta_set_wmm(dut, intf, val);
3650 break;
3651 default:
3652 sigma_dut_print(dut, DUT_MSG_DEBUG,
3653 "Setting wmm not supported");
3654 break;
3655 }
3656 }
3657
3658 val = get_param(cmd, "Powersave");
3659 if (val) {
3660 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
3661 if (wpa_command(get_station_ifname(),
3662 "P2P_SET ps 0") < 0)
3663 return -2;
3664 /* Make sure test modes are disabled */
3665 wpa_command(get_station_ifname(), "P2P_SET ps 98");
3666 wpa_command(get_station_ifname(), "P2P_SET ps 96");
3667 } else if (strcmp(val, "1") == 0 ||
3668 strcasecmp(val, "PSPoll") == 0 ||
3669 strcasecmp(val, "on") == 0) {
3670 /* Disable default power save mode */
3671 wpa_command(get_station_ifname(), "P2P_SET ps 0");
3672 /* Enable PS-Poll test mode */
3673 if (wpa_command(get_station_ifname(),
3674 "P2P_SET ps 97") < 0 ||
3675 wpa_command(get_station_ifname(),
3676 "P2P_SET ps 99") < 0)
3677 return -2;
3678 } else if (strcmp(val, "2") == 0 ||
3679 strcasecmp(val, "Fast") == 0) {
3680 /* TODO */
3681 send_resp(dut, conn, SIGMA_ERROR,
3682 "ErrorCode,Powersave=Fast not supported");
3683 return 0;
3684 } else if (strcmp(val, "3") == 0 ||
3685 strcasecmp(val, "PSNonPoll") == 0) {
3686 /* Make sure test modes are disabled */
3687 wpa_command(get_station_ifname(), "P2P_SET ps 98");
3688 wpa_command(get_station_ifname(), "P2P_SET ps 96");
3689
3690 /* Enable default power save mode */
3691 if (wpa_command(get_station_ifname(),
3692 "P2P_SET ps 1") < 0)
3693 return -2;
3694 } else
3695 return -1;
3696 }
3697
3698 val = get_param(cmd, "NoAck");
3699 if (val) {
3700 switch (get_driver_type()) {
3701 case DRIVER_ATHEROS:
3702 ath_sta_set_noack(dut, intf, val);
3703 break;
3704 default:
3705 send_resp(dut, conn, SIGMA_ERROR,
3706 "ErrorCode,Setting NoAck not supported");
3707 return 0;
3708 }
3709 }
3710
3711 val = get_param(cmd, "IgnoreChswitchProhibit");
3712 if (val) {
3713 /* TODO: Enabled/disabled */
3714 if (strcasecmp(val, "Enabled") == 0) {
3715 send_resp(dut, conn, SIGMA_ERROR,
3716 "ErrorCode,Enabling IgnoreChswitchProhibit "
3717 "not supported");
3718 return 0;
3719 }
3720 }
3721
3722 val = get_param(cmd, "TDLS");
3723 if (val) {
3724 if (strcasecmp(val, "Disabled") == 0) {
3725 if (wpa_command(intf, "SET tdls_disabled 1")) {
3726 send_resp(dut, conn, SIGMA_ERROR,
3727 "ErrorCode,Failed to disable TDLS");
3728 return 0;
3729 }
3730 } else if (strcasecmp(val, "Enabled") == 0) {
3731 if (wpa_command(intf, "SET tdls_disabled 0")) {
3732 send_resp(dut, conn, SIGMA_ERROR,
3733 "ErrorCode,Failed to enable TDLS");
3734 return 0;
3735 }
3736 } else {
3737 send_resp(dut, conn, SIGMA_ERROR,
3738 "ErrorCode,Unsupported TDLS value");
3739 return 0;
3740 }
3741 }
3742
3743 val = get_param(cmd, "TDLSmode");
3744 if (val) {
3745 if (strcasecmp(val, "Default") == 0) {
3746 wpa_command(intf, "SET tdls_testing 0");
3747 } else if (strcasecmp(val, "APProhibit") == 0) {
3748 if (wpa_command(intf, "SET tdls_testing 0x400")) {
3749 send_resp(dut, conn, SIGMA_ERROR,
3750 "ErrorCode,Failed to enable ignore "
3751 "APProhibit TDLS mode");
3752 return 0;
3753 }
3754 } else if (strcasecmp(val, "HiLoMac") == 0) {
3755 /* STA should respond with TDLS setup req for a TDLS
3756 * setup req */
3757 if (wpa_command(intf, "SET tdls_testing 0x80")) {
3758 send_resp(dut, conn, SIGMA_ERROR,
3759 "ErrorCode,Failed to enable HiLoMac "
3760 "TDLS mode");
3761 return 0;
3762 }
3763 } else if (strcasecmp(val, "WeakSecurity") == 0) {
3764 /*
3765 * Since all security modes are enabled by default when
3766 * Sigma control is used, there is no need to do
3767 * anything here.
3768 */
3769 } else if (strcasecmp(val, "ExistLink") == 0) {
3770 /*
3771 * Since we allow new TDLS Setup Request even if there
3772 * is an existing link, nothing needs to be done for
3773 * this.
3774 */
3775 } else {
3776 /* TODO:
3777 * ExistLink: STA should send TDLS setup req even if
3778 * direct link already exists
3779 */
3780 send_resp(dut, conn, SIGMA_ERROR,
3781 "ErrorCode,Unsupported TDLSmode value");
3782 return 0;
3783 }
3784 }
3785
3786 val = get_param(cmd, "FakePubKey");
3787 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
3788 send_resp(dut, conn, SIGMA_ERROR,
3789 "ErrorCode,Failed to enable FakePubKey");
3790 return 0;
3791 }
3792
3793 return 1;
3794}
3795
3796
3797static const char * ath_get_radio_name(const char *radio_name)
3798{
3799 if (radio_name == NULL)
3800 return "wifi0";
3801 if (strcmp(radio_name, "wifi1") == 0)
3802 return "wifi1";
3803 if (strcmp(radio_name, "wifi2") == 0)
3804 return "wifi2";
3805 return "wifi0";
3806}
3807
3808
3809static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
3810 const char *val)
3811{
3812 char buf[60];
3813 unsigned int vht_mcsmap = 0;
3814 int txchainmask = 0;
3815 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
3816
3817 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
3818 if (dut->testbed_flag_txsp == 1) {
3819 vht_mcsmap = 0xfffc;
3820 dut->testbed_flag_txsp = 0;
3821 } else {
3822 vht_mcsmap = 0xfffe;
3823 }
3824 txchainmask = 1;
3825 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
3826 if (dut->testbed_flag_txsp == 1) {
3827 vht_mcsmap = 0xfff0;
3828 dut->testbed_flag_txsp = 0;
3829 } else {
3830 vht_mcsmap = 0xfffa;
3831 }
3832 txchainmask = 3;
3833 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
3834 if (dut->testbed_flag_txsp == 1) {
3835 vht_mcsmap = 0xffc0;
3836 dut->testbed_flag_txsp = 0;
3837 } else {
3838 vht_mcsmap = 0xffea;
3839 }
3840 txchainmask = 7;
3841 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
3842 if (dut->testbed_flag_txsp == 1) {
3843 vht_mcsmap = 0xff00;
3844 dut->testbed_flag_txsp = 0;
3845 } else {
3846 vht_mcsmap = 0xffaa;
3847 }
3848 txchainmask = 15;
3849 } else {
3850 if (dut->testbed_flag_txsp == 1) {
3851 vht_mcsmap = 0xffc0;
3852 dut->testbed_flag_txsp = 0;
3853 } else {
3854 vht_mcsmap = 0xffea;
3855 }
3856 }
3857
3858 if (txchainmask) {
3859 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
3860 basedev, txchainmask);
3861 if (system(buf) != 0) {
3862 sigma_dut_print(dut, DUT_MSG_ERROR,
3863 "iwpriv txchainmask failed");
3864 }
3865 }
3866
3867 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
3868 intf, vht_mcsmap);
3869 if (system(buf) != 0) {
3870 sigma_dut_print(dut, DUT_MSG_ERROR,
3871 "iwpriv %s vht_mcsmap 0x%04x failed",
3872 intf, vht_mcsmap);
3873 }
3874}
3875
3876
3877static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
3878 const char *val)
3879{
3880 char buf[60];
3881 unsigned int vht_mcsmap = 0;
3882 int rxchainmask = 0;
3883 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
3884
3885 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
3886 if (dut->testbed_flag_rxsp == 1) {
3887 vht_mcsmap = 0xfffc;
3888 dut->testbed_flag_rxsp = 0;
3889 } else {
3890 vht_mcsmap = 0xfffe;
3891 }
3892 rxchainmask = 1;
3893 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
3894 if (dut->testbed_flag_rxsp == 1) {
3895 vht_mcsmap = 0xfff0;
3896 dut->testbed_flag_rxsp = 0;
3897 } else {
3898 vht_mcsmap = 0xfffa;
3899 }
3900 rxchainmask = 3;
3901 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
3902 if (dut->testbed_flag_rxsp == 1) {
3903 vht_mcsmap = 0xffc0;
3904 dut->testbed_flag_rxsp = 0;
3905 } else {
3906 vht_mcsmap = 0xffea;
3907 }
3908 rxchainmask = 7;
3909 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
3910 if (dut->testbed_flag_rxsp == 1) {
3911 vht_mcsmap = 0xff00;
3912 dut->testbed_flag_rxsp = 0;
3913 } else {
3914 vht_mcsmap = 0xffaa;
3915 }
3916 rxchainmask = 15;
3917 } else {
3918 if (dut->testbed_flag_rxsp == 1) {
3919 vht_mcsmap = 0xffc0;
3920 dut->testbed_flag_rxsp = 0;
3921 } else {
3922 vht_mcsmap = 0xffea;
3923 }
3924 }
3925
3926 if (rxchainmask) {
3927 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
3928 basedev, rxchainmask);
3929 if (system(buf) != 0) {
3930 sigma_dut_print(dut, DUT_MSG_ERROR,
3931 "iwpriv rxchainmask failed");
3932 }
3933 }
3934
3935 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
3936 intf, vht_mcsmap);
3937 if (system(buf) != 0) {
3938 sigma_dut_print(dut, DUT_MSG_ERROR,
3939 "iwpriv %s vht_mcsmap 0x%04x",
3940 intf, vht_mcsmap);
3941 }
3942}
3943
3944
3945void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
3946{
3947 if (strcasecmp(val, "enable") == 0) {
3948 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
3949 != 0) {
3950 sigma_dut_print(dut, DUT_MSG_ERROR,
3951 "Disable BB_VHTSIGB_CRC_CALC failed");
3952 }
3953
3954 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
3955 != 0) {
3956 sigma_dut_print(dut, DUT_MSG_ERROR,
3957 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
3958 }
3959 } else {
3960 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
3961 != 0) {
3962 sigma_dut_print(dut, DUT_MSG_ERROR,
3963 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
3964 }
3965
3966 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
3967 != 0) {
3968 sigma_dut_print(dut, DUT_MSG_ERROR,
3969 "Enable BB_VHTSIGB_CRC_CALC failed");
3970 }
3971 }
3972}
3973
3974
3975static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
3976 struct sigma_conn *conn,
3977 struct sigma_cmd *cmd)
3978{
3979 const char *val;
3980 int ampdu = -1;
3981 char buf[30];
3982
3983 val = get_param(cmd, "40_INTOLERANT");
3984 if (val) {
3985 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
3986 /* TODO: iwpriv ht40intol through wpa_supplicant */
3987 send_resp(dut, conn, SIGMA_ERROR,
3988 "ErrorCode,40_INTOLERANT not supported");
3989 return 0;
3990 }
3991 }
3992
3993 val = get_param(cmd, "ADDBA_REJECT");
3994 if (val) {
3995 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
3996 /* reject any ADDBA with status "decline" */
3997 ampdu = 0;
3998 } else {
3999 /* accept ADDBA */
4000 ampdu = 1;
4001 }
4002 }
4003
4004 val = get_param(cmd, "AMPDU");
4005 if (val) {
4006 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4007 /* enable AMPDU Aggregation */
4008 if (ampdu == 0) {
4009 send_resp(dut, conn, SIGMA_ERROR,
4010 "ErrorCode,Mismatch in "
4011 "addba_reject/ampdu - "
4012 "not supported");
4013 return 0;
4014 }
4015 ampdu = 1;
4016 } else {
4017 /* disable AMPDU Aggregation */
4018 if (ampdu == 1) {
4019 send_resp(dut, conn, SIGMA_ERROR,
4020 "ErrorCode,Mismatch in "
4021 "addba_reject/ampdu - "
4022 "not supported");
4023 return 0;
4024 }
4025 ampdu = 0;
4026 }
4027 }
4028
4029 if (ampdu >= 0) {
4030 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
4031 ampdu ? "Enabling" : "Disabling");
4032 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004033 if (wpa_command(intf, buf) < 0 &&
4034 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004035 send_resp(dut, conn, SIGMA_ERROR,
4036 "ErrorCode,set aggr failed");
4037 return 0;
4038 }
4039 }
4040
4041 val = get_param(cmd, "AMSDU");
4042 if (val) {
4043 switch (get_driver_type()) {
4044 case DRIVER_ATHEROS:
4045 ath_sta_set_amsdu(dut, intf, val);
4046 break;
4047 default:
4048 if (strcmp(val, "1") == 0 ||
4049 strcasecmp(val, "Enable") == 0) {
4050 /* Enable AMSDU Aggregation */
4051 send_resp(dut, conn, SIGMA_ERROR,
4052 "ErrorCode,AMSDU aggregation not supported");
4053 return 0;
4054 }
4055 break;
4056 }
4057 }
4058
4059 val = get_param(cmd, "STBC_RX");
4060 if (val) {
4061 switch (get_driver_type()) {
4062 case DRIVER_ATHEROS:
4063 ath_sta_set_stbc(dut, intf, val);
4064 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304065 case DRIVER_WCN:
4066 wcn_sta_set_stbc(dut, intf, val);
4067 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004068 default:
4069 send_resp(dut, conn, SIGMA_ERROR,
4070 "ErrorCode,STBC_RX not supported");
4071 return 0;
4072 }
4073 }
4074
4075 val = get_param(cmd, "WIDTH");
4076 if (val) {
4077 switch (get_driver_type()) {
4078 case DRIVER_WCN:
4079 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
4080 send_resp(dut, conn, SIGMA_ERROR,
4081 "ErrorCode,Failed to set WIDTH");
4082 return 0;
4083 }
4084 break;
4085 case DRIVER_ATHEROS:
4086 if (ath_set_width(dut, conn, intf, val) < 0)
4087 return 0;
4088 break;
4089 default:
4090 sigma_dut_print(dut, DUT_MSG_ERROR,
4091 "Setting WIDTH not supported");
4092 break;
4093 }
4094 }
4095
4096 val = get_param(cmd, "SMPS");
4097 if (val) {
4098 /* TODO: Dynamic/0, Static/1, No Limit/2 */
4099 send_resp(dut, conn, SIGMA_ERROR,
4100 "ErrorCode,SMPS not supported");
4101 return 0;
4102 }
4103
4104 val = get_param(cmd, "TXSP_STREAM");
4105 if (val) {
4106 switch (get_driver_type()) {
4107 case DRIVER_WCN:
4108 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4109 send_resp(dut, conn, SIGMA_ERROR,
4110 "ErrorCode,Failed to set TXSP_STREAM");
4111 return 0;
4112 }
4113 break;
4114 case DRIVER_ATHEROS:
4115 ath_sta_set_txsp_stream(dut, intf, val);
4116 break;
4117 default:
4118 sigma_dut_print(dut, DUT_MSG_ERROR,
4119 "Setting TXSP_STREAM not supported");
4120 break;
4121 }
4122 }
4123
4124 val = get_param(cmd, "RXSP_STREAM");
4125 if (val) {
4126 switch (get_driver_type()) {
4127 case DRIVER_WCN:
4128 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4129 send_resp(dut, conn, SIGMA_ERROR,
4130 "ErrorCode,Failed to set RXSP_STREAM");
4131 return 0;
4132 }
4133 break;
4134 case DRIVER_ATHEROS:
4135 ath_sta_set_rxsp_stream(dut, intf, val);
4136 break;
4137 default:
4138 sigma_dut_print(dut, DUT_MSG_ERROR,
4139 "Setting RXSP_STREAM not supported");
4140 break;
4141 }
4142 }
4143
4144 val = get_param(cmd, "DYN_BW_SGNL");
4145 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004146 switch (get_driver_type()) {
4147 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08004148 if (strcasecmp(val, "enable") == 0) {
4149 snprintf(buf, sizeof(buf),
4150 "iwpriv %s cwmenable 1", intf);
4151 if (system(buf) != 0) {
4152 sigma_dut_print(dut, DUT_MSG_ERROR,
4153 "iwpriv cwmenable 1 failed");
4154 return 0;
4155 }
4156 } else if (strcasecmp(val, "disable") == 0) {
4157 snprintf(buf, sizeof(buf),
4158 "iwpriv %s cwmenable 0", intf);
4159 if (system(buf) != 0) {
4160 sigma_dut_print(dut, DUT_MSG_ERROR,
4161 "iwpriv cwmenable 0 failed");
4162 return 0;
4163 }
4164 } else {
4165 sigma_dut_print(dut, DUT_MSG_ERROR,
4166 "Unsupported DYN_BW_SGL");
4167 }
4168
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004169 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4170 if (system(buf) != 0) {
4171 sigma_dut_print(dut, DUT_MSG_ERROR,
4172 "Failed to set cts_cbw in DYN_BW_SGNL");
4173 return 0;
4174 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004175 break;
4176 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004177 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004178 ath_config_dyn_bw_sig(dut, intf, val);
4179 break;
4180 default:
4181 sigma_dut_print(dut, DUT_MSG_ERROR,
4182 "Failed to set DYN_BW_SGNL");
4183 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004184 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004185 }
4186
4187 val = get_param(cmd, "RTS_FORCE");
4188 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004189 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004190 if (strcasecmp(val, "Enable") == 0) {
4191 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004192 if (system(buf) != 0) {
4193 sigma_dut_print(dut, DUT_MSG_ERROR,
4194 "Failed to set RTS_FORCE 64");
4195 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08004196 snprintf(buf, sizeof(buf),
4197 "wifitool %s beeliner_fw_test 100 1", intf);
4198 if (system(buf) != 0) {
4199 sigma_dut_print(dut, DUT_MSG_ERROR,
4200 "wifitool beeliner_fw_test 100 1 failed");
4201 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004202 } else if (strcasecmp(val, "Disable") == 0) {
4203 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
4204 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004205 if (system(buf) != 0) {
4206 sigma_dut_print(dut, DUT_MSG_ERROR,
4207 "Failed to set RTS_FORCE 2347");
4208 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004209 } else {
4210 send_resp(dut, conn, SIGMA_ERROR,
4211 "ErrorCode,RTS_FORCE value not supported");
4212 return 0;
4213 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004214 }
4215
4216 val = get_param(cmd, "CTS_WIDTH");
4217 if (val) {
4218 switch (get_driver_type()) {
4219 case DRIVER_WCN:
4220 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
4221 send_resp(dut, conn, SIGMA_ERROR,
4222 "ErrorCode,Failed to set CTS_WIDTH");
4223 return 0;
4224 }
4225 break;
4226 case DRIVER_ATHEROS:
4227 ath_set_cts_width(dut, intf, val);
4228 break;
4229 default:
4230 sigma_dut_print(dut, DUT_MSG_ERROR,
4231 "Setting CTS_WIDTH not supported");
4232 break;
4233 }
4234 }
4235
4236 val = get_param(cmd, "BW_SGNL");
4237 if (val) {
4238 if (strcasecmp(val, "Enable") == 0) {
4239 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1",
4240 intf);
4241 } else if (strcasecmp(val, "Disable") == 0) {
4242 /* TODO: Disable */
4243 buf[0] = '\0';
4244 } else {
4245 send_resp(dut, conn, SIGMA_ERROR,
4246 "ErrorCode,BW_SGNL value not supported");
4247 return 0;
4248 }
4249
4250 if (buf[0] != '\0' && system(buf) != 0) {
4251 sigma_dut_print(dut, DUT_MSG_ERROR,
4252 "Failed to set BW_SGNL");
4253 }
4254 }
4255
4256 val = get_param(cmd, "Band");
4257 if (val) {
4258 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
4259 /* STA supports all bands by default */
4260 } else {
4261 send_resp(dut, conn, SIGMA_ERROR,
4262 "ErrorCode,Unsupported Band");
4263 return 0;
4264 }
4265 }
4266
4267 val = get_param(cmd, "zero_crc");
4268 if (val) {
4269 switch (get_driver_type()) {
4270 case DRIVER_ATHEROS:
4271 ath_set_zero_crc(dut, val);
4272 break;
4273 default:
4274 break;
4275 }
4276 }
4277
4278 return 1;
4279}
4280
4281
4282static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
4283 struct sigma_cmd *cmd)
4284{
4285 const char *val;
4286 char buf[100];
4287
4288 val = get_param(cmd, "MSDUSize");
4289 if (val) {
4290 int mtu;
4291
4292 dut->amsdu_size = atoi(val);
4293 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
4294 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
4295 sigma_dut_print(dut, DUT_MSG_ERROR,
4296 "MSDUSize %d is above max %d or below min %d",
4297 dut->amsdu_size,
4298 IEEE80211_MAX_DATA_LEN_DMG,
4299 IEEE80211_SNAP_LEN_DMG);
4300 dut->amsdu_size = 0;
4301 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4302 }
4303
4304 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
4305 sigma_dut_print(dut, DUT_MSG_DEBUG,
4306 "Setting amsdu_size to %d", mtu);
4307 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
4308 get_station_ifname(), mtu);
4309
4310 if (system(buf) != 0) {
4311 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
4312 buf);
4313 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4314 }
4315 }
4316
4317 val = get_param(cmd, "BAckRcvBuf");
4318 if (val) {
4319 dut->back_rcv_buf = atoi(val);
4320 if (dut->back_rcv_buf == 0) {
4321 sigma_dut_print(dut, DUT_MSG_ERROR,
4322 "Failed to convert %s or value is 0",
4323 val);
4324 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4325 }
4326
4327 sigma_dut_print(dut, DUT_MSG_DEBUG,
4328 "Setting BAckRcvBuf to %s", val);
4329 }
4330
4331 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
4332}
4333
4334
4335static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
4336 struct sigma_cmd *cmd)
4337{
4338 int net_id;
4339 char *ifname;
4340 const char *val;
4341 char buf[100];
4342
4343 dut->mode = SIGMA_MODE_STATION;
4344 ifname = get_main_ifname();
4345 if (wpa_command(ifname, "PING") != 0) {
4346 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
4347 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4348 }
4349
4350 wpa_command(ifname, "FLUSH");
4351 net_id = add_network_common(dut, conn, ifname, cmd);
4352 if (net_id < 0) {
4353 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
4354 return net_id;
4355 }
4356
4357 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
4358 if (set_network(ifname, net_id, "mode", "2") < 0) {
4359 sigma_dut_print(dut, DUT_MSG_ERROR,
4360 "Failed to set supplicant network mode");
4361 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4362 }
4363
4364 sigma_dut_print(dut, DUT_MSG_DEBUG,
4365 "Supplicant set network with mode 2");
4366
4367 val = get_param(cmd, "Security");
4368 if (val && strcasecmp(val, "OPEN") == 0) {
4369 dut->ap_key_mgmt = AP_OPEN;
4370 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
4371 sigma_dut_print(dut, DUT_MSG_ERROR,
4372 "Failed to set supplicant to %s security",
4373 val);
4374 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4375 }
4376 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
4377 dut->ap_key_mgmt = AP_WPA2_PSK;
4378 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
4379 sigma_dut_print(dut, DUT_MSG_ERROR,
4380 "Failed to set supplicant to %s security",
4381 val);
4382 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4383 }
4384
4385 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
4386 sigma_dut_print(dut, DUT_MSG_ERROR,
4387 "Failed to set supplicant to proto RSN");
4388 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4389 }
4390 } else if (val) {
4391 sigma_dut_print(dut, DUT_MSG_ERROR,
4392 "Requested Security %s is not supported on 60GHz",
4393 val);
4394 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
4395 }
4396
4397 val = get_param(cmd, "Encrypt");
4398 if (val && strcasecmp(val, "AES-GCMP") == 0) {
4399 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
4400 sigma_dut_print(dut, DUT_MSG_ERROR,
4401 "Failed to set supplicant to pairwise GCMP");
4402 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4403 }
4404 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
4405 sigma_dut_print(dut, DUT_MSG_ERROR,
4406 "Failed to set supplicant to group GCMP");
4407 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4408 }
4409 } else if (val) {
4410 sigma_dut_print(dut, DUT_MSG_ERROR,
4411 "Requested Encrypt %s is not supported on 60 GHz",
4412 val);
4413 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
4414 }
4415
4416 val = get_param(cmd, "PSK");
4417 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
4418 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
4419 val);
4420 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4421 }
4422
4423 /* Convert 60G channel to freq */
4424 switch (dut->ap_channel) {
4425 case 1:
4426 val = "58320";
4427 break;
4428 case 2:
4429 val = "60480";
4430 break;
4431 case 3:
4432 val = "62640";
4433 break;
4434 default:
4435 sigma_dut_print(dut, DUT_MSG_ERROR,
4436 "Failed to configure channel %d. Not supported",
4437 dut->ap_channel);
4438 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4439 }
4440
4441 if (set_network(ifname, net_id, "frequency", val) < 0) {
4442 sigma_dut_print(dut, DUT_MSG_ERROR,
4443 "Failed to set supplicant network frequency");
4444 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4445 }
4446
4447 sigma_dut_print(dut, DUT_MSG_DEBUG,
4448 "Supplicant set network with frequency");
4449
4450 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
4451 if (wpa_command(ifname, buf) < 0) {
4452 sigma_dut_print(dut, DUT_MSG_INFO,
4453 "Failed to select network id %d on %s",
4454 net_id, ifname);
4455 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4456 }
4457
4458 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
4459
4460 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
4461}
4462
4463
Lior David67543f52017-01-03 19:04:22 +02004464static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
4465{
4466 char buf[128], fname[128];
4467 FILE *f;
4468
4469 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
4470 sigma_dut_print(dut, DUT_MSG_ERROR,
4471 "failed to get wil6210 debugfs dir");
4472 return -1;
4473 }
4474
4475 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
4476 f = fopen(fname, "w");
4477 if (!f) {
4478 sigma_dut_print(dut, DUT_MSG_ERROR,
4479 "failed to open: %s", fname);
4480 return -1;
4481 }
4482
4483 fprintf(f, "%d\n", abft_len);
4484 fclose(f);
4485
4486 return 0;
4487}
4488
4489
4490static int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
4491 int abft_len)
4492{
4493 switch (get_driver_type()) {
4494 case DRIVER_WIL6210:
4495 return wil6210_set_abft_len(dut, abft_len);
4496 default:
4497 sigma_dut_print(dut, DUT_MSG_ERROR,
4498 "set abft_len not supported");
4499 return -1;
4500 }
4501}
4502
4503
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004504static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
4505 struct sigma_cmd *cmd)
4506{
4507 const char *val;
Lior David67543f52017-01-03 19:04:22 +02004508 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004509
4510 if (dut->dev_role != DEVROLE_PCP) {
4511 send_resp(dut, conn, SIGMA_INVALID,
4512 "ErrorCode,Invalid DevRole");
4513 return 0;
4514 }
4515
4516 val = get_param(cmd, "SSID");
4517 if (val) {
4518 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
4519 send_resp(dut, conn, SIGMA_INVALID,
4520 "ErrorCode,Invalid SSID");
4521 return -1;
4522 }
4523
Peng Xub8fc5cc2017-05-10 17:27:28 -07004524 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004525 }
4526
4527 val = get_param(cmd, "CHANNEL");
4528 if (val) {
4529 const char *pos;
4530
4531 dut->ap_channel = atoi(val);
4532 pos = strchr(val, ';');
4533 if (pos) {
4534 pos++;
4535 dut->ap_channel_1 = atoi(pos);
4536 }
4537 }
4538
4539 switch (dut->ap_channel) {
4540 case 1:
4541 case 2:
4542 case 3:
4543 break;
4544 default:
4545 sigma_dut_print(dut, DUT_MSG_ERROR,
4546 "Channel %d is not supported", dut->ap_channel);
4547 send_resp(dut, conn, SIGMA_ERROR,
4548 "Requested channel is not supported");
4549 return -1;
4550 }
4551
4552 val = get_param(cmd, "BCNINT");
4553 if (val)
4554 dut->ap_bcnint = atoi(val);
4555
4556
4557 val = get_param(cmd, "ExtSchIE");
4558 if (val) {
4559 send_resp(dut, conn, SIGMA_ERROR,
4560 "ErrorCode,ExtSchIE is not supported yet");
4561 return -1;
4562 }
4563
4564 val = get_param(cmd, "AllocType");
4565 if (val) {
4566 send_resp(dut, conn, SIGMA_ERROR,
4567 "ErrorCode,AllocType is not supported yet");
4568 return -1;
4569 }
4570
4571 val = get_param(cmd, "PercentBI");
4572 if (val) {
4573 send_resp(dut, conn, SIGMA_ERROR,
4574 "ErrorCode,PercentBI is not supported yet");
4575 return -1;
4576 }
4577
4578 val = get_param(cmd, "CBAPOnly");
4579 if (val) {
4580 send_resp(dut, conn, SIGMA_ERROR,
4581 "ErrorCode,CBAPOnly is not supported yet");
4582 return -1;
4583 }
4584
4585 val = get_param(cmd, "AMPDU");
4586 if (val) {
4587 if (strcasecmp(val, "Enable") == 0)
4588 dut->ap_ampdu = 1;
4589 else if (strcasecmp(val, "Disable") == 0)
4590 dut->ap_ampdu = 2;
4591 else {
4592 send_resp(dut, conn, SIGMA_ERROR,
4593 "ErrorCode,AMPDU value is not Enable nor Disabled");
4594 return -1;
4595 }
4596 }
4597
4598 val = get_param(cmd, "AMSDU");
4599 if (val) {
4600 if (strcasecmp(val, "Enable") == 0)
4601 dut->ap_amsdu = 1;
4602 else if (strcasecmp(val, "Disable") == 0)
4603 dut->ap_amsdu = 2;
4604 }
4605
4606 val = get_param(cmd, "NumMSDU");
4607 if (val) {
4608 send_resp(dut, conn, SIGMA_ERROR,
4609 "ErrorCode, NumMSDU is not supported yet");
4610 return -1;
4611 }
4612
4613 val = get_param(cmd, "ABFTLRang");
4614 if (val) {
4615 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02004616 "ABFTLRang parameter %s", val);
4617 if (strcmp(val, "Gt1") == 0)
4618 abft_len = 2; /* 2 slots in this case */
4619 }
4620
4621 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
4622 send_resp(dut, conn, SIGMA_ERROR,
4623 "ErrorCode, Can't set ABFT length");
4624 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004625 }
4626
4627 if (sta_pcp_start(dut, conn, cmd) < 0) {
4628 send_resp(dut, conn, SIGMA_ERROR,
4629 "ErrorCode, Can't start PCP role");
4630 return -1;
4631 }
4632
4633 return sta_set_60g_common(dut, conn, cmd);
4634}
4635
4636
4637static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
4638 struct sigma_cmd *cmd)
4639{
4640 const char *val = get_param(cmd, "DiscoveryMode");
4641
4642 if (dut->dev_role != DEVROLE_STA) {
4643 send_resp(dut, conn, SIGMA_INVALID,
4644 "ErrorCode,Invalid DevRole");
4645 return 0;
4646 }
4647
4648 if (val) {
4649 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
4650 /* Ignore Discovery mode till Driver expose API. */
4651#if 0
4652 if (strcasecmp(val, "1") == 0) {
4653 send_resp(dut, conn, SIGMA_INVALID,
4654 "ErrorCode,DiscoveryMode 1 not supported");
4655 return 0;
4656 }
4657
4658 if (strcasecmp(val, "0") == 0) {
4659 /* OK */
4660 } else {
4661 send_resp(dut, conn, SIGMA_INVALID,
4662 "ErrorCode,DiscoveryMode not supported");
4663 return 0;
4664 }
4665#endif
4666 }
4667
4668 if (start_sta_mode(dut) != 0)
4669 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4670 return sta_set_60g_common(dut, conn, cmd);
4671}
4672
4673
4674static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
4675 struct sigma_cmd *cmd)
4676{
4677 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02004678 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05304679
Jouni Malinened77e672018-01-10 16:45:13 +02004680 if (dut->program == PROGRAM_OCE ||
4681 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05304682 wpa_command(intf, "DISCONNECT");
4683 return 1;
4684 }
4685
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004686 disconnect_station(dut);
4687 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
4688 * due to cached results. */
4689 wpa_command(intf, "SET ignore_old_scan_res 1");
4690 wpa_command(intf, "BSS_FLUSH");
4691 return 1;
4692}
4693
4694
4695static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
4696 struct sigma_cmd *cmd)
4697{
4698 const char *intf = get_param(cmd, "Interface");
4699 const char *bssid = get_param(cmd, "bssid");
4700 const char *val = get_param(cmd, "CHANNEL");
4701 struct wpa_ctrl *ctrl;
4702 char buf[100];
4703 int res;
4704 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05304705 int status = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004706
4707 if (bssid == NULL) {
4708 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
4709 "argument");
4710 return 0;
4711 }
4712
4713 if (val)
4714 chan = atoi(val);
4715
4716 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
4717 /* The current network may be from sta_associate or
4718 * sta_hs2_associate
4719 */
4720 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
4721 0 ||
4722 set_network(intf, 0, "bssid", bssid) < 0)
4723 return -2;
4724 }
4725
4726 ctrl = open_wpa_mon(intf);
4727 if (ctrl == NULL) {
4728 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
4729 "wpa_supplicant monitor connection");
4730 return -1;
4731 }
4732
4733 if (wifi_chip_type == DRIVER_WCN) {
4734#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05304735 if (chan) {
4736 unsigned int freq;
4737
4738 freq = channel_to_freq(chan);
4739 if (!freq) {
4740 sigma_dut_print(dut, DUT_MSG_ERROR,
4741 "Invalid channel number provided: %d",
4742 chan);
4743 send_resp(dut, conn, SIGMA_INVALID,
4744 "ErrorCode,Invalid channel number");
4745 goto close_mon_conn;
4746 }
4747 res = snprintf(buf, sizeof(buf),
4748 "SCAN TYPE=ONLY freq=%d", freq);
4749 } else {
4750 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
4751 }
4752 if (res < 0 || res >= (int) sizeof(buf)) {
4753 send_resp(dut, conn, SIGMA_ERROR,
4754 "ErrorCode,snprintf failed");
4755 goto close_mon_conn;
4756 }
4757 if (wpa_command(intf, buf) < 0) {
4758 sigma_dut_print(dut, DUT_MSG_INFO,
4759 "Failed to start scan");
4760 send_resp(dut, conn, SIGMA_ERROR,
4761 "ErrorCode,scan failed");
4762 goto close_mon_conn;
4763 }
4764
4765 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
4766 buf, sizeof(buf));
4767 if (res < 0) {
4768 sigma_dut_print(dut, DUT_MSG_INFO,
4769 "Scan did not complete");
4770 send_resp(dut, conn, SIGMA_ERROR,
4771 "ErrorCode,scan did not complete");
4772 goto close_mon_conn;
4773 }
4774
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004775 if (set_network(intf, dut->infra_network_id, "bssid", "any")
4776 < 0) {
4777 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
4778 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05304779 status = -2;
4780 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004781 }
4782 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
4783 bssid, chan);
4784 if (res > 0 && res < (int) sizeof(buf))
4785 res = wpa_command(intf, buf);
4786
4787 if (res < 0 || res >= (int) sizeof(buf)) {
4788 send_resp(dut, conn, SIGMA_ERROR,
4789 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05304790 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004791 }
4792#else /* ANDROID */
4793 sigma_dut_print(dut, DUT_MSG_DEBUG,
4794 "Reassoc using iwpriv - skip chan=%d info",
4795 chan);
4796 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
4797 if (system(buf) != 0) {
4798 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05304799 status = -2;
4800 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004801 }
4802#endif /* ANDROID */
4803 sigma_dut_print(dut, DUT_MSG_INFO,
4804 "sta_reassoc: Run %s successful", buf);
4805 } else if (wpa_command(intf, "REASSOCIATE")) {
4806 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
4807 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05304808 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004809 }
4810
4811 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
4812 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05304813 if (res < 0) {
4814 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
4815 status = -1;
4816 goto close_mon_conn;
4817 }
4818 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004819
Ashwini Patil467efef2017-05-25 12:18:27 +05304820close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004821 wpa_ctrl_detach(ctrl);
4822 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05304823 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004824}
4825
4826
4827static void hs2_clear_credentials(const char *intf)
4828{
4829 wpa_command(intf, "REMOVE_CRED all");
4830}
4831
4832
Lior Davidcc88b562017-01-03 18:52:09 +02004833#ifdef __linux__
4834static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
4835 unsigned int *aid)
4836{
Lior David0fe101e2017-03-09 16:09:50 +02004837 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02004838
Lior David0fe101e2017-03-09 16:09:50 +02004839 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02004840}
4841#endif /* __linux__ */
4842
4843
4844static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
4845 unsigned int *aid)
4846{
4847 switch (get_driver_type()) {
4848#ifdef __linux__
4849 case DRIVER_WIL6210:
4850 return wil6210_get_aid(dut, bssid, aid);
4851#endif /* __linux__ */
4852 default:
4853 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
4854 return -1;
4855 }
4856}
4857
4858
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004859static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
4860 struct sigma_cmd *cmd)
4861{
4862 char buf[MAX_CMD_LEN];
4863 char bss_list[MAX_CMD_LEN];
4864 const char *parameter = get_param(cmd, "Parameter");
4865
4866 if (parameter == NULL)
4867 return -1;
4868
Lior Davidcc88b562017-01-03 18:52:09 +02004869 if (strcasecmp(parameter, "AID") == 0) {
4870 unsigned int aid = 0;
4871 char bssid[20];
4872
4873 if (get_wpa_status(get_station_ifname(), "bssid",
4874 bssid, sizeof(bssid)) < 0) {
4875 sigma_dut_print(dut, DUT_MSG_ERROR,
4876 "could not get bssid");
4877 return -2;
4878 }
4879
4880 if (sta_get_aid_60g(dut, bssid, &aid))
4881 return -2;
4882
4883 snprintf(buf, sizeof(buf), "aid,%d", aid);
4884 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
4885 send_resp(dut, conn, SIGMA_COMPLETE, buf);
4886 return 0;
4887 }
4888
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004889 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
4890 char *bss_line;
4891 char *bss_id = NULL;
4892 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304893 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004894
4895 if (ifname == NULL) {
4896 sigma_dut_print(dut, DUT_MSG_INFO,
4897 "For get DiscoveredDevList need Interface name.");
4898 return -1;
4899 }
4900
4901 /*
4902 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
4903 * of BSSIDs in "bssid=<BSSID>\n"
4904 */
4905 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
4906 bss_list,
4907 sizeof(bss_list)) < 0) {
4908 sigma_dut_print(dut, DUT_MSG_ERROR,
4909 "Failed to get bss list");
4910 return -1;
4911 }
4912
4913 sigma_dut_print(dut, DUT_MSG_DEBUG,
4914 "bss list for ifname:%s is:%s",
4915 ifname, bss_list);
4916
4917 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304918 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004919 while (bss_line) {
4920 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
4921 bss_id) {
4922 int len;
4923
4924 len = snprintf(buf + strlen(buf),
4925 sizeof(buf) - strlen(buf),
4926 ",%s", bss_id);
4927 free(bss_id);
4928 bss_id = NULL;
4929 if (len < 0) {
4930 sigma_dut_print(dut,
4931 DUT_MSG_ERROR,
4932 "Failed to read BSSID");
4933 send_resp(dut, conn, SIGMA_ERROR,
4934 "ErrorCode,Failed to read BSS ID");
4935 return 0;
4936 }
4937
4938 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
4939 sigma_dut_print(dut,
4940 DUT_MSG_ERROR,
4941 "Response buf too small for list");
4942 send_resp(dut, conn,
4943 SIGMA_ERROR,
4944 "ErrorCode,Response buf too small for list");
4945 return 0;
4946 }
4947 }
4948
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304949 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004950 }
4951
4952 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
4953 buf);
4954 send_resp(dut, conn, SIGMA_COMPLETE, buf);
4955 return 0;
4956 }
4957
4958 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
4959 return 0;
4960}
4961
4962
4963static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
4964 struct sigma_cmd *cmd)
4965{
4966 const char *program = get_param(cmd, "Program");
4967
4968 if (program == NULL)
4969 return -1;
4970
4971 if (strcasecmp(program, "P2PNFC") == 0)
4972 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
4973
4974 if (strcasecmp(program, "60ghz") == 0)
4975 return sta_get_parameter_60g(dut, conn, cmd);
4976
4977#ifdef ANDROID_NAN
4978 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07004979 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004980#endif /* ANDROID_NAN */
4981
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004982#ifdef MIRACAST
4983 if (strcasecmp(program, "WFD") == 0 ||
4984 strcasecmp(program, "DisplayR2") == 0)
4985 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
4986#endif /* MIRACAST */
4987
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004988 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
4989 return 0;
4990}
4991
4992
4993static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
4994 const char *type)
4995{
4996 char buf[100];
4997
4998 if (dut->program == PROGRAM_VHT) {
4999 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5000 if (system(buf) != 0) {
5001 sigma_dut_print(dut, DUT_MSG_ERROR,
5002 "iwpriv %s chwidth failed", intf);
5003 }
5004
5005 snprintf(buf, sizeof(buf), "iwpriv %s mode 11ACVHT80", intf);
5006 if (system(buf) != 0) {
5007 sigma_dut_print(dut, DUT_MSG_ERROR,
5008 "iwpriv %s mode 11ACVHT80 failed",
5009 intf);
5010 }
5011
5012 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs -1", intf);
5013 if (system(buf) != 0) {
5014 sigma_dut_print(dut, DUT_MSG_ERROR,
5015 "iwpriv %s vhtmcs -1 failed", intf);
5016 }
5017 }
5018
5019 if (dut->program == PROGRAM_HT) {
5020 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5021 if (system(buf) != 0) {
5022 sigma_dut_print(dut, DUT_MSG_ERROR,
5023 "iwpriv %s chwidth failed", intf);
5024 }
5025
5026 snprintf(buf, sizeof(buf), "iwpriv %s mode 11naht40", intf);
5027 if (system(buf) != 0) {
5028 sigma_dut_print(dut, DUT_MSG_ERROR,
5029 "iwpriv %s mode 11naht40 failed",
5030 intf);
5031 }
5032
5033 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0", intf);
5034 if (system(buf) != 0) {
5035 sigma_dut_print(dut, DUT_MSG_ERROR,
5036 "iwpriv set11NRates failed");
5037 }
5038 }
5039
5040 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
5041 snprintf(buf, sizeof(buf), "iwpriv %s powersave 0", intf);
5042 if (system(buf) != 0) {
5043 sigma_dut_print(dut, DUT_MSG_ERROR,
5044 "disabling powersave failed");
5045 }
5046
5047 /* Reset CTS width */
5048 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
5049 intf);
5050 if (system(buf) != 0) {
5051 sigma_dut_print(dut, DUT_MSG_ERROR,
5052 "wifitool %s beeliner_fw_test 54 0 failed",
5053 intf);
5054 }
5055
5056 /* Enable Dynamic Bandwidth signalling by default */
5057 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", intf);
5058 if (system(buf) != 0) {
5059 sigma_dut_print(dut, DUT_MSG_ERROR,
5060 "iwpriv %s cwmenable 1 failed", intf);
5061 }
5062
5063 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
5064 if (system(buf) != 0) {
5065 sigma_dut_print(dut, DUT_MSG_ERROR,
5066 "iwpriv rts failed");
5067 }
5068 }
5069
5070 if (type && strcasecmp(type, "Testbed") == 0) {
5071 dut->testbed_flag_txsp = 1;
5072 dut->testbed_flag_rxsp = 1;
5073 /* STA has to set spatial stream to 2 per Appendix H */
5074 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0xfff0", intf);
5075 if (system(buf) != 0) {
5076 sigma_dut_print(dut, DUT_MSG_ERROR,
5077 "iwpriv vht_mcsmap failed");
5078 }
5079
5080 /* Disable LDPC per Appendix H */
5081 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", intf);
5082 if (system(buf) != 0) {
5083 sigma_dut_print(dut, DUT_MSG_ERROR,
5084 "iwpriv %s ldpc 0 failed", intf);
5085 }
5086
5087 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5088 if (system(buf) != 0) {
5089 sigma_dut_print(dut, DUT_MSG_ERROR,
5090 "iwpriv amsdu failed");
5091 }
5092
5093 /* TODO: Disable STBC 2x1 transmit and receive */
5094 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", intf);
5095 if (system(buf) != 0) {
5096 sigma_dut_print(dut, DUT_MSG_ERROR,
5097 "Disable tx_stbc 0 failed");
5098 }
5099
5100 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc 0", intf);
5101 if (system(buf) != 0) {
5102 sigma_dut_print(dut, DUT_MSG_ERROR,
5103 "Disable rx_stbc 0 failed");
5104 }
5105
5106 /* STA has to disable Short GI per Appendix H */
5107 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 0", intf);
5108 if (system(buf) != 0) {
5109 sigma_dut_print(dut, DUT_MSG_ERROR,
5110 "iwpriv %s shortgi 0 failed", intf);
5111 }
5112 }
5113
5114 if (type && strcasecmp(type, "DUT") == 0) {
5115 snprintf(buf, sizeof(buf), "iwpriv %s nss 3", intf);
5116 if (system(buf) != 0) {
5117 sigma_dut_print(dut, DUT_MSG_ERROR,
5118 "iwpriv %s nss 3 failed", intf);
5119 }
5120
5121 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 1", intf);
5122 if (system(buf) != 0) {
5123 sigma_dut_print(dut, DUT_MSG_ERROR,
5124 "iwpriv %s shortgi 1 failed", intf);
5125 }
5126 }
5127}
5128
5129
Sunil Dutt076081f2018-02-05 19:45:50 +05305130#ifdef NL80211_SUPPORT
5131static int sta_config_rsnie(struct sigma_dut *dut, int val)
5132{
5133 struct nl_msg *msg;
5134 int ret;
5135 struct nlattr *params;
5136 int ifindex;
5137
5138 ifindex = if_nametoindex("wlan0");
5139 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5140 NL80211_CMD_VENDOR)) ||
5141 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5142 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5143 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5144 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
5145 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5146 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
5147 sigma_dut_print(dut, DUT_MSG_ERROR,
5148 "%s: err in adding vendor_cmd and vendor_data",
5149 __func__);
5150 nlmsg_free(msg);
5151 return -1;
5152 }
5153 nla_nest_end(msg, params);
5154
5155 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5156 if (ret) {
5157 sigma_dut_print(dut, DUT_MSG_ERROR,
5158 "%s: err in send_and_recv_msgs, ret=%d",
5159 __func__, ret);
5160 return ret;
5161 }
5162
5163 return 0;
5164}
5165#endif /* NL80211_SUPPORT */
5166
5167
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005168static int cmd_sta_reset_default(struct sigma_dut *dut,
5169 struct sigma_conn *conn,
5170 struct sigma_cmd *cmd)
5171{
5172 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
5173 struct sigma_cmd *cmd);
5174 const char *intf = get_param(cmd, "Interface");
5175 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005176 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05305177 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005178
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005179 if (!program)
5180 program = get_param(cmd, "prog");
5181 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005182 dut->device_type = STA_unknown;
5183 type = get_param(cmd, "type");
5184 if (type && strcasecmp(type, "Testbed") == 0)
5185 dut->device_type = STA_testbed;
5186 if (type && strcasecmp(type, "DUT") == 0)
5187 dut->device_type = STA_dut;
5188
5189 if (dut->program == PROGRAM_TDLS) {
5190 /* Clear TDLS testing mode */
5191 wpa_command(intf, "SET tdls_disabled 0");
5192 wpa_command(intf, "SET tdls_testing 0");
5193 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05305194 if (get_driver_type() == DRIVER_WCN) {
5195 /* Enable the WCN driver in TDLS Explicit trigger mode
5196 */
5197 wpa_command(intf, "SET tdls_external_control 0");
5198 wpa_command(intf, "SET tdls_trigger_control 0");
5199 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005200 }
5201
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005202#ifdef MIRACAST
5203 if (dut->program == PROGRAM_WFD ||
5204 dut->program == PROGRAM_DISPLAYR2)
5205 miracast_sta_reset_default(dut, conn, cmd);
5206#endif /* MIRACAST */
5207
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005208 switch (get_driver_type()) {
5209 case DRIVER_ATHEROS:
5210 sta_reset_default_ath(dut, intf, type);
5211 break;
5212 default:
5213 break;
5214 }
5215
5216#ifdef ANDROID_NAN
5217 if (dut->program == PROGRAM_NAN)
5218 nan_cmd_sta_reset_default(dut, conn, cmd);
5219#endif /* ANDROID_NAN */
5220
5221 if (dut->program == PROGRAM_HS2_R2) {
5222 unlink("SP/wi-fi.org/pps.xml");
5223 if (system("rm -r SP/*") != 0) {
5224 }
5225 unlink("next-client-cert.pem");
5226 unlink("next-client-key.pem");
5227 }
5228
5229 if (dut->program == PROGRAM_60GHZ) {
5230 const char *dev_role = get_param(cmd, "DevRole");
5231
5232 if (!dev_role) {
5233 send_resp(dut, conn, SIGMA_ERROR,
5234 "errorCode,Missing DevRole argument");
5235 return 0;
5236 }
5237
5238 if (strcasecmp(dev_role, "STA") == 0)
5239 dut->dev_role = DEVROLE_STA;
5240 else if (strcasecmp(dev_role, "PCP") == 0)
5241 dut->dev_role = DEVROLE_PCP;
5242 else {
5243 send_resp(dut, conn, SIGMA_ERROR,
5244 "errorCode,Unknown DevRole");
5245 return 0;
5246 }
5247
5248 if (dut->device_type == STA_unknown) {
5249 sigma_dut_print(dut, DUT_MSG_ERROR,
5250 "Device type is not STA testbed or DUT");
5251 send_resp(dut, conn, SIGMA_ERROR,
5252 "errorCode,Unknown device type");
5253 return 0;
5254 }
5255 }
5256
5257 wpa_command(intf, "WPS_ER_STOP");
5258 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05305259 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005260 wpa_command(intf, "SET radio_disabled 0");
5261
5262 if (dut->tmp_mac_addr && dut->set_macaddr) {
5263 dut->tmp_mac_addr = 0;
5264 if (system(dut->set_macaddr) != 0) {
5265 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
5266 "temporary MAC address");
5267 }
5268 }
5269
5270 set_ps(intf, dut, 0);
5271
5272 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2) {
5273 wpa_command(intf, "SET interworking 1");
5274 wpa_command(intf, "SET hs20 1");
5275 }
5276
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08005277 if (dut->program == PROGRAM_HS2_R2 ||
5278 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005279 wpa_command(intf, "SET pmf 1");
5280 } else {
5281 wpa_command(intf, "SET pmf 0");
5282 }
5283
5284 hs2_clear_credentials(intf);
5285 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
5286 wpa_command(intf, "SET access_network_type 15");
5287
5288 static_ip_file(0, NULL, NULL, NULL);
5289 kill_dhcp_client(dut, intf);
5290 clear_ip_addr(dut, intf);
5291
5292 dut->er_oper_performed = 0;
5293 dut->er_oper_bssid[0] = '\0';
5294
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07005295 if (dut->program == PROGRAM_LOC) {
5296 /* Disable Interworking by default */
5297 wpa_command(get_station_ifname(), "SET interworking 0");
5298 }
5299
Ashwini Patil00402582017-04-13 12:29:39 +05305300 if (dut->program == PROGRAM_MBO) {
5301 free(dut->non_pref_ch_list);
5302 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05305303 free(dut->btm_query_cand_list);
5304 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05305305 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05305306 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05305307 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05305308 wpa_command(intf, "SET roaming 1");
Ashwini Patil00402582017-04-13 12:29:39 +05305309 }
5310
Jouni Malinen3c367e82017-06-23 17:01:47 +03005311 free(dut->rsne_override);
5312 dut->rsne_override = NULL;
5313
Jouni Malinen68143132017-09-02 02:34:08 +03005314 free(dut->sae_commit_override);
5315 dut->sae_commit_override = NULL;
5316
Jouni Malinend86e5822017-08-29 03:55:32 +03005317 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02005318 free(dut->dpp_peer_uri);
5319 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02005320 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02005321 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03005322
Jouni Malinenfac9cad2017-10-10 18:35:55 +03005323 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
5324
vamsi krishnaa2799492017-12-05 14:28:01 +05305325 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305326 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05305327 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305328 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
5329 dut->fils_hlp = 0;
5330#ifdef ANDROID
5331 hlp_thread_cleanup(dut);
5332#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05305333 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305334
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05305335 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
5336 dut->dev_role = DEVROLE_STA_CFON;
5337 return sta_cfon_reset_default(dut, conn, cmd);
5338 }
5339
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08005340 if (dut->program != PROGRAM_VHT)
5341 return cmd_sta_p2p_reset(dut, conn, cmd);
Sunil Dutt076081f2018-02-05 19:45:50 +05305342
5343#ifdef NL80211_SUPPORT
5344 if (get_driver_type() == DRIVER_WCN) {
5345 if (dut->program == PROGRAM_WPA3 &&
5346 dut->device_type == STA_testbed) {
5347 sta_config_rsnie(dut, 1);
5348 dut->config_rsnie = 1;
5349 } else if (dut->config_rsnie == 1) {
5350 dut->config_rsnie = 0;
5351 sta_config_rsnie(dut, 0);
5352 }
5353 }
5354#endif /* NL80211_SUPPORT */
5355
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08005356 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005357}
5358
5359
5360static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
5361 struct sigma_cmd *cmd)
5362{
5363 const char *program = get_param(cmd, "Program");
5364
5365 if (program == NULL)
5366 return -1;
5367#ifdef ANDROID_NAN
5368 if (strcasecmp(program, "NAN") == 0)
5369 return nan_cmd_sta_get_events(dut, conn, cmd);
5370#endif /* ANDROID_NAN */
5371 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5372 return 0;
5373}
5374
5375
5376static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
5377 struct sigma_cmd *cmd)
5378{
5379 const char *program = get_param(cmd, "Prog");
5380
5381 if (program == NULL)
5382 return -1;
5383#ifdef ANDROID_NAN
5384 if (strcasecmp(program, "NAN") == 0)
5385 return nan_cmd_sta_exec_action(dut, conn, cmd);
5386#endif /* ANDROID_NAN */
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005387 if (strcasecmp(program, "Loc") == 0)
5388 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005389 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5390 return 0;
5391}
5392
5393
5394static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
5395 struct sigma_cmd *cmd)
5396{
5397 const char *intf = get_param(cmd, "Interface");
5398 const char *val, *mcs32, *rate;
5399
5400 val = get_param(cmd, "GREENFIELD");
5401 if (val) {
5402 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5403 /* Enable GD */
5404 send_resp(dut, conn, SIGMA_ERROR,
5405 "ErrorCode,GF not supported");
5406 return 0;
5407 }
5408 }
5409
5410 val = get_param(cmd, "SGI20");
5411 if (val) {
5412 switch (get_driver_type()) {
5413 case DRIVER_ATHEROS:
5414 ath_sta_set_sgi(dut, intf, val);
5415 break;
5416 default:
5417 send_resp(dut, conn, SIGMA_ERROR,
5418 "ErrorCode,SGI20 not supported");
5419 return 0;
5420 }
5421 }
5422
5423 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
5424 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
5425 if (mcs32 && rate) {
5426 /* TODO */
5427 send_resp(dut, conn, SIGMA_ERROR,
5428 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
5429 return 0;
5430 } else if (mcs32 && !rate) {
5431 /* TODO */
5432 send_resp(dut, conn, SIGMA_ERROR,
5433 "ErrorCode,MCS32 not supported");
5434 return 0;
5435 } else if (!mcs32 && rate) {
5436 switch (get_driver_type()) {
5437 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005438 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005439 ath_sta_set_11nrates(dut, intf, rate);
5440 break;
5441 default:
5442 send_resp(dut, conn, SIGMA_ERROR,
5443 "ErrorCode,MCS32_FIXEDRATE not supported");
5444 return 0;
5445 }
5446 }
5447
5448 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
5449}
5450
5451
5452static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
5453 struct sigma_conn *conn,
5454 struct sigma_cmd *cmd)
5455{
5456 const char *intf = get_param(cmd, "Interface");
5457 const char *val;
5458 char buf[30];
5459 int tkip = -1;
5460 int wep = -1;
5461
5462 val = get_param(cmd, "SGI80");
5463 if (val) {
5464 int sgi80;
5465
5466 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5467 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi80);
5468 if (system(buf) != 0) {
5469 sigma_dut_print(dut, DUT_MSG_ERROR,
5470 "iwpriv shortgi failed");
5471 }
5472 }
5473
5474 val = get_param(cmd, "TxBF");
5475 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
5476 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 1", intf);
5477 if (system(buf) != 0) {
5478 sigma_dut_print(dut, DUT_MSG_ERROR,
5479 "iwpriv vhtsubfee failed");
5480 }
5481 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 1", intf);
5482 if (system(buf) != 0) {
5483 sigma_dut_print(dut, DUT_MSG_ERROR,
5484 "iwpriv vhtsubfer failed");
5485 }
5486 }
5487
5488 val = get_param(cmd, "MU_TxBF");
5489 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
5490 switch (get_driver_type()) {
5491 case DRIVER_ATHEROS:
5492 ath_sta_set_txsp_stream(dut, intf, "1SS");
5493 ath_sta_set_rxsp_stream(dut, intf, "1SS");
5494 case DRIVER_WCN:
5495 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
5496 send_resp(dut, conn, SIGMA_ERROR,
5497 "ErrorCode,Failed to set RX/TXSP_STREAM");
5498 return 0;
5499 }
5500 default:
5501 sigma_dut_print(dut, DUT_MSG_ERROR,
5502 "Setting SP_STREAM not supported");
5503 break;
5504 }
5505 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 1", intf);
5506 if (system(buf) != 0) {
5507 sigma_dut_print(dut, DUT_MSG_ERROR,
5508 "iwpriv vhtmubfee failed");
5509 }
5510 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 1", intf);
5511 if (system(buf) != 0) {
5512 sigma_dut_print(dut, DUT_MSG_ERROR,
5513 "iwpriv vhtmubfer failed");
5514 }
5515 }
5516
5517 val = get_param(cmd, "LDPC");
5518 if (val) {
5519 int ldpc;
5520
5521 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5522 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, ldpc);
5523 if (system(buf) != 0) {
5524 sigma_dut_print(dut, DUT_MSG_ERROR,
5525 "iwpriv ldpc failed");
5526 }
5527 }
5528
5529 val = get_param(cmd, "opt_md_notif_ie");
5530 if (val) {
5531 char *result = NULL;
5532 char delim[] = ";";
5533 char token[30];
5534 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305535 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005536
Peng Xub8fc5cc2017-05-10 17:27:28 -07005537 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305538 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005539
5540 /* Extract the NSS information */
5541 if (result) {
5542 value = atoi(result);
5543 switch (value) {
5544 case 1:
5545 config_val = 1;
5546 break;
5547 case 2:
5548 config_val = 3;
5549 break;
5550 case 3:
5551 config_val = 7;
5552 break;
5553 case 4:
5554 config_val = 15;
5555 break;
5556 default:
5557 config_val = 3;
5558 break;
5559 }
5560
5561 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
5562 intf, config_val);
5563 if (system(buf) != 0) {
5564 sigma_dut_print(dut, DUT_MSG_ERROR,
5565 "iwpriv rxchainmask failed");
5566 }
5567
5568 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
5569 intf, config_val);
5570 if (system(buf) != 0) {
5571 sigma_dut_print(dut, DUT_MSG_ERROR,
5572 "iwpriv txchainmask failed");
5573 }
5574 }
5575
5576 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305577 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005578 if (result) {
5579 value = atoi(result);
5580 switch (value) {
5581 case 20:
5582 config_val = 0;
5583 break;
5584 case 40:
5585 config_val = 1;
5586 break;
5587 case 80:
5588 config_val = 2;
5589 break;
5590 case 160:
5591 config_val = 3;
5592 break;
5593 default:
5594 config_val = 2;
5595 break;
5596 }
5597
5598 dut->chwidth = config_val;
5599
5600 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
5601 intf, config_val);
5602 if (system(buf) != 0) {
5603 sigma_dut_print(dut, DUT_MSG_ERROR,
5604 "iwpriv chwidth failed");
5605 }
5606 }
5607
5608 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", intf);
5609 if (system(buf) != 0) {
5610 sigma_dut_print(dut, DUT_MSG_ERROR,
5611 "iwpriv opmode_notify failed");
5612 }
5613 }
5614
5615 val = get_param(cmd, "nss_mcs_cap");
5616 if (val) {
5617 int nss, mcs;
5618 char token[20];
5619 char *result = NULL;
5620 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305621 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005622
Peng Xub8fc5cc2017-05-10 17:27:28 -07005623 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305624 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05305625 if (!result) {
5626 sigma_dut_print(dut, DUT_MSG_ERROR,
5627 "VHT NSS not specified");
5628 return 0;
5629 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005630 nss = atoi(result);
5631
5632 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
5633 if (system(buf) != 0) {
5634 sigma_dut_print(dut, DUT_MSG_ERROR,
5635 "iwpriv nss failed");
5636 }
5637
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305638 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005639 if (result == NULL) {
5640 sigma_dut_print(dut, DUT_MSG_ERROR,
5641 "VHTMCS NOT SPECIFIED!");
5642 return 0;
5643 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305644 result = strtok_r(result, "-", &saveptr);
5645 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05305646 if (!result) {
5647 sigma_dut_print(dut, DUT_MSG_ERROR,
5648 "VHT MCS not specified");
5649 return 0;
5650 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005651 mcs = atoi(result);
5652
5653 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d", intf, mcs);
5654 if (system(buf) != 0) {
5655 sigma_dut_print(dut, DUT_MSG_ERROR,
5656 "iwpriv mcs failed");
5657 }
5658
5659 switch (nss) {
5660 case 1:
5661 switch (mcs) {
5662 case 7:
5663 vht_mcsmap = 0xfffc;
5664 break;
5665 case 8:
5666 vht_mcsmap = 0xfffd;
5667 break;
5668 case 9:
5669 vht_mcsmap = 0xfffe;
5670 break;
5671 default:
5672 vht_mcsmap = 0xfffe;
5673 break;
5674 }
5675 break;
5676 case 2:
5677 switch (mcs) {
5678 case 7:
5679 vht_mcsmap = 0xfff0;
5680 break;
5681 case 8:
5682 vht_mcsmap = 0xfff5;
5683 break;
5684 case 9:
5685 vht_mcsmap = 0xfffa;
5686 break;
5687 default:
5688 vht_mcsmap = 0xfffa;
5689 break;
5690 }
5691 break;
5692 case 3:
5693 switch (mcs) {
5694 case 7:
5695 vht_mcsmap = 0xffc0;
5696 break;
5697 case 8:
5698 vht_mcsmap = 0xffd5;
5699 break;
5700 case 9:
5701 vht_mcsmap = 0xffea;
5702 break;
5703 default:
5704 vht_mcsmap = 0xffea;
5705 break;
5706 }
5707 break;
5708 default:
5709 vht_mcsmap = 0xffea;
5710 break;
5711 }
5712 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
5713 intf, vht_mcsmap);
5714 if (system(buf) != 0) {
5715 sigma_dut_print(dut, DUT_MSG_ERROR,
5716 "iwpriv vht_mcsmap failed");
5717 }
5718 }
5719
5720 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
5721
5722 val = get_param(cmd, "Vht_tkip");
5723 if (val)
5724 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5725
5726 val = get_param(cmd, "Vht_wep");
5727 if (val)
5728 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5729
5730 if (tkip != -1 || wep != -1) {
5731 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
5732 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1",
5733 intf);
5734 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
5735 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 0",
5736 intf);
5737 } else {
5738 sigma_dut_print(dut, DUT_MSG_ERROR,
5739 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
5740 return 0;
5741 }
5742
5743 if (system(buf) != 0) {
5744 sigma_dut_print(dut, DUT_MSG_ERROR,
5745 "iwpriv htweptkip failed");
5746 }
5747 }
5748
5749 val = get_param(cmd, "txBandwidth");
5750 if (val) {
5751 switch (get_driver_type()) {
5752 case DRIVER_ATHEROS:
5753 if (ath_set_width(dut, conn, intf, val) < 0) {
5754 send_resp(dut, conn, SIGMA_ERROR,
5755 "ErrorCode,Failed to set txBandwidth");
5756 return 0;
5757 }
5758 break;
5759 default:
5760 sigma_dut_print(dut, DUT_MSG_ERROR,
5761 "Setting txBandwidth not supported");
5762 break;
5763 }
5764 }
5765
5766 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
5767}
5768
5769
5770static int sta_set_wireless_60g(struct sigma_dut *dut,
5771 struct sigma_conn *conn,
5772 struct sigma_cmd *cmd)
5773{
5774 const char *dev_role = get_param(cmd, "DevRole");
5775
5776 if (!dev_role) {
5777 send_resp(dut, conn, SIGMA_INVALID,
5778 "ErrorCode,DevRole not specified");
5779 return 0;
5780 }
5781
5782 if (strcasecmp(dev_role, "PCP") == 0)
5783 return sta_set_60g_pcp(dut, conn, cmd);
5784 if (strcasecmp(dev_role, "STA") == 0)
5785 return sta_set_60g_sta(dut, conn, cmd);
5786 send_resp(dut, conn, SIGMA_INVALID,
5787 "ErrorCode,DevRole not supported");
5788 return 0;
5789}
5790
5791
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05305792static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
5793 struct sigma_cmd *cmd)
5794{
5795 int status;
5796 const char *intf = get_param(cmd, "Interface");
5797 const char *val = get_param(cmd, "DevRole");
5798
5799 if (val && strcasecmp(val, "STA-CFON") == 0) {
5800 status = sta_cfon_set_wireless(dut, conn, cmd);
5801 if (status)
5802 return status;
5803 }
5804 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
5805}
5806
5807
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005808static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
5809 struct sigma_cmd *cmd)
5810{
5811 const char *val;
5812
5813 val = get_param(cmd, "Program");
5814 if (val) {
5815 if (strcasecmp(val, "11n") == 0)
5816 return cmd_sta_set_11n(dut, conn, cmd);
5817 if (strcasecmp(val, "VHT") == 0)
5818 return cmd_sta_set_wireless_vht(dut, conn, cmd);
5819 if (strcasecmp(val, "60ghz") == 0)
5820 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05305821 if (strcasecmp(val, "OCE") == 0)
5822 return sta_set_wireless_oce(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005823 send_resp(dut, conn, SIGMA_ERROR,
5824 "ErrorCode,Program value not supported");
5825 } else {
5826 send_resp(dut, conn, SIGMA_ERROR,
5827 "ErrorCode,Program argument not available");
5828 }
5829
5830 return 0;
5831}
5832
5833
5834static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
5835 int tid)
5836{
5837 char buf[100];
5838 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
5839
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05305840 if (tid < 0 ||
5841 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
5842 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
5843 return;
5844 }
5845
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005846 /*
5847 * Two ways to ensure that addba request with a
5848 * non zero TID could be sent out. EV 117296
5849 */
5850 snprintf(buf, sizeof(buf),
5851 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
5852 tid);
5853 if (system(buf) != 0) {
5854 sigma_dut_print(dut, DUT_MSG_ERROR,
5855 "Ping did not send out");
5856 }
5857
5858 snprintf(buf, sizeof(buf),
5859 "iwconfig %s | grep Access | awk '{print $6}' > %s",
5860 intf, VI_QOS_TMP_FILE);
5861 if (system(buf) != 0)
5862 return;
5863
5864 snprintf(buf, sizeof(buf),
5865 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
5866 intf, VI_QOS_TMP_FILE);
5867 if (system(buf) != 0)
5868 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
5869
5870 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
5871 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
5872 if (system(buf) != 0) {
5873 sigma_dut_print(dut, DUT_MSG_ERROR,
5874 "VI_QOS_TEMP_FILE generation error failed");
5875 }
5876 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
5877 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
5878 if (system(buf) != 0) {
5879 sigma_dut_print(dut, DUT_MSG_ERROR,
5880 "VI_QOS_FILE generation failed");
5881 }
5882
5883 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
5884 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
5885 if (system(buf) != 0) {
5886 sigma_dut_print(dut, DUT_MSG_ERROR,
5887 "VI_QOS_FILE generation failed");
5888 }
5889
5890 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
5891 if (system(buf) != 0) {
5892 }
5893}
5894
5895
5896static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
5897 struct sigma_cmd *cmd)
5898{
5899 const char *intf = get_param(cmd, "Interface");
5900 const char *val;
5901 int tid = 0;
5902 char buf[100];
5903
5904 val = get_param(cmd, "TID");
5905 if (val) {
5906 tid = atoi(val);
5907 if (tid)
5908 ath_sta_inject_frame(dut, intf, tid);
5909 }
5910
5911 /* Command sequence for ADDBA request on Peregrine based devices */
5912 snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", intf);
5913 if (system(buf) != 0) {
5914 sigma_dut_print(dut, DUT_MSG_ERROR,
5915 "iwpriv setaddbaoper failed");
5916 }
5917
5918 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
5919 if (system(buf) != 0) {
5920 sigma_dut_print(dut, DUT_MSG_ERROR,
5921 "wifitool senddelba failed");
5922 }
5923
5924 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
5925 if (system(buf) != 0) {
5926 sigma_dut_print(dut, DUT_MSG_ERROR,
5927 "wifitool sendaddba failed");
5928 }
5929
5930 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
5931
5932 return 1;
5933}
5934
5935
Lior David9981b512017-01-20 13:16:40 +02005936#ifdef __linux__
5937
5938static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
5939 int agg_size)
5940{
5941 char dir[128], buf[128];
5942 FILE *f;
5943 regex_t re;
5944 regmatch_t m[2];
5945 int rc, ret = -1, vring_id, found;
5946
5947 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
5948 sigma_dut_print(dut, DUT_MSG_ERROR,
5949 "failed to get wil6210 debugfs dir");
5950 return -1;
5951 }
5952
5953 snprintf(buf, sizeof(buf), "%s/vrings", dir);
5954 f = fopen(buf, "r");
5955 if (!f) {
5956 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
5957 return -1;
5958 }
5959
5960 if (regcomp(&re, "VRING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
5961 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
5962 goto out;
5963 }
5964
5965 /* find TX VRING for the mac address */
5966 found = 0;
5967 while (fgets(buf, sizeof(buf), f)) {
5968 if (strcasestr(buf, dest_mac)) {
5969 found = 1;
5970 break;
5971 }
5972 }
5973
5974 if (!found) {
5975 sigma_dut_print(dut, DUT_MSG_ERROR,
5976 "no TX VRING for %s", dest_mac);
5977 goto out;
5978 }
5979
5980 /* extract VRING ID, "VRING tx_<id> = {" */
5981 if (!fgets(buf, sizeof(buf), f)) {
5982 sigma_dut_print(dut, DUT_MSG_ERROR,
5983 "no VRING start line for %s", dest_mac);
5984 goto out;
5985 }
5986
5987 rc = regexec(&re, buf, 2, m, 0);
5988 regfree(&re);
5989 if (rc || m[1].rm_so < 0) {
5990 sigma_dut_print(dut, DUT_MSG_ERROR,
5991 "no VRING TX ID for %s", dest_mac);
5992 goto out;
5993 }
5994 buf[m[1].rm_eo] = 0;
5995 vring_id = atoi(&buf[m[1].rm_so]);
5996
5997 /* send the addba command */
5998 fclose(f);
5999 snprintf(buf, sizeof(buf), "%s/back", dir);
6000 f = fopen(buf, "w");
6001 if (!f) {
6002 sigma_dut_print(dut, DUT_MSG_ERROR,
6003 "failed to open: %s", buf);
6004 return -1;
6005 }
6006
6007 fprintf(f, "add %d %d\n", vring_id, agg_size);
6008
6009 ret = 0;
6010
6011out:
6012 fclose(f);
6013
6014 return ret;
6015}
6016
6017
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006018static int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6019 struct sigma_cmd *cmd)
6020{
6021 const char *val;
6022 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006023
6024 val = get_param(cmd, "TID");
6025 if (val) {
6026 tid = atoi(val);
6027 if (tid != 0) {
6028 sigma_dut_print(dut, DUT_MSG_ERROR,
6029 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
6030 tid);
6031 }
6032 }
6033
6034 val = get_param(cmd, "Dest_mac");
6035 if (!val) {
6036 sigma_dut_print(dut, DUT_MSG_ERROR,
6037 "Currently not supporting addba for 60G without Dest_mac");
6038 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
6039 }
6040
Lior David9981b512017-01-20 13:16:40 +02006041 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006042 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006043
6044 return 1;
6045}
6046
Lior David9981b512017-01-20 13:16:40 +02006047#endif /* __linux__ */
6048
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006049
6050static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
6051 struct sigma_cmd *cmd)
6052{
6053 switch (get_driver_type()) {
6054 case DRIVER_ATHEROS:
6055 return ath_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02006056#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006057 case DRIVER_WIL6210:
6058 return send_addba_60g(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02006059#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006060 default:
6061 /*
6062 * There is no driver specific implementation for other drivers.
6063 * Ignore the command and report COMPLETE since the following
6064 * throughput test operation will end up sending ADDBA anyway.
6065 */
6066 return 1;
6067 }
6068}
6069
6070
6071int inject_eth_frame(int s, const void *data, size_t len,
6072 unsigned short ethtype, char *dst, char *src)
6073{
6074 struct iovec iov[4] = {
6075 {
6076 .iov_base = dst,
6077 .iov_len = ETH_ALEN,
6078 },
6079 {
6080 .iov_base = src,
6081 .iov_len = ETH_ALEN,
6082 },
6083 {
6084 .iov_base = &ethtype,
6085 .iov_len = sizeof(unsigned short),
6086 },
6087 {
6088 .iov_base = (void *) data,
6089 .iov_len = len,
6090 }
6091 };
6092 struct msghdr msg = {
6093 .msg_name = NULL,
6094 .msg_namelen = 0,
6095 .msg_iov = iov,
6096 .msg_iovlen = 4,
6097 .msg_control = NULL,
6098 .msg_controllen = 0,
6099 .msg_flags = 0,
6100 };
6101
6102 return sendmsg(s, &msg, 0);
6103}
6104
6105#if defined(__linux__) || defined(__QNXNTO__)
6106
6107int inject_frame(int s, const void *data, size_t len, int encrypt)
6108{
6109#define IEEE80211_RADIOTAP_F_WEP 0x04
6110#define IEEE80211_RADIOTAP_F_FRAG 0x08
6111 unsigned char rtap_hdr[] = {
6112 0x00, 0x00, /* radiotap version */
6113 0x0e, 0x00, /* radiotap length */
6114 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
6115 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
6116 0x00, /* padding */
6117 0x00, 0x00, /* RX and TX flags to indicate that */
6118 0x00, 0x00, /* this is the injected frame directly */
6119 };
6120 struct iovec iov[2] = {
6121 {
6122 .iov_base = &rtap_hdr,
6123 .iov_len = sizeof(rtap_hdr),
6124 },
6125 {
6126 .iov_base = (void *) data,
6127 .iov_len = len,
6128 }
6129 };
6130 struct msghdr msg = {
6131 .msg_name = NULL,
6132 .msg_namelen = 0,
6133 .msg_iov = iov,
6134 .msg_iovlen = 2,
6135 .msg_control = NULL,
6136 .msg_controllen = 0,
6137 .msg_flags = 0,
6138 };
6139
6140 if (encrypt)
6141 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
6142
6143 return sendmsg(s, &msg, 0);
6144}
6145
6146
6147int open_monitor(const char *ifname)
6148{
6149#ifdef __QNXNTO__
6150 struct sockaddr_dl ll;
6151 int s;
6152
6153 memset(&ll, 0, sizeof(ll));
6154 ll.sdl_family = AF_LINK;
6155 ll.sdl_index = if_nametoindex(ifname);
6156 if (ll.sdl_index == 0) {
6157 perror("if_nametoindex");
6158 return -1;
6159 }
6160 s = socket(PF_INET, SOCK_RAW, 0);
6161#else /* __QNXNTO__ */
6162 struct sockaddr_ll ll;
6163 int s;
6164
6165 memset(&ll, 0, sizeof(ll));
6166 ll.sll_family = AF_PACKET;
6167 ll.sll_ifindex = if_nametoindex(ifname);
6168 if (ll.sll_ifindex == 0) {
6169 perror("if_nametoindex");
6170 return -1;
6171 }
6172 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
6173#endif /* __QNXNTO__ */
6174 if (s < 0) {
6175 perror("socket[PF_PACKET,SOCK_RAW]");
6176 return -1;
6177 }
6178
6179 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
6180 perror("monitor socket bind");
6181 close(s);
6182 return -1;
6183 }
6184
6185 return s;
6186}
6187
6188
6189static int hex2num(char c)
6190{
6191 if (c >= '0' && c <= '9')
6192 return c - '0';
6193 if (c >= 'a' && c <= 'f')
6194 return c - 'a' + 10;
6195 if (c >= 'A' && c <= 'F')
6196 return c - 'A' + 10;
6197 return -1;
6198}
6199
6200
6201int hwaddr_aton(const char *txt, unsigned char *addr)
6202{
6203 int i;
6204
6205 for (i = 0; i < 6; i++) {
6206 int a, b;
6207
6208 a = hex2num(*txt++);
6209 if (a < 0)
6210 return -1;
6211 b = hex2num(*txt++);
6212 if (b < 0)
6213 return -1;
6214 *addr++ = (a << 4) | b;
6215 if (i < 5 && *txt++ != ':')
6216 return -1;
6217 }
6218
6219 return 0;
6220}
6221
6222#endif /* defined(__linux__) || defined(__QNXNTO__) */
6223
6224enum send_frame_type {
6225 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
6226};
6227enum send_frame_protection {
6228 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
6229};
6230
6231
6232static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
6233 enum send_frame_type frame,
6234 enum send_frame_protection protected,
6235 const char *dest)
6236{
6237#ifdef __linux__
6238 unsigned char buf[1000], *pos;
6239 int s, res;
6240 char bssid[20], addr[20];
6241 char result[32], ssid[100];
6242 size_t ssid_len;
6243
6244 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
6245 sizeof(result)) < 0 ||
6246 strncmp(result, "COMPLETED", 9) != 0) {
6247 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
6248 return 0;
6249 }
6250
6251 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
6252 < 0) {
6253 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
6254 "current BSSID");
6255 return 0;
6256 }
6257
6258 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
6259 < 0) {
6260 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
6261 "own MAC address");
6262 return 0;
6263 }
6264
6265 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
6266 < 0) {
6267 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
6268 "current SSID");
6269 return 0;
6270 }
6271 ssid_len = strlen(ssid);
6272
6273 pos = buf;
6274
6275 /* Frame Control */
6276 switch (frame) {
6277 case DISASSOC:
6278 *pos++ = 0xa0;
6279 break;
6280 case DEAUTH:
6281 *pos++ = 0xc0;
6282 break;
6283 case SAQUERY:
6284 *pos++ = 0xd0;
6285 break;
6286 case AUTH:
6287 *pos++ = 0xb0;
6288 break;
6289 case ASSOCREQ:
6290 *pos++ = 0x00;
6291 break;
6292 case REASSOCREQ:
6293 *pos++ = 0x20;
6294 break;
6295 case DLS_REQ:
6296 *pos++ = 0xd0;
6297 break;
6298 }
6299
6300 if (protected == INCORRECT_KEY)
6301 *pos++ = 0x40; /* Set Protected field to 1 */
6302 else
6303 *pos++ = 0x00;
6304
6305 /* Duration */
6306 *pos++ = 0x00;
6307 *pos++ = 0x00;
6308
6309 /* addr1 = DA (current AP) */
6310 hwaddr_aton(bssid, pos);
6311 pos += 6;
6312 /* addr2 = SA (own address) */
6313 hwaddr_aton(addr, pos);
6314 pos += 6;
6315 /* addr3 = BSSID (current AP) */
6316 hwaddr_aton(bssid, pos);
6317 pos += 6;
6318
6319 /* Seq# (to be filled by driver/mac80211) */
6320 *pos++ = 0x00;
6321 *pos++ = 0x00;
6322
6323 if (protected == INCORRECT_KEY) {
6324 /* CCMP parameters */
6325 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
6326 pos += 8;
6327 }
6328
6329 if (protected == INCORRECT_KEY) {
6330 switch (frame) {
6331 case DEAUTH:
6332 /* Reason code (encrypted) */
6333 memcpy(pos, "\xa7\x39", 2);
6334 pos += 2;
6335 break;
6336 case DISASSOC:
6337 /* Reason code (encrypted) */
6338 memcpy(pos, "\xa7\x39", 2);
6339 pos += 2;
6340 break;
6341 case SAQUERY:
6342 /* Category|Action|TransID (encrypted) */
6343 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
6344 pos += 4;
6345 break;
6346 default:
6347 return -1;
6348 }
6349
6350 /* CCMP MIC */
6351 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
6352 pos += 8;
6353 } else {
6354 switch (frame) {
6355 case DEAUTH:
6356 /* reason code = 8 */
6357 *pos++ = 0x08;
6358 *pos++ = 0x00;
6359 break;
6360 case DISASSOC:
6361 /* reason code = 8 */
6362 *pos++ = 0x08;
6363 *pos++ = 0x00;
6364 break;
6365 case SAQUERY:
6366 /* Category - SA Query */
6367 *pos++ = 0x08;
6368 /* SA query Action - Request */
6369 *pos++ = 0x00;
6370 /* Transaction ID */
6371 *pos++ = 0x12;
6372 *pos++ = 0x34;
6373 break;
6374 case AUTH:
6375 /* Auth Alg (Open) */
6376 *pos++ = 0x00;
6377 *pos++ = 0x00;
6378 /* Seq# */
6379 *pos++ = 0x01;
6380 *pos++ = 0x00;
6381 /* Status code */
6382 *pos++ = 0x00;
6383 *pos++ = 0x00;
6384 break;
6385 case ASSOCREQ:
6386 /* Capability Information */
6387 *pos++ = 0x31;
6388 *pos++ = 0x04;
6389 /* Listen Interval */
6390 *pos++ = 0x0a;
6391 *pos++ = 0x00;
6392 /* SSID */
6393 *pos++ = 0x00;
6394 *pos++ = ssid_len;
6395 memcpy(pos, ssid, ssid_len);
6396 pos += ssid_len;
6397 /* Supported Rates */
6398 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
6399 10);
6400 pos += 10;
6401 /* Extended Supported Rates */
6402 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
6403 pos += 6;
6404 /* RSN */
6405 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
6406 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
6407 "\x00\x00\x00\x00\x0f\xac\x06", 28);
6408 pos += 28;
6409 break;
6410 case REASSOCREQ:
6411 /* Capability Information */
6412 *pos++ = 0x31;
6413 *pos++ = 0x04;
6414 /* Listen Interval */
6415 *pos++ = 0x0a;
6416 *pos++ = 0x00;
6417 /* Current AP */
6418 hwaddr_aton(bssid, pos);
6419 pos += 6;
6420 /* SSID */
6421 *pos++ = 0x00;
6422 *pos++ = ssid_len;
6423 memcpy(pos, ssid, ssid_len);
6424 pos += ssid_len;
6425 /* Supported Rates */
6426 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
6427 10);
6428 pos += 10;
6429 /* Extended Supported Rates */
6430 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
6431 pos += 6;
6432 /* RSN */
6433 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
6434 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
6435 "\x00\x00\x00\x00\x0f\xac\x06", 28);
6436 pos += 28;
6437 break;
6438 case DLS_REQ:
6439 /* Category - DLS */
6440 *pos++ = 0x02;
6441 /* DLS Action - Request */
6442 *pos++ = 0x00;
6443 /* Destination MACAddress */
6444 if (dest)
6445 hwaddr_aton(dest, pos);
6446 else
6447 memset(pos, 0, 6);
6448 pos += 6;
6449 /* Source MACAddress */
6450 hwaddr_aton(addr, pos);
6451 pos += 6;
6452 /* Capability Information */
6453 *pos++ = 0x10; /* Privacy */
6454 *pos++ = 0x06; /* QoS */
6455 /* DLS Timeout Value */
6456 *pos++ = 0x00;
6457 *pos++ = 0x01;
6458 /* Supported rates */
6459 *pos++ = 0x01;
6460 *pos++ = 0x08;
6461 *pos++ = 0x0c; /* 6 Mbps */
6462 *pos++ = 0x12; /* 9 Mbps */
6463 *pos++ = 0x18; /* 12 Mbps */
6464 *pos++ = 0x24; /* 18 Mbps */
6465 *pos++ = 0x30; /* 24 Mbps */
6466 *pos++ = 0x48; /* 36 Mbps */
6467 *pos++ = 0x60; /* 48 Mbps */
6468 *pos++ = 0x6c; /* 54 Mbps */
6469 /* TODO: Extended Supported Rates */
6470 /* TODO: HT Capabilities */
6471 break;
6472 }
6473 }
6474
6475 s = open_monitor("sigmadut");
6476 if (s < 0) {
6477 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
6478 "monitor socket");
6479 return 0;
6480 }
6481
6482 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
6483 if (res < 0) {
6484 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6485 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05306486 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006487 return 0;
6488 }
6489 if (res < pos - buf) {
6490 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
6491 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05306492 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006493 return 0;
6494 }
6495
6496 close(s);
6497
6498 return 1;
6499#else /* __linux__ */
6500 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
6501 "yet supported");
6502 return 0;
6503#endif /* __linux__ */
6504}
6505
6506
6507static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
6508 struct sigma_conn *conn,
6509 struct sigma_cmd *cmd)
6510{
6511 const char *intf = get_param(cmd, "Interface");
6512 const char *sta, *val;
6513 unsigned char addr[ETH_ALEN];
6514 char buf[100];
6515
6516 sta = get_param(cmd, "peer");
6517 if (sta == NULL)
6518 sta = get_param(cmd, "station");
6519 if (sta == NULL) {
6520 send_resp(dut, conn, SIGMA_ERROR,
6521 "ErrorCode,Missing peer address");
6522 return 0;
6523 }
6524 if (hwaddr_aton(sta, addr) < 0) {
6525 send_resp(dut, conn, SIGMA_ERROR,
6526 "ErrorCode,Invalid peer address");
6527 return 0;
6528 }
6529
6530 val = get_param(cmd, "type");
6531 if (val == NULL)
6532 return -1;
6533
6534 if (strcasecmp(val, "DISCOVERY") == 0) {
6535 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
6536 if (wpa_command(intf, buf) < 0) {
6537 send_resp(dut, conn, SIGMA_ERROR,
6538 "ErrorCode,Failed to send TDLS discovery");
6539 return 0;
6540 }
6541 return 1;
6542 }
6543
6544 if (strcasecmp(val, "SETUP") == 0) {
6545 int status = 0, timeout = 0;
6546
6547 val = get_param(cmd, "Status");
6548 if (val)
6549 status = atoi(val);
6550
6551 val = get_param(cmd, "Timeout");
6552 if (val)
6553 timeout = atoi(val);
6554
6555 if (status != 0 && status != 37) {
6556 send_resp(dut, conn, SIGMA_ERROR,
6557 "ErrorCode,Unsupported status value");
6558 return 0;
6559 }
6560
6561 if (timeout != 0 && timeout != 301) {
6562 send_resp(dut, conn, SIGMA_ERROR,
6563 "ErrorCode,Unsupported timeout value");
6564 return 0;
6565 }
6566
6567 if (status && timeout) {
6568 send_resp(dut, conn, SIGMA_ERROR,
6569 "ErrorCode,Unsupported timeout+status "
6570 "combination");
6571 return 0;
6572 }
6573
6574 if (status == 37 &&
6575 wpa_command(intf, "SET tdls_testing 0x200")) {
6576 send_resp(dut, conn, SIGMA_ERROR,
6577 "ErrorCode,Failed to enable "
6578 "decline setup response test mode");
6579 return 0;
6580 }
6581
6582 if (timeout == 301) {
6583 int res;
6584 if (dut->no_tpk_expiration)
6585 res = wpa_command(intf,
6586 "SET tdls_testing 0x108");
6587 else
6588 res = wpa_command(intf,
6589 "SET tdls_testing 0x8");
6590 if (res) {
6591 send_resp(dut, conn, SIGMA_ERROR,
6592 "ErrorCode,Failed to set short TPK "
6593 "lifetime");
6594 return 0;
6595 }
6596 }
6597
6598 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
6599 if (wpa_command(intf, buf) < 0) {
6600 send_resp(dut, conn, SIGMA_ERROR,
6601 "ErrorCode,Failed to send TDLS setup");
6602 return 0;
6603 }
6604 return 1;
6605 }
6606
6607 if (strcasecmp(val, "TEARDOWN") == 0) {
6608 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
6609 if (wpa_command(intf, buf) < 0) {
6610 send_resp(dut, conn, SIGMA_ERROR,
6611 "ErrorCode,Failed to send TDLS teardown");
6612 return 0;
6613 }
6614 return 1;
6615 }
6616
6617 send_resp(dut, conn, SIGMA_ERROR,
6618 "ErrorCode,Unsupported TDLS frame");
6619 return 0;
6620}
6621
6622
6623static int sta_ap_known(const char *ifname, const char *bssid)
6624{
6625 char buf[4096];
6626
6627 snprintf(buf, sizeof(buf), "BSS %s", bssid);
6628 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
6629 return 0;
6630 if (strncmp(buf, "id=", 3) != 0)
6631 return 0;
6632 return 1;
6633}
6634
6635
6636static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
6637 const char *bssid)
6638{
6639 int res;
6640 struct wpa_ctrl *ctrl;
6641 char buf[256];
6642
6643 if (sta_ap_known(ifname, bssid))
6644 return 0;
6645 sigma_dut_print(dut, DUT_MSG_DEBUG,
6646 "AP not in BSS table - start scan");
6647
6648 ctrl = open_wpa_mon(ifname);
6649 if (ctrl == NULL) {
6650 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6651 "wpa_supplicant monitor connection");
6652 return -1;
6653 }
6654
6655 if (wpa_command(ifname, "SCAN") < 0) {
6656 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
6657 wpa_ctrl_detach(ctrl);
6658 wpa_ctrl_close(ctrl);
6659 return -1;
6660 }
6661
6662 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6663 buf, sizeof(buf));
6664
6665 wpa_ctrl_detach(ctrl);
6666 wpa_ctrl_close(ctrl);
6667
6668 if (res < 0) {
6669 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
6670 return -1;
6671 }
6672
6673 if (sta_ap_known(ifname, bssid))
6674 return 0;
6675 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
6676 return -1;
6677}
6678
6679
6680static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
6681 struct sigma_conn *conn,
6682 struct sigma_cmd *cmd,
6683 const char *intf)
6684{
6685 char buf[200];
6686
6687 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
6688 if (system(buf) != 0) {
6689 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
6690 "ndsend");
6691 return 0;
6692 }
6693
6694 return 1;
6695}
6696
6697
6698static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
6699 struct sigma_conn *conn,
6700 struct sigma_cmd *cmd,
6701 const char *intf)
6702{
6703 char buf[200];
6704 const char *ip = get_param(cmd, "SenderIP");
6705
Peng Xu26b356d2017-10-04 17:58:16 -07006706 if (!ip)
6707 return 0;
6708
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006709 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
6710 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6711 if (system(buf) == 0) {
6712 sigma_dut_print(dut, DUT_MSG_INFO,
6713 "Neighbor Solicitation got a response "
6714 "for %s@%s", ip, intf);
6715 }
6716
6717 return 1;
6718}
6719
6720
6721static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
6722 struct sigma_conn *conn,
6723 struct sigma_cmd *cmd,
6724 const char *ifname)
6725{
6726 char buf[200];
6727 const char *ip = get_param(cmd, "SenderIP");
6728
6729 if (ip == NULL) {
6730 send_resp(dut, conn, SIGMA_ERROR,
6731 "ErrorCode,Missing SenderIP parameter");
6732 return 0;
6733 }
6734 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
6735 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6736 if (system(buf) != 0) {
6737 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
6738 "for %s@%s", ip, ifname);
6739 }
6740
6741 return 1;
6742}
6743
6744
6745static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
6746 struct sigma_conn *conn,
6747 struct sigma_cmd *cmd,
6748 const char *ifname)
6749{
6750 char buf[200];
6751 char ip[16];
6752 int s;
Peng Xub3756882017-10-04 14:39:09 -07006753 struct ifreq ifr;
6754 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006755
6756 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07006757 if (s < 0) {
6758 perror("socket");
6759 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006760 }
6761
Peng Xub3756882017-10-04 14:39:09 -07006762 memset(&ifr, 0, sizeof(ifr));
6763 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
6764 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
6765 sigma_dut_print(dut, DUT_MSG_INFO,
6766 "Failed to get %s IP address: %s",
6767 ifname, strerror(errno));
6768 close(s);
6769 return -1;
6770 }
6771 close(s);
6772
6773 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
6774 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
6775
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006776 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
6777 ip);
6778 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6779 if (system(buf) != 0) {
6780 }
6781
6782 return 1;
6783}
6784
6785
6786static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
6787 struct sigma_conn *conn,
6788 struct sigma_cmd *cmd,
6789 const char *ifname)
6790{
6791 char buf[200], addr[20];
6792 char dst[ETH_ALEN], src[ETH_ALEN];
6793 short ethtype = htons(ETH_P_ARP);
6794 char *pos;
6795 int s, res;
6796 const char *val;
6797 struct sockaddr_in taddr;
6798
6799 val = get_param(cmd, "dest");
6800 if (val)
6801 hwaddr_aton(val, (unsigned char *) dst);
6802
6803 val = get_param(cmd, "DestIP");
6804 if (val)
6805 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07006806 else
6807 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006808
6809 if (get_wpa_status(get_station_ifname(), "address", addr,
6810 sizeof(addr)) < 0)
6811 return -2;
6812 hwaddr_aton(addr, (unsigned char *) src);
6813
6814 pos = buf;
6815 *pos++ = 0x00;
6816 *pos++ = 0x01;
6817 *pos++ = 0x08;
6818 *pos++ = 0x00;
6819 *pos++ = 0x06;
6820 *pos++ = 0x04;
6821 *pos++ = 0x00;
6822 *pos++ = 0x02;
6823 memcpy(pos, src, ETH_ALEN);
6824 pos += ETH_ALEN;
6825 memcpy(pos, &taddr.sin_addr, 4);
6826 pos += 4;
6827 memcpy(pos, dst, ETH_ALEN);
6828 pos += ETH_ALEN;
6829 memcpy(pos, &taddr.sin_addr, 4);
6830 pos += 4;
6831
6832 s = open_monitor(get_station_ifname());
6833 if (s < 0) {
6834 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
6835 "monitor socket");
6836 return 0;
6837 }
6838
6839 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
6840 if (res < 0) {
6841 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6842 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05306843 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006844 return 0;
6845 }
6846
6847 close(s);
6848
6849 return 1;
6850}
6851
6852
6853static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
6854 struct sigma_conn *conn,
6855 struct sigma_cmd *cmd,
6856 const char *intf, const char *dest)
6857{
6858 char buf[100];
6859
6860 if (if_nametoindex("sigmadut") == 0) {
6861 snprintf(buf, sizeof(buf),
6862 "iw dev %s interface add sigmadut type monitor",
6863 get_station_ifname());
6864 if (system(buf) != 0 ||
6865 if_nametoindex("sigmadut") == 0) {
6866 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
6867 "monitor interface with '%s'", buf);
6868 return -2;
6869 }
6870 }
6871
6872 if (system("ifconfig sigmadut up") != 0) {
6873 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6874 "monitor interface up");
6875 return -2;
6876 }
6877
6878 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
6879}
6880
6881
6882static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
6883 struct sigma_conn *conn,
6884 struct sigma_cmd *cmd)
6885{
6886 const char *intf = get_param(cmd, "Interface");
6887 const char *dest = get_param(cmd, "Dest");
6888 const char *type = get_param(cmd, "FrameName");
6889 const char *val;
6890 char buf[200], *pos, *end;
6891 int count, count2;
6892
6893 if (type == NULL)
6894 type = get_param(cmd, "Type");
6895
6896 if (intf == NULL || dest == NULL || type == NULL)
6897 return -1;
6898
6899 if (strcasecmp(type, "NeighAdv") == 0)
6900 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
6901
6902 if (strcasecmp(type, "NeighSolicitReq") == 0)
6903 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
6904
6905 if (strcasecmp(type, "ARPProbe") == 0)
6906 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
6907
6908 if (strcasecmp(type, "ARPAnnounce") == 0)
6909 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
6910
6911 if (strcasecmp(type, "ARPReply") == 0)
6912 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
6913
6914 if (strcasecmp(type, "DLS-request") == 0 ||
6915 strcasecmp(type, "DLSrequest") == 0)
6916 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
6917 dest);
6918
6919 if (strcasecmp(type, "ANQPQuery") != 0 &&
6920 strcasecmp(type, "Query") != 0) {
6921 send_resp(dut, conn, SIGMA_ERROR,
6922 "ErrorCode,Unsupported HS 2.0 send frame type");
6923 return 0;
6924 }
6925
6926 if (sta_scan_ap(dut, intf, dest) < 0) {
6927 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
6928 "the requested AP");
6929 return 0;
6930 }
6931
6932 pos = buf;
6933 end = buf + sizeof(buf);
6934 count = 0;
6935 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
6936
6937 val = get_param(cmd, "ANQP_CAP_LIST");
6938 if (val && atoi(val)) {
6939 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
6940 count++;
6941 }
6942
6943 val = get_param(cmd, "VENUE_NAME");
6944 if (val && atoi(val)) {
6945 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
6946 count++;
6947 }
6948
6949 val = get_param(cmd, "NETWORK_AUTH_TYPE");
6950 if (val && atoi(val)) {
6951 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
6952 count++;
6953 }
6954
6955 val = get_param(cmd, "ROAMING_CONS");
6956 if (val && atoi(val)) {
6957 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
6958 count++;
6959 }
6960
6961 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
6962 if (val && atoi(val)) {
6963 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
6964 count++;
6965 }
6966
6967 val = get_param(cmd, "NAI_REALM_LIST");
6968 if (val && atoi(val)) {
6969 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
6970 count++;
6971 }
6972
6973 val = get_param(cmd, "3GPP_INFO");
6974 if (val && atoi(val)) {
6975 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
6976 count++;
6977 }
6978
6979 val = get_param(cmd, "DOMAIN_LIST");
6980 if (val && atoi(val)) {
6981 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
6982 count++;
6983 }
6984
6985 if (count && wpa_command(intf, buf)) {
6986 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
6987 return 0;
6988 }
6989
6990 pos = buf;
6991 end = buf + sizeof(buf);
6992 count2 = 0;
6993 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
6994
6995 val = get_param(cmd, "HS_CAP_LIST");
6996 if (val && atoi(val)) {
6997 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
6998 count2++;
6999 }
7000
7001 val = get_param(cmd, "OPER_NAME");
7002 if (val && atoi(val)) {
7003 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
7004 count2++;
7005 }
7006
7007 val = get_param(cmd, "WAN_METRICS");
7008 if (!val)
7009 val = get_param(cmd, "WAN_MAT");
7010 if (!val)
7011 val = get_param(cmd, "WAN_MET");
7012 if (val && atoi(val)) {
7013 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
7014 count2++;
7015 }
7016
7017 val = get_param(cmd, "CONNECTION_CAPABILITY");
7018 if (val && atoi(val)) {
7019 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
7020 count2++;
7021 }
7022
7023 val = get_param(cmd, "OP_CLASS");
7024 if (val && atoi(val)) {
7025 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
7026 count2++;
7027 }
7028
7029 val = get_param(cmd, "OSU_PROVIDER_LIST");
7030 if (val && atoi(val)) {
7031 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
7032 count2++;
7033 }
7034
7035 if (count && count2) {
7036 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
7037 "second query");
7038 sleep(1);
7039 }
7040
7041 if (count2 && wpa_command(intf, buf)) {
7042 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
7043 "failed");
7044 return 0;
7045 }
7046
7047 val = get_param(cmd, "NAI_HOME_REALM_LIST");
7048 if (val) {
7049 if (count || count2) {
7050 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
7051 "sending out second query");
7052 sleep(1);
7053 }
7054
7055 if (strcmp(val, "1") == 0)
7056 val = "mail.example.com";
7057 snprintf(buf, end - pos,
7058 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
7059 dest, val);
7060 if (wpa_command(intf, buf)) {
7061 send_resp(dut, conn, SIGMA_ERROR,
7062 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
7063 "failed");
7064 return 0;
7065 }
7066 }
7067
7068 val = get_param(cmd, "ICON_REQUEST");
7069 if (val) {
7070 if (count || count2) {
7071 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
7072 "sending out second query");
7073 sleep(1);
7074 }
7075
7076 snprintf(buf, end - pos,
7077 "HS20_ICON_REQUEST %s %s", dest, val);
7078 if (wpa_command(intf, buf)) {
7079 send_resp(dut, conn, SIGMA_ERROR,
7080 "ErrorCode,HS20_ICON_REQUEST failed");
7081 return 0;
7082 }
7083 }
7084
7085 return 1;
7086}
7087
7088
7089static int ath_sta_send_frame_vht(struct sigma_dut *dut,
7090 struct sigma_conn *conn,
7091 struct sigma_cmd *cmd)
7092{
7093 const char *val;
7094 char *ifname;
7095 char buf[100];
7096 int chwidth, nss;
7097
7098 val = get_param(cmd, "framename");
7099 if (!val)
7100 return -1;
7101 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
7102
7103 /* Command sequence to generate Op mode notification */
7104 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
7105 ifname = get_station_ifname();
7106
7107 /* Disable STBC */
7108 snprintf(buf, sizeof(buf),
7109 "iwpriv %s tx_stbc 0", ifname);
7110 if (system(buf) != 0) {
7111 sigma_dut_print(dut, DUT_MSG_ERROR,
7112 "iwpriv tx_stbc 0 failed!");
7113 }
7114
7115 /* Extract Channel width */
7116 val = get_param(cmd, "Channel_width");
7117 if (val) {
7118 switch (atoi(val)) {
7119 case 20:
7120 chwidth = 0;
7121 break;
7122 case 40:
7123 chwidth = 1;
7124 break;
7125 case 80:
7126 chwidth = 2;
7127 break;
7128 case 160:
7129 chwidth = 3;
7130 break;
7131 default:
7132 chwidth = 2;
7133 break;
7134 }
7135
7136 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
7137 ifname, chwidth);
7138 if (system(buf) != 0) {
7139 sigma_dut_print(dut, DUT_MSG_ERROR,
7140 "iwpriv chwidth failed!");
7141 }
7142 }
7143
7144 /* Extract NSS */
7145 val = get_param(cmd, "NSS");
7146 if (val) {
7147 switch (atoi(val)) {
7148 case 1:
7149 nss = 1;
7150 break;
7151 case 2:
7152 nss = 3;
7153 break;
7154 case 3:
7155 nss = 7;
7156 break;
7157 default:
7158 /* We do not support NSS > 3 */
7159 nss = 3;
7160 break;
7161 }
7162 snprintf(buf, sizeof(buf),
7163 "iwpriv %s rxchainmask %d", ifname, nss);
7164 if (system(buf) != 0) {
7165 sigma_dut_print(dut, DUT_MSG_ERROR,
7166 "iwpriv rxchainmask failed!");
7167 }
7168 }
7169
7170 /* Opmode notify */
7171 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
7172 if (system(buf) != 0) {
7173 sigma_dut_print(dut, DUT_MSG_ERROR,
7174 "iwpriv opmode_notify failed!");
7175 } else {
7176 sigma_dut_print(dut, DUT_MSG_INFO,
7177 "Sent out the notify frame!");
7178 }
7179 }
7180
7181 return 1;
7182}
7183
7184
7185static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
7186 struct sigma_conn *conn,
7187 struct sigma_cmd *cmd)
7188{
7189 switch (get_driver_type()) {
7190 case DRIVER_ATHEROS:
7191 return ath_sta_send_frame_vht(dut, conn, cmd);
7192 default:
7193 send_resp(dut, conn, SIGMA_ERROR,
7194 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
7195 return 0;
7196 }
7197}
7198
7199
Lior David0fe101e2017-03-09 16:09:50 +02007200#ifdef __linux__
7201int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7202 struct sigma_cmd *cmd)
7203{
7204 const char *frame_name = get_param(cmd, "framename");
7205 const char *mac = get_param(cmd, "dest_mac");
7206
7207 if (!frame_name || !mac) {
7208 sigma_dut_print(dut, DUT_MSG_ERROR,
7209 "framename and dest_mac must be provided");
7210 return -1;
7211 }
7212
7213 if (strcasecmp(frame_name, "brp") == 0) {
7214 const char *l_rx = get_param(cmd, "L-RX");
7215 int l_rx_i;
7216
7217 if (!l_rx) {
7218 sigma_dut_print(dut, DUT_MSG_ERROR,
7219 "L-RX must be provided");
7220 return -1;
7221 }
7222 l_rx_i = atoi(l_rx);
7223
7224 sigma_dut_print(dut, DUT_MSG_INFO,
7225 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
7226 mac, l_rx);
7227 if (l_rx_i != 16) {
7228 sigma_dut_print(dut, DUT_MSG_ERROR,
7229 "unsupported L-RX: %s", l_rx);
7230 return -1;
7231 }
7232
7233 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
7234 return -1;
7235 } else if (strcasecmp(frame_name, "ssw") == 0) {
7236 sigma_dut_print(dut, DUT_MSG_INFO,
7237 "dev_send_frame: SLS, dest_mac %s", mac);
7238 if (wil6210_send_sls(dut, mac))
7239 return -1;
7240 } else {
7241 sigma_dut_print(dut, DUT_MSG_ERROR,
7242 "unsupported frame type: %s", frame_name);
7243 return -1;
7244 }
7245
7246 return 1;
7247}
7248#endif /* __linux__ */
7249
7250
7251static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
7252 struct sigma_conn *conn,
7253 struct sigma_cmd *cmd)
7254{
7255 switch (get_driver_type()) {
7256#ifdef __linux__
7257 case DRIVER_WIL6210:
7258 return wil6210_send_frame_60g(dut, conn, cmd);
7259#endif /* __linux__ */
7260 default:
7261 send_resp(dut, conn, SIGMA_ERROR,
7262 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
7263 return 0;
7264 }
7265}
7266
7267
Ashwini Patildb59b3c2017-04-13 15:19:23 +05307268static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
7269 const char *intf, struct sigma_cmd *cmd)
7270{
7271 const char *val, *addr;
7272 char buf[100];
7273
7274 addr = get_param(cmd, "DestMac");
7275 if (!addr) {
7276 send_resp(dut, conn, SIGMA_INVALID,
7277 "ErrorCode,AP MAC address is missing");
7278 return 0;
7279 }
7280
7281 val = get_param(cmd, "ANQPQuery_ID");
7282 if (!val) {
7283 send_resp(dut, conn, SIGMA_INVALID,
7284 "ErrorCode,Missing ANQPQuery_ID");
7285 return 0;
7286 }
7287
7288 if (strcasecmp(val, "NeighborReportReq") == 0) {
7289 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
7290 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
7291 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
7292 } else {
7293 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
7294 val);
7295 send_resp(dut, conn, SIGMA_INVALID,
7296 "ErrorCode,Invalid ANQPQuery_ID");
7297 return 0;
7298 }
7299
Ashwini Patild174f2c2017-04-13 16:49:46 +05307300 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
7301 * (Address3 = Wildcard BSSID when sent to not-associated AP;
7302 * if associated, AP BSSID).
7303 */
7304 if (wpa_command(intf, "SET gas_address3 1") < 0) {
7305 send_resp(dut, conn, SIGMA_ERROR,
7306 "ErrorCode,Failed to set gas_address3");
7307 return 0;
7308 }
7309
Ashwini Patildb59b3c2017-04-13 15:19:23 +05307310 if (wpa_command(intf, buf) < 0) {
7311 send_resp(dut, conn, SIGMA_ERROR,
7312 "ErrorCode,Failed to send ANQP query");
7313 return 0;
7314 }
7315
7316 return 1;
7317}
7318
7319
7320static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
7321 struct sigma_conn *conn,
7322 const char *intf,
7323 struct sigma_cmd *cmd)
7324{
7325 const char *val = get_param(cmd, "FrameName");
7326
7327 if (val && strcasecmp(val, "ANQPQuery") == 0)
7328 return mbo_send_anqp_query(dut, conn, intf, cmd);
7329
7330 return 2;
7331}
7332
7333
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007334int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
7335 struct sigma_cmd *cmd)
7336{
7337 const char *intf = get_param(cmd, "Interface");
7338 const char *val;
7339 enum send_frame_type frame;
7340 enum send_frame_protection protected;
7341 char buf[100];
7342 unsigned char addr[ETH_ALEN];
7343 int res;
7344
7345 val = get_param(cmd, "program");
7346 if (val == NULL)
7347 val = get_param(cmd, "frame");
7348 if (val && strcasecmp(val, "TDLS") == 0)
7349 return cmd_sta_send_frame_tdls(dut, conn, cmd);
7350 if (val && (strcasecmp(val, "HS2") == 0 ||
7351 strcasecmp(val, "HS2-R2") == 0))
7352 return cmd_sta_send_frame_hs2(dut, conn, cmd);
7353 if (val && strcasecmp(val, "VHT") == 0)
7354 return cmd_sta_send_frame_vht(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007355 if (val && strcasecmp(val, "LOC") == 0)
7356 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +02007357 if (val && strcasecmp(val, "60GHz") == 0)
7358 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +05307359 if (val && strcasecmp(val, "MBO") == 0) {
7360 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
7361 if (res != 2)
7362 return res;
7363 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007364
7365 val = get_param(cmd, "TD_DISC");
7366 if (val) {
7367 if (hwaddr_aton(val, addr) < 0)
7368 return -1;
7369 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
7370 if (wpa_command(intf, buf) < 0) {
7371 send_resp(dut, conn, SIGMA_ERROR,
7372 "ErrorCode,Failed to send TDLS discovery");
7373 return 0;
7374 }
7375 return 1;
7376 }
7377
7378 val = get_param(cmd, "TD_Setup");
7379 if (val) {
7380 if (hwaddr_aton(val, addr) < 0)
7381 return -1;
7382 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
7383 if (wpa_command(intf, buf) < 0) {
7384 send_resp(dut, conn, SIGMA_ERROR,
7385 "ErrorCode,Failed to start TDLS setup");
7386 return 0;
7387 }
7388 return 1;
7389 }
7390
7391 val = get_param(cmd, "TD_TearDown");
7392 if (val) {
7393 if (hwaddr_aton(val, addr) < 0)
7394 return -1;
7395 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
7396 if (wpa_command(intf, buf) < 0) {
7397 send_resp(dut, conn, SIGMA_ERROR,
7398 "ErrorCode,Failed to tear down TDLS link");
7399 return 0;
7400 }
7401 return 1;
7402 }
7403
7404 val = get_param(cmd, "TD_ChannelSwitch");
7405 if (val) {
7406 /* TODO */
7407 send_resp(dut, conn, SIGMA_ERROR,
7408 "ErrorCode,TD_ChannelSwitch not yet supported");
7409 return 0;
7410 }
7411
7412 val = get_param(cmd, "TD_NF");
7413 if (val) {
7414 /* TODO */
7415 send_resp(dut, conn, SIGMA_ERROR,
7416 "ErrorCode,TD_NF not yet supported");
7417 return 0;
7418 }
7419
7420 val = get_param(cmd, "PMFFrameType");
7421 if (val == NULL)
7422 val = get_param(cmd, "FrameName");
7423 if (val == NULL)
7424 val = get_param(cmd, "Type");
7425 if (val == NULL)
7426 return -1;
7427 if (strcasecmp(val, "disassoc") == 0)
7428 frame = DISASSOC;
7429 else if (strcasecmp(val, "deauth") == 0)
7430 frame = DEAUTH;
7431 else if (strcasecmp(val, "saquery") == 0)
7432 frame = SAQUERY;
7433 else if (strcasecmp(val, "auth") == 0)
7434 frame = AUTH;
7435 else if (strcasecmp(val, "assocreq") == 0)
7436 frame = ASSOCREQ;
7437 else if (strcasecmp(val, "reassocreq") == 0)
7438 frame = REASSOCREQ;
7439 else if (strcasecmp(val, "neigreq") == 0) {
7440 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
7441
7442 val = get_param(cmd, "ssid");
7443 if (val == NULL)
7444 return -1;
7445
7446 res = send_neighbor_request(dut, intf, val);
7447 if (res) {
7448 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
7449 "Failed to send neighbor report request");
7450 return 0;
7451 }
7452
7453 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307454 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
7455 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007456 sigma_dut_print(dut, DUT_MSG_DEBUG,
7457 "Got Transition Management Query");
7458
Ashwini Patil5acd7382017-04-13 15:55:04 +05307459 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007460 if (res) {
7461 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
7462 "Failed to send Transition Management Query");
7463 return 0;
7464 }
7465
7466 return 1;
7467 } else {
7468 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
7469 "PMFFrameType");
7470 return 0;
7471 }
7472
7473 val = get_param(cmd, "PMFProtected");
7474 if (val == NULL)
7475 val = get_param(cmd, "Protected");
7476 if (val == NULL)
7477 return -1;
7478 if (strcasecmp(val, "Correct-key") == 0 ||
7479 strcasecmp(val, "CorrectKey") == 0)
7480 protected = CORRECT_KEY;
7481 else if (strcasecmp(val, "IncorrectKey") == 0)
7482 protected = INCORRECT_KEY;
7483 else if (strcasecmp(val, "Unprotected") == 0)
7484 protected = UNPROTECTED;
7485 else {
7486 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
7487 "PMFProtected");
7488 return 0;
7489 }
7490
7491 if (protected != UNPROTECTED &&
7492 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
7493 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
7494 "PMFProtected for auth/assocreq/reassocreq");
7495 return 0;
7496 }
7497
7498 if (if_nametoindex("sigmadut") == 0) {
7499 snprintf(buf, sizeof(buf),
7500 "iw dev %s interface add sigmadut type monitor",
7501 get_station_ifname());
7502 if (system(buf) != 0 ||
7503 if_nametoindex("sigmadut") == 0) {
7504 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
7505 "monitor interface with '%s'", buf);
7506 return -2;
7507 }
7508 }
7509
7510 if (system("ifconfig sigmadut up") != 0) {
7511 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7512 "monitor interface up");
7513 return -2;
7514 }
7515
7516 return sta_inject_frame(dut, conn, frame, protected, NULL);
7517}
7518
7519
7520static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
7521 struct sigma_conn *conn,
7522 struct sigma_cmd *cmd,
7523 const char *ifname)
7524{
7525 char buf[200];
7526 const char *val;
7527
7528 val = get_param(cmd, "ClearARP");
7529 if (val && atoi(val) == 1) {
7530 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
7531 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7532 if (system(buf) != 0) {
7533 send_resp(dut, conn, SIGMA_ERROR,
7534 "errorCode,Failed to clear ARP cache");
7535 return 0;
7536 }
7537 }
7538
7539 return 1;
7540}
7541
7542
7543int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
7544 struct sigma_cmd *cmd)
7545{
7546 const char *intf = get_param(cmd, "Interface");
7547 const char *val;
7548
7549 if (intf == NULL)
7550 return -1;
7551
7552 val = get_param(cmd, "program");
7553 if (val && (strcasecmp(val, "HS2") == 0 ||
7554 strcasecmp(val, "HS2-R2") == 0))
7555 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
7556
7557 return -1;
7558}
7559
7560
7561static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
7562 struct sigma_cmd *cmd)
7563{
7564 const char *intf = get_param(cmd, "Interface");
7565 const char *mac = get_param(cmd, "MAC");
7566
7567 if (intf == NULL || mac == NULL)
7568 return -1;
7569
7570 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
7571 "interface %s to %s", intf, mac);
7572
7573 if (dut->set_macaddr) {
7574 char buf[128];
7575 int res;
7576 if (strcasecmp(mac, "default") == 0) {
7577 res = snprintf(buf, sizeof(buf), "%s",
7578 dut->set_macaddr);
7579 dut->tmp_mac_addr = 0;
7580 } else {
7581 res = snprintf(buf, sizeof(buf), "%s %s",
7582 dut->set_macaddr, mac);
7583 dut->tmp_mac_addr = 1;
7584 }
7585 if (res < 0 || res >= (int) sizeof(buf))
7586 return -1;
7587 if (system(buf) != 0) {
7588 send_resp(dut, conn, SIGMA_ERROR,
7589 "errorCode,Failed to set MAC "
7590 "address");
7591 return 0;
7592 }
7593 return 1;
7594 }
7595
7596 if (strcasecmp(mac, "default") == 0)
7597 return 1;
7598
7599 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
7600 "command");
7601 return 0;
7602}
7603
7604
7605static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
7606 struct sigma_conn *conn, const char *intf,
7607 int val)
7608{
7609 char buf[200];
7610 int res;
7611
7612 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
7613 intf, val);
7614 if (res < 0 || res >= (int) sizeof(buf))
7615 return -1;
7616 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7617 if (system(buf) != 0) {
7618 send_resp(dut, conn, SIGMA_ERROR,
7619 "errorCode,Failed to configure offchannel mode");
7620 return 0;
7621 }
7622
7623 return 1;
7624}
7625
7626
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007627static int off_chan_val(enum sec_ch_offset off)
7628{
7629 switch (off) {
7630 case SEC_CH_NO:
7631 return 0;
7632 case SEC_CH_40ABOVE:
7633 return 40;
7634 case SEC_CH_40BELOW:
7635 return -40;
7636 }
7637
7638 return 0;
7639}
7640
7641
7642static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
7643 const char *intf, int off_ch_num,
7644 enum sec_ch_offset sec)
7645{
7646 char buf[200];
7647 int res;
7648
7649 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
7650 intf, off_ch_num);
7651 if (res < 0 || res >= (int) sizeof(buf))
7652 return -1;
7653 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7654 if (system(buf) != 0) {
7655 send_resp(dut, conn, SIGMA_ERROR,
7656 "errorCode,Failed to set offchan");
7657 return 0;
7658 }
7659
7660 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
7661 intf, off_chan_val(sec));
7662 if (res < 0 || res >= (int) sizeof(buf))
7663 return -1;
7664 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7665 if (system(buf) != 0) {
7666 send_resp(dut, conn, SIGMA_ERROR,
7667 "errorCode,Failed to set sec chan offset");
7668 return 0;
7669 }
7670
7671 return 1;
7672}
7673
7674
7675static int tdls_set_offchannel_offset(struct sigma_dut *dut,
7676 struct sigma_conn *conn,
7677 const char *intf, int off_ch_num,
7678 enum sec_ch_offset sec)
7679{
7680 char buf[200];
7681 int res;
7682
7683 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
7684 off_ch_num);
7685 if (res < 0 || res >= (int) sizeof(buf))
7686 return -1;
7687 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7688
7689 if (wpa_command(intf, buf) < 0) {
7690 send_resp(dut, conn, SIGMA_ERROR,
7691 "ErrorCode,Failed to set offchan");
7692 return 0;
7693 }
7694 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
7695 off_chan_val(sec));
7696 if (res < 0 || res >= (int) sizeof(buf))
7697 return -1;
7698
7699 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7700
7701 if (wpa_command(intf, buf) < 0) {
7702 send_resp(dut, conn, SIGMA_ERROR,
7703 "ErrorCode,Failed to set sec chan offset");
7704 return 0;
7705 }
7706
7707 return 1;
7708}
7709
7710
7711static int tdls_set_offchannel_mode(struct sigma_dut *dut,
7712 struct sigma_conn *conn,
7713 const char *intf, int val)
7714{
7715 char buf[200];
7716 int res;
7717
7718 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
7719 val);
7720 if (res < 0 || res >= (int) sizeof(buf))
7721 return -1;
7722 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7723
7724 if (wpa_command(intf, buf) < 0) {
7725 send_resp(dut, conn, SIGMA_ERROR,
7726 "ErrorCode,Failed to configure offchannel mode");
7727 return 0;
7728 }
7729
7730 return 1;
7731}
7732
7733
7734static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
7735 struct sigma_conn *conn,
7736 struct sigma_cmd *cmd)
7737{
7738 const char *val;
7739 enum {
7740 CHSM_NOT_SET,
7741 CHSM_ENABLE,
7742 CHSM_DISABLE,
7743 CHSM_REJREQ,
7744 CHSM_UNSOLRESP
7745 } chsm = CHSM_NOT_SET;
7746 int off_ch_num = -1;
7747 enum sec_ch_offset sec_ch = SEC_CH_NO;
7748 int res;
7749
7750 val = get_param(cmd, "Uapsd");
7751 if (val) {
7752 char buf[100];
7753 if (strcasecmp(val, "Enable") == 0)
7754 snprintf(buf, sizeof(buf), "SET ps 99");
7755 else if (strcasecmp(val, "Disable") == 0)
7756 snprintf(buf, sizeof(buf), "SET ps 98");
7757 else {
7758 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
7759 "Unsupported uapsd parameter value");
7760 return 0;
7761 }
7762 if (wpa_command(intf, buf)) {
7763 send_resp(dut, conn, SIGMA_ERROR,
7764 "ErrorCode,Failed to change U-APSD "
7765 "powersave mode");
7766 return 0;
7767 }
7768 }
7769
7770 val = get_param(cmd, "TPKTIMER");
7771 if (val && strcasecmp(val, "DISABLE") == 0) {
7772 if (wpa_command(intf, "SET tdls_testing 0x100")) {
7773 send_resp(dut, conn, SIGMA_ERROR,
7774 "ErrorCode,Failed to enable no TPK "
7775 "expiration test mode");
7776 return 0;
7777 }
7778 dut->no_tpk_expiration = 1;
7779 }
7780
7781 val = get_param(cmd, "ChSwitchMode");
7782 if (val) {
7783 if (strcasecmp(val, "Enable") == 0 ||
7784 strcasecmp(val, "Initiate") == 0)
7785 chsm = CHSM_ENABLE;
7786 else if (strcasecmp(val, "Disable") == 0 ||
7787 strcasecmp(val, "passive") == 0)
7788 chsm = CHSM_DISABLE;
7789 else if (strcasecmp(val, "RejReq") == 0)
7790 chsm = CHSM_REJREQ;
7791 else if (strcasecmp(val, "UnSolResp") == 0)
7792 chsm = CHSM_UNSOLRESP;
7793 else {
7794 send_resp(dut, conn, SIGMA_ERROR,
7795 "ErrorCode,Unknown ChSwitchMode value");
7796 return 0;
7797 }
7798 }
7799
7800 val = get_param(cmd, "OffChNum");
7801 if (val) {
7802 off_ch_num = atoi(val);
7803 if (off_ch_num == 0) {
7804 send_resp(dut, conn, SIGMA_ERROR,
7805 "ErrorCode,Invalid OffChNum");
7806 return 0;
7807 }
7808 }
7809
7810 val = get_param(cmd, "SecChOffset");
7811 if (val) {
7812 if (strcmp(val, "20") == 0)
7813 sec_ch = SEC_CH_NO;
7814 else if (strcasecmp(val, "40above") == 0)
7815 sec_ch = SEC_CH_40ABOVE;
7816 else if (strcasecmp(val, "40below") == 0)
7817 sec_ch = SEC_CH_40BELOW;
7818 else {
7819 send_resp(dut, conn, SIGMA_ERROR,
7820 "ErrorCode,Unknown SecChOffset value");
7821 return 0;
7822 }
7823 }
7824
7825 if (chsm == CHSM_NOT_SET) {
7826 /* no offchannel changes requested */
7827 return 1;
7828 }
7829
7830 if (strcmp(intf, get_main_ifname()) != 0 &&
7831 strcmp(intf, get_station_ifname()) != 0) {
7832 send_resp(dut, conn, SIGMA_ERROR,
7833 "ErrorCode,Unknown interface");
7834 return 0;
7835 }
7836
7837 switch (chsm) {
7838 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +03007839 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007840 break;
7841 case CHSM_ENABLE:
7842 if (off_ch_num < 0) {
7843 send_resp(dut, conn, SIGMA_ERROR,
7844 "ErrorCode,Missing OffChNum argument");
7845 return 0;
7846 }
7847 if (wifi_chip_type == DRIVER_WCN) {
7848 res = tdls_set_offchannel_offset(dut, conn, intf,
7849 off_ch_num, sec_ch);
7850 } else {
7851 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
7852 sec_ch);
7853 }
7854 if (res != 1)
7855 return res;
7856 if (wifi_chip_type == DRIVER_WCN)
7857 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
7858 else
7859 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
7860 break;
7861 case CHSM_DISABLE:
7862 if (wifi_chip_type == DRIVER_WCN)
7863 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
7864 else
7865 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
7866 break;
7867 case CHSM_REJREQ:
7868 if (wifi_chip_type == DRIVER_WCN)
7869 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
7870 else
7871 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
7872 break;
7873 case CHSM_UNSOLRESP:
7874 if (off_ch_num < 0) {
7875 send_resp(dut, conn, SIGMA_ERROR,
7876 "ErrorCode,Missing OffChNum argument");
7877 return 0;
7878 }
7879 if (wifi_chip_type == DRIVER_WCN) {
7880 res = tdls_set_offchannel_offset(dut, conn, intf,
7881 off_ch_num, sec_ch);
7882 } else {
7883 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
7884 sec_ch);
7885 }
7886 if (res != 1)
7887 return res;
7888 if (wifi_chip_type == DRIVER_WCN)
7889 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
7890 else
7891 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
7892 break;
7893 }
7894
7895 return res;
7896}
7897
7898
7899static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
7900 struct sigma_conn *conn,
7901 struct sigma_cmd *cmd)
7902{
7903 const char *val;
7904 char *token, *result;
7905
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007906 novap_reset(dut, intf);
7907
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007908 val = get_param(cmd, "nss_mcs_opt");
7909 if (val) {
7910 /* String (nss_operating_mode; mcs_operating_mode) */
7911 int nss, mcs;
7912 char buf[50];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307913 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007914
7915 token = strdup(val);
7916 if (!token)
7917 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307918 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05307919 if (!result) {
7920 sigma_dut_print(dut, DUT_MSG_ERROR,
7921 "VHT NSS not specified");
7922 goto failed;
7923 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007924 if (strcasecmp(result, "def") != 0) {
7925 nss = atoi(result);
7926 if (nss == 4)
7927 ath_disable_txbf(dut, intf);
7928 snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
7929 intf, nss);
7930 if (system(buf) != 0) {
7931 sigma_dut_print(dut, DUT_MSG_ERROR,
7932 "iwpriv nss failed");
7933 goto failed;
7934 }
7935 }
7936
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307937 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05307938 if (!result) {
7939 sigma_dut_print(dut, DUT_MSG_ERROR,
7940 "VHT MCS not specified");
7941 goto failed;
7942 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007943 if (strcasecmp(result, "def") == 0) {
7944 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0",
7945 intf);
7946 if (system(buf) != 0) {
7947 sigma_dut_print(dut, DUT_MSG_ERROR,
7948 "iwpriv set11NRates failed");
7949 goto failed;
7950 }
7951
7952 } else {
7953 mcs = atoi(result);
7954 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
7955 intf, mcs);
7956 if (system(buf) != 0) {
7957 sigma_dut_print(dut, DUT_MSG_ERROR,
7958 "iwpriv vhtmcs failed");
7959 goto failed;
7960 }
7961 }
7962 /* Channel width gets messed up, fix this */
7963 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
7964 intf, dut->chwidth);
7965 if (system(buf) != 0) {
7966 sigma_dut_print(dut, DUT_MSG_ERROR,
7967 "iwpriv chwidth failed");
7968 }
7969 }
7970
7971 return 1;
7972failed:
7973 free(token);
7974 return 0;
7975}
7976
7977
7978static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
7979 struct sigma_conn *conn,
7980 struct sigma_cmd *cmd)
7981{
7982 switch (get_driver_type()) {
7983 case DRIVER_ATHEROS:
7984 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
7985 default:
7986 send_resp(dut, conn, SIGMA_ERROR,
7987 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
7988 return 0;
7989 }
7990}
7991
7992
Ashwini Patil5acd7382017-04-13 15:55:04 +05307993static int btm_query_candidate_list(struct sigma_dut *dut,
7994 struct sigma_conn *conn,
7995 struct sigma_cmd *cmd)
7996{
7997 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
7998 int len, ret;
7999 char buf[10];
8000
8001 /*
8002 * Neighbor Report elements format:
8003 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
8004 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
8005 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
8006 */
8007
8008 bssid = get_param(cmd, "Nebor_BSSID");
8009 if (!bssid) {
8010 send_resp(dut, conn, SIGMA_INVALID,
8011 "errorCode,Nebor_BSSID is missing");
8012 return 0;
8013 }
8014
8015 info = get_param(cmd, "Nebor_Bssid_Info");
8016 if (!info) {
8017 sigma_dut_print(dut, DUT_MSG_INFO,
8018 "Using default value for Nebor_Bssid_Info: %s",
8019 DEFAULT_NEIGHBOR_BSSID_INFO);
8020 info = DEFAULT_NEIGHBOR_BSSID_INFO;
8021 }
8022
8023 op_class = get_param(cmd, "Nebor_Op_Class");
8024 if (!op_class) {
8025 send_resp(dut, conn, SIGMA_INVALID,
8026 "errorCode,Nebor_Op_Class is missing");
8027 return 0;
8028 }
8029
8030 ch = get_param(cmd, "Nebor_Op_Ch");
8031 if (!ch) {
8032 send_resp(dut, conn, SIGMA_INVALID,
8033 "errorCode,Nebor_Op_Ch is missing");
8034 return 0;
8035 }
8036
8037 phy_type = get_param(cmd, "Nebor_Phy_Type");
8038 if (!phy_type) {
8039 sigma_dut_print(dut, DUT_MSG_INFO,
8040 "Using default value for Nebor_Phy_Type: %s",
8041 DEFAULT_NEIGHBOR_PHY_TYPE);
8042 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
8043 }
8044
8045 /* Parse optional subelements */
8046 buf[0] = '\0';
8047 pref = get_param(cmd, "Nebor_Pref");
8048 if (pref) {
8049 /* hexdump for preferrence subelement */
8050 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
8051 if (ret < 0 || ret >= (int) sizeof(buf)) {
8052 sigma_dut_print(dut, DUT_MSG_ERROR,
8053 "snprintf failed for optional subelement ret: %d",
8054 ret);
8055 send_resp(dut, conn, SIGMA_ERROR,
8056 "errorCode,snprintf failed for subelement");
8057 return 0;
8058 }
8059 }
8060
8061 if (!dut->btm_query_cand_list) {
8062 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
8063 if (!dut->btm_query_cand_list) {
8064 send_resp(dut, conn, SIGMA_ERROR,
8065 "errorCode,Failed to allocate memory for btm_query_cand_list");
8066 return 0;
8067 }
8068 }
8069
8070 len = strlen(dut->btm_query_cand_list);
8071 ret = snprintf(dut->btm_query_cand_list + len,
8072 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
8073 bssid, info, op_class, ch, phy_type, buf);
8074 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
8075 sigma_dut_print(dut, DUT_MSG_ERROR,
8076 "snprintf failed for neighbor report list ret: %d",
8077 ret);
8078 send_resp(dut, conn, SIGMA_ERROR,
8079 "errorCode,snprintf failed for neighbor report");
8080 free(dut->btm_query_cand_list);
8081 dut->btm_query_cand_list = NULL;
8082 return 0;
8083 }
8084
8085 return 1;
8086}
8087
8088
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008089static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
8090 struct sigma_cmd *cmd)
8091{
8092 const char *intf = get_param(cmd, "Interface");
8093 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +05308094 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008095
8096 if (intf == NULL || prog == NULL)
8097 return -1;
8098
Ashwini Patil5acd7382017-04-13 15:55:04 +05308099 /* BSS Transition candidate list for BTM query */
8100 val = get_param(cmd, "Nebor_BSSID");
8101 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
8102 return 0;
8103
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008104 if (strcasecmp(prog, "TDLS") == 0)
8105 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
8106
8107 if (strcasecmp(prog, "VHT") == 0)
8108 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
8109
Ashwini Patil68d02cd2017-01-10 15:39:16 +05308110 if (strcasecmp(prog, "MBO") == 0) {
8111 val = get_param(cmd, "Cellular_Data_Cap");
8112 if (val &&
8113 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
8114 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05308115
8116 val = get_param(cmd, "Ch_Pref");
8117 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
8118 return 0;
8119
Ashwini Patil68d02cd2017-01-10 15:39:16 +05308120 return 1;
8121 }
8122
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008123 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
8124 return 0;
8125}
8126
8127
8128static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
8129 struct sigma_cmd *cmd)
8130{
8131 const char *intf = get_param(cmd, "Interface");
8132 const char *mode = get_param(cmd, "Mode");
8133 int res;
8134
8135 if (intf == NULL || mode == NULL)
8136 return -1;
8137
8138 if (strcasecmp(mode, "On") == 0)
8139 res = wpa_command(intf, "SET radio_disabled 0");
8140 else if (strcasecmp(mode, "Off") == 0)
8141 res = wpa_command(intf, "SET radio_disabled 1");
8142 else
8143 return -1;
8144
8145 if (res) {
8146 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
8147 "radio mode");
8148 return 0;
8149 }
8150
8151 return 1;
8152}
8153
8154
8155static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
8156 struct sigma_cmd *cmd)
8157{
8158 const char *intf = get_param(cmd, "Interface");
8159 const char *mode = get_param(cmd, "Mode");
8160 int res;
8161
8162 if (intf == NULL || mode == NULL)
8163 return -1;
8164
8165 if (strcasecmp(mode, "On") == 0)
8166 res = set_ps(intf, dut, 1);
8167 else if (strcasecmp(mode, "Off") == 0)
8168 res = set_ps(intf, dut, 0);
8169 else
8170 return -1;
8171
8172 if (res) {
8173 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
8174 "power save mode");
8175 return 0;
8176 }
8177
8178 return 1;
8179}
8180
8181
8182static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
8183 struct sigma_cmd *cmd)
8184{
8185 const char *intf = get_param(cmd, "Interface");
8186 const char *val, *bssid;
8187 int res;
8188 char *buf;
8189 size_t buf_len;
8190
8191 val = get_param(cmd, "BSSID_FILTER");
8192 if (val == NULL)
8193 return -1;
8194
8195 bssid = get_param(cmd, "BSSID_List");
8196 if (atoi(val) == 0 || bssid == NULL) {
8197 /* Disable BSSID filter */
8198 if (wpa_command(intf, "SET bssid_filter ")) {
8199 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
8200 "to disable BSSID filter");
8201 return 0;
8202 }
8203
8204 return 1;
8205 }
8206
8207 buf_len = 100 + strlen(bssid);
8208 buf = malloc(buf_len);
8209 if (buf == NULL)
8210 return -1;
8211
8212 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
8213 res = wpa_command(intf, buf);
8214 free(buf);
8215 if (res) {
8216 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
8217 "BSSID filter");
8218 return 0;
8219 }
8220
8221 return 1;
8222}
8223
8224
8225static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
8226 struct sigma_cmd *cmd)
8227{
8228 const char *intf = get_param(cmd, "Interface");
8229 const char *val;
8230
8231 /* TODO: ARP */
8232
8233 val = get_param(cmd, "HS2_CACHE_PROFILE");
8234 if (val && strcasecmp(val, "All") == 0)
8235 hs2_clear_credentials(intf);
8236
8237 return 1;
8238}
8239
8240
8241static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
8242 struct sigma_cmd *cmd)
8243{
8244 const char *intf = get_param(cmd, "Interface");
8245 const char *key_type = get_param(cmd, "KeyType");
8246 char buf[100], resp[200];
8247
8248 if (key_type == NULL)
8249 return -1;
8250
8251 if (strcasecmp(key_type, "GTK") == 0) {
8252 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
8253 strncmp(buf, "FAIL", 4) == 0) {
8254 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8255 "not fetch current GTK");
8256 return 0;
8257 }
8258 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
8259 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8260 return 0;
8261 } else {
8262 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
8263 "KeyType");
8264 return 0;
8265 }
8266
8267 return 1;
8268}
8269
8270
8271static int hs2_set_policy(struct sigma_dut *dut)
8272{
8273#ifdef ANDROID
8274 system("ip rule del prio 23000");
8275 if (system("ip rule add from all lookup main prio 23000") != 0) {
8276 sigma_dut_print(dut, DUT_MSG_ERROR,
8277 "Failed to run:ip rule add from all lookup main prio");
8278 return -1;
8279 }
8280 if (system("ip route flush cache") != 0) {
8281 sigma_dut_print(dut, DUT_MSG_ERROR,
8282 "Failed to run ip route flush cache");
8283 return -1;
8284 }
8285 return 1;
8286#else /* ANDROID */
8287 return 0;
8288#endif /* ANDROID */
8289}
8290
8291
8292static int cmd_sta_hs2_associate(struct sigma_dut *dut,
8293 struct sigma_conn *conn,
8294 struct sigma_cmd *cmd)
8295{
8296 const char *intf = get_param(cmd, "Interface");
8297 const char *val = get_param(cmd, "Ignore_blacklist");
8298 struct wpa_ctrl *ctrl;
8299 int res;
8300 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
8301 int tries = 0;
8302 int ignore_blacklist = 0;
8303 const char *events[] = {
8304 "CTRL-EVENT-CONNECTED",
8305 "INTERWORKING-BLACKLISTED",
8306 "INTERWORKING-NO-MATCH",
8307 NULL
8308 };
8309
8310 start_sta_mode(dut);
8311
8312 blacklisted[0] = '\0';
8313 if (val && atoi(val))
8314 ignore_blacklist = 1;
8315
8316try_again:
8317 ctrl = open_wpa_mon(intf);
8318 if (ctrl == NULL) {
8319 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
8320 "wpa_supplicant monitor connection");
8321 return -2;
8322 }
8323
8324 tries++;
8325 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
8326 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
8327 "Interworking connection");
8328 wpa_ctrl_detach(ctrl);
8329 wpa_ctrl_close(ctrl);
8330 return 0;
8331 }
8332
8333 buf[0] = '\0';
8334 while (1) {
8335 char *pos;
8336 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
8337 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
8338 if (!pos)
8339 break;
8340 pos += 25;
8341 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
8342 pos);
8343 if (!blacklisted[0])
8344 memcpy(blacklisted, pos, strlen(pos) + 1);
8345 }
8346
8347 if (ignore_blacklist && blacklisted[0]) {
8348 char *end;
8349 end = strchr(blacklisted, ' ');
8350 if (end)
8351 *end = '\0';
8352 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
8353 blacklisted);
8354 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
8355 blacklisted);
8356 if (wpa_command(intf, buf)) {
8357 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
8358 wpa_ctrl_detach(ctrl);
8359 wpa_ctrl_close(ctrl);
8360 return 0;
8361 }
8362 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
8363 buf, sizeof(buf));
8364 }
8365
8366 wpa_ctrl_detach(ctrl);
8367 wpa_ctrl_close(ctrl);
8368
8369 if (res < 0) {
8370 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
8371 "connect");
8372 return 0;
8373 }
8374
8375 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
8376 strstr(buf, "INTERWORKING-BLACKLISTED")) {
8377 if (tries < 2) {
8378 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
8379 goto try_again;
8380 }
8381 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
8382 "matching credentials found");
8383 return 0;
8384 }
8385
8386 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
8387 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
8388 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
8389 "get current BSSID/SSID");
8390 return 0;
8391 }
8392
8393 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
8394 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8395 hs2_set_policy(dut);
8396 return 0;
8397}
8398
8399
8400static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
8401 struct sigma_conn *conn,
8402 const char *ifname,
8403 struct sigma_cmd *cmd)
8404{
8405 const char *val;
8406 int id;
8407
8408 id = add_cred(ifname);
8409 if (id < 0)
8410 return -2;
8411 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
8412
8413 val = get_param(cmd, "prefer");
8414 if (val && atoi(val) > 0)
8415 set_cred(ifname, id, "priority", "1");
8416
8417 val = get_param(cmd, "REALM");
8418 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
8419 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8420 "realm");
8421 return 0;
8422 }
8423
8424 val = get_param(cmd, "HOME_FQDN");
8425 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
8426 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8427 "home_fqdn");
8428 return 0;
8429 }
8430
8431 val = get_param(cmd, "Username");
8432 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
8433 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8434 "username");
8435 return 0;
8436 }
8437
8438 val = get_param(cmd, "Password");
8439 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
8440 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8441 "password");
8442 return 0;
8443 }
8444
8445 val = get_param(cmd, "ROOT_CA");
8446 if (val) {
8447 char fname[200];
8448 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
8449#ifdef __linux__
8450 if (!file_exists(fname)) {
8451 char msg[300];
8452 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
8453 "file (%s) not found", fname);
8454 send_resp(dut, conn, SIGMA_ERROR, msg);
8455 return 0;
8456 }
8457#endif /* __linux__ */
8458 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
8459 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8460 "not set root CA");
8461 return 0;
8462 }
8463 }
8464
8465 return 1;
8466}
8467
8468
8469static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
8470{
8471 FILE *in, *out;
8472 char buf[500];
8473 int found = 0;
8474
8475 in = fopen("devdetail.xml", "r");
8476 if (in == NULL)
8477 return -1;
8478 out = fopen("devdetail.xml.tmp", "w");
8479 if (out == NULL) {
8480 fclose(in);
8481 return -1;
8482 }
8483
8484 while (fgets(buf, sizeof(buf), in)) {
8485 char *pos = strstr(buf, "<IMSI>");
8486 if (pos) {
8487 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
8488 imsi);
8489 pos += 6;
8490 *pos = '\0';
8491 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
8492 found++;
8493 } else {
8494 fprintf(out, "%s", buf);
8495 }
8496 }
8497
8498 fclose(out);
8499 fclose(in);
8500 if (found)
8501 rename("devdetail.xml.tmp", "devdetail.xml");
8502 else
8503 unlink("devdetail.xml.tmp");
8504
8505 return 0;
8506}
8507
8508
8509static int sta_add_credential_sim(struct sigma_dut *dut,
8510 struct sigma_conn *conn,
8511 const char *ifname, struct sigma_cmd *cmd)
8512{
8513 const char *val, *imsi = NULL;
8514 int id;
8515 char buf[200];
8516 int res;
8517 const char *pos;
8518 size_t mnc_len;
8519 char plmn_mcc[4];
8520 char plmn_mnc[4];
8521
8522 id = add_cred(ifname);
8523 if (id < 0)
8524 return -2;
8525 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
8526
8527 val = get_param(cmd, "prefer");
8528 if (val && atoi(val) > 0)
8529 set_cred(ifname, id, "priority", "1");
8530
8531 val = get_param(cmd, "PLMN_MCC");
8532 if (val == NULL) {
8533 send_resp(dut, conn, SIGMA_ERROR,
8534 "errorCode,Missing PLMN_MCC");
8535 return 0;
8536 }
8537 if (strlen(val) != 3) {
8538 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
8539 return 0;
8540 }
8541 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
8542
8543 val = get_param(cmd, "PLMN_MNC");
8544 if (val == NULL) {
8545 send_resp(dut, conn, SIGMA_ERROR,
8546 "errorCode,Missing PLMN_MNC");
8547 return 0;
8548 }
8549 if (strlen(val) != 2 && strlen(val) != 3) {
8550 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
8551 return 0;
8552 }
8553 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
8554
8555 val = get_param(cmd, "IMSI");
8556 if (val == NULL) {
8557 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
8558 "IMSI");
8559 return 0;
8560 }
8561
8562 imsi = pos = val;
8563
8564 if (strncmp(plmn_mcc, pos, 3) != 0) {
8565 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
8566 return 0;
8567 }
8568 pos += 3;
8569
8570 mnc_len = strlen(plmn_mnc);
8571 if (mnc_len < 2) {
8572 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
8573 return 0;
8574 }
8575
8576 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
8577 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
8578 return 0;
8579 }
8580 pos += mnc_len;
8581
8582 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
8583 if (res < 0 || res >= (int) sizeof(buf))
8584 return -1;
8585 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
8586 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8587 "not set IMSI");
8588 return 0;
8589 }
8590
8591 val = get_param(cmd, "Password");
8592 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
8593 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8594 "not set password");
8595 return 0;
8596 }
8597
8598 if (dut->program == PROGRAM_HS2_R2) {
8599 /*
8600 * Set provisioning_sp for the test cases where SIM/USIM
8601 * provisioning is used.
8602 */
8603 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
8604 "wi-fi.org") < 0) {
8605 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8606 "not set provisioning_sp");
8607 return 0;
8608 }
8609
8610 update_devdetail_imsi(dut, imsi);
8611 }
8612
8613 return 1;
8614}
8615
8616
8617static int sta_add_credential_cert(struct sigma_dut *dut,
8618 struct sigma_conn *conn,
8619 const char *ifname,
8620 struct sigma_cmd *cmd)
8621{
8622 const char *val;
8623 int id;
8624
8625 id = add_cred(ifname);
8626 if (id < 0)
8627 return -2;
8628 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
8629
8630 val = get_param(cmd, "prefer");
8631 if (val && atoi(val) > 0)
8632 set_cred(ifname, id, "priority", "1");
8633
8634 val = get_param(cmd, "REALM");
8635 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
8636 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8637 "realm");
8638 return 0;
8639 }
8640
8641 val = get_param(cmd, "HOME_FQDN");
8642 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
8643 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8644 "home_fqdn");
8645 return 0;
8646 }
8647
8648 val = get_param(cmd, "Username");
8649 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
8650 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8651 "username");
8652 return 0;
8653 }
8654
8655 val = get_param(cmd, "clientCertificate");
8656 if (val) {
8657 char fname[200];
8658 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
8659#ifdef __linux__
8660 if (!file_exists(fname)) {
8661 char msg[300];
8662 snprintf(msg, sizeof(msg),
8663 "ErrorCode,clientCertificate "
8664 "file (%s) not found", fname);
8665 send_resp(dut, conn, SIGMA_ERROR, msg);
8666 return 0;
8667 }
8668#endif /* __linux__ */
8669 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
8670 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8671 "not set client_cert");
8672 return 0;
8673 }
8674 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
8675 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8676 "not set private_key");
8677 return 0;
8678 }
8679 }
8680
8681 val = get_param(cmd, "ROOT_CA");
8682 if (val) {
8683 char fname[200];
8684 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
8685#ifdef __linux__
8686 if (!file_exists(fname)) {
8687 char msg[300];
8688 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
8689 "file (%s) not found", fname);
8690 send_resp(dut, conn, SIGMA_ERROR, msg);
8691 return 0;
8692 }
8693#endif /* __linux__ */
8694 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
8695 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8696 "not set root CA");
8697 return 0;
8698 }
8699 }
8700
8701 return 1;
8702}
8703
8704
8705static int cmd_sta_add_credential(struct sigma_dut *dut,
8706 struct sigma_conn *conn,
8707 struct sigma_cmd *cmd)
8708{
8709 const char *intf = get_param(cmd, "Interface");
8710 const char *type;
8711
8712 start_sta_mode(dut);
8713
8714 type = get_param(cmd, "Type");
8715 if (!type)
8716 return -1;
8717
8718 if (strcasecmp(type, "uname_pwd") == 0)
8719 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
8720
8721 if (strcasecmp(type, "sim") == 0)
8722 return sta_add_credential_sim(dut, conn, intf, cmd);
8723
8724 if (strcasecmp(type, "cert") == 0)
8725 return sta_add_credential_cert(dut, conn, intf, cmd);
8726
8727 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
8728 "type");
8729 return 0;
8730}
8731
8732
8733static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
8734 struct sigma_cmd *cmd)
8735{
8736 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +05308737 const char *val, *bssid, *ssid;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008738 char buf[100];
vamsi krishna89ad8c62017-09-19 12:51:18 +05308739 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008740 int res;
8741
8742 val = get_param(cmd, "HESSID");
8743 if (val) {
8744 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
8745 if (res < 0 || res >= (int) sizeof(buf))
8746 return -1;
8747 wpa_command(intf, buf);
8748 }
8749
8750 val = get_param(cmd, "ACCS_NET_TYPE");
8751 if (val) {
8752 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
8753 val);
8754 if (res < 0 || res >= (int) sizeof(buf))
8755 return -1;
8756 wpa_command(intf, buf);
8757 }
8758
vamsi krishna89ad8c62017-09-19 12:51:18 +05308759 bssid = get_param(cmd, "Bssid");
8760 ssid = get_param(cmd, "Ssid");
8761
8762 if (ssid) {
8763 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
8764 send_resp(dut, conn, SIGMA_ERROR,
8765 "ErrorCode,Too long SSID");
8766 return 0;
8767 }
8768 ascii2hexstr(ssid, ssid_hex);
8769 }
8770
8771 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
8772 bssid ? " bssid=": "",
8773 bssid ? bssid : "",
8774 ssid ? " ssid " : "",
8775 ssid ? ssid_hex : "");
8776 if (res < 0 || res >= (int) sizeof(buf))
8777 return -1;
8778
8779 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008780 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
8781 "scan");
8782 return 0;
8783 }
8784
8785 return 1;
8786}
8787
8788
Jouni Malinen5e5d43d2018-01-10 17:29:33 +02008789static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
8790 struct sigma_cmd *cmd)
8791{
8792 const char *intf = get_param(cmd, "Interface");
8793 const char *bssid;
8794 char buf[4096], *pos;
8795 int freq, chan;
8796 char *ssid;
8797 char resp[100];
8798 int res;
8799 struct wpa_ctrl *ctrl;
8800
8801 bssid = get_param(cmd, "BSSID");
8802 if (!bssid) {
8803 send_resp(dut, conn, SIGMA_INVALID,
8804 "errorCode,BSSID argument is missing");
8805 return 0;
8806 }
8807
8808 ctrl = open_wpa_mon(intf);
8809 if (!ctrl) {
8810 sigma_dut_print(dut, DUT_MSG_ERROR,
8811 "Failed to open wpa_supplicant monitor connection");
8812 return -1;
8813 }
8814
8815 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
8816 send_resp(dut, conn, SIGMA_ERROR,
8817 "errorCode,Could not start scan");
8818 wpa_ctrl_detach(ctrl);
8819 wpa_ctrl_close(ctrl);
8820 return 0;
8821 }
8822
8823 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
8824 buf, sizeof(buf));
8825
8826 wpa_ctrl_detach(ctrl);
8827 wpa_ctrl_close(ctrl);
8828
8829 if (res < 0) {
8830 send_resp(dut, conn, SIGMA_ERROR,
8831 "errorCode,Scan did not complete");
8832 return 0;
8833 }
8834
8835 snprintf(buf, sizeof(buf), "BSS %s", bssid);
8836 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8837 strncmp(buf, "id=", 3) != 0) {
8838 send_resp(dut, conn, SIGMA_ERROR,
8839 "errorCode,Specified BSSID not found");
8840 return 0;
8841 }
8842
8843 pos = strstr(buf, "\nfreq=");
8844 if (!pos) {
8845 send_resp(dut, conn, SIGMA_ERROR,
8846 "errorCode,Channel not found");
8847 return 0;
8848 }
8849 freq = atoi(pos + 6);
8850 chan = freq_to_channel(freq);
8851
8852 pos = strstr(buf, "\nssid=");
8853 if (!pos) {
8854 send_resp(dut, conn, SIGMA_ERROR,
8855 "errorCode,SSID not found");
8856 return 0;
8857 }
8858 ssid = pos + 6;
8859 pos = strchr(ssid, '\n');
8860 if (pos)
8861 *pos = '\0';
8862 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
8863 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8864 return 0;
8865}
8866
8867
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008868static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
8869 struct sigma_cmd *cmd)
8870{
8871#ifdef __linux__
8872 struct timeval tv;
8873 struct tm tm;
8874 time_t t;
8875 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +05308876 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008877
8878 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
8879
8880 memset(&tm, 0, sizeof(tm));
8881 val = get_param(cmd, "seconds");
8882 if (val)
8883 tm.tm_sec = atoi(val);
8884 val = get_param(cmd, "minutes");
8885 if (val)
8886 tm.tm_min = atoi(val);
8887 val = get_param(cmd, "hours");
8888 if (val)
8889 tm.tm_hour = atoi(val);
8890 val = get_param(cmd, "date");
8891 if (val)
8892 tm.tm_mday = atoi(val);
8893 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +05308894 if (val) {
8895 v = atoi(val);
8896 if (v < 1 || v > 12) {
8897 send_resp(dut, conn, SIGMA_INVALID,
8898 "errorCode,Invalid month");
8899 return 0;
8900 }
8901 tm.tm_mon = v - 1;
8902 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008903 val = get_param(cmd, "year");
8904 if (val) {
8905 int year = atoi(val);
8906#ifdef ANDROID
8907 if (year > 2035)
8908 year = 2035; /* years beyond 2035 not supported */
8909#endif /* ANDROID */
8910 tm.tm_year = year - 1900;
8911 }
8912 t = mktime(&tm);
8913 if (t == (time_t) -1) {
8914 send_resp(dut, conn, SIGMA_ERROR,
8915 "errorCode,Invalid date or time");
8916 return 0;
8917 }
8918
8919 memset(&tv, 0, sizeof(tv));
8920 tv.tv_sec = t;
8921
8922 if (settimeofday(&tv, NULL) < 0) {
8923 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
8924 strerror(errno));
8925 send_resp(dut, conn, SIGMA_ERROR,
8926 "errorCode,Failed to set time");
8927 return 0;
8928 }
8929
8930 return 1;
8931#endif /* __linux__ */
8932
8933 return -1;
8934}
8935
8936
8937static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
8938 struct sigma_cmd *cmd)
8939{
8940 const char *intf = get_param(cmd, "Interface");
8941 const char *name, *val;
8942 int prod_ess_assoc = 1;
8943 char buf[200], bssid[100], ssid[100];
8944 int res;
8945 struct wpa_ctrl *ctrl;
8946
8947 name = get_param(cmd, "osuFriendlyName");
8948
8949 val = get_param(cmd, "ProdESSAssoc");
8950 if (val)
8951 prod_ess_assoc = atoi(val);
8952
8953 kill_dhcp_client(dut, intf);
8954 if (start_dhcp_client(dut, intf) < 0)
8955 return -2;
8956
8957 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
8958 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
8959 res = snprintf(buf, sizeof(buf),
8960 "%s %s%s%s signup osu-ca.pem",
8961 prod_ess_assoc ? "" : "-N",
8962 name ? "-O'" : "", name ? name : "",
8963 name ? "'" : "");
8964
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +05308965 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008966 if (run_hs20_osu(dut, buf) < 0) {
8967 FILE *f;
8968
8969 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
8970
8971 f = fopen("hs20-osu-client.res", "r");
8972 if (f) {
8973 char resp[400], res[300], *pos;
8974 if (!fgets(res, sizeof(res), f))
8975 res[0] = '\0';
8976 pos = strchr(res, '\n');
8977 if (pos)
8978 *pos = '\0';
8979 fclose(f);
8980 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
8981 res);
8982 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
8983 if (system(resp) != 0) {
8984 }
8985 snprintf(resp, sizeof(resp),
8986 "SSID,,BSSID,,failureReason,%s", res);
8987 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8988 return 0;
8989 }
8990
8991 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
8992 return 0;
8993 }
8994
8995 if (!prod_ess_assoc)
8996 goto report;
8997
8998 ctrl = open_wpa_mon(intf);
8999 if (ctrl == NULL) {
9000 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9001 "wpa_supplicant monitor connection");
9002 return -1;
9003 }
9004
9005 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
9006 buf, sizeof(buf));
9007
9008 wpa_ctrl_detach(ctrl);
9009 wpa_ctrl_close(ctrl);
9010
9011 if (res < 0) {
9012 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
9013 "network after OSU");
9014 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
9015 return 0;
9016 }
9017
9018report:
9019 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
9020 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
9021 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
9022 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
9023 return 0;
9024 }
9025
9026 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
9027 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009028 return 0;
9029}
9030
9031
9032static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
9033 struct sigma_cmd *cmd)
9034{
9035 const char *val;
9036 int timeout = 120;
9037
9038 val = get_param(cmd, "PolicyUpdate");
9039 if (val == NULL || atoi(val) == 0)
9040 return 1; /* No operation requested */
9041
9042 val = get_param(cmd, "Timeout");
9043 if (val)
9044 timeout = atoi(val);
9045
9046 if (timeout) {
9047 /* TODO: time out the command and return
9048 * PolicyUpdateStatus,TIMEOUT if needed. */
9049 }
9050
9051 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
9052 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
9053 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
9054 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
9055 return 0;
9056 }
9057
9058 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
9059 return 0;
9060}
9061
9062
9063static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
9064 struct sigma_cmd *cmd)
9065{
9066 struct wpa_ctrl *ctrl;
9067 const char *intf = get_param(cmd, "Interface");
9068 const char *bssid = get_param(cmd, "Bssid");
9069 const char *ssid = get_param(cmd, "SSID");
9070 const char *security = get_param(cmd, "Security");
9071 const char *passphrase = get_param(cmd, "Passphrase");
9072 const char *pin = get_param(cmd, "PIN");
9073 char buf[1000];
9074 char ssid_hex[200], passphrase_hex[200];
9075 const char *keymgmt, *cipher;
9076
9077 if (intf == NULL)
9078 intf = get_main_ifname();
9079
9080 if (!bssid) {
9081 send_resp(dut, conn, SIGMA_ERROR,
9082 "ErrorCode,Missing Bssid argument");
9083 return 0;
9084 }
9085
9086 if (!ssid) {
9087 send_resp(dut, conn, SIGMA_ERROR,
9088 "ErrorCode,Missing SSID argument");
9089 return 0;
9090 }
9091
9092 if (!security) {
9093 send_resp(dut, conn, SIGMA_ERROR,
9094 "ErrorCode,Missing Security argument");
9095 return 0;
9096 }
9097
9098 if (!passphrase) {
9099 send_resp(dut, conn, SIGMA_ERROR,
9100 "ErrorCode,Missing Passphrase argument");
9101 return 0;
9102 }
9103
9104 if (!pin) {
9105 send_resp(dut, conn, SIGMA_ERROR,
9106 "ErrorCode,Missing PIN argument");
9107 return 0;
9108 }
9109
vamsi krishna8c9c1562017-05-12 15:51:46 +05309110 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
9111 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009112 send_resp(dut, conn, SIGMA_ERROR,
9113 "ErrorCode,Too long SSID/passphrase");
9114 return 0;
9115 }
9116
9117 ctrl = open_wpa_mon(intf);
9118 if (ctrl == NULL) {
9119 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9120 "wpa_supplicant monitor connection");
9121 return -2;
9122 }
9123
9124 if (strcasecmp(security, "wpa2-psk") == 0) {
9125 keymgmt = "WPA2PSK";
9126 cipher = "CCMP";
9127 } else {
9128 wpa_ctrl_detach(ctrl);
9129 wpa_ctrl_close(ctrl);
9130 send_resp(dut, conn, SIGMA_ERROR,
9131 "ErrorCode,Unsupported Security value");
9132 return 0;
9133 }
9134
9135 ascii2hexstr(ssid, ssid_hex);
9136 ascii2hexstr(passphrase, passphrase_hex);
9137 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
9138 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
9139
9140 if (wpa_command(intf, buf) < 0) {
9141 wpa_ctrl_detach(ctrl);
9142 wpa_ctrl_close(ctrl);
9143 send_resp(dut, conn, SIGMA_ERROR,
9144 "ErrorCode,Failed to start registrar");
9145 return 0;
9146 }
9147
9148 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
9149 dut->er_oper_performed = 1;
9150
9151 return wps_connection_event(dut, conn, ctrl, intf, 0);
9152}
9153
9154
9155static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
9156 struct sigma_conn *conn,
9157 struct sigma_cmd *cmd)
9158{
9159 struct wpa_ctrl *ctrl;
9160 const char *intf = get_param(cmd, "Interface");
9161 const char *bssid = get_param(cmd, "Bssid");
9162 char buf[100];
9163
9164 if (!bssid) {
9165 send_resp(dut, conn, SIGMA_ERROR,
9166 "ErrorCode,Missing Bssid argument");
9167 return 0;
9168 }
9169
9170 ctrl = open_wpa_mon(intf);
9171 if (ctrl == NULL) {
9172 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9173 "wpa_supplicant monitor connection");
9174 return -2;
9175 }
9176
9177 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
9178
9179 if (wpa_command(intf, buf) < 0) {
9180 wpa_ctrl_detach(ctrl);
9181 wpa_ctrl_close(ctrl);
9182 send_resp(dut, conn, SIGMA_ERROR,
9183 "ErrorCode,Failed to start registrar");
9184 return 0;
9185 }
9186
9187 return wps_connection_event(dut, conn, ctrl, intf, 0);
9188}
9189
9190
vamsi krishna9b144002017-09-20 13:28:13 +05309191static int cmd_start_wps_registration(struct sigma_dut *dut,
9192 struct sigma_conn *conn,
9193 struct sigma_cmd *cmd)
9194{
9195 struct wpa_ctrl *ctrl;
9196 const char *intf = get_param(cmd, "Interface");
9197 const char *role, *method;
9198 int res;
9199 char buf[256];
9200 const char *events[] = {
9201 "CTRL-EVENT-CONNECTED",
9202 "WPS-OVERLAP-DETECTED",
9203 "WPS-TIMEOUT",
9204 "WPS-FAIL",
9205 NULL
9206 };
9207
9208 ctrl = open_wpa_mon(intf);
9209 if (!ctrl) {
9210 sigma_dut_print(dut, DUT_MSG_ERROR,
9211 "Failed to open wpa_supplicant monitor connection");
9212 return -2;
9213 }
9214
9215 role = get_param(cmd, "WpsRole");
9216 if (!role) {
9217 send_resp(dut, conn, SIGMA_INVALID,
9218 "ErrorCode,WpsRole not provided");
9219 goto fail;
9220 }
9221
9222 if (strcasecmp(role, "Enrollee") == 0) {
9223 method = get_param(cmd, "WpsConfigMethod");
9224 if (!method) {
9225 send_resp(dut, conn, SIGMA_INVALID,
9226 "ErrorCode,WpsConfigMethod not provided");
9227 goto fail;
9228 }
9229 if (strcasecmp(method, "PBC") == 0) {
9230 if (wpa_command(intf, "WPS_PBC") < 0) {
9231 send_resp(dut, conn, SIGMA_ERROR,
9232 "ErrorCode,Failed to enable PBC");
9233 goto fail;
9234 }
9235 } else {
9236 /* TODO: PIN method */
9237 send_resp(dut, conn, SIGMA_ERROR,
9238 "ErrorCode,Unsupported WpsConfigMethod value");
9239 goto fail;
9240 }
9241 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
9242 if (res < 0) {
9243 send_resp(dut, conn, SIGMA_ERROR,
9244 "ErrorCode,WPS connection did not complete");
9245 goto fail;
9246 }
9247 if (strstr(buf, "WPS-TIMEOUT")) {
9248 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
9249 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
9250 send_resp(dut, conn, SIGMA_ERROR,
9251 "ErrorCode,OverlapSession");
9252 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
9253 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
9254 } else {
9255 send_resp(dut, conn, SIGMA_ERROR,
9256 "ErrorCode,WPS operation failed");
9257 }
9258 } else {
9259 /* TODO: Registrar role */
9260 send_resp(dut, conn, SIGMA_ERROR,
9261 "ErrorCode,Unsupported WpsRole value");
9262 }
9263
9264fail:
9265 wpa_ctrl_detach(ctrl);
9266 wpa_ctrl_close(ctrl);
9267 return 0;
9268}
9269
9270
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009271static int req_intf(struct sigma_cmd *cmd)
9272{
9273 return get_param(cmd, "interface") == NULL ? -1 : 0;
9274}
9275
9276
9277void sta_register_cmds(void)
9278{
9279 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
9280 cmd_sta_get_ip_config);
9281 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
9282 cmd_sta_set_ip_config);
9283 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
9284 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
9285 cmd_sta_get_mac_address);
9286 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
9287 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
9288 cmd_sta_verify_ip_connection);
9289 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
9290 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
9291 cmd_sta_set_encryption);
9292 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
9293 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
9294 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
9295 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
9296 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
9297 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
9298 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
9299 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
9300 cmd_sta_set_eapakaprime);
9301 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
9302 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
9303 /* TODO: sta_set_ibss */
9304 /* TODO: sta_set_mode */
9305 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
9306 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
9307 /* TODO: sta_up_load */
9308 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
9309 cmd_sta_preset_testparameters);
9310 /* TODO: sta_set_system */
9311 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
9312 /* TODO: sta_set_rifs_test */
9313 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
9314 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
9315 /* TODO: sta_send_coexist_mgmt */
9316 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
9317 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
9318 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
9319 sigma_dut_reg_cmd("sta_reset_default", req_intf,
9320 cmd_sta_reset_default);
9321 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
9322 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
9323 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
9324 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
9325 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
9326 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
9327 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
9328 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
9329 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
9330 cmd_sta_hs2_associate);
9331 sigma_dut_reg_cmd("sta_add_credential", req_intf,
9332 cmd_sta_add_credential);
9333 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +02009334 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009335 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
9336 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
9337 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
9338 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
9339 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
9340 cmd_sta_wps_connect_pw_token);
9341 sigma_dut_reg_cmd("sta_exec_action", req_intf, cmd_sta_exec_action);
9342 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
9343 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
vamsi krishna9b144002017-09-20 13:28:13 +05309344 sigma_dut_reg_cmd("start_wps_registration", req_intf,
9345 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009346}