blob: 5d7e80a99d89aeb54e6253b7e5fefff76cdea551 [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
Sunil Dutt44595082018-02-12 19:41:45 +05302586#ifdef NL80211_SUPPORT
2587static int sta_config_rsnie(struct sigma_dut *dut, int val)
2588{
2589 struct nl_msg *msg;
2590 int ret;
2591 struct nlattr *params;
2592 int ifindex;
2593
2594 ifindex = if_nametoindex("wlan0");
2595 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
2596 NL80211_CMD_VENDOR)) ||
2597 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
2598 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
2599 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
2600 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
2601 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
2602 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
2603 sigma_dut_print(dut, DUT_MSG_ERROR,
2604 "%s: err in adding vendor_cmd and vendor_data",
2605 __func__);
2606 nlmsg_free(msg);
2607 return -1;
2608 }
2609 nla_nest_end(msg, params);
2610
2611 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
2612 if (ret) {
2613 sigma_dut_print(dut, DUT_MSG_ERROR,
2614 "%s: err in send_and_recv_msgs, ret=%d",
2615 __func__, ret);
2616 return ret;
2617 }
2618
2619 return 0;
2620}
2621#endif /* NL80211_SUPPORT */
2622
2623
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002624static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
2625 struct sigma_cmd *cmd)
2626{
2627 /* const char *intf = get_param(cmd, "Interface"); */
2628 const char *ssid = get_param(cmd, "ssid");
2629 const char *wps_param = get_param(cmd, "WPS");
2630 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03002631 const char *chan = get_param(cmd, "channel");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002632 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03002633 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002634
2635 if (ssid == NULL)
2636 return -1;
2637
Jouni Malinen3c367e82017-06-23 17:01:47 +03002638 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05302639#ifdef NL80211_SUPPORT
2640 if (get_driver_type() == DRIVER_WCN) {
2641 sta_config_rsnie(dut, 1);
2642 dut->config_rsnie = 1;
2643 }
2644#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03002645 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
2646 dut->rsne_override);
2647 if (wpa_command(get_station_ifname(), buf) < 0) {
2648 send_resp(dut, conn, SIGMA_ERROR,
2649 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
2650 return 0;
2651 }
2652 }
2653
Jouni Malinen68143132017-09-02 02:34:08 +03002654 if (dut->sae_commit_override) {
2655 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
2656 dut->sae_commit_override);
2657 if (wpa_command(get_station_ifname(), buf) < 0) {
2658 send_resp(dut, conn, SIGMA_ERROR,
2659 "ErrorCode,Failed to set SAE commit override");
2660 return 0;
2661 }
2662 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05302663#ifdef ANDROID
2664 if (dut->fils_hlp)
2665 process_fils_hlp(dut);
2666#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03002667
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002668 if (wps_param &&
2669 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
2670 wps = 1;
2671
2672 if (wps) {
2673 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
2674 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
2675 "parameters not yet set");
2676 return 0;
2677 }
2678 if (dut->wps_method == WFA_CS_WPS_PBC) {
2679 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
2680 return -2;
2681 } else {
2682 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
2683 dut->wps_pin);
2684 if (wpa_command(get_station_ifname(), buf) < 0)
2685 return -2;
2686 }
2687 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05302688 if (strcmp(ssid, dut->infra_ssid) == 0) {
2689 sigma_dut_print(dut, DUT_MSG_DEBUG,
2690 "sta_associate for the most recently added network");
2691 } else if (find_network(dut, ssid) < 0) {
2692 sigma_dut_print(dut, DUT_MSG_DEBUG,
2693 "sta_associate for a previously stored network profile");
2694 send_resp(dut, conn, SIGMA_ERROR,
2695 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002696 return 0;
2697 }
2698
2699 if (bssid &&
2700 set_network(get_station_ifname(), dut->infra_network_id,
2701 "bssid", bssid) < 0) {
2702 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2703 "Invalid bssid argument");
2704 return 0;
2705 }
2706
Jouni Malinen46a19b62017-06-23 14:31:27 +03002707 extra[0] = '\0';
2708 if (chan)
2709 snprintf(extra, sizeof(extra), " freq=%u",
2710 channel_to_freq(atoi(chan)));
2711 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
2712 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002713 if (wpa_command(get_station_ifname(), buf) < 0) {
2714 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
2715 "network id %d on %s",
2716 dut->infra_network_id,
2717 get_station_ifname());
2718 return -2;
2719 }
2720 }
2721
2722 return 1;
2723}
2724
2725
2726static int run_hs20_osu(struct sigma_dut *dut, const char *params)
2727{
2728 char buf[500], cmd[200];
2729 int res;
2730
2731 /* Use hs20-osu-client file at the current dir, if found; otherwise use
2732 * default path */
2733 res = snprintf(cmd, sizeof(cmd),
2734 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
2735 file_exists("./hs20-osu-client") ?
2736 "./hs20-osu-client" : "hs20-osu-client",
2737 sigma_wpas_ctrl,
2738 dut->summary_log ? "-s " : "",
2739 dut->summary_log ? dut->summary_log : "");
2740 if (res < 0 || res >= (int) sizeof(cmd))
2741 return -1;
2742
2743 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
2744 if (res < 0 || res >= (int) sizeof(buf))
2745 return -1;
2746 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
2747
2748 if (system(buf) != 0) {
2749 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
2750 return -1;
2751 }
2752 sigma_dut_print(dut, DUT_MSG_DEBUG,
2753 "Completed hs20-osu-client operation");
2754
2755 return 0;
2756}
2757
2758
2759static int download_ppsmo(struct sigma_dut *dut,
2760 struct sigma_conn *conn,
2761 const char *intf,
2762 struct sigma_cmd *cmd)
2763{
2764 const char *name, *path, *val;
2765 char url[500], buf[600], fbuf[100];
2766 char *fqdn = NULL;
2767
2768 name = get_param(cmd, "FileName");
2769 path = get_param(cmd, "FilePath");
2770 if (name == NULL || path == NULL)
2771 return -1;
2772
2773 if (strcasecmp(path, "VendorSpecific") == 0) {
2774 snprintf(url, sizeof(url), "PPS/%s", name);
2775 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
2776 "from the device (%s)", url);
2777 if (!file_exists(url)) {
2778 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2779 "PPS MO file does not exist");
2780 return 0;
2781 }
2782 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
2783 if (system(buf) != 0) {
2784 send_resp(dut, conn, SIGMA_ERROR,
2785 "errorCode,Failed to copy PPS MO");
2786 return 0;
2787 }
2788 } else if (strncasecmp(path, "http:", 5) != 0 &&
2789 strncasecmp(path, "https:", 6) != 0) {
2790 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2791 "Unsupported FilePath value");
2792 return 0;
2793 } else {
2794 snprintf(url, sizeof(url), "%s/%s", path, name);
2795 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
2796 url);
2797 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
2798 remove("pps-tnds.xml");
2799 if (system(buf) != 0) {
2800 send_resp(dut, conn, SIGMA_ERROR,
2801 "errorCode,Failed to download PPS MO");
2802 return 0;
2803 }
2804 }
2805
2806 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
2807 send_resp(dut, conn, SIGMA_ERROR,
2808 "errorCode,Failed to parse downloaded PPSMO");
2809 return 0;
2810 }
2811 unlink("pps-tnds.xml");
2812
2813 val = get_param(cmd, "managementTreeURI");
2814 if (val) {
2815 const char *pos, *end;
2816 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
2817 val);
2818 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
2819 send_resp(dut, conn, SIGMA_ERROR,
2820 "errorCode,Invalid managementTreeURI prefix");
2821 return 0;
2822 }
2823 pos = val + 8;
2824 end = strchr(pos, '/');
2825 if (end == NULL ||
2826 strcmp(end, "/PerProviderSubscription") != 0) {
2827 send_resp(dut, conn, SIGMA_ERROR,
2828 "errorCode,Invalid managementTreeURI postfix");
2829 return 0;
2830 }
2831 if (end - pos >= (int) sizeof(fbuf)) {
2832 send_resp(dut, conn, SIGMA_ERROR,
2833 "errorCode,Too long FQDN in managementTreeURI");
2834 return 0;
2835 }
2836 memcpy(fbuf, pos, end - pos);
2837 fbuf[end - pos] = '\0';
2838 fqdn = fbuf;
2839 sigma_dut_print(dut, DUT_MSG_INFO,
2840 "FQDN from managementTreeURI: %s", fqdn);
2841 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
2842 FILE *f = fopen("pps-fqdn", "r");
2843 if (f) {
2844 if (fgets(fbuf, sizeof(fbuf), f)) {
2845 fbuf[sizeof(fbuf) - 1] = '\0';
2846 fqdn = fbuf;
2847 sigma_dut_print(dut, DUT_MSG_DEBUG,
2848 "Use FQDN %s", fqdn);
2849 }
2850 fclose(f);
2851 }
2852 }
2853
2854 if (fqdn == NULL) {
2855 send_resp(dut, conn, SIGMA_ERROR,
2856 "errorCode,No FQDN specified");
2857 return 0;
2858 }
2859
2860 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2861 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
2862 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2863
2864 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
2865 if (rename("pps.xml", buf) < 0) {
2866 send_resp(dut, conn, SIGMA_ERROR,
2867 "errorCode,Could not move PPS MO");
2868 return 0;
2869 }
2870
2871 if (strcasecmp(path, "VendorSpecific") == 0) {
2872 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
2873 fqdn);
2874 if (system(buf)) {
2875 send_resp(dut, conn, SIGMA_ERROR,
2876 "errorCode,Failed to copy OSU CA cert");
2877 return 0;
2878 }
2879
2880 snprintf(buf, sizeof(buf),
2881 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
2882 fqdn);
2883 if (system(buf)) {
2884 send_resp(dut, conn, SIGMA_ERROR,
2885 "errorCode,Failed to copy AAA CA cert");
2886 return 0;
2887 }
2888 } else {
2889 snprintf(buf, sizeof(buf),
2890 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
2891 fqdn, fqdn);
2892 if (run_hs20_osu(dut, buf) < 0) {
2893 send_resp(dut, conn, SIGMA_ERROR,
2894 "errorCode,Failed to download OSU CA cert");
2895 return 0;
2896 }
2897
2898 snprintf(buf, sizeof(buf),
2899 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
2900 fqdn, fqdn);
2901 if (run_hs20_osu(dut, buf) < 0) {
2902 sigma_dut_print(dut, DUT_MSG_INFO,
2903 "Failed to download AAA CA cert");
2904 }
2905 }
2906
2907 if (file_exists("next-client-cert.pem")) {
2908 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
2909 if (rename("next-client-cert.pem", buf) < 0) {
2910 send_resp(dut, conn, SIGMA_ERROR,
2911 "errorCode,Could not move client certificate");
2912 return 0;
2913 }
2914 }
2915
2916 if (file_exists("next-client-key.pem")) {
2917 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
2918 if (rename("next-client-key.pem", buf) < 0) {
2919 send_resp(dut, conn, SIGMA_ERROR,
2920 "errorCode,Could not move client key");
2921 return 0;
2922 }
2923 }
2924
2925 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
2926 if (run_hs20_osu(dut, buf) < 0) {
2927 send_resp(dut, conn, SIGMA_ERROR,
2928 "errorCode,Failed to configure credential from "
2929 "PPSMO");
2930 return 0;
2931 }
2932
2933 return 1;
2934}
2935
2936
2937static int download_cert(struct sigma_dut *dut,
2938 struct sigma_conn *conn,
2939 const char *intf,
2940 struct sigma_cmd *cmd)
2941{
2942 const char *name, *path;
2943 char url[500], buf[600];
2944
2945 name = get_param(cmd, "FileName");
2946 path = get_param(cmd, "FilePath");
2947 if (name == NULL || path == NULL)
2948 return -1;
2949
2950 if (strcasecmp(path, "VendorSpecific") == 0) {
2951 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
2952 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2953 "certificate from the device (%s)", url);
2954 if (!file_exists(url)) {
2955 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2956 "certificate file does not exist");
2957 return 0;
2958 }
2959 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
2960 if (system(buf) != 0) {
2961 send_resp(dut, conn, SIGMA_ERROR,
2962 "errorCode,Failed to copy client "
2963 "certificate");
2964 return 0;
2965 }
2966
2967 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
2968 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2969 "private key from the device (%s)", url);
2970 if (!file_exists(url)) {
2971 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2972 "private key file does not exist");
2973 return 0;
2974 }
2975 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
2976 if (system(buf) != 0) {
2977 send_resp(dut, conn, SIGMA_ERROR,
2978 "errorCode,Failed to copy client key");
2979 return 0;
2980 }
2981 } else if (strncasecmp(path, "http:", 5) != 0 &&
2982 strncasecmp(path, "https:", 6) != 0) {
2983 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2984 "Unsupported FilePath value");
2985 return 0;
2986 } else {
2987 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
2988 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
2989 "certificate/key from %s", url);
2990 snprintf(buf, sizeof(buf),
2991 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
2992 if (system(buf) != 0) {
2993 send_resp(dut, conn, SIGMA_ERROR,
2994 "errorCode,Failed to download client "
2995 "certificate");
2996 return 0;
2997 }
2998
2999 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3000 {
3001 send_resp(dut, conn, SIGMA_ERROR,
3002 "errorCode,Failed to copy client key");
3003 return 0;
3004 }
3005 }
3006
3007 return 1;
3008}
3009
3010
3011static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3012 struct sigma_conn *conn,
3013 const char *intf,
3014 struct sigma_cmd *cmd)
3015{
3016 const char *val;
3017
3018 val = get_param(cmd, "FileType");
3019 if (val && strcasecmp(val, "PPSMO") == 0)
3020 return download_ppsmo(dut, conn, intf, cmd);
3021 if (val && strcasecmp(val, "CERT") == 0)
3022 return download_cert(dut, conn, intf, cmd);
3023 if (val) {
3024 send_resp(dut, conn, SIGMA_ERROR,
3025 "ErrorCode,Unsupported FileType");
3026 return 0;
3027 }
3028
3029 return 1;
3030}
3031
3032
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303033static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3034 struct sigma_conn *conn,
3035 const char *intf,
3036 struct sigma_cmd *cmd)
3037{
3038 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303039 char buf[1000];
3040 char text[20];
3041 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303042
3043 val = get_param(cmd, "OCESupport");
3044 if (val && strcasecmp(val, "Disable") == 0) {
3045 if (wpa_command(intf, "SET oce 0") < 0) {
3046 send_resp(dut, conn, SIGMA_ERROR,
3047 "ErrorCode,Failed to disable OCE");
3048 return 0;
3049 }
3050 } else if (val && strcasecmp(val, "Enable") == 0) {
3051 if (wpa_command(intf, "SET oce 1") < 0) {
3052 send_resp(dut, conn, SIGMA_ERROR,
3053 "ErrorCode,Failed to enable OCE");
3054 return 0;
3055 }
3056 }
3057
vamsi krishnaa2799492017-12-05 14:28:01 +05303058 val = get_param(cmd, "FILScap");
3059 if (val && (atoi(val) == 1)) {
3060 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3061 send_resp(dut, conn, SIGMA_ERROR,
3062 "ErrorCode,Failed to enable FILS");
3063 return 0;
3064 }
3065 } else if (val && (atoi(val) == 0)) {
3066 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3067 send_resp(dut, conn, SIGMA_ERROR,
3068 "ErrorCode,Failed to disable FILS");
3069 return 0;
3070 }
3071 }
3072
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303073 val = get_param(cmd, "FILSHLP");
3074 if (val && strcasecmp(val, "Enable") == 0) {
3075 if (get_wpa_status(get_station_ifname(), "address", text,
3076 sizeof(text)) < 0)
3077 return -2;
3078 hwaddr_aton(text, addr);
3079 snprintf(buf, sizeof(buf),
3080 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3081 "080045100140000040004011399e00000000ffffffff00440043"
3082 "012cb30001010600fd4f46410000000000000000000000000000"
3083 "000000000000"
3084 "%02x%02x%02x%02x%02x%02x"
3085 "0000000000000000000000000000000000000000000000000000"
3086 "0000000000000000000000000000000000000000000000000000"
3087 "0000000000000000000000000000000000000000000000000000"
3088 "0000000000000000000000000000000000000000000000000000"
3089 "0000000000000000000000000000000000000000000000000000"
3090 "0000000000000000000000000000000000000000000000000000"
3091 "0000000000000000000000000000000000000000000000000000"
3092 "0000000000000000000000000000000000000000638253633501"
3093 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3094 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3095 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3096 if (wpa_command(intf, buf)) {
3097 send_resp(dut, conn, SIGMA_ERROR,
3098 "ErrorCode,Failed to add HLP");
3099 return 0;
3100 }
3101 dut->fils_hlp = 1;
3102 }
3103
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303104 return 1;
3105}
3106
3107
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003108static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3109 const char *val)
3110{
3111 int counter = 0;
3112 char token[50];
3113 char *result;
3114 char buf[100];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303115 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003116
Peng Xub8fc5cc2017-05-10 17:27:28 -07003117 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003118 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303119 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003120 while (result) {
3121 if (strcmp(result, "disable") == 0) {
3122 snprintf(buf, sizeof(buf),
3123 "iwpriv %s noackpolicy %d 1 0",
3124 intf, counter);
3125 } else {
3126 snprintf(buf, sizeof(buf),
3127 "iwpriv %s noackpolicy %d 1 1",
3128 intf, counter);
3129 }
3130 if (system(buf) != 0) {
3131 sigma_dut_print(dut, DUT_MSG_ERROR,
3132 "iwpriv noackpolicy failed");
3133 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303134 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003135 counter++;
3136 }
3137}
3138
3139
3140static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3141 const char *val)
3142{
3143 char buf[100];
3144
3145 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3146 if (system(buf) != 0) {
3147 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3148 }
3149}
3150
3151
3152static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3153 const char *val)
3154{
3155 char buf[100];
3156
3157 if (strcasecmp(val, "off") == 0) {
3158 snprintf(buf, sizeof(buf), "iwpriv %s wmm 0", intf);
3159 if (system(buf) != 0) {
3160 sigma_dut_print(dut, DUT_MSG_ERROR,
3161 "Failed to turn off WMM");
3162 }
3163 }
3164}
3165
3166
3167static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3168 const char *val)
3169{
3170 char buf[100];
3171 int sgi20;
3172
3173 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3174
3175 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi20);
3176 if (system(buf) != 0)
3177 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv shortgi failed");
3178}
3179
3180
3181static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3182 const char *val)
3183{
3184 char buf[100];
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303185 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003186
3187 /* Disable Tx Beam forming when using a fixed rate */
3188 ath_disable_txbf(dut, intf);
3189
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303190 v = atoi(val);
3191 if (v < 0 || v > 32) {
3192 sigma_dut_print(dut, DUT_MSG_ERROR,
3193 "Invalid Fixed MCS rate: %d", v);
3194 return;
3195 }
3196 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003197
3198 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0x%x",
3199 intf, rate_code);
3200 if (system(buf) != 0) {
3201 sigma_dut_print(dut, DUT_MSG_ERROR,
3202 "iwpriv set11NRates failed");
3203 }
3204
3205 /* Channel width gets messed up, fix this */
3206 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d", intf, dut->chwidth);
3207 if (system(buf) != 0)
3208 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
3209}
3210
3211
3212static void ath_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3213 const char *val)
3214{
3215 char buf[60];
3216
3217 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3218 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3219 else
3220 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3221
3222 if (system(buf) != 0)
3223 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3224}
3225
3226
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003227static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3228 int ampdu)
3229{
3230 char buf[60];
3231
3232 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3233 if (system(buf) != 0) {
3234 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3235 return -1;
3236 }
3237
3238 return 0;
3239}
3240
3241
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003242static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3243 const char *val)
3244{
3245 char buf[60];
3246
3247 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3248 if (system(buf) != 0) {
3249 sigma_dut_print(dut, DUT_MSG_ERROR,
3250 "iwpriv tx_stbc failed");
3251 }
3252
3253 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3254 if (system(buf) != 0) {
3255 sigma_dut_print(dut, DUT_MSG_ERROR,
3256 "iwpriv rx_stbc failed");
3257 }
3258}
3259
3260
3261static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3262 const char *val)
3263{
3264 char buf[60];
3265
Peng Xucc317ed2017-05-18 16:44:37 -07003266 if (strcmp(val, "160") == 0) {
3267 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3268 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003269 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3270 } else if (strcmp(val, "40") == 0) {
3271 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3272 } else if (strcmp(val, "20") == 0) {
3273 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3274 } else if (strcasecmp(val, "Auto") == 0) {
3275 buf[0] = '\0';
3276 } else {
3277 sigma_dut_print(dut, DUT_MSG_ERROR,
3278 "WIDTH/CTS_WIDTH value not supported");
3279 return -1;
3280 }
3281
3282 if (buf[0] != '\0' && system(buf) != 0) {
3283 sigma_dut_print(dut, DUT_MSG_ERROR,
3284 "Failed to set WIDTH/CTS_WIDTH");
3285 return -1;
3286 }
3287
3288 return 0;
3289}
3290
3291
3292int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3293 const char *intf, const char *val)
3294{
3295 char buf[60];
3296
3297 if (strcasecmp(val, "Auto") == 0) {
3298 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3299 dut->chwidth = 0;
3300 } else if (strcasecmp(val, "20") == 0) {
3301 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3302 dut->chwidth = 0;
3303 } else if (strcasecmp(val, "40") == 0) {
3304 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
3305 dut->chwidth = 1;
3306 } else if (strcasecmp(val, "80") == 0) {
3307 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
3308 dut->chwidth = 2;
3309 } else if (strcasecmp(val, "160") == 0) {
3310 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 3", intf);
3311 dut->chwidth = 3;
3312 } else {
3313 send_resp(dut, conn, SIGMA_ERROR,
3314 "ErrorCode,WIDTH not supported");
3315 return -1;
3316 }
3317
3318 if (system(buf) != 0) {
3319 sigma_dut_print(dut, DUT_MSG_ERROR,
3320 "iwpriv chwidth failed");
3321 }
3322
3323 return 0;
3324}
3325
3326
3327static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3328 const char *val)
3329{
3330 char buf[60];
3331
3332 if (strcmp(val, "1SS") == 0) {
3333 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
3334 } else if (strcmp(val, "2SS") == 0) {
3335 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
3336 } else {
3337 sigma_dut_print(dut, DUT_MSG_ERROR,
3338 "SP_STREAM value not supported");
3339 return -1;
3340 }
3341
3342 if (system(buf) != 0) {
3343 sigma_dut_print(dut, DUT_MSG_ERROR,
3344 "Failed to set SP_STREAM");
3345 return -1;
3346 }
3347
3348 return 0;
3349}
3350
3351
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303352static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3353 const char *val)
3354{
3355 char buf[60];
3356
3357 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3358 if (system(buf) != 0)
3359 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
3360
3361 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3362 if (system(buf) != 0)
3363 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
3364}
3365
3366
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303367static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
3368 struct sigma_conn *conn,
3369 const char *intf, int capa)
3370{
3371 char buf[32];
3372
3373 if (capa > 0 && capa < 4) {
3374 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
3375 if (wpa_command(intf, buf) < 0) {
3376 send_resp(dut, conn, SIGMA_ERROR,
3377 "ErrorCode, Failed to set cellular data capability");
3378 return 0;
3379 }
3380 return 1;
3381 }
3382
3383 sigma_dut_print(dut, DUT_MSG_ERROR,
3384 "Invalid Cellular data capability: %d", capa);
3385 send_resp(dut, conn, SIGMA_INVALID,
3386 "ErrorCode,Invalid cellular data capability");
3387 return 0;
3388}
3389
3390
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303391static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
3392 const char *intf, const char *val)
3393{
3394 if (strcasecmp(val, "Disable") == 0) {
3395 if (wpa_command(intf, "SET roaming 0") < 0) {
3396 send_resp(dut, conn, SIGMA_ERROR,
3397 "ErrorCode,Failed to disable roaming");
3398 return 0;
3399 }
3400 return 1;
3401 }
3402
3403 if (strcasecmp(val, "Enable") == 0) {
3404 if (wpa_command(intf, "SET roaming 1") < 0) {
3405 send_resp(dut, conn, SIGMA_ERROR,
3406 "ErrorCode,Failed to enable roaming");
3407 return 0;
3408 }
3409 return 1;
3410 }
3411
3412 sigma_dut_print(dut, DUT_MSG_ERROR,
3413 "Invalid value provided for roaming: %s", val);
3414 send_resp(dut, conn, SIGMA_INVALID,
3415 "ErrorCode,Unknown value provided for Roaming");
3416 return 0;
3417}
3418
3419
Ashwini Patila75de5a2017-04-13 16:35:05 +05303420static int mbo_set_assoc_disallow(struct sigma_dut *dut,
3421 struct sigma_conn *conn,
3422 const char *intf, const char *val)
3423{
3424 if (strcasecmp(val, "Disable") == 0) {
3425 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
3426 send_resp(dut, conn, SIGMA_ERROR,
3427 "ErrorCode,Failed to disable Assoc_disallow");
3428 return 0;
3429 }
3430 return 1;
3431 }
3432
3433 if (strcasecmp(val, "Enable") == 0) {
3434 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
3435 send_resp(dut, conn, SIGMA_ERROR,
3436 "ErrorCode,Failed to enable Assoc_disallow");
3437 return 0;
3438 }
3439 return 1;
3440 }
3441
3442 sigma_dut_print(dut, DUT_MSG_ERROR,
3443 "Invalid value provided for Assoc_disallow: %s", val);
3444 send_resp(dut, conn, SIGMA_INVALID,
3445 "ErrorCode,Unknown value provided for Assoc_disallow");
3446 return 0;
3447}
3448
3449
Ashwini Patilc63161e2017-04-13 16:30:23 +05303450static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
3451 const char *intf, const char *val)
3452{
3453 if (strcasecmp(val, "Reject") == 0) {
3454 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
3455 send_resp(dut, conn, SIGMA_ERROR,
3456 "ErrorCode,Failed to Reject BTM Request");
3457 return 0;
3458 }
3459 return 1;
3460 }
3461
3462 if (strcasecmp(val, "Accept") == 0) {
3463 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
3464 send_resp(dut, conn, SIGMA_ERROR,
3465 "ErrorCode,Failed to Accept BTM Request");
3466 return 0;
3467 }
3468 return 1;
3469 }
3470
3471 sigma_dut_print(dut, DUT_MSG_ERROR,
3472 "Invalid value provided for BSS_Transition: %s", val);
3473 send_resp(dut, conn, SIGMA_INVALID,
3474 "ErrorCode,Unknown value provided for BSS_Transition");
3475 return 0;
3476}
3477
3478
Ashwini Patil00402582017-04-13 12:29:39 +05303479static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
3480 struct sigma_conn *conn,
3481 const char *intf,
3482 struct sigma_cmd *cmd)
3483{
3484 const char *ch, *pref, *op_class, *reason;
3485 char buf[120];
3486 int len, ret;
3487
3488 pref = get_param(cmd, "Ch_Pref");
3489 if (!pref)
3490 return 1;
3491
3492 if (strcasecmp(pref, "clear") == 0) {
3493 free(dut->non_pref_ch_list);
3494 dut->non_pref_ch_list = NULL;
3495 } else {
3496 op_class = get_param(cmd, "Ch_Op_Class");
3497 if (!op_class) {
3498 send_resp(dut, conn, SIGMA_INVALID,
3499 "ErrorCode,Ch_Op_Class not provided");
3500 return 0;
3501 }
3502
3503 ch = get_param(cmd, "Ch_Pref_Num");
3504 if (!ch) {
3505 send_resp(dut, conn, SIGMA_INVALID,
3506 "ErrorCode,Ch_Pref_Num not provided");
3507 return 0;
3508 }
3509
3510 reason = get_param(cmd, "Ch_Reason_Code");
3511 if (!reason) {
3512 send_resp(dut, conn, SIGMA_INVALID,
3513 "ErrorCode,Ch_Reason_Code not provided");
3514 return 0;
3515 }
3516
3517 if (!dut->non_pref_ch_list) {
3518 dut->non_pref_ch_list =
3519 calloc(1, NON_PREF_CH_LIST_SIZE);
3520 if (!dut->non_pref_ch_list) {
3521 send_resp(dut, conn, SIGMA_ERROR,
3522 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
3523 return 0;
3524 }
3525 }
3526 len = strlen(dut->non_pref_ch_list);
3527 ret = snprintf(dut->non_pref_ch_list + len,
3528 NON_PREF_CH_LIST_SIZE - len,
3529 " %s:%s:%s:%s", op_class, ch, pref, reason);
3530 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
3531 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
3532 dut->non_pref_ch_list);
3533 } else {
3534 sigma_dut_print(dut, DUT_MSG_ERROR,
3535 "snprintf failed for non_pref_list, ret = %d",
3536 ret);
3537 send_resp(dut, conn, SIGMA_ERROR,
3538 "ErrorCode,snprintf failed");
3539 free(dut->non_pref_ch_list);
3540 dut->non_pref_ch_list = NULL;
3541 return 0;
3542 }
3543 }
3544
3545 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
3546 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
3547 if (ret < 0 || ret >= (int) sizeof(buf)) {
3548 sigma_dut_print(dut, DUT_MSG_DEBUG,
3549 "snprintf failed for set non_pref_chan, ret: %d",
3550 ret);
3551 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
3552 return 0;
3553 }
3554
3555 if (wpa_command(intf, buf) < 0) {
3556 send_resp(dut, conn, SIGMA_ERROR,
3557 "ErrorCode,Failed to set non-preferred channel list");
3558 return 0;
3559 }
3560
3561 return 1;
3562}
3563
3564
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003565static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
3566 struct sigma_conn *conn,
3567 struct sigma_cmd *cmd)
3568{
3569 const char *intf = get_param(cmd, "Interface");
3570 const char *val;
3571
3572 val = get_param(cmd, "Program");
Peng Xue9fa7952017-05-09 15:59:49 -07003573 if (val && strcasecmp(val, "HS2-R2") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003574 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
3575 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003576
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07003577 if (val && strcasecmp(val, "LOC") == 0)
3578 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
3579
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003580#ifdef ANDROID_NAN
3581 if (val && strcasecmp(val, "NAN") == 0)
3582 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
3583#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07003584#ifdef MIRACAST
3585 if (val && (strcasecmp(val, "WFD") == 0 ||
3586 strcasecmp(val, "DisplayR2") == 0))
3587 return miracast_preset_testparameters(dut, conn, cmd);
3588#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003589
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303590 if (val && strcasecmp(val, "MBO") == 0) {
3591 val = get_param(cmd, "Cellular_Data_Cap");
3592 if (val &&
3593 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
3594 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05303595
3596 val = get_param(cmd, "Ch_Pref");
3597 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
3598 return 0;
3599
Ashwini Patilc63161e2017-04-13 16:30:23 +05303600 val = get_param(cmd, "BSS_Transition");
3601 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
3602 return 0;
3603
Ashwini Patila75de5a2017-04-13 16:35:05 +05303604 val = get_param(cmd, "Assoc_Disallow");
3605 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
3606 return 0;
3607
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303608 val = get_param(cmd, "Roaming");
3609 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
3610 return 0;
3611
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303612 return 1;
3613 }
3614
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303615 if (val && strcasecmp(val, "OCE") == 0)
3616 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
3617
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003618#if 0
3619 val = get_param(cmd, "Supplicant");
3620 if (val && strcasecmp(val, "Default") != 0) {
3621 send_resp(dut, conn, SIGMA_ERROR,
3622 "ErrorCode,Only default(Vendor) supplicant "
3623 "supported");
3624 return 0;
3625 }
3626#endif
3627
3628 val = get_param(cmd, "RTS");
3629 if (val) {
3630 switch (get_driver_type()) {
3631 case DRIVER_ATHEROS:
3632 ath_sta_set_rts(dut, intf, val);
3633 break;
3634 default:
3635#if 0
3636 send_resp(dut, conn, SIGMA_ERROR,
3637 "ErrorCode,Setting RTS not supported");
3638 return 0;
3639#else
3640 sigma_dut_print(dut, DUT_MSG_DEBUG,
3641 "Setting RTS not supported");
3642 break;
3643#endif
3644 }
3645 }
3646
3647#if 0
3648 val = get_param(cmd, "FRGMNT");
3649 if (val) {
3650 /* TODO */
3651 send_resp(dut, conn, SIGMA_ERROR,
3652 "ErrorCode,Setting FRGMNT not supported");
3653 return 0;
3654 }
3655#endif
3656
3657#if 0
3658 val = get_param(cmd, "Preamble");
3659 if (val) {
3660 /* TODO: Long/Short */
3661 send_resp(dut, conn, SIGMA_ERROR,
3662 "ErrorCode,Setting Preamble not supported");
3663 return 0;
3664 }
3665#endif
3666
3667 val = get_param(cmd, "Mode");
3668 if (val) {
3669 if (strcmp(val, "11b") == 0 ||
3670 strcmp(val, "11g") == 0 ||
3671 strcmp(val, "11a") == 0 ||
3672 strcmp(val, "11n") == 0 ||
3673 strcmp(val, "11ng") == 0 ||
3674 strcmp(val, "11nl") == 0 ||
3675 strcmp(val, "11nl(nabg)") == 0 ||
3676 strcmp(val, "AC") == 0 ||
3677 strcmp(val, "11AC") == 0 ||
3678 strcmp(val, "11ac") == 0 ||
3679 strcmp(val, "11na") == 0 ||
3680 strcmp(val, "11an") == 0) {
3681 /* STA supports all modes by default */
3682 } else {
3683 send_resp(dut, conn, SIGMA_ERROR,
3684 "ErrorCode,Setting Mode not supported");
3685 return 0;
3686 }
3687 }
3688
3689 val = get_param(cmd, "wmm");
3690 if (val) {
3691 switch (get_driver_type()) {
3692 case DRIVER_ATHEROS:
3693 ath_sta_set_wmm(dut, intf, val);
3694 break;
3695 default:
3696 sigma_dut_print(dut, DUT_MSG_DEBUG,
3697 "Setting wmm not supported");
3698 break;
3699 }
3700 }
3701
3702 val = get_param(cmd, "Powersave");
3703 if (val) {
3704 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
3705 if (wpa_command(get_station_ifname(),
3706 "P2P_SET ps 0") < 0)
3707 return -2;
3708 /* Make sure test modes are disabled */
3709 wpa_command(get_station_ifname(), "P2P_SET ps 98");
3710 wpa_command(get_station_ifname(), "P2P_SET ps 96");
3711 } else if (strcmp(val, "1") == 0 ||
3712 strcasecmp(val, "PSPoll") == 0 ||
3713 strcasecmp(val, "on") == 0) {
3714 /* Disable default power save mode */
3715 wpa_command(get_station_ifname(), "P2P_SET ps 0");
3716 /* Enable PS-Poll test mode */
3717 if (wpa_command(get_station_ifname(),
3718 "P2P_SET ps 97") < 0 ||
3719 wpa_command(get_station_ifname(),
3720 "P2P_SET ps 99") < 0)
3721 return -2;
3722 } else if (strcmp(val, "2") == 0 ||
3723 strcasecmp(val, "Fast") == 0) {
3724 /* TODO */
3725 send_resp(dut, conn, SIGMA_ERROR,
3726 "ErrorCode,Powersave=Fast not supported");
3727 return 0;
3728 } else if (strcmp(val, "3") == 0 ||
3729 strcasecmp(val, "PSNonPoll") == 0) {
3730 /* Make sure test modes are disabled */
3731 wpa_command(get_station_ifname(), "P2P_SET ps 98");
3732 wpa_command(get_station_ifname(), "P2P_SET ps 96");
3733
3734 /* Enable default power save mode */
3735 if (wpa_command(get_station_ifname(),
3736 "P2P_SET ps 1") < 0)
3737 return -2;
3738 } else
3739 return -1;
3740 }
3741
3742 val = get_param(cmd, "NoAck");
3743 if (val) {
3744 switch (get_driver_type()) {
3745 case DRIVER_ATHEROS:
3746 ath_sta_set_noack(dut, intf, val);
3747 break;
3748 default:
3749 send_resp(dut, conn, SIGMA_ERROR,
3750 "ErrorCode,Setting NoAck not supported");
3751 return 0;
3752 }
3753 }
3754
3755 val = get_param(cmd, "IgnoreChswitchProhibit");
3756 if (val) {
3757 /* TODO: Enabled/disabled */
3758 if (strcasecmp(val, "Enabled") == 0) {
3759 send_resp(dut, conn, SIGMA_ERROR,
3760 "ErrorCode,Enabling IgnoreChswitchProhibit "
3761 "not supported");
3762 return 0;
3763 }
3764 }
3765
3766 val = get_param(cmd, "TDLS");
3767 if (val) {
3768 if (strcasecmp(val, "Disabled") == 0) {
3769 if (wpa_command(intf, "SET tdls_disabled 1")) {
3770 send_resp(dut, conn, SIGMA_ERROR,
3771 "ErrorCode,Failed to disable TDLS");
3772 return 0;
3773 }
3774 } else if (strcasecmp(val, "Enabled") == 0) {
3775 if (wpa_command(intf, "SET tdls_disabled 0")) {
3776 send_resp(dut, conn, SIGMA_ERROR,
3777 "ErrorCode,Failed to enable TDLS");
3778 return 0;
3779 }
3780 } else {
3781 send_resp(dut, conn, SIGMA_ERROR,
3782 "ErrorCode,Unsupported TDLS value");
3783 return 0;
3784 }
3785 }
3786
3787 val = get_param(cmd, "TDLSmode");
3788 if (val) {
3789 if (strcasecmp(val, "Default") == 0) {
3790 wpa_command(intf, "SET tdls_testing 0");
3791 } else if (strcasecmp(val, "APProhibit") == 0) {
3792 if (wpa_command(intf, "SET tdls_testing 0x400")) {
3793 send_resp(dut, conn, SIGMA_ERROR,
3794 "ErrorCode,Failed to enable ignore "
3795 "APProhibit TDLS mode");
3796 return 0;
3797 }
3798 } else if (strcasecmp(val, "HiLoMac") == 0) {
3799 /* STA should respond with TDLS setup req for a TDLS
3800 * setup req */
3801 if (wpa_command(intf, "SET tdls_testing 0x80")) {
3802 send_resp(dut, conn, SIGMA_ERROR,
3803 "ErrorCode,Failed to enable HiLoMac "
3804 "TDLS mode");
3805 return 0;
3806 }
3807 } else if (strcasecmp(val, "WeakSecurity") == 0) {
3808 /*
3809 * Since all security modes are enabled by default when
3810 * Sigma control is used, there is no need to do
3811 * anything here.
3812 */
3813 } else if (strcasecmp(val, "ExistLink") == 0) {
3814 /*
3815 * Since we allow new TDLS Setup Request even if there
3816 * is an existing link, nothing needs to be done for
3817 * this.
3818 */
3819 } else {
3820 /* TODO:
3821 * ExistLink: STA should send TDLS setup req even if
3822 * direct link already exists
3823 */
3824 send_resp(dut, conn, SIGMA_ERROR,
3825 "ErrorCode,Unsupported TDLSmode value");
3826 return 0;
3827 }
3828 }
3829
3830 val = get_param(cmd, "FakePubKey");
3831 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
3832 send_resp(dut, conn, SIGMA_ERROR,
3833 "ErrorCode,Failed to enable FakePubKey");
3834 return 0;
3835 }
3836
3837 return 1;
3838}
3839
3840
3841static const char * ath_get_radio_name(const char *radio_name)
3842{
3843 if (radio_name == NULL)
3844 return "wifi0";
3845 if (strcmp(radio_name, "wifi1") == 0)
3846 return "wifi1";
3847 if (strcmp(radio_name, "wifi2") == 0)
3848 return "wifi2";
3849 return "wifi0";
3850}
3851
3852
3853static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
3854 const char *val)
3855{
3856 char buf[60];
3857 unsigned int vht_mcsmap = 0;
3858 int txchainmask = 0;
3859 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
3860
3861 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
3862 if (dut->testbed_flag_txsp == 1) {
3863 vht_mcsmap = 0xfffc;
3864 dut->testbed_flag_txsp = 0;
3865 } else {
3866 vht_mcsmap = 0xfffe;
3867 }
3868 txchainmask = 1;
3869 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
3870 if (dut->testbed_flag_txsp == 1) {
3871 vht_mcsmap = 0xfff0;
3872 dut->testbed_flag_txsp = 0;
3873 } else {
3874 vht_mcsmap = 0xfffa;
3875 }
3876 txchainmask = 3;
3877 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
3878 if (dut->testbed_flag_txsp == 1) {
3879 vht_mcsmap = 0xffc0;
3880 dut->testbed_flag_txsp = 0;
3881 } else {
3882 vht_mcsmap = 0xffea;
3883 }
3884 txchainmask = 7;
3885 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
3886 if (dut->testbed_flag_txsp == 1) {
3887 vht_mcsmap = 0xff00;
3888 dut->testbed_flag_txsp = 0;
3889 } else {
3890 vht_mcsmap = 0xffaa;
3891 }
3892 txchainmask = 15;
3893 } else {
3894 if (dut->testbed_flag_txsp == 1) {
3895 vht_mcsmap = 0xffc0;
3896 dut->testbed_flag_txsp = 0;
3897 } else {
3898 vht_mcsmap = 0xffea;
3899 }
3900 }
3901
3902 if (txchainmask) {
3903 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
3904 basedev, txchainmask);
3905 if (system(buf) != 0) {
3906 sigma_dut_print(dut, DUT_MSG_ERROR,
3907 "iwpriv txchainmask failed");
3908 }
3909 }
3910
3911 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
3912 intf, vht_mcsmap);
3913 if (system(buf) != 0) {
3914 sigma_dut_print(dut, DUT_MSG_ERROR,
3915 "iwpriv %s vht_mcsmap 0x%04x failed",
3916 intf, vht_mcsmap);
3917 }
3918}
3919
3920
3921static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
3922 const char *val)
3923{
3924 char buf[60];
3925 unsigned int vht_mcsmap = 0;
3926 int rxchainmask = 0;
3927 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
3928
3929 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
3930 if (dut->testbed_flag_rxsp == 1) {
3931 vht_mcsmap = 0xfffc;
3932 dut->testbed_flag_rxsp = 0;
3933 } else {
3934 vht_mcsmap = 0xfffe;
3935 }
3936 rxchainmask = 1;
3937 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
3938 if (dut->testbed_flag_rxsp == 1) {
3939 vht_mcsmap = 0xfff0;
3940 dut->testbed_flag_rxsp = 0;
3941 } else {
3942 vht_mcsmap = 0xfffa;
3943 }
3944 rxchainmask = 3;
3945 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
3946 if (dut->testbed_flag_rxsp == 1) {
3947 vht_mcsmap = 0xffc0;
3948 dut->testbed_flag_rxsp = 0;
3949 } else {
3950 vht_mcsmap = 0xffea;
3951 }
3952 rxchainmask = 7;
3953 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
3954 if (dut->testbed_flag_rxsp == 1) {
3955 vht_mcsmap = 0xff00;
3956 dut->testbed_flag_rxsp = 0;
3957 } else {
3958 vht_mcsmap = 0xffaa;
3959 }
3960 rxchainmask = 15;
3961 } else {
3962 if (dut->testbed_flag_rxsp == 1) {
3963 vht_mcsmap = 0xffc0;
3964 dut->testbed_flag_rxsp = 0;
3965 } else {
3966 vht_mcsmap = 0xffea;
3967 }
3968 }
3969
3970 if (rxchainmask) {
3971 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
3972 basedev, rxchainmask);
3973 if (system(buf) != 0) {
3974 sigma_dut_print(dut, DUT_MSG_ERROR,
3975 "iwpriv rxchainmask failed");
3976 }
3977 }
3978
3979 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
3980 intf, vht_mcsmap);
3981 if (system(buf) != 0) {
3982 sigma_dut_print(dut, DUT_MSG_ERROR,
3983 "iwpriv %s vht_mcsmap 0x%04x",
3984 intf, vht_mcsmap);
3985 }
3986}
3987
3988
3989void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
3990{
3991 if (strcasecmp(val, "enable") == 0) {
3992 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
3993 != 0) {
3994 sigma_dut_print(dut, DUT_MSG_ERROR,
3995 "Disable BB_VHTSIGB_CRC_CALC failed");
3996 }
3997
3998 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
3999 != 0) {
4000 sigma_dut_print(dut, DUT_MSG_ERROR,
4001 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4002 }
4003 } else {
4004 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4005 != 0) {
4006 sigma_dut_print(dut, DUT_MSG_ERROR,
4007 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4008 }
4009
4010 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4011 != 0) {
4012 sigma_dut_print(dut, DUT_MSG_ERROR,
4013 "Enable BB_VHTSIGB_CRC_CALC failed");
4014 }
4015 }
4016}
4017
4018
4019static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
4020 struct sigma_conn *conn,
4021 struct sigma_cmd *cmd)
4022{
4023 const char *val;
4024 int ampdu = -1;
4025 char buf[30];
4026
4027 val = get_param(cmd, "40_INTOLERANT");
4028 if (val) {
4029 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4030 /* TODO: iwpriv ht40intol through wpa_supplicant */
4031 send_resp(dut, conn, SIGMA_ERROR,
4032 "ErrorCode,40_INTOLERANT not supported");
4033 return 0;
4034 }
4035 }
4036
4037 val = get_param(cmd, "ADDBA_REJECT");
4038 if (val) {
4039 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4040 /* reject any ADDBA with status "decline" */
4041 ampdu = 0;
4042 } else {
4043 /* accept ADDBA */
4044 ampdu = 1;
4045 }
4046 }
4047
4048 val = get_param(cmd, "AMPDU");
4049 if (val) {
4050 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4051 /* enable AMPDU Aggregation */
4052 if (ampdu == 0) {
4053 send_resp(dut, conn, SIGMA_ERROR,
4054 "ErrorCode,Mismatch in "
4055 "addba_reject/ampdu - "
4056 "not supported");
4057 return 0;
4058 }
4059 ampdu = 1;
4060 } else {
4061 /* disable AMPDU Aggregation */
4062 if (ampdu == 1) {
4063 send_resp(dut, conn, SIGMA_ERROR,
4064 "ErrorCode,Mismatch in "
4065 "addba_reject/ampdu - "
4066 "not supported");
4067 return 0;
4068 }
4069 ampdu = 0;
4070 }
4071 }
4072
4073 if (ampdu >= 0) {
4074 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
4075 ampdu ? "Enabling" : "Disabling");
4076 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004077 if (wpa_command(intf, buf) < 0 &&
4078 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004079 send_resp(dut, conn, SIGMA_ERROR,
4080 "ErrorCode,set aggr failed");
4081 return 0;
4082 }
4083 }
4084
4085 val = get_param(cmd, "AMSDU");
4086 if (val) {
4087 switch (get_driver_type()) {
4088 case DRIVER_ATHEROS:
4089 ath_sta_set_amsdu(dut, intf, val);
4090 break;
4091 default:
4092 if (strcmp(val, "1") == 0 ||
4093 strcasecmp(val, "Enable") == 0) {
4094 /* Enable AMSDU Aggregation */
4095 send_resp(dut, conn, SIGMA_ERROR,
4096 "ErrorCode,AMSDU aggregation not supported");
4097 return 0;
4098 }
4099 break;
4100 }
4101 }
4102
4103 val = get_param(cmd, "STBC_RX");
4104 if (val) {
4105 switch (get_driver_type()) {
4106 case DRIVER_ATHEROS:
4107 ath_sta_set_stbc(dut, intf, val);
4108 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304109 case DRIVER_WCN:
4110 wcn_sta_set_stbc(dut, intf, val);
4111 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004112 default:
4113 send_resp(dut, conn, SIGMA_ERROR,
4114 "ErrorCode,STBC_RX not supported");
4115 return 0;
4116 }
4117 }
4118
4119 val = get_param(cmd, "WIDTH");
4120 if (val) {
4121 switch (get_driver_type()) {
4122 case DRIVER_WCN:
4123 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
4124 send_resp(dut, conn, SIGMA_ERROR,
4125 "ErrorCode,Failed to set WIDTH");
4126 return 0;
4127 }
4128 break;
4129 case DRIVER_ATHEROS:
4130 if (ath_set_width(dut, conn, intf, val) < 0)
4131 return 0;
4132 break;
4133 default:
4134 sigma_dut_print(dut, DUT_MSG_ERROR,
4135 "Setting WIDTH not supported");
4136 break;
4137 }
4138 }
4139
4140 val = get_param(cmd, "SMPS");
4141 if (val) {
4142 /* TODO: Dynamic/0, Static/1, No Limit/2 */
4143 send_resp(dut, conn, SIGMA_ERROR,
4144 "ErrorCode,SMPS not supported");
4145 return 0;
4146 }
4147
4148 val = get_param(cmd, "TXSP_STREAM");
4149 if (val) {
4150 switch (get_driver_type()) {
4151 case DRIVER_WCN:
4152 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4153 send_resp(dut, conn, SIGMA_ERROR,
4154 "ErrorCode,Failed to set TXSP_STREAM");
4155 return 0;
4156 }
4157 break;
4158 case DRIVER_ATHEROS:
4159 ath_sta_set_txsp_stream(dut, intf, val);
4160 break;
4161 default:
4162 sigma_dut_print(dut, DUT_MSG_ERROR,
4163 "Setting TXSP_STREAM not supported");
4164 break;
4165 }
4166 }
4167
4168 val = get_param(cmd, "RXSP_STREAM");
4169 if (val) {
4170 switch (get_driver_type()) {
4171 case DRIVER_WCN:
4172 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4173 send_resp(dut, conn, SIGMA_ERROR,
4174 "ErrorCode,Failed to set RXSP_STREAM");
4175 return 0;
4176 }
4177 break;
4178 case DRIVER_ATHEROS:
4179 ath_sta_set_rxsp_stream(dut, intf, val);
4180 break;
4181 default:
4182 sigma_dut_print(dut, DUT_MSG_ERROR,
4183 "Setting RXSP_STREAM not supported");
4184 break;
4185 }
4186 }
4187
4188 val = get_param(cmd, "DYN_BW_SGNL");
4189 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004190 switch (get_driver_type()) {
4191 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08004192 if (strcasecmp(val, "enable") == 0) {
4193 snprintf(buf, sizeof(buf),
4194 "iwpriv %s cwmenable 1", intf);
4195 if (system(buf) != 0) {
4196 sigma_dut_print(dut, DUT_MSG_ERROR,
4197 "iwpriv cwmenable 1 failed");
4198 return 0;
4199 }
4200 } else if (strcasecmp(val, "disable") == 0) {
4201 snprintf(buf, sizeof(buf),
4202 "iwpriv %s cwmenable 0", intf);
4203 if (system(buf) != 0) {
4204 sigma_dut_print(dut, DUT_MSG_ERROR,
4205 "iwpriv cwmenable 0 failed");
4206 return 0;
4207 }
4208 } else {
4209 sigma_dut_print(dut, DUT_MSG_ERROR,
4210 "Unsupported DYN_BW_SGL");
4211 }
4212
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004213 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4214 if (system(buf) != 0) {
4215 sigma_dut_print(dut, DUT_MSG_ERROR,
4216 "Failed to set cts_cbw in DYN_BW_SGNL");
4217 return 0;
4218 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004219 break;
4220 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004221 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004222 ath_config_dyn_bw_sig(dut, intf, val);
4223 break;
4224 default:
4225 sigma_dut_print(dut, DUT_MSG_ERROR,
4226 "Failed to set DYN_BW_SGNL");
4227 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004228 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004229 }
4230
4231 val = get_param(cmd, "RTS_FORCE");
4232 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004233 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004234 if (strcasecmp(val, "Enable") == 0) {
4235 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004236 if (system(buf) != 0) {
4237 sigma_dut_print(dut, DUT_MSG_ERROR,
4238 "Failed to set RTS_FORCE 64");
4239 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08004240 snprintf(buf, sizeof(buf),
4241 "wifitool %s beeliner_fw_test 100 1", intf);
4242 if (system(buf) != 0) {
4243 sigma_dut_print(dut, DUT_MSG_ERROR,
4244 "wifitool beeliner_fw_test 100 1 failed");
4245 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004246 } else if (strcasecmp(val, "Disable") == 0) {
4247 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
4248 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004249 if (system(buf) != 0) {
4250 sigma_dut_print(dut, DUT_MSG_ERROR,
4251 "Failed to set RTS_FORCE 2347");
4252 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004253 } else {
4254 send_resp(dut, conn, SIGMA_ERROR,
4255 "ErrorCode,RTS_FORCE value not supported");
4256 return 0;
4257 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004258 }
4259
4260 val = get_param(cmd, "CTS_WIDTH");
4261 if (val) {
4262 switch (get_driver_type()) {
4263 case DRIVER_WCN:
4264 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
4265 send_resp(dut, conn, SIGMA_ERROR,
4266 "ErrorCode,Failed to set CTS_WIDTH");
4267 return 0;
4268 }
4269 break;
4270 case DRIVER_ATHEROS:
4271 ath_set_cts_width(dut, intf, val);
4272 break;
4273 default:
4274 sigma_dut_print(dut, DUT_MSG_ERROR,
4275 "Setting CTS_WIDTH not supported");
4276 break;
4277 }
4278 }
4279
4280 val = get_param(cmd, "BW_SGNL");
4281 if (val) {
4282 if (strcasecmp(val, "Enable") == 0) {
4283 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1",
4284 intf);
4285 } else if (strcasecmp(val, "Disable") == 0) {
4286 /* TODO: Disable */
4287 buf[0] = '\0';
4288 } else {
4289 send_resp(dut, conn, SIGMA_ERROR,
4290 "ErrorCode,BW_SGNL value not supported");
4291 return 0;
4292 }
4293
4294 if (buf[0] != '\0' && system(buf) != 0) {
4295 sigma_dut_print(dut, DUT_MSG_ERROR,
4296 "Failed to set BW_SGNL");
4297 }
4298 }
4299
4300 val = get_param(cmd, "Band");
4301 if (val) {
4302 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
4303 /* STA supports all bands by default */
4304 } else {
4305 send_resp(dut, conn, SIGMA_ERROR,
4306 "ErrorCode,Unsupported Band");
4307 return 0;
4308 }
4309 }
4310
4311 val = get_param(cmd, "zero_crc");
4312 if (val) {
4313 switch (get_driver_type()) {
4314 case DRIVER_ATHEROS:
4315 ath_set_zero_crc(dut, val);
4316 break;
4317 default:
4318 break;
4319 }
4320 }
4321
4322 return 1;
4323}
4324
4325
4326static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
4327 struct sigma_cmd *cmd)
4328{
4329 const char *val;
4330 char buf[100];
4331
4332 val = get_param(cmd, "MSDUSize");
4333 if (val) {
4334 int mtu;
4335
4336 dut->amsdu_size = atoi(val);
4337 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
4338 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
4339 sigma_dut_print(dut, DUT_MSG_ERROR,
4340 "MSDUSize %d is above max %d or below min %d",
4341 dut->amsdu_size,
4342 IEEE80211_MAX_DATA_LEN_DMG,
4343 IEEE80211_SNAP_LEN_DMG);
4344 dut->amsdu_size = 0;
4345 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4346 }
4347
4348 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
4349 sigma_dut_print(dut, DUT_MSG_DEBUG,
4350 "Setting amsdu_size to %d", mtu);
4351 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
4352 get_station_ifname(), mtu);
4353
4354 if (system(buf) != 0) {
4355 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
4356 buf);
4357 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4358 }
4359 }
4360
4361 val = get_param(cmd, "BAckRcvBuf");
4362 if (val) {
4363 dut->back_rcv_buf = atoi(val);
4364 if (dut->back_rcv_buf == 0) {
4365 sigma_dut_print(dut, DUT_MSG_ERROR,
4366 "Failed to convert %s or value is 0",
4367 val);
4368 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4369 }
4370
4371 sigma_dut_print(dut, DUT_MSG_DEBUG,
4372 "Setting BAckRcvBuf to %s", val);
4373 }
4374
4375 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
4376}
4377
4378
4379static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
4380 struct sigma_cmd *cmd)
4381{
4382 int net_id;
4383 char *ifname;
4384 const char *val;
4385 char buf[100];
4386
4387 dut->mode = SIGMA_MODE_STATION;
4388 ifname = get_main_ifname();
4389 if (wpa_command(ifname, "PING") != 0) {
4390 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
4391 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4392 }
4393
4394 wpa_command(ifname, "FLUSH");
4395 net_id = add_network_common(dut, conn, ifname, cmd);
4396 if (net_id < 0) {
4397 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
4398 return net_id;
4399 }
4400
4401 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
4402 if (set_network(ifname, net_id, "mode", "2") < 0) {
4403 sigma_dut_print(dut, DUT_MSG_ERROR,
4404 "Failed to set supplicant network mode");
4405 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4406 }
4407
4408 sigma_dut_print(dut, DUT_MSG_DEBUG,
4409 "Supplicant set network with mode 2");
4410
4411 val = get_param(cmd, "Security");
4412 if (val && strcasecmp(val, "OPEN") == 0) {
4413 dut->ap_key_mgmt = AP_OPEN;
4414 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
4415 sigma_dut_print(dut, DUT_MSG_ERROR,
4416 "Failed to set supplicant to %s security",
4417 val);
4418 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4419 }
4420 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
4421 dut->ap_key_mgmt = AP_WPA2_PSK;
4422 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
4423 sigma_dut_print(dut, DUT_MSG_ERROR,
4424 "Failed to set supplicant to %s security",
4425 val);
4426 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4427 }
4428
4429 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
4430 sigma_dut_print(dut, DUT_MSG_ERROR,
4431 "Failed to set supplicant to proto RSN");
4432 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4433 }
4434 } else if (val) {
4435 sigma_dut_print(dut, DUT_MSG_ERROR,
4436 "Requested Security %s is not supported on 60GHz",
4437 val);
4438 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
4439 }
4440
4441 val = get_param(cmd, "Encrypt");
4442 if (val && strcasecmp(val, "AES-GCMP") == 0) {
4443 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
4444 sigma_dut_print(dut, DUT_MSG_ERROR,
4445 "Failed to set supplicant to pairwise GCMP");
4446 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4447 }
4448 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
4449 sigma_dut_print(dut, DUT_MSG_ERROR,
4450 "Failed to set supplicant to group GCMP");
4451 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4452 }
4453 } else if (val) {
4454 sigma_dut_print(dut, DUT_MSG_ERROR,
4455 "Requested Encrypt %s is not supported on 60 GHz",
4456 val);
4457 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
4458 }
4459
4460 val = get_param(cmd, "PSK");
4461 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
4462 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
4463 val);
4464 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4465 }
4466
4467 /* Convert 60G channel to freq */
4468 switch (dut->ap_channel) {
4469 case 1:
4470 val = "58320";
4471 break;
4472 case 2:
4473 val = "60480";
4474 break;
4475 case 3:
4476 val = "62640";
4477 break;
4478 default:
4479 sigma_dut_print(dut, DUT_MSG_ERROR,
4480 "Failed to configure channel %d. Not supported",
4481 dut->ap_channel);
4482 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4483 }
4484
4485 if (set_network(ifname, net_id, "frequency", val) < 0) {
4486 sigma_dut_print(dut, DUT_MSG_ERROR,
4487 "Failed to set supplicant network frequency");
4488 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4489 }
4490
4491 sigma_dut_print(dut, DUT_MSG_DEBUG,
4492 "Supplicant set network with frequency");
4493
4494 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
4495 if (wpa_command(ifname, buf) < 0) {
4496 sigma_dut_print(dut, DUT_MSG_INFO,
4497 "Failed to select network id %d on %s",
4498 net_id, ifname);
4499 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4500 }
4501
4502 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
4503
4504 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
4505}
4506
4507
Lior David67543f52017-01-03 19:04:22 +02004508static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
4509{
4510 char buf[128], fname[128];
4511 FILE *f;
4512
4513 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
4514 sigma_dut_print(dut, DUT_MSG_ERROR,
4515 "failed to get wil6210 debugfs dir");
4516 return -1;
4517 }
4518
4519 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
4520 f = fopen(fname, "w");
4521 if (!f) {
4522 sigma_dut_print(dut, DUT_MSG_ERROR,
4523 "failed to open: %s", fname);
4524 return -1;
4525 }
4526
4527 fprintf(f, "%d\n", abft_len);
4528 fclose(f);
4529
4530 return 0;
4531}
4532
4533
4534static int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
4535 int abft_len)
4536{
4537 switch (get_driver_type()) {
4538 case DRIVER_WIL6210:
4539 return wil6210_set_abft_len(dut, abft_len);
4540 default:
4541 sigma_dut_print(dut, DUT_MSG_ERROR,
4542 "set abft_len not supported");
4543 return -1;
4544 }
4545}
4546
4547
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004548static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
4549 struct sigma_cmd *cmd)
4550{
4551 const char *val;
Lior David67543f52017-01-03 19:04:22 +02004552 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004553
4554 if (dut->dev_role != DEVROLE_PCP) {
4555 send_resp(dut, conn, SIGMA_INVALID,
4556 "ErrorCode,Invalid DevRole");
4557 return 0;
4558 }
4559
4560 val = get_param(cmd, "SSID");
4561 if (val) {
4562 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
4563 send_resp(dut, conn, SIGMA_INVALID,
4564 "ErrorCode,Invalid SSID");
4565 return -1;
4566 }
4567
Peng Xub8fc5cc2017-05-10 17:27:28 -07004568 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004569 }
4570
4571 val = get_param(cmd, "CHANNEL");
4572 if (val) {
4573 const char *pos;
4574
4575 dut->ap_channel = atoi(val);
4576 pos = strchr(val, ';');
4577 if (pos) {
4578 pos++;
4579 dut->ap_channel_1 = atoi(pos);
4580 }
4581 }
4582
4583 switch (dut->ap_channel) {
4584 case 1:
4585 case 2:
4586 case 3:
4587 break;
4588 default:
4589 sigma_dut_print(dut, DUT_MSG_ERROR,
4590 "Channel %d is not supported", dut->ap_channel);
4591 send_resp(dut, conn, SIGMA_ERROR,
4592 "Requested channel is not supported");
4593 return -1;
4594 }
4595
4596 val = get_param(cmd, "BCNINT");
4597 if (val)
4598 dut->ap_bcnint = atoi(val);
4599
4600
4601 val = get_param(cmd, "ExtSchIE");
4602 if (val) {
4603 send_resp(dut, conn, SIGMA_ERROR,
4604 "ErrorCode,ExtSchIE is not supported yet");
4605 return -1;
4606 }
4607
4608 val = get_param(cmd, "AllocType");
4609 if (val) {
4610 send_resp(dut, conn, SIGMA_ERROR,
4611 "ErrorCode,AllocType is not supported yet");
4612 return -1;
4613 }
4614
4615 val = get_param(cmd, "PercentBI");
4616 if (val) {
4617 send_resp(dut, conn, SIGMA_ERROR,
4618 "ErrorCode,PercentBI is not supported yet");
4619 return -1;
4620 }
4621
4622 val = get_param(cmd, "CBAPOnly");
4623 if (val) {
4624 send_resp(dut, conn, SIGMA_ERROR,
4625 "ErrorCode,CBAPOnly is not supported yet");
4626 return -1;
4627 }
4628
4629 val = get_param(cmd, "AMPDU");
4630 if (val) {
4631 if (strcasecmp(val, "Enable") == 0)
4632 dut->ap_ampdu = 1;
4633 else if (strcasecmp(val, "Disable") == 0)
4634 dut->ap_ampdu = 2;
4635 else {
4636 send_resp(dut, conn, SIGMA_ERROR,
4637 "ErrorCode,AMPDU value is not Enable nor Disabled");
4638 return -1;
4639 }
4640 }
4641
4642 val = get_param(cmd, "AMSDU");
4643 if (val) {
4644 if (strcasecmp(val, "Enable") == 0)
4645 dut->ap_amsdu = 1;
4646 else if (strcasecmp(val, "Disable") == 0)
4647 dut->ap_amsdu = 2;
4648 }
4649
4650 val = get_param(cmd, "NumMSDU");
4651 if (val) {
4652 send_resp(dut, conn, SIGMA_ERROR,
4653 "ErrorCode, NumMSDU is not supported yet");
4654 return -1;
4655 }
4656
4657 val = get_param(cmd, "ABFTLRang");
4658 if (val) {
4659 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02004660 "ABFTLRang parameter %s", val);
4661 if (strcmp(val, "Gt1") == 0)
4662 abft_len = 2; /* 2 slots in this case */
4663 }
4664
4665 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
4666 send_resp(dut, conn, SIGMA_ERROR,
4667 "ErrorCode, Can't set ABFT length");
4668 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004669 }
4670
4671 if (sta_pcp_start(dut, conn, cmd) < 0) {
4672 send_resp(dut, conn, SIGMA_ERROR,
4673 "ErrorCode, Can't start PCP role");
4674 return -1;
4675 }
4676
4677 return sta_set_60g_common(dut, conn, cmd);
4678}
4679
4680
4681static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
4682 struct sigma_cmd *cmd)
4683{
4684 const char *val = get_param(cmd, "DiscoveryMode");
4685
4686 if (dut->dev_role != DEVROLE_STA) {
4687 send_resp(dut, conn, SIGMA_INVALID,
4688 "ErrorCode,Invalid DevRole");
4689 return 0;
4690 }
4691
4692 if (val) {
4693 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
4694 /* Ignore Discovery mode till Driver expose API. */
4695#if 0
4696 if (strcasecmp(val, "1") == 0) {
4697 send_resp(dut, conn, SIGMA_INVALID,
4698 "ErrorCode,DiscoveryMode 1 not supported");
4699 return 0;
4700 }
4701
4702 if (strcasecmp(val, "0") == 0) {
4703 /* OK */
4704 } else {
4705 send_resp(dut, conn, SIGMA_INVALID,
4706 "ErrorCode,DiscoveryMode not supported");
4707 return 0;
4708 }
4709#endif
4710 }
4711
4712 if (start_sta_mode(dut) != 0)
4713 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4714 return sta_set_60g_common(dut, conn, cmd);
4715}
4716
4717
4718static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
4719 struct sigma_cmd *cmd)
4720{
4721 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02004722 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05304723
Jouni Malinened77e672018-01-10 16:45:13 +02004724 if (dut->program == PROGRAM_OCE ||
4725 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05304726 wpa_command(intf, "DISCONNECT");
4727 return 1;
4728 }
4729
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004730 disconnect_station(dut);
4731 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
4732 * due to cached results. */
4733 wpa_command(intf, "SET ignore_old_scan_res 1");
4734 wpa_command(intf, "BSS_FLUSH");
4735 return 1;
4736}
4737
4738
4739static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
4740 struct sigma_cmd *cmd)
4741{
4742 const char *intf = get_param(cmd, "Interface");
4743 const char *bssid = get_param(cmd, "bssid");
4744 const char *val = get_param(cmd, "CHANNEL");
4745 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05304746 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05304747 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004748 int res;
4749 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05304750 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05304751 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004752
4753 if (bssid == NULL) {
4754 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
4755 "argument");
4756 return 0;
4757 }
4758
4759 if (val)
4760 chan = atoi(val);
4761
4762 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
4763 /* The current network may be from sta_associate or
4764 * sta_hs2_associate
4765 */
4766 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
4767 0 ||
4768 set_network(intf, 0, "bssid", bssid) < 0)
4769 return -2;
4770 }
4771
4772 ctrl = open_wpa_mon(intf);
4773 if (ctrl == NULL) {
4774 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
4775 "wpa_supplicant monitor connection");
4776 return -1;
4777 }
4778
Sunil Duttd30ce092018-01-11 23:56:29 +05304779 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
4780 sizeof(result)) < 0 ||
4781 strncmp(result, "COMPLETED", 9) != 0) {
4782 sigma_dut_print(dut, DUT_MSG_DEBUG,
4783 "sta_reassoc: Not connected");
4784 fastreassoc = 0;
4785 }
4786
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05304787 if (dut->rsne_override) {
4788#ifdef NL80211_SUPPORT
4789 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
4790 sta_config_rsnie(dut, 1);
4791 dut->config_rsnie = 1;
4792 }
4793#endif /* NL80211_SUPPORT */
4794 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
4795 dut->rsne_override);
4796 if (wpa_command(intf, buf) < 0) {
4797 send_resp(dut, conn, SIGMA_ERROR,
4798 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
4799 return 0;
4800 }
4801 }
4802
Sunil Duttd30ce092018-01-11 23:56:29 +05304803 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004804#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05304805 if (chan) {
4806 unsigned int freq;
4807
4808 freq = channel_to_freq(chan);
4809 if (!freq) {
4810 sigma_dut_print(dut, DUT_MSG_ERROR,
4811 "Invalid channel number provided: %d",
4812 chan);
4813 send_resp(dut, conn, SIGMA_INVALID,
4814 "ErrorCode,Invalid channel number");
4815 goto close_mon_conn;
4816 }
4817 res = snprintf(buf, sizeof(buf),
4818 "SCAN TYPE=ONLY freq=%d", freq);
4819 } else {
4820 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
4821 }
4822 if (res < 0 || res >= (int) sizeof(buf)) {
4823 send_resp(dut, conn, SIGMA_ERROR,
4824 "ErrorCode,snprintf failed");
4825 goto close_mon_conn;
4826 }
4827 if (wpa_command(intf, buf) < 0) {
4828 sigma_dut_print(dut, DUT_MSG_INFO,
4829 "Failed to start scan");
4830 send_resp(dut, conn, SIGMA_ERROR,
4831 "ErrorCode,scan failed");
4832 goto close_mon_conn;
4833 }
4834
4835 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
4836 buf, sizeof(buf));
4837 if (res < 0) {
4838 sigma_dut_print(dut, DUT_MSG_INFO,
4839 "Scan did not complete");
4840 send_resp(dut, conn, SIGMA_ERROR,
4841 "ErrorCode,scan did not complete");
4842 goto close_mon_conn;
4843 }
4844
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004845 if (set_network(intf, dut->infra_network_id, "bssid", "any")
4846 < 0) {
4847 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
4848 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05304849 status = -2;
4850 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004851 }
4852 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
4853 bssid, chan);
4854 if (res > 0 && res < (int) sizeof(buf))
4855 res = wpa_command(intf, buf);
4856
4857 if (res < 0 || res >= (int) sizeof(buf)) {
4858 send_resp(dut, conn, SIGMA_ERROR,
4859 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05304860 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004861 }
4862#else /* ANDROID */
4863 sigma_dut_print(dut, DUT_MSG_DEBUG,
4864 "Reassoc using iwpriv - skip chan=%d info",
4865 chan);
4866 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
4867 if (system(buf) != 0) {
4868 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05304869 status = -2;
4870 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004871 }
4872#endif /* ANDROID */
4873 sigma_dut_print(dut, DUT_MSG_INFO,
4874 "sta_reassoc: Run %s successful", buf);
4875 } else if (wpa_command(intf, "REASSOCIATE")) {
4876 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
4877 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05304878 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004879 }
4880
4881 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
4882 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05304883 if (res < 0) {
4884 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
4885 status = -1;
4886 goto close_mon_conn;
4887 }
4888 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004889
Ashwini Patil467efef2017-05-25 12:18:27 +05304890close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004891 wpa_ctrl_detach(ctrl);
4892 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05304893 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004894}
4895
4896
4897static void hs2_clear_credentials(const char *intf)
4898{
4899 wpa_command(intf, "REMOVE_CRED all");
4900}
4901
4902
Lior Davidcc88b562017-01-03 18:52:09 +02004903#ifdef __linux__
4904static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
4905 unsigned int *aid)
4906{
Lior David0fe101e2017-03-09 16:09:50 +02004907 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02004908
Lior David0fe101e2017-03-09 16:09:50 +02004909 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02004910}
4911#endif /* __linux__ */
4912
4913
4914static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
4915 unsigned int *aid)
4916{
4917 switch (get_driver_type()) {
4918#ifdef __linux__
4919 case DRIVER_WIL6210:
4920 return wil6210_get_aid(dut, bssid, aid);
4921#endif /* __linux__ */
4922 default:
4923 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
4924 return -1;
4925 }
4926}
4927
4928
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004929static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
4930 struct sigma_cmd *cmd)
4931{
4932 char buf[MAX_CMD_LEN];
4933 char bss_list[MAX_CMD_LEN];
4934 const char *parameter = get_param(cmd, "Parameter");
4935
4936 if (parameter == NULL)
4937 return -1;
4938
Lior Davidcc88b562017-01-03 18:52:09 +02004939 if (strcasecmp(parameter, "AID") == 0) {
4940 unsigned int aid = 0;
4941 char bssid[20];
4942
4943 if (get_wpa_status(get_station_ifname(), "bssid",
4944 bssid, sizeof(bssid)) < 0) {
4945 sigma_dut_print(dut, DUT_MSG_ERROR,
4946 "could not get bssid");
4947 return -2;
4948 }
4949
4950 if (sta_get_aid_60g(dut, bssid, &aid))
4951 return -2;
4952
4953 snprintf(buf, sizeof(buf), "aid,%d", aid);
4954 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
4955 send_resp(dut, conn, SIGMA_COMPLETE, buf);
4956 return 0;
4957 }
4958
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004959 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
4960 char *bss_line;
4961 char *bss_id = NULL;
4962 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304963 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004964
4965 if (ifname == NULL) {
4966 sigma_dut_print(dut, DUT_MSG_INFO,
4967 "For get DiscoveredDevList need Interface name.");
4968 return -1;
4969 }
4970
4971 /*
4972 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
4973 * of BSSIDs in "bssid=<BSSID>\n"
4974 */
4975 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
4976 bss_list,
4977 sizeof(bss_list)) < 0) {
4978 sigma_dut_print(dut, DUT_MSG_ERROR,
4979 "Failed to get bss list");
4980 return -1;
4981 }
4982
4983 sigma_dut_print(dut, DUT_MSG_DEBUG,
4984 "bss list for ifname:%s is:%s",
4985 ifname, bss_list);
4986
4987 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304988 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004989 while (bss_line) {
4990 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
4991 bss_id) {
4992 int len;
4993
4994 len = snprintf(buf + strlen(buf),
4995 sizeof(buf) - strlen(buf),
4996 ",%s", bss_id);
4997 free(bss_id);
4998 bss_id = NULL;
4999 if (len < 0) {
5000 sigma_dut_print(dut,
5001 DUT_MSG_ERROR,
5002 "Failed to read BSSID");
5003 send_resp(dut, conn, SIGMA_ERROR,
5004 "ErrorCode,Failed to read BSS ID");
5005 return 0;
5006 }
5007
5008 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
5009 sigma_dut_print(dut,
5010 DUT_MSG_ERROR,
5011 "Response buf too small for list");
5012 send_resp(dut, conn,
5013 SIGMA_ERROR,
5014 "ErrorCode,Response buf too small for list");
5015 return 0;
5016 }
5017 }
5018
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305019 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005020 }
5021
5022 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
5023 buf);
5024 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5025 return 0;
5026 }
5027
5028 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5029 return 0;
5030}
5031
5032
5033static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
5034 struct sigma_cmd *cmd)
5035{
5036 const char *program = get_param(cmd, "Program");
5037
5038 if (program == NULL)
5039 return -1;
5040
5041 if (strcasecmp(program, "P2PNFC") == 0)
5042 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
5043
5044 if (strcasecmp(program, "60ghz") == 0)
5045 return sta_get_parameter_60g(dut, conn, cmd);
5046
5047#ifdef ANDROID_NAN
5048 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07005049 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005050#endif /* ANDROID_NAN */
5051
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005052#ifdef MIRACAST
5053 if (strcasecmp(program, "WFD") == 0 ||
5054 strcasecmp(program, "DisplayR2") == 0)
5055 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
5056#endif /* MIRACAST */
5057
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005058 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5059 return 0;
5060}
5061
5062
5063static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
5064 const char *type)
5065{
5066 char buf[100];
5067
5068 if (dut->program == PROGRAM_VHT) {
5069 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5070 if (system(buf) != 0) {
5071 sigma_dut_print(dut, DUT_MSG_ERROR,
5072 "iwpriv %s chwidth failed", intf);
5073 }
5074
5075 snprintf(buf, sizeof(buf), "iwpriv %s mode 11ACVHT80", intf);
5076 if (system(buf) != 0) {
5077 sigma_dut_print(dut, DUT_MSG_ERROR,
5078 "iwpriv %s mode 11ACVHT80 failed",
5079 intf);
5080 }
5081
5082 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs -1", intf);
5083 if (system(buf) != 0) {
5084 sigma_dut_print(dut, DUT_MSG_ERROR,
5085 "iwpriv %s vhtmcs -1 failed", intf);
5086 }
5087 }
5088
5089 if (dut->program == PROGRAM_HT) {
5090 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5091 if (system(buf) != 0) {
5092 sigma_dut_print(dut, DUT_MSG_ERROR,
5093 "iwpriv %s chwidth failed", intf);
5094 }
5095
5096 snprintf(buf, sizeof(buf), "iwpriv %s mode 11naht40", intf);
5097 if (system(buf) != 0) {
5098 sigma_dut_print(dut, DUT_MSG_ERROR,
5099 "iwpriv %s mode 11naht40 failed",
5100 intf);
5101 }
5102
5103 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0", intf);
5104 if (system(buf) != 0) {
5105 sigma_dut_print(dut, DUT_MSG_ERROR,
5106 "iwpriv set11NRates failed");
5107 }
5108 }
5109
5110 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
5111 snprintf(buf, sizeof(buf), "iwpriv %s powersave 0", intf);
5112 if (system(buf) != 0) {
5113 sigma_dut_print(dut, DUT_MSG_ERROR,
5114 "disabling powersave failed");
5115 }
5116
5117 /* Reset CTS width */
5118 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
5119 intf);
5120 if (system(buf) != 0) {
5121 sigma_dut_print(dut, DUT_MSG_ERROR,
5122 "wifitool %s beeliner_fw_test 54 0 failed",
5123 intf);
5124 }
5125
5126 /* Enable Dynamic Bandwidth signalling by default */
5127 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", intf);
5128 if (system(buf) != 0) {
5129 sigma_dut_print(dut, DUT_MSG_ERROR,
5130 "iwpriv %s cwmenable 1 failed", intf);
5131 }
5132
5133 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
5134 if (system(buf) != 0) {
5135 sigma_dut_print(dut, DUT_MSG_ERROR,
5136 "iwpriv rts failed");
5137 }
5138 }
5139
5140 if (type && strcasecmp(type, "Testbed") == 0) {
5141 dut->testbed_flag_txsp = 1;
5142 dut->testbed_flag_rxsp = 1;
5143 /* STA has to set spatial stream to 2 per Appendix H */
5144 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0xfff0", intf);
5145 if (system(buf) != 0) {
5146 sigma_dut_print(dut, DUT_MSG_ERROR,
5147 "iwpriv vht_mcsmap failed");
5148 }
5149
5150 /* Disable LDPC per Appendix H */
5151 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", intf);
5152 if (system(buf) != 0) {
5153 sigma_dut_print(dut, DUT_MSG_ERROR,
5154 "iwpriv %s ldpc 0 failed", intf);
5155 }
5156
5157 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5158 if (system(buf) != 0) {
5159 sigma_dut_print(dut, DUT_MSG_ERROR,
5160 "iwpriv amsdu failed");
5161 }
5162
5163 /* TODO: Disable STBC 2x1 transmit and receive */
5164 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", intf);
5165 if (system(buf) != 0) {
5166 sigma_dut_print(dut, DUT_MSG_ERROR,
5167 "Disable tx_stbc 0 failed");
5168 }
5169
5170 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc 0", intf);
5171 if (system(buf) != 0) {
5172 sigma_dut_print(dut, DUT_MSG_ERROR,
5173 "Disable rx_stbc 0 failed");
5174 }
5175
5176 /* STA has to disable Short GI per Appendix H */
5177 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 0", intf);
5178 if (system(buf) != 0) {
5179 sigma_dut_print(dut, DUT_MSG_ERROR,
5180 "iwpriv %s shortgi 0 failed", intf);
5181 }
5182 }
5183
5184 if (type && strcasecmp(type, "DUT") == 0) {
5185 snprintf(buf, sizeof(buf), "iwpriv %s nss 3", intf);
5186 if (system(buf) != 0) {
5187 sigma_dut_print(dut, DUT_MSG_ERROR,
5188 "iwpriv %s nss 3 failed", intf);
5189 }
5190
5191 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 1", intf);
5192 if (system(buf) != 0) {
5193 sigma_dut_print(dut, DUT_MSG_ERROR,
5194 "iwpriv %s shortgi 1 failed", intf);
5195 }
5196 }
5197}
5198
5199
5200static int cmd_sta_reset_default(struct sigma_dut *dut,
5201 struct sigma_conn *conn,
5202 struct sigma_cmd *cmd)
5203{
5204 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
5205 struct sigma_cmd *cmd);
5206 const char *intf = get_param(cmd, "Interface");
5207 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005208 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05305209 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005210
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005211 if (!program)
5212 program = get_param(cmd, "prog");
5213 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005214 dut->device_type = STA_unknown;
5215 type = get_param(cmd, "type");
5216 if (type && strcasecmp(type, "Testbed") == 0)
5217 dut->device_type = STA_testbed;
5218 if (type && strcasecmp(type, "DUT") == 0)
5219 dut->device_type = STA_dut;
5220
5221 if (dut->program == PROGRAM_TDLS) {
5222 /* Clear TDLS testing mode */
5223 wpa_command(intf, "SET tdls_disabled 0");
5224 wpa_command(intf, "SET tdls_testing 0");
5225 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05305226 if (get_driver_type() == DRIVER_WCN) {
5227 /* Enable the WCN driver in TDLS Explicit trigger mode
5228 */
5229 wpa_command(intf, "SET tdls_external_control 0");
5230 wpa_command(intf, "SET tdls_trigger_control 0");
5231 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005232 }
5233
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005234#ifdef MIRACAST
5235 if (dut->program == PROGRAM_WFD ||
5236 dut->program == PROGRAM_DISPLAYR2)
5237 miracast_sta_reset_default(dut, conn, cmd);
5238#endif /* MIRACAST */
5239
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005240 switch (get_driver_type()) {
5241 case DRIVER_ATHEROS:
5242 sta_reset_default_ath(dut, intf, type);
5243 break;
5244 default:
5245 break;
5246 }
5247
5248#ifdef ANDROID_NAN
5249 if (dut->program == PROGRAM_NAN)
5250 nan_cmd_sta_reset_default(dut, conn, cmd);
5251#endif /* ANDROID_NAN */
5252
5253 if (dut->program == PROGRAM_HS2_R2) {
5254 unlink("SP/wi-fi.org/pps.xml");
5255 if (system("rm -r SP/*") != 0) {
5256 }
5257 unlink("next-client-cert.pem");
5258 unlink("next-client-key.pem");
5259 }
5260
5261 if (dut->program == PROGRAM_60GHZ) {
5262 const char *dev_role = get_param(cmd, "DevRole");
5263
5264 if (!dev_role) {
5265 send_resp(dut, conn, SIGMA_ERROR,
5266 "errorCode,Missing DevRole argument");
5267 return 0;
5268 }
5269
5270 if (strcasecmp(dev_role, "STA") == 0)
5271 dut->dev_role = DEVROLE_STA;
5272 else if (strcasecmp(dev_role, "PCP") == 0)
5273 dut->dev_role = DEVROLE_PCP;
5274 else {
5275 send_resp(dut, conn, SIGMA_ERROR,
5276 "errorCode,Unknown DevRole");
5277 return 0;
5278 }
5279
5280 if (dut->device_type == STA_unknown) {
5281 sigma_dut_print(dut, DUT_MSG_ERROR,
5282 "Device type is not STA testbed or DUT");
5283 send_resp(dut, conn, SIGMA_ERROR,
5284 "errorCode,Unknown device type");
5285 return 0;
5286 }
5287 }
5288
5289 wpa_command(intf, "WPS_ER_STOP");
5290 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05305291 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005292 wpa_command(intf, "SET radio_disabled 0");
5293
5294 if (dut->tmp_mac_addr && dut->set_macaddr) {
5295 dut->tmp_mac_addr = 0;
5296 if (system(dut->set_macaddr) != 0) {
5297 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
5298 "temporary MAC address");
5299 }
5300 }
5301
5302 set_ps(intf, dut, 0);
5303
5304 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2) {
5305 wpa_command(intf, "SET interworking 1");
5306 wpa_command(intf, "SET hs20 1");
5307 }
5308
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08005309 if (dut->program == PROGRAM_HS2_R2 ||
5310 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005311 wpa_command(intf, "SET pmf 1");
5312 } else {
5313 wpa_command(intf, "SET pmf 0");
5314 }
5315
5316 hs2_clear_credentials(intf);
5317 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
5318 wpa_command(intf, "SET access_network_type 15");
5319
5320 static_ip_file(0, NULL, NULL, NULL);
5321 kill_dhcp_client(dut, intf);
5322 clear_ip_addr(dut, intf);
5323
5324 dut->er_oper_performed = 0;
5325 dut->er_oper_bssid[0] = '\0';
5326
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07005327 if (dut->program == PROGRAM_LOC) {
5328 /* Disable Interworking by default */
5329 wpa_command(get_station_ifname(), "SET interworking 0");
5330 }
5331
Ashwini Patil00402582017-04-13 12:29:39 +05305332 if (dut->program == PROGRAM_MBO) {
5333 free(dut->non_pref_ch_list);
5334 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05305335 free(dut->btm_query_cand_list);
5336 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05305337 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05305338 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05305339 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05305340 wpa_command(intf, "SET roaming 1");
Ashwini Patil00402582017-04-13 12:29:39 +05305341 }
5342
Jouni Malinen3c367e82017-06-23 17:01:47 +03005343 free(dut->rsne_override);
5344 dut->rsne_override = NULL;
5345
Jouni Malinen68143132017-09-02 02:34:08 +03005346 free(dut->sae_commit_override);
5347 dut->sae_commit_override = NULL;
5348
Jouni Malinend86e5822017-08-29 03:55:32 +03005349 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02005350 free(dut->dpp_peer_uri);
5351 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02005352 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02005353 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03005354
Jouni Malinenfac9cad2017-10-10 18:35:55 +03005355 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
5356
vamsi krishnaa2799492017-12-05 14:28:01 +05305357 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305358 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05305359 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305360 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
5361 dut->fils_hlp = 0;
5362#ifdef ANDROID
5363 hlp_thread_cleanup(dut);
5364#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05305365 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305366
Sunil Dutt076081f2018-02-05 19:45:50 +05305367#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05305368 if (get_driver_type() == DRIVER_WCN &&
5369 dut->config_rsnie == 1) {
5370 dut->config_rsnie = 0;
5371 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05305372 }
5373#endif /* NL80211_SUPPORT */
5374
Sunil Duttfebf8a82018-02-09 18:50:13 +05305375 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
5376 dut->dev_role = DEVROLE_STA_CFON;
5377 return sta_cfon_reset_default(dut, conn, cmd);
5378 }
5379
5380 if (dut->program != PROGRAM_VHT)
5381 return cmd_sta_p2p_reset(dut, conn, cmd);
5382
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08005383 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005384}
5385
5386
5387static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
5388 struct sigma_cmd *cmd)
5389{
5390 const char *program = get_param(cmd, "Program");
5391
5392 if (program == NULL)
5393 return -1;
5394#ifdef ANDROID_NAN
5395 if (strcasecmp(program, "NAN") == 0)
5396 return nan_cmd_sta_get_events(dut, conn, cmd);
5397#endif /* ANDROID_NAN */
5398 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5399 return 0;
5400}
5401
5402
5403static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
5404 struct sigma_cmd *cmd)
5405{
5406 const char *program = get_param(cmd, "Prog");
5407
5408 if (program == NULL)
5409 return -1;
5410#ifdef ANDROID_NAN
5411 if (strcasecmp(program, "NAN") == 0)
5412 return nan_cmd_sta_exec_action(dut, conn, cmd);
5413#endif /* ANDROID_NAN */
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005414 if (strcasecmp(program, "Loc") == 0)
5415 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005416 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5417 return 0;
5418}
5419
5420
5421static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
5422 struct sigma_cmd *cmd)
5423{
5424 const char *intf = get_param(cmd, "Interface");
5425 const char *val, *mcs32, *rate;
5426
5427 val = get_param(cmd, "GREENFIELD");
5428 if (val) {
5429 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5430 /* Enable GD */
5431 send_resp(dut, conn, SIGMA_ERROR,
5432 "ErrorCode,GF not supported");
5433 return 0;
5434 }
5435 }
5436
5437 val = get_param(cmd, "SGI20");
5438 if (val) {
5439 switch (get_driver_type()) {
5440 case DRIVER_ATHEROS:
5441 ath_sta_set_sgi(dut, intf, val);
5442 break;
5443 default:
5444 send_resp(dut, conn, SIGMA_ERROR,
5445 "ErrorCode,SGI20 not supported");
5446 return 0;
5447 }
5448 }
5449
5450 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
5451 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
5452 if (mcs32 && rate) {
5453 /* TODO */
5454 send_resp(dut, conn, SIGMA_ERROR,
5455 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
5456 return 0;
5457 } else if (mcs32 && !rate) {
5458 /* TODO */
5459 send_resp(dut, conn, SIGMA_ERROR,
5460 "ErrorCode,MCS32 not supported");
5461 return 0;
5462 } else if (!mcs32 && rate) {
5463 switch (get_driver_type()) {
5464 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08005465 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005466 ath_sta_set_11nrates(dut, intf, rate);
5467 break;
5468 default:
5469 send_resp(dut, conn, SIGMA_ERROR,
5470 "ErrorCode,MCS32_FIXEDRATE not supported");
5471 return 0;
5472 }
5473 }
5474
5475 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
5476}
5477
5478
5479static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
5480 struct sigma_conn *conn,
5481 struct sigma_cmd *cmd)
5482{
5483 const char *intf = get_param(cmd, "Interface");
5484 const char *val;
5485 char buf[30];
5486 int tkip = -1;
5487 int wep = -1;
5488
5489 val = get_param(cmd, "SGI80");
5490 if (val) {
5491 int sgi80;
5492
5493 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5494 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi80);
5495 if (system(buf) != 0) {
5496 sigma_dut_print(dut, DUT_MSG_ERROR,
5497 "iwpriv shortgi failed");
5498 }
5499 }
5500
5501 val = get_param(cmd, "TxBF");
5502 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
5503 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 1", intf);
5504 if (system(buf) != 0) {
5505 sigma_dut_print(dut, DUT_MSG_ERROR,
5506 "iwpriv vhtsubfee failed");
5507 }
5508 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 1", intf);
5509 if (system(buf) != 0) {
5510 sigma_dut_print(dut, DUT_MSG_ERROR,
5511 "iwpriv vhtsubfer failed");
5512 }
5513 }
5514
5515 val = get_param(cmd, "MU_TxBF");
5516 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
5517 switch (get_driver_type()) {
5518 case DRIVER_ATHEROS:
5519 ath_sta_set_txsp_stream(dut, intf, "1SS");
5520 ath_sta_set_rxsp_stream(dut, intf, "1SS");
5521 case DRIVER_WCN:
5522 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
5523 send_resp(dut, conn, SIGMA_ERROR,
5524 "ErrorCode,Failed to set RX/TXSP_STREAM");
5525 return 0;
5526 }
5527 default:
5528 sigma_dut_print(dut, DUT_MSG_ERROR,
5529 "Setting SP_STREAM not supported");
5530 break;
5531 }
5532 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 1", intf);
5533 if (system(buf) != 0) {
5534 sigma_dut_print(dut, DUT_MSG_ERROR,
5535 "iwpriv vhtmubfee failed");
5536 }
5537 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 1", intf);
5538 if (system(buf) != 0) {
5539 sigma_dut_print(dut, DUT_MSG_ERROR,
5540 "iwpriv vhtmubfer failed");
5541 }
5542 }
5543
5544 val = get_param(cmd, "LDPC");
5545 if (val) {
5546 int ldpc;
5547
5548 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5549 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, ldpc);
5550 if (system(buf) != 0) {
5551 sigma_dut_print(dut, DUT_MSG_ERROR,
5552 "iwpriv ldpc failed");
5553 }
5554 }
5555
5556 val = get_param(cmd, "opt_md_notif_ie");
5557 if (val) {
5558 char *result = NULL;
5559 char delim[] = ";";
5560 char token[30];
5561 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305562 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005563
Peng Xub8fc5cc2017-05-10 17:27:28 -07005564 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305565 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005566
5567 /* Extract the NSS information */
5568 if (result) {
5569 value = atoi(result);
5570 switch (value) {
5571 case 1:
5572 config_val = 1;
5573 break;
5574 case 2:
5575 config_val = 3;
5576 break;
5577 case 3:
5578 config_val = 7;
5579 break;
5580 case 4:
5581 config_val = 15;
5582 break;
5583 default:
5584 config_val = 3;
5585 break;
5586 }
5587
5588 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
5589 intf, config_val);
5590 if (system(buf) != 0) {
5591 sigma_dut_print(dut, DUT_MSG_ERROR,
5592 "iwpriv rxchainmask failed");
5593 }
5594
5595 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
5596 intf, config_val);
5597 if (system(buf) != 0) {
5598 sigma_dut_print(dut, DUT_MSG_ERROR,
5599 "iwpriv txchainmask failed");
5600 }
5601 }
5602
5603 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305604 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005605 if (result) {
5606 value = atoi(result);
5607 switch (value) {
5608 case 20:
5609 config_val = 0;
5610 break;
5611 case 40:
5612 config_val = 1;
5613 break;
5614 case 80:
5615 config_val = 2;
5616 break;
5617 case 160:
5618 config_val = 3;
5619 break;
5620 default:
5621 config_val = 2;
5622 break;
5623 }
5624
5625 dut->chwidth = config_val;
5626
5627 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
5628 intf, config_val);
5629 if (system(buf) != 0) {
5630 sigma_dut_print(dut, DUT_MSG_ERROR,
5631 "iwpriv chwidth failed");
5632 }
5633 }
5634
5635 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", intf);
5636 if (system(buf) != 0) {
5637 sigma_dut_print(dut, DUT_MSG_ERROR,
5638 "iwpriv opmode_notify failed");
5639 }
5640 }
5641
5642 val = get_param(cmd, "nss_mcs_cap");
5643 if (val) {
5644 int nss, mcs;
5645 char token[20];
5646 char *result = NULL;
5647 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305648 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005649
Peng Xub8fc5cc2017-05-10 17:27:28 -07005650 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305651 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05305652 if (!result) {
5653 sigma_dut_print(dut, DUT_MSG_ERROR,
5654 "VHT NSS not specified");
5655 return 0;
5656 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005657 nss = atoi(result);
5658
5659 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
5660 if (system(buf) != 0) {
5661 sigma_dut_print(dut, DUT_MSG_ERROR,
5662 "iwpriv nss failed");
5663 }
5664
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305665 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005666 if (result == NULL) {
5667 sigma_dut_print(dut, DUT_MSG_ERROR,
5668 "VHTMCS NOT SPECIFIED!");
5669 return 0;
5670 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305671 result = strtok_r(result, "-", &saveptr);
5672 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05305673 if (!result) {
5674 sigma_dut_print(dut, DUT_MSG_ERROR,
5675 "VHT MCS not specified");
5676 return 0;
5677 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005678 mcs = atoi(result);
5679
5680 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d", intf, mcs);
5681 if (system(buf) != 0) {
5682 sigma_dut_print(dut, DUT_MSG_ERROR,
5683 "iwpriv mcs failed");
5684 }
5685
5686 switch (nss) {
5687 case 1:
5688 switch (mcs) {
5689 case 7:
5690 vht_mcsmap = 0xfffc;
5691 break;
5692 case 8:
5693 vht_mcsmap = 0xfffd;
5694 break;
5695 case 9:
5696 vht_mcsmap = 0xfffe;
5697 break;
5698 default:
5699 vht_mcsmap = 0xfffe;
5700 break;
5701 }
5702 break;
5703 case 2:
5704 switch (mcs) {
5705 case 7:
5706 vht_mcsmap = 0xfff0;
5707 break;
5708 case 8:
5709 vht_mcsmap = 0xfff5;
5710 break;
5711 case 9:
5712 vht_mcsmap = 0xfffa;
5713 break;
5714 default:
5715 vht_mcsmap = 0xfffa;
5716 break;
5717 }
5718 break;
5719 case 3:
5720 switch (mcs) {
5721 case 7:
5722 vht_mcsmap = 0xffc0;
5723 break;
5724 case 8:
5725 vht_mcsmap = 0xffd5;
5726 break;
5727 case 9:
5728 vht_mcsmap = 0xffea;
5729 break;
5730 default:
5731 vht_mcsmap = 0xffea;
5732 break;
5733 }
5734 break;
5735 default:
5736 vht_mcsmap = 0xffea;
5737 break;
5738 }
5739 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
5740 intf, vht_mcsmap);
5741 if (system(buf) != 0) {
5742 sigma_dut_print(dut, DUT_MSG_ERROR,
5743 "iwpriv vht_mcsmap failed");
5744 }
5745 }
5746
5747 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
5748
5749 val = get_param(cmd, "Vht_tkip");
5750 if (val)
5751 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5752
5753 val = get_param(cmd, "Vht_wep");
5754 if (val)
5755 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5756
5757 if (tkip != -1 || wep != -1) {
5758 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
5759 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1",
5760 intf);
5761 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
5762 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 0",
5763 intf);
5764 } else {
5765 sigma_dut_print(dut, DUT_MSG_ERROR,
5766 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
5767 return 0;
5768 }
5769
5770 if (system(buf) != 0) {
5771 sigma_dut_print(dut, DUT_MSG_ERROR,
5772 "iwpriv htweptkip failed");
5773 }
5774 }
5775
5776 val = get_param(cmd, "txBandwidth");
5777 if (val) {
5778 switch (get_driver_type()) {
5779 case DRIVER_ATHEROS:
5780 if (ath_set_width(dut, conn, intf, val) < 0) {
5781 send_resp(dut, conn, SIGMA_ERROR,
5782 "ErrorCode,Failed to set txBandwidth");
5783 return 0;
5784 }
5785 break;
5786 default:
5787 sigma_dut_print(dut, DUT_MSG_ERROR,
5788 "Setting txBandwidth not supported");
5789 break;
5790 }
5791 }
5792
5793 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
5794}
5795
5796
5797static int sta_set_wireless_60g(struct sigma_dut *dut,
5798 struct sigma_conn *conn,
5799 struct sigma_cmd *cmd)
5800{
5801 const char *dev_role = get_param(cmd, "DevRole");
5802
5803 if (!dev_role) {
5804 send_resp(dut, conn, SIGMA_INVALID,
5805 "ErrorCode,DevRole not specified");
5806 return 0;
5807 }
5808
5809 if (strcasecmp(dev_role, "PCP") == 0)
5810 return sta_set_60g_pcp(dut, conn, cmd);
5811 if (strcasecmp(dev_role, "STA") == 0)
5812 return sta_set_60g_sta(dut, conn, cmd);
5813 send_resp(dut, conn, SIGMA_INVALID,
5814 "ErrorCode,DevRole not supported");
5815 return 0;
5816}
5817
5818
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05305819static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
5820 struct sigma_cmd *cmd)
5821{
5822 int status;
5823 const char *intf = get_param(cmd, "Interface");
5824 const char *val = get_param(cmd, "DevRole");
5825
5826 if (val && strcasecmp(val, "STA-CFON") == 0) {
5827 status = sta_cfon_set_wireless(dut, conn, cmd);
5828 if (status)
5829 return status;
5830 }
5831 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
5832}
5833
5834
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005835static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
5836 struct sigma_cmd *cmd)
5837{
5838 const char *val;
5839
5840 val = get_param(cmd, "Program");
5841 if (val) {
5842 if (strcasecmp(val, "11n") == 0)
5843 return cmd_sta_set_11n(dut, conn, cmd);
5844 if (strcasecmp(val, "VHT") == 0)
5845 return cmd_sta_set_wireless_vht(dut, conn, cmd);
5846 if (strcasecmp(val, "60ghz") == 0)
5847 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05305848 if (strcasecmp(val, "OCE") == 0)
5849 return sta_set_wireless_oce(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005850 send_resp(dut, conn, SIGMA_ERROR,
5851 "ErrorCode,Program value not supported");
5852 } else {
5853 send_resp(dut, conn, SIGMA_ERROR,
5854 "ErrorCode,Program argument not available");
5855 }
5856
5857 return 0;
5858}
5859
5860
5861static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
5862 int tid)
5863{
5864 char buf[100];
5865 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
5866
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05305867 if (tid < 0 ||
5868 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
5869 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
5870 return;
5871 }
5872
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005873 /*
5874 * Two ways to ensure that addba request with a
5875 * non zero TID could be sent out. EV 117296
5876 */
5877 snprintf(buf, sizeof(buf),
5878 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
5879 tid);
5880 if (system(buf) != 0) {
5881 sigma_dut_print(dut, DUT_MSG_ERROR,
5882 "Ping did not send out");
5883 }
5884
5885 snprintf(buf, sizeof(buf),
5886 "iwconfig %s | grep Access | awk '{print $6}' > %s",
5887 intf, VI_QOS_TMP_FILE);
5888 if (system(buf) != 0)
5889 return;
5890
5891 snprintf(buf, sizeof(buf),
5892 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
5893 intf, VI_QOS_TMP_FILE);
5894 if (system(buf) != 0)
5895 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
5896
5897 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
5898 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
5899 if (system(buf) != 0) {
5900 sigma_dut_print(dut, DUT_MSG_ERROR,
5901 "VI_QOS_TEMP_FILE generation error failed");
5902 }
5903 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
5904 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
5905 if (system(buf) != 0) {
5906 sigma_dut_print(dut, DUT_MSG_ERROR,
5907 "VI_QOS_FILE generation failed");
5908 }
5909
5910 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
5911 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
5912 if (system(buf) != 0) {
5913 sigma_dut_print(dut, DUT_MSG_ERROR,
5914 "VI_QOS_FILE generation failed");
5915 }
5916
5917 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
5918 if (system(buf) != 0) {
5919 }
5920}
5921
5922
5923static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
5924 struct sigma_cmd *cmd)
5925{
5926 const char *intf = get_param(cmd, "Interface");
5927 const char *val;
5928 int tid = 0;
5929 char buf[100];
5930
5931 val = get_param(cmd, "TID");
5932 if (val) {
5933 tid = atoi(val);
5934 if (tid)
5935 ath_sta_inject_frame(dut, intf, tid);
5936 }
5937
5938 /* Command sequence for ADDBA request on Peregrine based devices */
5939 snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", intf);
5940 if (system(buf) != 0) {
5941 sigma_dut_print(dut, DUT_MSG_ERROR,
5942 "iwpriv setaddbaoper failed");
5943 }
5944
5945 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
5946 if (system(buf) != 0) {
5947 sigma_dut_print(dut, DUT_MSG_ERROR,
5948 "wifitool senddelba failed");
5949 }
5950
5951 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
5952 if (system(buf) != 0) {
5953 sigma_dut_print(dut, DUT_MSG_ERROR,
5954 "wifitool sendaddba failed");
5955 }
5956
5957 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
5958
5959 return 1;
5960}
5961
5962
Lior David9981b512017-01-20 13:16:40 +02005963#ifdef __linux__
5964
5965static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
5966 int agg_size)
5967{
5968 char dir[128], buf[128];
5969 FILE *f;
5970 regex_t re;
5971 regmatch_t m[2];
5972 int rc, ret = -1, vring_id, found;
5973
5974 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
5975 sigma_dut_print(dut, DUT_MSG_ERROR,
5976 "failed to get wil6210 debugfs dir");
5977 return -1;
5978 }
5979
5980 snprintf(buf, sizeof(buf), "%s/vrings", dir);
5981 f = fopen(buf, "r");
5982 if (!f) {
5983 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
5984 return -1;
5985 }
5986
5987 if (regcomp(&re, "VRING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
5988 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
5989 goto out;
5990 }
5991
5992 /* find TX VRING for the mac address */
5993 found = 0;
5994 while (fgets(buf, sizeof(buf), f)) {
5995 if (strcasestr(buf, dest_mac)) {
5996 found = 1;
5997 break;
5998 }
5999 }
6000
6001 if (!found) {
6002 sigma_dut_print(dut, DUT_MSG_ERROR,
6003 "no TX VRING for %s", dest_mac);
6004 goto out;
6005 }
6006
6007 /* extract VRING ID, "VRING tx_<id> = {" */
6008 if (!fgets(buf, sizeof(buf), f)) {
6009 sigma_dut_print(dut, DUT_MSG_ERROR,
6010 "no VRING start line for %s", dest_mac);
6011 goto out;
6012 }
6013
6014 rc = regexec(&re, buf, 2, m, 0);
6015 regfree(&re);
6016 if (rc || m[1].rm_so < 0) {
6017 sigma_dut_print(dut, DUT_MSG_ERROR,
6018 "no VRING TX ID for %s", dest_mac);
6019 goto out;
6020 }
6021 buf[m[1].rm_eo] = 0;
6022 vring_id = atoi(&buf[m[1].rm_so]);
6023
6024 /* send the addba command */
6025 fclose(f);
6026 snprintf(buf, sizeof(buf), "%s/back", dir);
6027 f = fopen(buf, "w");
6028 if (!f) {
6029 sigma_dut_print(dut, DUT_MSG_ERROR,
6030 "failed to open: %s", buf);
6031 return -1;
6032 }
6033
6034 fprintf(f, "add %d %d\n", vring_id, agg_size);
6035
6036 ret = 0;
6037
6038out:
6039 fclose(f);
6040
6041 return ret;
6042}
6043
6044
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006045static int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6046 struct sigma_cmd *cmd)
6047{
6048 const char *val;
6049 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006050
6051 val = get_param(cmd, "TID");
6052 if (val) {
6053 tid = atoi(val);
6054 if (tid != 0) {
6055 sigma_dut_print(dut, DUT_MSG_ERROR,
6056 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
6057 tid);
6058 }
6059 }
6060
6061 val = get_param(cmd, "Dest_mac");
6062 if (!val) {
6063 sigma_dut_print(dut, DUT_MSG_ERROR,
6064 "Currently not supporting addba for 60G without Dest_mac");
6065 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
6066 }
6067
Lior David9981b512017-01-20 13:16:40 +02006068 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006069 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006070
6071 return 1;
6072}
6073
Lior David9981b512017-01-20 13:16:40 +02006074#endif /* __linux__ */
6075
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006076
6077static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
6078 struct sigma_cmd *cmd)
6079{
6080 switch (get_driver_type()) {
6081 case DRIVER_ATHEROS:
6082 return ath_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02006083#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006084 case DRIVER_WIL6210:
6085 return send_addba_60g(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02006086#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006087 default:
6088 /*
6089 * There is no driver specific implementation for other drivers.
6090 * Ignore the command and report COMPLETE since the following
6091 * throughput test operation will end up sending ADDBA anyway.
6092 */
6093 return 1;
6094 }
6095}
6096
6097
6098int inject_eth_frame(int s, const void *data, size_t len,
6099 unsigned short ethtype, char *dst, char *src)
6100{
6101 struct iovec iov[4] = {
6102 {
6103 .iov_base = dst,
6104 .iov_len = ETH_ALEN,
6105 },
6106 {
6107 .iov_base = src,
6108 .iov_len = ETH_ALEN,
6109 },
6110 {
6111 .iov_base = &ethtype,
6112 .iov_len = sizeof(unsigned short),
6113 },
6114 {
6115 .iov_base = (void *) data,
6116 .iov_len = len,
6117 }
6118 };
6119 struct msghdr msg = {
6120 .msg_name = NULL,
6121 .msg_namelen = 0,
6122 .msg_iov = iov,
6123 .msg_iovlen = 4,
6124 .msg_control = NULL,
6125 .msg_controllen = 0,
6126 .msg_flags = 0,
6127 };
6128
6129 return sendmsg(s, &msg, 0);
6130}
6131
6132#if defined(__linux__) || defined(__QNXNTO__)
6133
6134int inject_frame(int s, const void *data, size_t len, int encrypt)
6135{
6136#define IEEE80211_RADIOTAP_F_WEP 0x04
6137#define IEEE80211_RADIOTAP_F_FRAG 0x08
6138 unsigned char rtap_hdr[] = {
6139 0x00, 0x00, /* radiotap version */
6140 0x0e, 0x00, /* radiotap length */
6141 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
6142 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
6143 0x00, /* padding */
6144 0x00, 0x00, /* RX and TX flags to indicate that */
6145 0x00, 0x00, /* this is the injected frame directly */
6146 };
6147 struct iovec iov[2] = {
6148 {
6149 .iov_base = &rtap_hdr,
6150 .iov_len = sizeof(rtap_hdr),
6151 },
6152 {
6153 .iov_base = (void *) data,
6154 .iov_len = len,
6155 }
6156 };
6157 struct msghdr msg = {
6158 .msg_name = NULL,
6159 .msg_namelen = 0,
6160 .msg_iov = iov,
6161 .msg_iovlen = 2,
6162 .msg_control = NULL,
6163 .msg_controllen = 0,
6164 .msg_flags = 0,
6165 };
6166
6167 if (encrypt)
6168 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
6169
6170 return sendmsg(s, &msg, 0);
6171}
6172
6173
6174int open_monitor(const char *ifname)
6175{
6176#ifdef __QNXNTO__
6177 struct sockaddr_dl ll;
6178 int s;
6179
6180 memset(&ll, 0, sizeof(ll));
6181 ll.sdl_family = AF_LINK;
6182 ll.sdl_index = if_nametoindex(ifname);
6183 if (ll.sdl_index == 0) {
6184 perror("if_nametoindex");
6185 return -1;
6186 }
6187 s = socket(PF_INET, SOCK_RAW, 0);
6188#else /* __QNXNTO__ */
6189 struct sockaddr_ll ll;
6190 int s;
6191
6192 memset(&ll, 0, sizeof(ll));
6193 ll.sll_family = AF_PACKET;
6194 ll.sll_ifindex = if_nametoindex(ifname);
6195 if (ll.sll_ifindex == 0) {
6196 perror("if_nametoindex");
6197 return -1;
6198 }
6199 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
6200#endif /* __QNXNTO__ */
6201 if (s < 0) {
6202 perror("socket[PF_PACKET,SOCK_RAW]");
6203 return -1;
6204 }
6205
6206 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
6207 perror("monitor socket bind");
6208 close(s);
6209 return -1;
6210 }
6211
6212 return s;
6213}
6214
6215
6216static int hex2num(char c)
6217{
6218 if (c >= '0' && c <= '9')
6219 return c - '0';
6220 if (c >= 'a' && c <= 'f')
6221 return c - 'a' + 10;
6222 if (c >= 'A' && c <= 'F')
6223 return c - 'A' + 10;
6224 return -1;
6225}
6226
6227
6228int hwaddr_aton(const char *txt, unsigned char *addr)
6229{
6230 int i;
6231
6232 for (i = 0; i < 6; i++) {
6233 int a, b;
6234
6235 a = hex2num(*txt++);
6236 if (a < 0)
6237 return -1;
6238 b = hex2num(*txt++);
6239 if (b < 0)
6240 return -1;
6241 *addr++ = (a << 4) | b;
6242 if (i < 5 && *txt++ != ':')
6243 return -1;
6244 }
6245
6246 return 0;
6247}
6248
6249#endif /* defined(__linux__) || defined(__QNXNTO__) */
6250
6251enum send_frame_type {
6252 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
6253};
6254enum send_frame_protection {
6255 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
6256};
6257
6258
6259static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
6260 enum send_frame_type frame,
6261 enum send_frame_protection protected,
6262 const char *dest)
6263{
6264#ifdef __linux__
6265 unsigned char buf[1000], *pos;
6266 int s, res;
6267 char bssid[20], addr[20];
6268 char result[32], ssid[100];
6269 size_t ssid_len;
6270
6271 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
6272 sizeof(result)) < 0 ||
6273 strncmp(result, "COMPLETED", 9) != 0) {
6274 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
6275 return 0;
6276 }
6277
6278 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
6279 < 0) {
6280 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
6281 "current BSSID");
6282 return 0;
6283 }
6284
6285 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
6286 < 0) {
6287 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
6288 "own MAC address");
6289 return 0;
6290 }
6291
6292 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
6293 < 0) {
6294 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
6295 "current SSID");
6296 return 0;
6297 }
6298 ssid_len = strlen(ssid);
6299
6300 pos = buf;
6301
6302 /* Frame Control */
6303 switch (frame) {
6304 case DISASSOC:
6305 *pos++ = 0xa0;
6306 break;
6307 case DEAUTH:
6308 *pos++ = 0xc0;
6309 break;
6310 case SAQUERY:
6311 *pos++ = 0xd0;
6312 break;
6313 case AUTH:
6314 *pos++ = 0xb0;
6315 break;
6316 case ASSOCREQ:
6317 *pos++ = 0x00;
6318 break;
6319 case REASSOCREQ:
6320 *pos++ = 0x20;
6321 break;
6322 case DLS_REQ:
6323 *pos++ = 0xd0;
6324 break;
6325 }
6326
6327 if (protected == INCORRECT_KEY)
6328 *pos++ = 0x40; /* Set Protected field to 1 */
6329 else
6330 *pos++ = 0x00;
6331
6332 /* Duration */
6333 *pos++ = 0x00;
6334 *pos++ = 0x00;
6335
6336 /* addr1 = DA (current AP) */
6337 hwaddr_aton(bssid, pos);
6338 pos += 6;
6339 /* addr2 = SA (own address) */
6340 hwaddr_aton(addr, pos);
6341 pos += 6;
6342 /* addr3 = BSSID (current AP) */
6343 hwaddr_aton(bssid, pos);
6344 pos += 6;
6345
6346 /* Seq# (to be filled by driver/mac80211) */
6347 *pos++ = 0x00;
6348 *pos++ = 0x00;
6349
6350 if (protected == INCORRECT_KEY) {
6351 /* CCMP parameters */
6352 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
6353 pos += 8;
6354 }
6355
6356 if (protected == INCORRECT_KEY) {
6357 switch (frame) {
6358 case DEAUTH:
6359 /* Reason code (encrypted) */
6360 memcpy(pos, "\xa7\x39", 2);
6361 pos += 2;
6362 break;
6363 case DISASSOC:
6364 /* Reason code (encrypted) */
6365 memcpy(pos, "\xa7\x39", 2);
6366 pos += 2;
6367 break;
6368 case SAQUERY:
6369 /* Category|Action|TransID (encrypted) */
6370 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
6371 pos += 4;
6372 break;
6373 default:
6374 return -1;
6375 }
6376
6377 /* CCMP MIC */
6378 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
6379 pos += 8;
6380 } else {
6381 switch (frame) {
6382 case DEAUTH:
6383 /* reason code = 8 */
6384 *pos++ = 0x08;
6385 *pos++ = 0x00;
6386 break;
6387 case DISASSOC:
6388 /* reason code = 8 */
6389 *pos++ = 0x08;
6390 *pos++ = 0x00;
6391 break;
6392 case SAQUERY:
6393 /* Category - SA Query */
6394 *pos++ = 0x08;
6395 /* SA query Action - Request */
6396 *pos++ = 0x00;
6397 /* Transaction ID */
6398 *pos++ = 0x12;
6399 *pos++ = 0x34;
6400 break;
6401 case AUTH:
6402 /* Auth Alg (Open) */
6403 *pos++ = 0x00;
6404 *pos++ = 0x00;
6405 /* Seq# */
6406 *pos++ = 0x01;
6407 *pos++ = 0x00;
6408 /* Status code */
6409 *pos++ = 0x00;
6410 *pos++ = 0x00;
6411 break;
6412 case ASSOCREQ:
6413 /* Capability Information */
6414 *pos++ = 0x31;
6415 *pos++ = 0x04;
6416 /* Listen Interval */
6417 *pos++ = 0x0a;
6418 *pos++ = 0x00;
6419 /* SSID */
6420 *pos++ = 0x00;
6421 *pos++ = ssid_len;
6422 memcpy(pos, ssid, ssid_len);
6423 pos += ssid_len;
6424 /* Supported Rates */
6425 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
6426 10);
6427 pos += 10;
6428 /* Extended Supported Rates */
6429 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
6430 pos += 6;
6431 /* RSN */
6432 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
6433 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
6434 "\x00\x00\x00\x00\x0f\xac\x06", 28);
6435 pos += 28;
6436 break;
6437 case REASSOCREQ:
6438 /* Capability Information */
6439 *pos++ = 0x31;
6440 *pos++ = 0x04;
6441 /* Listen Interval */
6442 *pos++ = 0x0a;
6443 *pos++ = 0x00;
6444 /* Current AP */
6445 hwaddr_aton(bssid, pos);
6446 pos += 6;
6447 /* SSID */
6448 *pos++ = 0x00;
6449 *pos++ = ssid_len;
6450 memcpy(pos, ssid, ssid_len);
6451 pos += ssid_len;
6452 /* Supported Rates */
6453 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
6454 10);
6455 pos += 10;
6456 /* Extended Supported Rates */
6457 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
6458 pos += 6;
6459 /* RSN */
6460 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
6461 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
6462 "\x00\x00\x00\x00\x0f\xac\x06", 28);
6463 pos += 28;
6464 break;
6465 case DLS_REQ:
6466 /* Category - DLS */
6467 *pos++ = 0x02;
6468 /* DLS Action - Request */
6469 *pos++ = 0x00;
6470 /* Destination MACAddress */
6471 if (dest)
6472 hwaddr_aton(dest, pos);
6473 else
6474 memset(pos, 0, 6);
6475 pos += 6;
6476 /* Source MACAddress */
6477 hwaddr_aton(addr, pos);
6478 pos += 6;
6479 /* Capability Information */
6480 *pos++ = 0x10; /* Privacy */
6481 *pos++ = 0x06; /* QoS */
6482 /* DLS Timeout Value */
6483 *pos++ = 0x00;
6484 *pos++ = 0x01;
6485 /* Supported rates */
6486 *pos++ = 0x01;
6487 *pos++ = 0x08;
6488 *pos++ = 0x0c; /* 6 Mbps */
6489 *pos++ = 0x12; /* 9 Mbps */
6490 *pos++ = 0x18; /* 12 Mbps */
6491 *pos++ = 0x24; /* 18 Mbps */
6492 *pos++ = 0x30; /* 24 Mbps */
6493 *pos++ = 0x48; /* 36 Mbps */
6494 *pos++ = 0x60; /* 48 Mbps */
6495 *pos++ = 0x6c; /* 54 Mbps */
6496 /* TODO: Extended Supported Rates */
6497 /* TODO: HT Capabilities */
6498 break;
6499 }
6500 }
6501
6502 s = open_monitor("sigmadut");
6503 if (s < 0) {
6504 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
6505 "monitor socket");
6506 return 0;
6507 }
6508
6509 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
6510 if (res < 0) {
6511 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6512 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05306513 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006514 return 0;
6515 }
6516 if (res < pos - buf) {
6517 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
6518 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05306519 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006520 return 0;
6521 }
6522
6523 close(s);
6524
6525 return 1;
6526#else /* __linux__ */
6527 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
6528 "yet supported");
6529 return 0;
6530#endif /* __linux__ */
6531}
6532
6533
6534static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
6535 struct sigma_conn *conn,
6536 struct sigma_cmd *cmd)
6537{
6538 const char *intf = get_param(cmd, "Interface");
6539 const char *sta, *val;
6540 unsigned char addr[ETH_ALEN];
6541 char buf[100];
6542
6543 sta = get_param(cmd, "peer");
6544 if (sta == NULL)
6545 sta = get_param(cmd, "station");
6546 if (sta == NULL) {
6547 send_resp(dut, conn, SIGMA_ERROR,
6548 "ErrorCode,Missing peer address");
6549 return 0;
6550 }
6551 if (hwaddr_aton(sta, addr) < 0) {
6552 send_resp(dut, conn, SIGMA_ERROR,
6553 "ErrorCode,Invalid peer address");
6554 return 0;
6555 }
6556
6557 val = get_param(cmd, "type");
6558 if (val == NULL)
6559 return -1;
6560
6561 if (strcasecmp(val, "DISCOVERY") == 0) {
6562 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
6563 if (wpa_command(intf, buf) < 0) {
6564 send_resp(dut, conn, SIGMA_ERROR,
6565 "ErrorCode,Failed to send TDLS discovery");
6566 return 0;
6567 }
6568 return 1;
6569 }
6570
6571 if (strcasecmp(val, "SETUP") == 0) {
6572 int status = 0, timeout = 0;
6573
6574 val = get_param(cmd, "Status");
6575 if (val)
6576 status = atoi(val);
6577
6578 val = get_param(cmd, "Timeout");
6579 if (val)
6580 timeout = atoi(val);
6581
6582 if (status != 0 && status != 37) {
6583 send_resp(dut, conn, SIGMA_ERROR,
6584 "ErrorCode,Unsupported status value");
6585 return 0;
6586 }
6587
6588 if (timeout != 0 && timeout != 301) {
6589 send_resp(dut, conn, SIGMA_ERROR,
6590 "ErrorCode,Unsupported timeout value");
6591 return 0;
6592 }
6593
6594 if (status && timeout) {
6595 send_resp(dut, conn, SIGMA_ERROR,
6596 "ErrorCode,Unsupported timeout+status "
6597 "combination");
6598 return 0;
6599 }
6600
6601 if (status == 37 &&
6602 wpa_command(intf, "SET tdls_testing 0x200")) {
6603 send_resp(dut, conn, SIGMA_ERROR,
6604 "ErrorCode,Failed to enable "
6605 "decline setup response test mode");
6606 return 0;
6607 }
6608
6609 if (timeout == 301) {
6610 int res;
6611 if (dut->no_tpk_expiration)
6612 res = wpa_command(intf,
6613 "SET tdls_testing 0x108");
6614 else
6615 res = wpa_command(intf,
6616 "SET tdls_testing 0x8");
6617 if (res) {
6618 send_resp(dut, conn, SIGMA_ERROR,
6619 "ErrorCode,Failed to set short TPK "
6620 "lifetime");
6621 return 0;
6622 }
6623 }
6624
6625 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
6626 if (wpa_command(intf, buf) < 0) {
6627 send_resp(dut, conn, SIGMA_ERROR,
6628 "ErrorCode,Failed to send TDLS setup");
6629 return 0;
6630 }
6631 return 1;
6632 }
6633
6634 if (strcasecmp(val, "TEARDOWN") == 0) {
6635 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
6636 if (wpa_command(intf, buf) < 0) {
6637 send_resp(dut, conn, SIGMA_ERROR,
6638 "ErrorCode,Failed to send TDLS teardown");
6639 return 0;
6640 }
6641 return 1;
6642 }
6643
6644 send_resp(dut, conn, SIGMA_ERROR,
6645 "ErrorCode,Unsupported TDLS frame");
6646 return 0;
6647}
6648
6649
6650static int sta_ap_known(const char *ifname, const char *bssid)
6651{
6652 char buf[4096];
6653
6654 snprintf(buf, sizeof(buf), "BSS %s", bssid);
6655 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
6656 return 0;
6657 if (strncmp(buf, "id=", 3) != 0)
6658 return 0;
6659 return 1;
6660}
6661
6662
6663static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
6664 const char *bssid)
6665{
6666 int res;
6667 struct wpa_ctrl *ctrl;
6668 char buf[256];
6669
6670 if (sta_ap_known(ifname, bssid))
6671 return 0;
6672 sigma_dut_print(dut, DUT_MSG_DEBUG,
6673 "AP not in BSS table - start scan");
6674
6675 ctrl = open_wpa_mon(ifname);
6676 if (ctrl == NULL) {
6677 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6678 "wpa_supplicant monitor connection");
6679 return -1;
6680 }
6681
6682 if (wpa_command(ifname, "SCAN") < 0) {
6683 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
6684 wpa_ctrl_detach(ctrl);
6685 wpa_ctrl_close(ctrl);
6686 return -1;
6687 }
6688
6689 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6690 buf, sizeof(buf));
6691
6692 wpa_ctrl_detach(ctrl);
6693 wpa_ctrl_close(ctrl);
6694
6695 if (res < 0) {
6696 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
6697 return -1;
6698 }
6699
6700 if (sta_ap_known(ifname, bssid))
6701 return 0;
6702 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
6703 return -1;
6704}
6705
6706
6707static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
6708 struct sigma_conn *conn,
6709 struct sigma_cmd *cmd,
6710 const char *intf)
6711{
6712 char buf[200];
6713
6714 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
6715 if (system(buf) != 0) {
6716 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
6717 "ndsend");
6718 return 0;
6719 }
6720
6721 return 1;
6722}
6723
6724
6725static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
6726 struct sigma_conn *conn,
6727 struct sigma_cmd *cmd,
6728 const char *intf)
6729{
6730 char buf[200];
6731 const char *ip = get_param(cmd, "SenderIP");
6732
Peng Xu26b356d2017-10-04 17:58:16 -07006733 if (!ip)
6734 return 0;
6735
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006736 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
6737 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6738 if (system(buf) == 0) {
6739 sigma_dut_print(dut, DUT_MSG_INFO,
6740 "Neighbor Solicitation got a response "
6741 "for %s@%s", ip, intf);
6742 }
6743
6744 return 1;
6745}
6746
6747
6748static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
6749 struct sigma_conn *conn,
6750 struct sigma_cmd *cmd,
6751 const char *ifname)
6752{
6753 char buf[200];
6754 const char *ip = get_param(cmd, "SenderIP");
6755
6756 if (ip == NULL) {
6757 send_resp(dut, conn, SIGMA_ERROR,
6758 "ErrorCode,Missing SenderIP parameter");
6759 return 0;
6760 }
6761 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
6762 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6763 if (system(buf) != 0) {
6764 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
6765 "for %s@%s", ip, ifname);
6766 }
6767
6768 return 1;
6769}
6770
6771
6772static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
6773 struct sigma_conn *conn,
6774 struct sigma_cmd *cmd,
6775 const char *ifname)
6776{
6777 char buf[200];
6778 char ip[16];
6779 int s;
Peng Xub3756882017-10-04 14:39:09 -07006780 struct ifreq ifr;
6781 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006782
6783 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07006784 if (s < 0) {
6785 perror("socket");
6786 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006787 }
6788
Peng Xub3756882017-10-04 14:39:09 -07006789 memset(&ifr, 0, sizeof(ifr));
6790 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
6791 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
6792 sigma_dut_print(dut, DUT_MSG_INFO,
6793 "Failed to get %s IP address: %s",
6794 ifname, strerror(errno));
6795 close(s);
6796 return -1;
6797 }
6798 close(s);
6799
6800 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
6801 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
6802
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006803 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
6804 ip);
6805 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
6806 if (system(buf) != 0) {
6807 }
6808
6809 return 1;
6810}
6811
6812
6813static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
6814 struct sigma_conn *conn,
6815 struct sigma_cmd *cmd,
6816 const char *ifname)
6817{
6818 char buf[200], addr[20];
6819 char dst[ETH_ALEN], src[ETH_ALEN];
6820 short ethtype = htons(ETH_P_ARP);
6821 char *pos;
6822 int s, res;
6823 const char *val;
6824 struct sockaddr_in taddr;
6825
6826 val = get_param(cmd, "dest");
6827 if (val)
6828 hwaddr_aton(val, (unsigned char *) dst);
6829
6830 val = get_param(cmd, "DestIP");
6831 if (val)
6832 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07006833 else
6834 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006835
6836 if (get_wpa_status(get_station_ifname(), "address", addr,
6837 sizeof(addr)) < 0)
6838 return -2;
6839 hwaddr_aton(addr, (unsigned char *) src);
6840
6841 pos = buf;
6842 *pos++ = 0x00;
6843 *pos++ = 0x01;
6844 *pos++ = 0x08;
6845 *pos++ = 0x00;
6846 *pos++ = 0x06;
6847 *pos++ = 0x04;
6848 *pos++ = 0x00;
6849 *pos++ = 0x02;
6850 memcpy(pos, src, ETH_ALEN);
6851 pos += ETH_ALEN;
6852 memcpy(pos, &taddr.sin_addr, 4);
6853 pos += 4;
6854 memcpy(pos, dst, ETH_ALEN);
6855 pos += ETH_ALEN;
6856 memcpy(pos, &taddr.sin_addr, 4);
6857 pos += 4;
6858
6859 s = open_monitor(get_station_ifname());
6860 if (s < 0) {
6861 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
6862 "monitor socket");
6863 return 0;
6864 }
6865
6866 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
6867 if (res < 0) {
6868 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6869 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05306870 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006871 return 0;
6872 }
6873
6874 close(s);
6875
6876 return 1;
6877}
6878
6879
6880static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
6881 struct sigma_conn *conn,
6882 struct sigma_cmd *cmd,
6883 const char *intf, const char *dest)
6884{
6885 char buf[100];
6886
6887 if (if_nametoindex("sigmadut") == 0) {
6888 snprintf(buf, sizeof(buf),
6889 "iw dev %s interface add sigmadut type monitor",
6890 get_station_ifname());
6891 if (system(buf) != 0 ||
6892 if_nametoindex("sigmadut") == 0) {
6893 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
6894 "monitor interface with '%s'", buf);
6895 return -2;
6896 }
6897 }
6898
6899 if (system("ifconfig sigmadut up") != 0) {
6900 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6901 "monitor interface up");
6902 return -2;
6903 }
6904
6905 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
6906}
6907
6908
6909static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
6910 struct sigma_conn *conn,
6911 struct sigma_cmd *cmd)
6912{
6913 const char *intf = get_param(cmd, "Interface");
6914 const char *dest = get_param(cmd, "Dest");
6915 const char *type = get_param(cmd, "FrameName");
6916 const char *val;
6917 char buf[200], *pos, *end;
6918 int count, count2;
6919
6920 if (type == NULL)
6921 type = get_param(cmd, "Type");
6922
6923 if (intf == NULL || dest == NULL || type == NULL)
6924 return -1;
6925
6926 if (strcasecmp(type, "NeighAdv") == 0)
6927 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
6928
6929 if (strcasecmp(type, "NeighSolicitReq") == 0)
6930 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
6931
6932 if (strcasecmp(type, "ARPProbe") == 0)
6933 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
6934
6935 if (strcasecmp(type, "ARPAnnounce") == 0)
6936 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
6937
6938 if (strcasecmp(type, "ARPReply") == 0)
6939 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
6940
6941 if (strcasecmp(type, "DLS-request") == 0 ||
6942 strcasecmp(type, "DLSrequest") == 0)
6943 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
6944 dest);
6945
6946 if (strcasecmp(type, "ANQPQuery") != 0 &&
6947 strcasecmp(type, "Query") != 0) {
6948 send_resp(dut, conn, SIGMA_ERROR,
6949 "ErrorCode,Unsupported HS 2.0 send frame type");
6950 return 0;
6951 }
6952
6953 if (sta_scan_ap(dut, intf, dest) < 0) {
6954 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
6955 "the requested AP");
6956 return 0;
6957 }
6958
6959 pos = buf;
6960 end = buf + sizeof(buf);
6961 count = 0;
6962 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
6963
6964 val = get_param(cmd, "ANQP_CAP_LIST");
6965 if (val && atoi(val)) {
6966 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
6967 count++;
6968 }
6969
6970 val = get_param(cmd, "VENUE_NAME");
6971 if (val && atoi(val)) {
6972 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
6973 count++;
6974 }
6975
6976 val = get_param(cmd, "NETWORK_AUTH_TYPE");
6977 if (val && atoi(val)) {
6978 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
6979 count++;
6980 }
6981
6982 val = get_param(cmd, "ROAMING_CONS");
6983 if (val && atoi(val)) {
6984 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
6985 count++;
6986 }
6987
6988 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
6989 if (val && atoi(val)) {
6990 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
6991 count++;
6992 }
6993
6994 val = get_param(cmd, "NAI_REALM_LIST");
6995 if (val && atoi(val)) {
6996 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
6997 count++;
6998 }
6999
7000 val = get_param(cmd, "3GPP_INFO");
7001 if (val && atoi(val)) {
7002 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
7003 count++;
7004 }
7005
7006 val = get_param(cmd, "DOMAIN_LIST");
7007 if (val && atoi(val)) {
7008 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
7009 count++;
7010 }
7011
7012 if (count && wpa_command(intf, buf)) {
7013 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
7014 return 0;
7015 }
7016
7017 pos = buf;
7018 end = buf + sizeof(buf);
7019 count2 = 0;
7020 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
7021
7022 val = get_param(cmd, "HS_CAP_LIST");
7023 if (val && atoi(val)) {
7024 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
7025 count2++;
7026 }
7027
7028 val = get_param(cmd, "OPER_NAME");
7029 if (val && atoi(val)) {
7030 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
7031 count2++;
7032 }
7033
7034 val = get_param(cmd, "WAN_METRICS");
7035 if (!val)
7036 val = get_param(cmd, "WAN_MAT");
7037 if (!val)
7038 val = get_param(cmd, "WAN_MET");
7039 if (val && atoi(val)) {
7040 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
7041 count2++;
7042 }
7043
7044 val = get_param(cmd, "CONNECTION_CAPABILITY");
7045 if (val && atoi(val)) {
7046 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
7047 count2++;
7048 }
7049
7050 val = get_param(cmd, "OP_CLASS");
7051 if (val && atoi(val)) {
7052 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
7053 count2++;
7054 }
7055
7056 val = get_param(cmd, "OSU_PROVIDER_LIST");
7057 if (val && atoi(val)) {
7058 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
7059 count2++;
7060 }
7061
7062 if (count && count2) {
7063 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
7064 "second query");
7065 sleep(1);
7066 }
7067
7068 if (count2 && wpa_command(intf, buf)) {
7069 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
7070 "failed");
7071 return 0;
7072 }
7073
7074 val = get_param(cmd, "NAI_HOME_REALM_LIST");
7075 if (val) {
7076 if (count || count2) {
7077 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
7078 "sending out second query");
7079 sleep(1);
7080 }
7081
7082 if (strcmp(val, "1") == 0)
7083 val = "mail.example.com";
7084 snprintf(buf, end - pos,
7085 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
7086 dest, val);
7087 if (wpa_command(intf, buf)) {
7088 send_resp(dut, conn, SIGMA_ERROR,
7089 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
7090 "failed");
7091 return 0;
7092 }
7093 }
7094
7095 val = get_param(cmd, "ICON_REQUEST");
7096 if (val) {
7097 if (count || count2) {
7098 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
7099 "sending out second query");
7100 sleep(1);
7101 }
7102
7103 snprintf(buf, end - pos,
7104 "HS20_ICON_REQUEST %s %s", dest, val);
7105 if (wpa_command(intf, buf)) {
7106 send_resp(dut, conn, SIGMA_ERROR,
7107 "ErrorCode,HS20_ICON_REQUEST failed");
7108 return 0;
7109 }
7110 }
7111
7112 return 1;
7113}
7114
7115
7116static int ath_sta_send_frame_vht(struct sigma_dut *dut,
7117 struct sigma_conn *conn,
7118 struct sigma_cmd *cmd)
7119{
7120 const char *val;
7121 char *ifname;
7122 char buf[100];
7123 int chwidth, nss;
7124
7125 val = get_param(cmd, "framename");
7126 if (!val)
7127 return -1;
7128 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
7129
7130 /* Command sequence to generate Op mode notification */
7131 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
7132 ifname = get_station_ifname();
7133
7134 /* Disable STBC */
7135 snprintf(buf, sizeof(buf),
7136 "iwpriv %s tx_stbc 0", ifname);
7137 if (system(buf) != 0) {
7138 sigma_dut_print(dut, DUT_MSG_ERROR,
7139 "iwpriv tx_stbc 0 failed!");
7140 }
7141
7142 /* Extract Channel width */
7143 val = get_param(cmd, "Channel_width");
7144 if (val) {
7145 switch (atoi(val)) {
7146 case 20:
7147 chwidth = 0;
7148 break;
7149 case 40:
7150 chwidth = 1;
7151 break;
7152 case 80:
7153 chwidth = 2;
7154 break;
7155 case 160:
7156 chwidth = 3;
7157 break;
7158 default:
7159 chwidth = 2;
7160 break;
7161 }
7162
7163 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
7164 ifname, chwidth);
7165 if (system(buf) != 0) {
7166 sigma_dut_print(dut, DUT_MSG_ERROR,
7167 "iwpriv chwidth failed!");
7168 }
7169 }
7170
7171 /* Extract NSS */
7172 val = get_param(cmd, "NSS");
7173 if (val) {
7174 switch (atoi(val)) {
7175 case 1:
7176 nss = 1;
7177 break;
7178 case 2:
7179 nss = 3;
7180 break;
7181 case 3:
7182 nss = 7;
7183 break;
7184 default:
7185 /* We do not support NSS > 3 */
7186 nss = 3;
7187 break;
7188 }
7189 snprintf(buf, sizeof(buf),
7190 "iwpriv %s rxchainmask %d", ifname, nss);
7191 if (system(buf) != 0) {
7192 sigma_dut_print(dut, DUT_MSG_ERROR,
7193 "iwpriv rxchainmask failed!");
7194 }
7195 }
7196
7197 /* Opmode notify */
7198 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
7199 if (system(buf) != 0) {
7200 sigma_dut_print(dut, DUT_MSG_ERROR,
7201 "iwpriv opmode_notify failed!");
7202 } else {
7203 sigma_dut_print(dut, DUT_MSG_INFO,
7204 "Sent out the notify frame!");
7205 }
7206 }
7207
7208 return 1;
7209}
7210
7211
7212static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
7213 struct sigma_conn *conn,
7214 struct sigma_cmd *cmd)
7215{
7216 switch (get_driver_type()) {
7217 case DRIVER_ATHEROS:
7218 return ath_sta_send_frame_vht(dut, conn, cmd);
7219 default:
7220 send_resp(dut, conn, SIGMA_ERROR,
7221 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
7222 return 0;
7223 }
7224}
7225
7226
Lior David0fe101e2017-03-09 16:09:50 +02007227#ifdef __linux__
7228int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7229 struct sigma_cmd *cmd)
7230{
7231 const char *frame_name = get_param(cmd, "framename");
7232 const char *mac = get_param(cmd, "dest_mac");
7233
7234 if (!frame_name || !mac) {
7235 sigma_dut_print(dut, DUT_MSG_ERROR,
7236 "framename and dest_mac must be provided");
7237 return -1;
7238 }
7239
7240 if (strcasecmp(frame_name, "brp") == 0) {
7241 const char *l_rx = get_param(cmd, "L-RX");
7242 int l_rx_i;
7243
7244 if (!l_rx) {
7245 sigma_dut_print(dut, DUT_MSG_ERROR,
7246 "L-RX must be provided");
7247 return -1;
7248 }
7249 l_rx_i = atoi(l_rx);
7250
7251 sigma_dut_print(dut, DUT_MSG_INFO,
7252 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
7253 mac, l_rx);
7254 if (l_rx_i != 16) {
7255 sigma_dut_print(dut, DUT_MSG_ERROR,
7256 "unsupported L-RX: %s", l_rx);
7257 return -1;
7258 }
7259
7260 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
7261 return -1;
7262 } else if (strcasecmp(frame_name, "ssw") == 0) {
7263 sigma_dut_print(dut, DUT_MSG_INFO,
7264 "dev_send_frame: SLS, dest_mac %s", mac);
7265 if (wil6210_send_sls(dut, mac))
7266 return -1;
7267 } else {
7268 sigma_dut_print(dut, DUT_MSG_ERROR,
7269 "unsupported frame type: %s", frame_name);
7270 return -1;
7271 }
7272
7273 return 1;
7274}
7275#endif /* __linux__ */
7276
7277
7278static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
7279 struct sigma_conn *conn,
7280 struct sigma_cmd *cmd)
7281{
7282 switch (get_driver_type()) {
7283#ifdef __linux__
7284 case DRIVER_WIL6210:
7285 return wil6210_send_frame_60g(dut, conn, cmd);
7286#endif /* __linux__ */
7287 default:
7288 send_resp(dut, conn, SIGMA_ERROR,
7289 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
7290 return 0;
7291 }
7292}
7293
7294
Ashwini Patildb59b3c2017-04-13 15:19:23 +05307295static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
7296 const char *intf, struct sigma_cmd *cmd)
7297{
7298 const char *val, *addr;
7299 char buf[100];
7300
7301 addr = get_param(cmd, "DestMac");
7302 if (!addr) {
7303 send_resp(dut, conn, SIGMA_INVALID,
7304 "ErrorCode,AP MAC address is missing");
7305 return 0;
7306 }
7307
7308 val = get_param(cmd, "ANQPQuery_ID");
7309 if (!val) {
7310 send_resp(dut, conn, SIGMA_INVALID,
7311 "ErrorCode,Missing ANQPQuery_ID");
7312 return 0;
7313 }
7314
7315 if (strcasecmp(val, "NeighborReportReq") == 0) {
7316 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
7317 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
7318 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
7319 } else {
7320 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
7321 val);
7322 send_resp(dut, conn, SIGMA_INVALID,
7323 "ErrorCode,Invalid ANQPQuery_ID");
7324 return 0;
7325 }
7326
Ashwini Patild174f2c2017-04-13 16:49:46 +05307327 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
7328 * (Address3 = Wildcard BSSID when sent to not-associated AP;
7329 * if associated, AP BSSID).
7330 */
7331 if (wpa_command(intf, "SET gas_address3 1") < 0) {
7332 send_resp(dut, conn, SIGMA_ERROR,
7333 "ErrorCode,Failed to set gas_address3");
7334 return 0;
7335 }
7336
Ashwini Patildb59b3c2017-04-13 15:19:23 +05307337 if (wpa_command(intf, buf) < 0) {
7338 send_resp(dut, conn, SIGMA_ERROR,
7339 "ErrorCode,Failed to send ANQP query");
7340 return 0;
7341 }
7342
7343 return 1;
7344}
7345
7346
7347static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
7348 struct sigma_conn *conn,
7349 const char *intf,
7350 struct sigma_cmd *cmd)
7351{
7352 const char *val = get_param(cmd, "FrameName");
7353
7354 if (val && strcasecmp(val, "ANQPQuery") == 0)
7355 return mbo_send_anqp_query(dut, conn, intf, cmd);
7356
7357 return 2;
7358}
7359
7360
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007361int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
7362 struct sigma_cmd *cmd)
7363{
7364 const char *intf = get_param(cmd, "Interface");
7365 const char *val;
7366 enum send_frame_type frame;
7367 enum send_frame_protection protected;
7368 char buf[100];
7369 unsigned char addr[ETH_ALEN];
7370 int res;
7371
7372 val = get_param(cmd, "program");
7373 if (val == NULL)
7374 val = get_param(cmd, "frame");
7375 if (val && strcasecmp(val, "TDLS") == 0)
7376 return cmd_sta_send_frame_tdls(dut, conn, cmd);
7377 if (val && (strcasecmp(val, "HS2") == 0 ||
7378 strcasecmp(val, "HS2-R2") == 0))
7379 return cmd_sta_send_frame_hs2(dut, conn, cmd);
7380 if (val && strcasecmp(val, "VHT") == 0)
7381 return cmd_sta_send_frame_vht(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007382 if (val && strcasecmp(val, "LOC") == 0)
7383 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +02007384 if (val && strcasecmp(val, "60GHz") == 0)
7385 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +05307386 if (val && strcasecmp(val, "MBO") == 0) {
7387 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
7388 if (res != 2)
7389 return res;
7390 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007391
7392 val = get_param(cmd, "TD_DISC");
7393 if (val) {
7394 if (hwaddr_aton(val, addr) < 0)
7395 return -1;
7396 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
7397 if (wpa_command(intf, buf) < 0) {
7398 send_resp(dut, conn, SIGMA_ERROR,
7399 "ErrorCode,Failed to send TDLS discovery");
7400 return 0;
7401 }
7402 return 1;
7403 }
7404
7405 val = get_param(cmd, "TD_Setup");
7406 if (val) {
7407 if (hwaddr_aton(val, addr) < 0)
7408 return -1;
7409 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
7410 if (wpa_command(intf, buf) < 0) {
7411 send_resp(dut, conn, SIGMA_ERROR,
7412 "ErrorCode,Failed to start TDLS setup");
7413 return 0;
7414 }
7415 return 1;
7416 }
7417
7418 val = get_param(cmd, "TD_TearDown");
7419 if (val) {
7420 if (hwaddr_aton(val, addr) < 0)
7421 return -1;
7422 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
7423 if (wpa_command(intf, buf) < 0) {
7424 send_resp(dut, conn, SIGMA_ERROR,
7425 "ErrorCode,Failed to tear down TDLS link");
7426 return 0;
7427 }
7428 return 1;
7429 }
7430
7431 val = get_param(cmd, "TD_ChannelSwitch");
7432 if (val) {
7433 /* TODO */
7434 send_resp(dut, conn, SIGMA_ERROR,
7435 "ErrorCode,TD_ChannelSwitch not yet supported");
7436 return 0;
7437 }
7438
7439 val = get_param(cmd, "TD_NF");
7440 if (val) {
7441 /* TODO */
7442 send_resp(dut, conn, SIGMA_ERROR,
7443 "ErrorCode,TD_NF not yet supported");
7444 return 0;
7445 }
7446
7447 val = get_param(cmd, "PMFFrameType");
7448 if (val == NULL)
7449 val = get_param(cmd, "FrameName");
7450 if (val == NULL)
7451 val = get_param(cmd, "Type");
7452 if (val == NULL)
7453 return -1;
7454 if (strcasecmp(val, "disassoc") == 0)
7455 frame = DISASSOC;
7456 else if (strcasecmp(val, "deauth") == 0)
7457 frame = DEAUTH;
7458 else if (strcasecmp(val, "saquery") == 0)
7459 frame = SAQUERY;
7460 else if (strcasecmp(val, "auth") == 0)
7461 frame = AUTH;
7462 else if (strcasecmp(val, "assocreq") == 0)
7463 frame = ASSOCREQ;
7464 else if (strcasecmp(val, "reassocreq") == 0)
7465 frame = REASSOCREQ;
7466 else if (strcasecmp(val, "neigreq") == 0) {
7467 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
7468
7469 val = get_param(cmd, "ssid");
7470 if (val == NULL)
7471 return -1;
7472
7473 res = send_neighbor_request(dut, intf, val);
7474 if (res) {
7475 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
7476 "Failed to send neighbor report request");
7477 return 0;
7478 }
7479
7480 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307481 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
7482 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007483 sigma_dut_print(dut, DUT_MSG_DEBUG,
7484 "Got Transition Management Query");
7485
Ashwini Patil5acd7382017-04-13 15:55:04 +05307486 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007487 if (res) {
7488 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
7489 "Failed to send Transition Management Query");
7490 return 0;
7491 }
7492
7493 return 1;
7494 } else {
7495 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
7496 "PMFFrameType");
7497 return 0;
7498 }
7499
7500 val = get_param(cmd, "PMFProtected");
7501 if (val == NULL)
7502 val = get_param(cmd, "Protected");
7503 if (val == NULL)
7504 return -1;
7505 if (strcasecmp(val, "Correct-key") == 0 ||
7506 strcasecmp(val, "CorrectKey") == 0)
7507 protected = CORRECT_KEY;
7508 else if (strcasecmp(val, "IncorrectKey") == 0)
7509 protected = INCORRECT_KEY;
7510 else if (strcasecmp(val, "Unprotected") == 0)
7511 protected = UNPROTECTED;
7512 else {
7513 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
7514 "PMFProtected");
7515 return 0;
7516 }
7517
7518 if (protected != UNPROTECTED &&
7519 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
7520 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
7521 "PMFProtected for auth/assocreq/reassocreq");
7522 return 0;
7523 }
7524
7525 if (if_nametoindex("sigmadut") == 0) {
7526 snprintf(buf, sizeof(buf),
7527 "iw dev %s interface add sigmadut type monitor",
7528 get_station_ifname());
7529 if (system(buf) != 0 ||
7530 if_nametoindex("sigmadut") == 0) {
7531 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
7532 "monitor interface with '%s'", buf);
7533 return -2;
7534 }
7535 }
7536
7537 if (system("ifconfig sigmadut up") != 0) {
7538 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7539 "monitor interface up");
7540 return -2;
7541 }
7542
7543 return sta_inject_frame(dut, conn, frame, protected, NULL);
7544}
7545
7546
7547static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
7548 struct sigma_conn *conn,
7549 struct sigma_cmd *cmd,
7550 const char *ifname)
7551{
7552 char buf[200];
7553 const char *val;
7554
7555 val = get_param(cmd, "ClearARP");
7556 if (val && atoi(val) == 1) {
7557 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
7558 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7559 if (system(buf) != 0) {
7560 send_resp(dut, conn, SIGMA_ERROR,
7561 "errorCode,Failed to clear ARP cache");
7562 return 0;
7563 }
7564 }
7565
7566 return 1;
7567}
7568
7569
7570int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
7571 struct sigma_cmd *cmd)
7572{
7573 const char *intf = get_param(cmd, "Interface");
7574 const char *val;
7575
7576 if (intf == NULL)
7577 return -1;
7578
7579 val = get_param(cmd, "program");
7580 if (val && (strcasecmp(val, "HS2") == 0 ||
7581 strcasecmp(val, "HS2-R2") == 0))
7582 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
7583
7584 return -1;
7585}
7586
7587
7588static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
7589 struct sigma_cmd *cmd)
7590{
7591 const char *intf = get_param(cmd, "Interface");
7592 const char *mac = get_param(cmd, "MAC");
7593
7594 if (intf == NULL || mac == NULL)
7595 return -1;
7596
7597 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
7598 "interface %s to %s", intf, mac);
7599
7600 if (dut->set_macaddr) {
7601 char buf[128];
7602 int res;
7603 if (strcasecmp(mac, "default") == 0) {
7604 res = snprintf(buf, sizeof(buf), "%s",
7605 dut->set_macaddr);
7606 dut->tmp_mac_addr = 0;
7607 } else {
7608 res = snprintf(buf, sizeof(buf), "%s %s",
7609 dut->set_macaddr, mac);
7610 dut->tmp_mac_addr = 1;
7611 }
7612 if (res < 0 || res >= (int) sizeof(buf))
7613 return -1;
7614 if (system(buf) != 0) {
7615 send_resp(dut, conn, SIGMA_ERROR,
7616 "errorCode,Failed to set MAC "
7617 "address");
7618 return 0;
7619 }
7620 return 1;
7621 }
7622
7623 if (strcasecmp(mac, "default") == 0)
7624 return 1;
7625
7626 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
7627 "command");
7628 return 0;
7629}
7630
7631
7632static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
7633 struct sigma_conn *conn, const char *intf,
7634 int val)
7635{
7636 char buf[200];
7637 int res;
7638
7639 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
7640 intf, val);
7641 if (res < 0 || res >= (int) sizeof(buf))
7642 return -1;
7643 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7644 if (system(buf) != 0) {
7645 send_resp(dut, conn, SIGMA_ERROR,
7646 "errorCode,Failed to configure offchannel mode");
7647 return 0;
7648 }
7649
7650 return 1;
7651}
7652
7653
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007654static int off_chan_val(enum sec_ch_offset off)
7655{
7656 switch (off) {
7657 case SEC_CH_NO:
7658 return 0;
7659 case SEC_CH_40ABOVE:
7660 return 40;
7661 case SEC_CH_40BELOW:
7662 return -40;
7663 }
7664
7665 return 0;
7666}
7667
7668
7669static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
7670 const char *intf, int off_ch_num,
7671 enum sec_ch_offset sec)
7672{
7673 char buf[200];
7674 int res;
7675
7676 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
7677 intf, off_ch_num);
7678 if (res < 0 || res >= (int) sizeof(buf))
7679 return -1;
7680 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7681 if (system(buf) != 0) {
7682 send_resp(dut, conn, SIGMA_ERROR,
7683 "errorCode,Failed to set offchan");
7684 return 0;
7685 }
7686
7687 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
7688 intf, off_chan_val(sec));
7689 if (res < 0 || res >= (int) sizeof(buf))
7690 return -1;
7691 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7692 if (system(buf) != 0) {
7693 send_resp(dut, conn, SIGMA_ERROR,
7694 "errorCode,Failed to set sec chan offset");
7695 return 0;
7696 }
7697
7698 return 1;
7699}
7700
7701
7702static int tdls_set_offchannel_offset(struct sigma_dut *dut,
7703 struct sigma_conn *conn,
7704 const char *intf, int off_ch_num,
7705 enum sec_ch_offset sec)
7706{
7707 char buf[200];
7708 int res;
7709
7710 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
7711 off_ch_num);
7712 if (res < 0 || res >= (int) sizeof(buf))
7713 return -1;
7714 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7715
7716 if (wpa_command(intf, buf) < 0) {
7717 send_resp(dut, conn, SIGMA_ERROR,
7718 "ErrorCode,Failed to set offchan");
7719 return 0;
7720 }
7721 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
7722 off_chan_val(sec));
7723 if (res < 0 || res >= (int) sizeof(buf))
7724 return -1;
7725
7726 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7727
7728 if (wpa_command(intf, buf) < 0) {
7729 send_resp(dut, conn, SIGMA_ERROR,
7730 "ErrorCode,Failed to set sec chan offset");
7731 return 0;
7732 }
7733
7734 return 1;
7735}
7736
7737
7738static int tdls_set_offchannel_mode(struct sigma_dut *dut,
7739 struct sigma_conn *conn,
7740 const char *intf, int val)
7741{
7742 char buf[200];
7743 int res;
7744
7745 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
7746 val);
7747 if (res < 0 || res >= (int) sizeof(buf))
7748 return -1;
7749 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
7750
7751 if (wpa_command(intf, buf) < 0) {
7752 send_resp(dut, conn, SIGMA_ERROR,
7753 "ErrorCode,Failed to configure offchannel mode");
7754 return 0;
7755 }
7756
7757 return 1;
7758}
7759
7760
7761static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
7762 struct sigma_conn *conn,
7763 struct sigma_cmd *cmd)
7764{
7765 const char *val;
7766 enum {
7767 CHSM_NOT_SET,
7768 CHSM_ENABLE,
7769 CHSM_DISABLE,
7770 CHSM_REJREQ,
7771 CHSM_UNSOLRESP
7772 } chsm = CHSM_NOT_SET;
7773 int off_ch_num = -1;
7774 enum sec_ch_offset sec_ch = SEC_CH_NO;
7775 int res;
7776
7777 val = get_param(cmd, "Uapsd");
7778 if (val) {
7779 char buf[100];
7780 if (strcasecmp(val, "Enable") == 0)
7781 snprintf(buf, sizeof(buf), "SET ps 99");
7782 else if (strcasecmp(val, "Disable") == 0)
7783 snprintf(buf, sizeof(buf), "SET ps 98");
7784 else {
7785 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
7786 "Unsupported uapsd parameter value");
7787 return 0;
7788 }
7789 if (wpa_command(intf, buf)) {
7790 send_resp(dut, conn, SIGMA_ERROR,
7791 "ErrorCode,Failed to change U-APSD "
7792 "powersave mode");
7793 return 0;
7794 }
7795 }
7796
7797 val = get_param(cmd, "TPKTIMER");
7798 if (val && strcasecmp(val, "DISABLE") == 0) {
7799 if (wpa_command(intf, "SET tdls_testing 0x100")) {
7800 send_resp(dut, conn, SIGMA_ERROR,
7801 "ErrorCode,Failed to enable no TPK "
7802 "expiration test mode");
7803 return 0;
7804 }
7805 dut->no_tpk_expiration = 1;
7806 }
7807
7808 val = get_param(cmd, "ChSwitchMode");
7809 if (val) {
7810 if (strcasecmp(val, "Enable") == 0 ||
7811 strcasecmp(val, "Initiate") == 0)
7812 chsm = CHSM_ENABLE;
7813 else if (strcasecmp(val, "Disable") == 0 ||
7814 strcasecmp(val, "passive") == 0)
7815 chsm = CHSM_DISABLE;
7816 else if (strcasecmp(val, "RejReq") == 0)
7817 chsm = CHSM_REJREQ;
7818 else if (strcasecmp(val, "UnSolResp") == 0)
7819 chsm = CHSM_UNSOLRESP;
7820 else {
7821 send_resp(dut, conn, SIGMA_ERROR,
7822 "ErrorCode,Unknown ChSwitchMode value");
7823 return 0;
7824 }
7825 }
7826
7827 val = get_param(cmd, "OffChNum");
7828 if (val) {
7829 off_ch_num = atoi(val);
7830 if (off_ch_num == 0) {
7831 send_resp(dut, conn, SIGMA_ERROR,
7832 "ErrorCode,Invalid OffChNum");
7833 return 0;
7834 }
7835 }
7836
7837 val = get_param(cmd, "SecChOffset");
7838 if (val) {
7839 if (strcmp(val, "20") == 0)
7840 sec_ch = SEC_CH_NO;
7841 else if (strcasecmp(val, "40above") == 0)
7842 sec_ch = SEC_CH_40ABOVE;
7843 else if (strcasecmp(val, "40below") == 0)
7844 sec_ch = SEC_CH_40BELOW;
7845 else {
7846 send_resp(dut, conn, SIGMA_ERROR,
7847 "ErrorCode,Unknown SecChOffset value");
7848 return 0;
7849 }
7850 }
7851
7852 if (chsm == CHSM_NOT_SET) {
7853 /* no offchannel changes requested */
7854 return 1;
7855 }
7856
7857 if (strcmp(intf, get_main_ifname()) != 0 &&
7858 strcmp(intf, get_station_ifname()) != 0) {
7859 send_resp(dut, conn, SIGMA_ERROR,
7860 "ErrorCode,Unknown interface");
7861 return 0;
7862 }
7863
7864 switch (chsm) {
7865 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +03007866 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007867 break;
7868 case CHSM_ENABLE:
7869 if (off_ch_num < 0) {
7870 send_resp(dut, conn, SIGMA_ERROR,
7871 "ErrorCode,Missing OffChNum argument");
7872 return 0;
7873 }
7874 if (wifi_chip_type == DRIVER_WCN) {
7875 res = tdls_set_offchannel_offset(dut, conn, intf,
7876 off_ch_num, sec_ch);
7877 } else {
7878 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
7879 sec_ch);
7880 }
7881 if (res != 1)
7882 return res;
7883 if (wifi_chip_type == DRIVER_WCN)
7884 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
7885 else
7886 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
7887 break;
7888 case CHSM_DISABLE:
7889 if (wifi_chip_type == DRIVER_WCN)
7890 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
7891 else
7892 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
7893 break;
7894 case CHSM_REJREQ:
7895 if (wifi_chip_type == DRIVER_WCN)
7896 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
7897 else
7898 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
7899 break;
7900 case CHSM_UNSOLRESP:
7901 if (off_ch_num < 0) {
7902 send_resp(dut, conn, SIGMA_ERROR,
7903 "ErrorCode,Missing OffChNum argument");
7904 return 0;
7905 }
7906 if (wifi_chip_type == DRIVER_WCN) {
7907 res = tdls_set_offchannel_offset(dut, conn, intf,
7908 off_ch_num, sec_ch);
7909 } else {
7910 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
7911 sec_ch);
7912 }
7913 if (res != 1)
7914 return res;
7915 if (wifi_chip_type == DRIVER_WCN)
7916 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
7917 else
7918 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
7919 break;
7920 }
7921
7922 return res;
7923}
7924
7925
7926static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
7927 struct sigma_conn *conn,
7928 struct sigma_cmd *cmd)
7929{
7930 const char *val;
7931 char *token, *result;
7932
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007933 novap_reset(dut, intf);
7934
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007935 val = get_param(cmd, "nss_mcs_opt");
7936 if (val) {
7937 /* String (nss_operating_mode; mcs_operating_mode) */
7938 int nss, mcs;
7939 char buf[50];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307940 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007941
7942 token = strdup(val);
7943 if (!token)
7944 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307945 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05307946 if (!result) {
7947 sigma_dut_print(dut, DUT_MSG_ERROR,
7948 "VHT NSS not specified");
7949 goto failed;
7950 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007951 if (strcasecmp(result, "def") != 0) {
7952 nss = atoi(result);
7953 if (nss == 4)
7954 ath_disable_txbf(dut, intf);
7955 snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
7956 intf, nss);
7957 if (system(buf) != 0) {
7958 sigma_dut_print(dut, DUT_MSG_ERROR,
7959 "iwpriv nss failed");
7960 goto failed;
7961 }
7962 }
7963
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307964 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05307965 if (!result) {
7966 sigma_dut_print(dut, DUT_MSG_ERROR,
7967 "VHT MCS not specified");
7968 goto failed;
7969 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007970 if (strcasecmp(result, "def") == 0) {
7971 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0",
7972 intf);
7973 if (system(buf) != 0) {
7974 sigma_dut_print(dut, DUT_MSG_ERROR,
7975 "iwpriv set11NRates failed");
7976 goto failed;
7977 }
7978
7979 } else {
7980 mcs = atoi(result);
7981 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
7982 intf, mcs);
7983 if (system(buf) != 0) {
7984 sigma_dut_print(dut, DUT_MSG_ERROR,
7985 "iwpriv vhtmcs failed");
7986 goto failed;
7987 }
7988 }
7989 /* Channel width gets messed up, fix this */
7990 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
7991 intf, dut->chwidth);
7992 if (system(buf) != 0) {
7993 sigma_dut_print(dut, DUT_MSG_ERROR,
7994 "iwpriv chwidth failed");
7995 }
7996 }
7997
7998 return 1;
7999failed:
8000 free(token);
8001 return 0;
8002}
8003
8004
8005static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
8006 struct sigma_conn *conn,
8007 struct sigma_cmd *cmd)
8008{
8009 switch (get_driver_type()) {
8010 case DRIVER_ATHEROS:
8011 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
8012 default:
8013 send_resp(dut, conn, SIGMA_ERROR,
8014 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
8015 return 0;
8016 }
8017}
8018
8019
Ashwini Patil5acd7382017-04-13 15:55:04 +05308020static int btm_query_candidate_list(struct sigma_dut *dut,
8021 struct sigma_conn *conn,
8022 struct sigma_cmd *cmd)
8023{
8024 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
8025 int len, ret;
8026 char buf[10];
8027
8028 /*
8029 * Neighbor Report elements format:
8030 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
8031 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
8032 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
8033 */
8034
8035 bssid = get_param(cmd, "Nebor_BSSID");
8036 if (!bssid) {
8037 send_resp(dut, conn, SIGMA_INVALID,
8038 "errorCode,Nebor_BSSID is missing");
8039 return 0;
8040 }
8041
8042 info = get_param(cmd, "Nebor_Bssid_Info");
8043 if (!info) {
8044 sigma_dut_print(dut, DUT_MSG_INFO,
8045 "Using default value for Nebor_Bssid_Info: %s",
8046 DEFAULT_NEIGHBOR_BSSID_INFO);
8047 info = DEFAULT_NEIGHBOR_BSSID_INFO;
8048 }
8049
8050 op_class = get_param(cmd, "Nebor_Op_Class");
8051 if (!op_class) {
8052 send_resp(dut, conn, SIGMA_INVALID,
8053 "errorCode,Nebor_Op_Class is missing");
8054 return 0;
8055 }
8056
8057 ch = get_param(cmd, "Nebor_Op_Ch");
8058 if (!ch) {
8059 send_resp(dut, conn, SIGMA_INVALID,
8060 "errorCode,Nebor_Op_Ch is missing");
8061 return 0;
8062 }
8063
8064 phy_type = get_param(cmd, "Nebor_Phy_Type");
8065 if (!phy_type) {
8066 sigma_dut_print(dut, DUT_MSG_INFO,
8067 "Using default value for Nebor_Phy_Type: %s",
8068 DEFAULT_NEIGHBOR_PHY_TYPE);
8069 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
8070 }
8071
8072 /* Parse optional subelements */
8073 buf[0] = '\0';
8074 pref = get_param(cmd, "Nebor_Pref");
8075 if (pref) {
8076 /* hexdump for preferrence subelement */
8077 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
8078 if (ret < 0 || ret >= (int) sizeof(buf)) {
8079 sigma_dut_print(dut, DUT_MSG_ERROR,
8080 "snprintf failed for optional subelement ret: %d",
8081 ret);
8082 send_resp(dut, conn, SIGMA_ERROR,
8083 "errorCode,snprintf failed for subelement");
8084 return 0;
8085 }
8086 }
8087
8088 if (!dut->btm_query_cand_list) {
8089 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
8090 if (!dut->btm_query_cand_list) {
8091 send_resp(dut, conn, SIGMA_ERROR,
8092 "errorCode,Failed to allocate memory for btm_query_cand_list");
8093 return 0;
8094 }
8095 }
8096
8097 len = strlen(dut->btm_query_cand_list);
8098 ret = snprintf(dut->btm_query_cand_list + len,
8099 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
8100 bssid, info, op_class, ch, phy_type, buf);
8101 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
8102 sigma_dut_print(dut, DUT_MSG_ERROR,
8103 "snprintf failed for neighbor report list ret: %d",
8104 ret);
8105 send_resp(dut, conn, SIGMA_ERROR,
8106 "errorCode,snprintf failed for neighbor report");
8107 free(dut->btm_query_cand_list);
8108 dut->btm_query_cand_list = NULL;
8109 return 0;
8110 }
8111
8112 return 1;
8113}
8114
8115
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008116static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
8117 struct sigma_cmd *cmd)
8118{
8119 const char *intf = get_param(cmd, "Interface");
8120 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +05308121 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008122
8123 if (intf == NULL || prog == NULL)
8124 return -1;
8125
Ashwini Patil5acd7382017-04-13 15:55:04 +05308126 /* BSS Transition candidate list for BTM query */
8127 val = get_param(cmd, "Nebor_BSSID");
8128 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
8129 return 0;
8130
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008131 if (strcasecmp(prog, "TDLS") == 0)
8132 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
8133
8134 if (strcasecmp(prog, "VHT") == 0)
8135 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
8136
Ashwini Patil68d02cd2017-01-10 15:39:16 +05308137 if (strcasecmp(prog, "MBO") == 0) {
8138 val = get_param(cmd, "Cellular_Data_Cap");
8139 if (val &&
8140 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
8141 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05308142
8143 val = get_param(cmd, "Ch_Pref");
8144 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
8145 return 0;
8146
Ashwini Patil68d02cd2017-01-10 15:39:16 +05308147 return 1;
8148 }
8149
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008150 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
8151 return 0;
8152}
8153
8154
8155static int cmd_sta_set_radio(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 = wpa_command(intf, "SET radio_disabled 0");
8167 else if (strcasecmp(mode, "Off") == 0)
8168 res = wpa_command(intf, "SET radio_disabled 1");
8169 else
8170 return -1;
8171
8172 if (res) {
8173 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
8174 "radio mode");
8175 return 0;
8176 }
8177
8178 return 1;
8179}
8180
8181
8182static int cmd_sta_set_pwrsave(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 *mode = get_param(cmd, "Mode");
8187 int res;
8188
8189 if (intf == NULL || mode == NULL)
8190 return -1;
8191
8192 if (strcasecmp(mode, "On") == 0)
8193 res = set_ps(intf, dut, 1);
8194 else if (strcasecmp(mode, "Off") == 0)
8195 res = set_ps(intf, dut, 0);
8196 else
8197 return -1;
8198
8199 if (res) {
8200 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
8201 "power save mode");
8202 return 0;
8203 }
8204
8205 return 1;
8206}
8207
8208
8209static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
8210 struct sigma_cmd *cmd)
8211{
8212 const char *intf = get_param(cmd, "Interface");
8213 const char *val, *bssid;
8214 int res;
8215 char *buf;
8216 size_t buf_len;
8217
8218 val = get_param(cmd, "BSSID_FILTER");
8219 if (val == NULL)
8220 return -1;
8221
8222 bssid = get_param(cmd, "BSSID_List");
8223 if (atoi(val) == 0 || bssid == NULL) {
8224 /* Disable BSSID filter */
8225 if (wpa_command(intf, "SET bssid_filter ")) {
8226 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
8227 "to disable BSSID filter");
8228 return 0;
8229 }
8230
8231 return 1;
8232 }
8233
8234 buf_len = 100 + strlen(bssid);
8235 buf = malloc(buf_len);
8236 if (buf == NULL)
8237 return -1;
8238
8239 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
8240 res = wpa_command(intf, buf);
8241 free(buf);
8242 if (res) {
8243 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
8244 "BSSID filter");
8245 return 0;
8246 }
8247
8248 return 1;
8249}
8250
8251
8252static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
8253 struct sigma_cmd *cmd)
8254{
8255 const char *intf = get_param(cmd, "Interface");
8256 const char *val;
8257
8258 /* TODO: ARP */
8259
8260 val = get_param(cmd, "HS2_CACHE_PROFILE");
8261 if (val && strcasecmp(val, "All") == 0)
8262 hs2_clear_credentials(intf);
8263
8264 return 1;
8265}
8266
8267
8268static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
8269 struct sigma_cmd *cmd)
8270{
8271 const char *intf = get_param(cmd, "Interface");
8272 const char *key_type = get_param(cmd, "KeyType");
8273 char buf[100], resp[200];
8274
8275 if (key_type == NULL)
8276 return -1;
8277
8278 if (strcasecmp(key_type, "GTK") == 0) {
8279 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
8280 strncmp(buf, "FAIL", 4) == 0) {
8281 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8282 "not fetch current GTK");
8283 return 0;
8284 }
8285 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
8286 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8287 return 0;
8288 } else {
8289 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
8290 "KeyType");
8291 return 0;
8292 }
8293
8294 return 1;
8295}
8296
8297
8298static int hs2_set_policy(struct sigma_dut *dut)
8299{
8300#ifdef ANDROID
8301 system("ip rule del prio 23000");
8302 if (system("ip rule add from all lookup main prio 23000") != 0) {
8303 sigma_dut_print(dut, DUT_MSG_ERROR,
8304 "Failed to run:ip rule add from all lookup main prio");
8305 return -1;
8306 }
8307 if (system("ip route flush cache") != 0) {
8308 sigma_dut_print(dut, DUT_MSG_ERROR,
8309 "Failed to run ip route flush cache");
8310 return -1;
8311 }
8312 return 1;
8313#else /* ANDROID */
8314 return 0;
8315#endif /* ANDROID */
8316}
8317
8318
8319static int cmd_sta_hs2_associate(struct sigma_dut *dut,
8320 struct sigma_conn *conn,
8321 struct sigma_cmd *cmd)
8322{
8323 const char *intf = get_param(cmd, "Interface");
8324 const char *val = get_param(cmd, "Ignore_blacklist");
8325 struct wpa_ctrl *ctrl;
8326 int res;
8327 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
8328 int tries = 0;
8329 int ignore_blacklist = 0;
8330 const char *events[] = {
8331 "CTRL-EVENT-CONNECTED",
8332 "INTERWORKING-BLACKLISTED",
8333 "INTERWORKING-NO-MATCH",
8334 NULL
8335 };
8336
8337 start_sta_mode(dut);
8338
8339 blacklisted[0] = '\0';
8340 if (val && atoi(val))
8341 ignore_blacklist = 1;
8342
8343try_again:
8344 ctrl = open_wpa_mon(intf);
8345 if (ctrl == NULL) {
8346 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
8347 "wpa_supplicant monitor connection");
8348 return -2;
8349 }
8350
8351 tries++;
8352 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
8353 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
8354 "Interworking connection");
8355 wpa_ctrl_detach(ctrl);
8356 wpa_ctrl_close(ctrl);
8357 return 0;
8358 }
8359
8360 buf[0] = '\0';
8361 while (1) {
8362 char *pos;
8363 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
8364 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
8365 if (!pos)
8366 break;
8367 pos += 25;
8368 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
8369 pos);
8370 if (!blacklisted[0])
8371 memcpy(blacklisted, pos, strlen(pos) + 1);
8372 }
8373
8374 if (ignore_blacklist && blacklisted[0]) {
8375 char *end;
8376 end = strchr(blacklisted, ' ');
8377 if (end)
8378 *end = '\0';
8379 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
8380 blacklisted);
8381 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
8382 blacklisted);
8383 if (wpa_command(intf, buf)) {
8384 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
8385 wpa_ctrl_detach(ctrl);
8386 wpa_ctrl_close(ctrl);
8387 return 0;
8388 }
8389 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
8390 buf, sizeof(buf));
8391 }
8392
8393 wpa_ctrl_detach(ctrl);
8394 wpa_ctrl_close(ctrl);
8395
8396 if (res < 0) {
8397 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
8398 "connect");
8399 return 0;
8400 }
8401
8402 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
8403 strstr(buf, "INTERWORKING-BLACKLISTED")) {
8404 if (tries < 2) {
8405 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
8406 goto try_again;
8407 }
8408 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
8409 "matching credentials found");
8410 return 0;
8411 }
8412
8413 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
8414 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
8415 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
8416 "get current BSSID/SSID");
8417 return 0;
8418 }
8419
8420 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
8421 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8422 hs2_set_policy(dut);
8423 return 0;
8424}
8425
8426
8427static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
8428 struct sigma_conn *conn,
8429 const char *ifname,
8430 struct sigma_cmd *cmd)
8431{
8432 const char *val;
8433 int id;
8434
8435 id = add_cred(ifname);
8436 if (id < 0)
8437 return -2;
8438 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
8439
8440 val = get_param(cmd, "prefer");
8441 if (val && atoi(val) > 0)
8442 set_cred(ifname, id, "priority", "1");
8443
8444 val = get_param(cmd, "REALM");
8445 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
8446 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8447 "realm");
8448 return 0;
8449 }
8450
8451 val = get_param(cmd, "HOME_FQDN");
8452 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
8453 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8454 "home_fqdn");
8455 return 0;
8456 }
8457
8458 val = get_param(cmd, "Username");
8459 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
8460 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8461 "username");
8462 return 0;
8463 }
8464
8465 val = get_param(cmd, "Password");
8466 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
8467 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8468 "password");
8469 return 0;
8470 }
8471
8472 val = get_param(cmd, "ROOT_CA");
8473 if (val) {
8474 char fname[200];
8475 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
8476#ifdef __linux__
8477 if (!file_exists(fname)) {
8478 char msg[300];
8479 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
8480 "file (%s) not found", fname);
8481 send_resp(dut, conn, SIGMA_ERROR, msg);
8482 return 0;
8483 }
8484#endif /* __linux__ */
8485 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
8486 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8487 "not set root CA");
8488 return 0;
8489 }
8490 }
8491
8492 return 1;
8493}
8494
8495
8496static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
8497{
8498 FILE *in, *out;
8499 char buf[500];
8500 int found = 0;
8501
8502 in = fopen("devdetail.xml", "r");
8503 if (in == NULL)
8504 return -1;
8505 out = fopen("devdetail.xml.tmp", "w");
8506 if (out == NULL) {
8507 fclose(in);
8508 return -1;
8509 }
8510
8511 while (fgets(buf, sizeof(buf), in)) {
8512 char *pos = strstr(buf, "<IMSI>");
8513 if (pos) {
8514 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
8515 imsi);
8516 pos += 6;
8517 *pos = '\0';
8518 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
8519 found++;
8520 } else {
8521 fprintf(out, "%s", buf);
8522 }
8523 }
8524
8525 fclose(out);
8526 fclose(in);
8527 if (found)
8528 rename("devdetail.xml.tmp", "devdetail.xml");
8529 else
8530 unlink("devdetail.xml.tmp");
8531
8532 return 0;
8533}
8534
8535
8536static int sta_add_credential_sim(struct sigma_dut *dut,
8537 struct sigma_conn *conn,
8538 const char *ifname, struct sigma_cmd *cmd)
8539{
8540 const char *val, *imsi = NULL;
8541 int id;
8542 char buf[200];
8543 int res;
8544 const char *pos;
8545 size_t mnc_len;
8546 char plmn_mcc[4];
8547 char plmn_mnc[4];
8548
8549 id = add_cred(ifname);
8550 if (id < 0)
8551 return -2;
8552 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
8553
8554 val = get_param(cmd, "prefer");
8555 if (val && atoi(val) > 0)
8556 set_cred(ifname, id, "priority", "1");
8557
8558 val = get_param(cmd, "PLMN_MCC");
8559 if (val == NULL) {
8560 send_resp(dut, conn, SIGMA_ERROR,
8561 "errorCode,Missing PLMN_MCC");
8562 return 0;
8563 }
8564 if (strlen(val) != 3) {
8565 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
8566 return 0;
8567 }
8568 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
8569
8570 val = get_param(cmd, "PLMN_MNC");
8571 if (val == NULL) {
8572 send_resp(dut, conn, SIGMA_ERROR,
8573 "errorCode,Missing PLMN_MNC");
8574 return 0;
8575 }
8576 if (strlen(val) != 2 && strlen(val) != 3) {
8577 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
8578 return 0;
8579 }
8580 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
8581
8582 val = get_param(cmd, "IMSI");
8583 if (val == NULL) {
8584 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
8585 "IMSI");
8586 return 0;
8587 }
8588
8589 imsi = pos = val;
8590
8591 if (strncmp(plmn_mcc, pos, 3) != 0) {
8592 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
8593 return 0;
8594 }
8595 pos += 3;
8596
8597 mnc_len = strlen(plmn_mnc);
8598 if (mnc_len < 2) {
8599 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
8600 return 0;
8601 }
8602
8603 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
8604 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
8605 return 0;
8606 }
8607 pos += mnc_len;
8608
8609 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
8610 if (res < 0 || res >= (int) sizeof(buf))
8611 return -1;
8612 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
8613 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8614 "not set IMSI");
8615 return 0;
8616 }
8617
8618 val = get_param(cmd, "Password");
8619 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
8620 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8621 "not set password");
8622 return 0;
8623 }
8624
8625 if (dut->program == PROGRAM_HS2_R2) {
8626 /*
8627 * Set provisioning_sp for the test cases where SIM/USIM
8628 * provisioning is used.
8629 */
8630 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
8631 "wi-fi.org") < 0) {
8632 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8633 "not set provisioning_sp");
8634 return 0;
8635 }
8636
8637 update_devdetail_imsi(dut, imsi);
8638 }
8639
8640 return 1;
8641}
8642
8643
8644static int sta_add_credential_cert(struct sigma_dut *dut,
8645 struct sigma_conn *conn,
8646 const char *ifname,
8647 struct sigma_cmd *cmd)
8648{
8649 const char *val;
8650 int id;
8651
8652 id = add_cred(ifname);
8653 if (id < 0)
8654 return -2;
8655 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
8656
8657 val = get_param(cmd, "prefer");
8658 if (val && atoi(val) > 0)
8659 set_cred(ifname, id, "priority", "1");
8660
8661 val = get_param(cmd, "REALM");
8662 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
8663 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8664 "realm");
8665 return 0;
8666 }
8667
8668 val = get_param(cmd, "HOME_FQDN");
8669 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
8670 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8671 "home_fqdn");
8672 return 0;
8673 }
8674
8675 val = get_param(cmd, "Username");
8676 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
8677 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
8678 "username");
8679 return 0;
8680 }
8681
8682 val = get_param(cmd, "clientCertificate");
8683 if (val) {
8684 char fname[200];
8685 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
8686#ifdef __linux__
8687 if (!file_exists(fname)) {
8688 char msg[300];
8689 snprintf(msg, sizeof(msg),
8690 "ErrorCode,clientCertificate "
8691 "file (%s) not found", fname);
8692 send_resp(dut, conn, SIGMA_ERROR, msg);
8693 return 0;
8694 }
8695#endif /* __linux__ */
8696 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
8697 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8698 "not set client_cert");
8699 return 0;
8700 }
8701 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
8702 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8703 "not set private_key");
8704 return 0;
8705 }
8706 }
8707
8708 val = get_param(cmd, "ROOT_CA");
8709 if (val) {
8710 char fname[200];
8711 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
8712#ifdef __linux__
8713 if (!file_exists(fname)) {
8714 char msg[300];
8715 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
8716 "file (%s) not found", fname);
8717 send_resp(dut, conn, SIGMA_ERROR, msg);
8718 return 0;
8719 }
8720#endif /* __linux__ */
8721 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
8722 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
8723 "not set root CA");
8724 return 0;
8725 }
8726 }
8727
8728 return 1;
8729}
8730
8731
8732static int cmd_sta_add_credential(struct sigma_dut *dut,
8733 struct sigma_conn *conn,
8734 struct sigma_cmd *cmd)
8735{
8736 const char *intf = get_param(cmd, "Interface");
8737 const char *type;
8738
8739 start_sta_mode(dut);
8740
8741 type = get_param(cmd, "Type");
8742 if (!type)
8743 return -1;
8744
8745 if (strcasecmp(type, "uname_pwd") == 0)
8746 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
8747
8748 if (strcasecmp(type, "sim") == 0)
8749 return sta_add_credential_sim(dut, conn, intf, cmd);
8750
8751 if (strcasecmp(type, "cert") == 0)
8752 return sta_add_credential_cert(dut, conn, intf, cmd);
8753
8754 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
8755 "type");
8756 return 0;
8757}
8758
8759
8760static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
8761 struct sigma_cmd *cmd)
8762{
8763 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +05308764 const char *val, *bssid, *ssid;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008765 char buf[100];
vamsi krishna89ad8c62017-09-19 12:51:18 +05308766 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008767 int res;
8768
8769 val = get_param(cmd, "HESSID");
8770 if (val) {
8771 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
8772 if (res < 0 || res >= (int) sizeof(buf))
8773 return -1;
8774 wpa_command(intf, buf);
8775 }
8776
8777 val = get_param(cmd, "ACCS_NET_TYPE");
8778 if (val) {
8779 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
8780 val);
8781 if (res < 0 || res >= (int) sizeof(buf))
8782 return -1;
8783 wpa_command(intf, buf);
8784 }
8785
vamsi krishna89ad8c62017-09-19 12:51:18 +05308786 bssid = get_param(cmd, "Bssid");
8787 ssid = get_param(cmd, "Ssid");
8788
8789 if (ssid) {
8790 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
8791 send_resp(dut, conn, SIGMA_ERROR,
8792 "ErrorCode,Too long SSID");
8793 return 0;
8794 }
8795 ascii2hexstr(ssid, ssid_hex);
8796 }
8797
8798 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
8799 bssid ? " bssid=": "",
8800 bssid ? bssid : "",
8801 ssid ? " ssid " : "",
8802 ssid ? ssid_hex : "");
8803 if (res < 0 || res >= (int) sizeof(buf))
8804 return -1;
8805
8806 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008807 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
8808 "scan");
8809 return 0;
8810 }
8811
8812 return 1;
8813}
8814
8815
Jouni Malinen5e5d43d2018-01-10 17:29:33 +02008816static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
8817 struct sigma_cmd *cmd)
8818{
8819 const char *intf = get_param(cmd, "Interface");
8820 const char *bssid;
8821 char buf[4096], *pos;
8822 int freq, chan;
8823 char *ssid;
8824 char resp[100];
8825 int res;
8826 struct wpa_ctrl *ctrl;
8827
8828 bssid = get_param(cmd, "BSSID");
8829 if (!bssid) {
8830 send_resp(dut, conn, SIGMA_INVALID,
8831 "errorCode,BSSID argument is missing");
8832 return 0;
8833 }
8834
8835 ctrl = open_wpa_mon(intf);
8836 if (!ctrl) {
8837 sigma_dut_print(dut, DUT_MSG_ERROR,
8838 "Failed to open wpa_supplicant monitor connection");
8839 return -1;
8840 }
8841
8842 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
8843 send_resp(dut, conn, SIGMA_ERROR,
8844 "errorCode,Could not start scan");
8845 wpa_ctrl_detach(ctrl);
8846 wpa_ctrl_close(ctrl);
8847 return 0;
8848 }
8849
8850 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
8851 buf, sizeof(buf));
8852
8853 wpa_ctrl_detach(ctrl);
8854 wpa_ctrl_close(ctrl);
8855
8856 if (res < 0) {
8857 send_resp(dut, conn, SIGMA_ERROR,
8858 "errorCode,Scan did not complete");
8859 return 0;
8860 }
8861
8862 snprintf(buf, sizeof(buf), "BSS %s", bssid);
8863 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8864 strncmp(buf, "id=", 3) != 0) {
8865 send_resp(dut, conn, SIGMA_ERROR,
8866 "errorCode,Specified BSSID not found");
8867 return 0;
8868 }
8869
8870 pos = strstr(buf, "\nfreq=");
8871 if (!pos) {
8872 send_resp(dut, conn, SIGMA_ERROR,
8873 "errorCode,Channel not found");
8874 return 0;
8875 }
8876 freq = atoi(pos + 6);
8877 chan = freq_to_channel(freq);
8878
8879 pos = strstr(buf, "\nssid=");
8880 if (!pos) {
8881 send_resp(dut, conn, SIGMA_ERROR,
8882 "errorCode,SSID not found");
8883 return 0;
8884 }
8885 ssid = pos + 6;
8886 pos = strchr(ssid, '\n');
8887 if (pos)
8888 *pos = '\0';
8889 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
8890 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8891 return 0;
8892}
8893
8894
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008895static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
8896 struct sigma_cmd *cmd)
8897{
8898#ifdef __linux__
8899 struct timeval tv;
8900 struct tm tm;
8901 time_t t;
8902 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +05308903 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008904
8905 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
8906
8907 memset(&tm, 0, sizeof(tm));
8908 val = get_param(cmd, "seconds");
8909 if (val)
8910 tm.tm_sec = atoi(val);
8911 val = get_param(cmd, "minutes");
8912 if (val)
8913 tm.tm_min = atoi(val);
8914 val = get_param(cmd, "hours");
8915 if (val)
8916 tm.tm_hour = atoi(val);
8917 val = get_param(cmd, "date");
8918 if (val)
8919 tm.tm_mday = atoi(val);
8920 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +05308921 if (val) {
8922 v = atoi(val);
8923 if (v < 1 || v > 12) {
8924 send_resp(dut, conn, SIGMA_INVALID,
8925 "errorCode,Invalid month");
8926 return 0;
8927 }
8928 tm.tm_mon = v - 1;
8929 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008930 val = get_param(cmd, "year");
8931 if (val) {
8932 int year = atoi(val);
8933#ifdef ANDROID
8934 if (year > 2035)
8935 year = 2035; /* years beyond 2035 not supported */
8936#endif /* ANDROID */
8937 tm.tm_year = year - 1900;
8938 }
8939 t = mktime(&tm);
8940 if (t == (time_t) -1) {
8941 send_resp(dut, conn, SIGMA_ERROR,
8942 "errorCode,Invalid date or time");
8943 return 0;
8944 }
8945
8946 memset(&tv, 0, sizeof(tv));
8947 tv.tv_sec = t;
8948
8949 if (settimeofday(&tv, NULL) < 0) {
8950 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
8951 strerror(errno));
8952 send_resp(dut, conn, SIGMA_ERROR,
8953 "errorCode,Failed to set time");
8954 return 0;
8955 }
8956
8957 return 1;
8958#endif /* __linux__ */
8959
8960 return -1;
8961}
8962
8963
8964static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
8965 struct sigma_cmd *cmd)
8966{
8967 const char *intf = get_param(cmd, "Interface");
8968 const char *name, *val;
8969 int prod_ess_assoc = 1;
8970 char buf[200], bssid[100], ssid[100];
8971 int res;
8972 struct wpa_ctrl *ctrl;
8973
8974 name = get_param(cmd, "osuFriendlyName");
8975
8976 val = get_param(cmd, "ProdESSAssoc");
8977 if (val)
8978 prod_ess_assoc = atoi(val);
8979
8980 kill_dhcp_client(dut, intf);
8981 if (start_dhcp_client(dut, intf) < 0)
8982 return -2;
8983
8984 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
8985 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
8986 res = snprintf(buf, sizeof(buf),
8987 "%s %s%s%s signup osu-ca.pem",
8988 prod_ess_assoc ? "" : "-N",
8989 name ? "-O'" : "", name ? name : "",
8990 name ? "'" : "");
8991
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +05308992 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008993 if (run_hs20_osu(dut, buf) < 0) {
8994 FILE *f;
8995
8996 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
8997
8998 f = fopen("hs20-osu-client.res", "r");
8999 if (f) {
9000 char resp[400], res[300], *pos;
9001 if (!fgets(res, sizeof(res), f))
9002 res[0] = '\0';
9003 pos = strchr(res, '\n');
9004 if (pos)
9005 *pos = '\0';
9006 fclose(f);
9007 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
9008 res);
9009 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
9010 if (system(resp) != 0) {
9011 }
9012 snprintf(resp, sizeof(resp),
9013 "SSID,,BSSID,,failureReason,%s", res);
9014 send_resp(dut, conn, SIGMA_COMPLETE, resp);
9015 return 0;
9016 }
9017
9018 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
9019 return 0;
9020 }
9021
9022 if (!prod_ess_assoc)
9023 goto report;
9024
9025 ctrl = open_wpa_mon(intf);
9026 if (ctrl == NULL) {
9027 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9028 "wpa_supplicant monitor connection");
9029 return -1;
9030 }
9031
9032 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
9033 buf, sizeof(buf));
9034
9035 wpa_ctrl_detach(ctrl);
9036 wpa_ctrl_close(ctrl);
9037
9038 if (res < 0) {
9039 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
9040 "network after OSU");
9041 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
9042 return 0;
9043 }
9044
9045report:
9046 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
9047 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
9048 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
9049 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
9050 return 0;
9051 }
9052
9053 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
9054 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009055 return 0;
9056}
9057
9058
9059static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
9060 struct sigma_cmd *cmd)
9061{
9062 const char *val;
9063 int timeout = 120;
9064
9065 val = get_param(cmd, "PolicyUpdate");
9066 if (val == NULL || atoi(val) == 0)
9067 return 1; /* No operation requested */
9068
9069 val = get_param(cmd, "Timeout");
9070 if (val)
9071 timeout = atoi(val);
9072
9073 if (timeout) {
9074 /* TODO: time out the command and return
9075 * PolicyUpdateStatus,TIMEOUT if needed. */
9076 }
9077
9078 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
9079 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
9080 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
9081 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
9082 return 0;
9083 }
9084
9085 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
9086 return 0;
9087}
9088
9089
9090static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
9091 struct sigma_cmd *cmd)
9092{
9093 struct wpa_ctrl *ctrl;
9094 const char *intf = get_param(cmd, "Interface");
9095 const char *bssid = get_param(cmd, "Bssid");
9096 const char *ssid = get_param(cmd, "SSID");
9097 const char *security = get_param(cmd, "Security");
9098 const char *passphrase = get_param(cmd, "Passphrase");
9099 const char *pin = get_param(cmd, "PIN");
9100 char buf[1000];
9101 char ssid_hex[200], passphrase_hex[200];
9102 const char *keymgmt, *cipher;
9103
9104 if (intf == NULL)
9105 intf = get_main_ifname();
9106
9107 if (!bssid) {
9108 send_resp(dut, conn, SIGMA_ERROR,
9109 "ErrorCode,Missing Bssid argument");
9110 return 0;
9111 }
9112
9113 if (!ssid) {
9114 send_resp(dut, conn, SIGMA_ERROR,
9115 "ErrorCode,Missing SSID argument");
9116 return 0;
9117 }
9118
9119 if (!security) {
9120 send_resp(dut, conn, SIGMA_ERROR,
9121 "ErrorCode,Missing Security argument");
9122 return 0;
9123 }
9124
9125 if (!passphrase) {
9126 send_resp(dut, conn, SIGMA_ERROR,
9127 "ErrorCode,Missing Passphrase argument");
9128 return 0;
9129 }
9130
9131 if (!pin) {
9132 send_resp(dut, conn, SIGMA_ERROR,
9133 "ErrorCode,Missing PIN argument");
9134 return 0;
9135 }
9136
vamsi krishna8c9c1562017-05-12 15:51:46 +05309137 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
9138 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009139 send_resp(dut, conn, SIGMA_ERROR,
9140 "ErrorCode,Too long SSID/passphrase");
9141 return 0;
9142 }
9143
9144 ctrl = open_wpa_mon(intf);
9145 if (ctrl == NULL) {
9146 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9147 "wpa_supplicant monitor connection");
9148 return -2;
9149 }
9150
9151 if (strcasecmp(security, "wpa2-psk") == 0) {
9152 keymgmt = "WPA2PSK";
9153 cipher = "CCMP";
9154 } else {
9155 wpa_ctrl_detach(ctrl);
9156 wpa_ctrl_close(ctrl);
9157 send_resp(dut, conn, SIGMA_ERROR,
9158 "ErrorCode,Unsupported Security value");
9159 return 0;
9160 }
9161
9162 ascii2hexstr(ssid, ssid_hex);
9163 ascii2hexstr(passphrase, passphrase_hex);
9164 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
9165 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
9166
9167 if (wpa_command(intf, buf) < 0) {
9168 wpa_ctrl_detach(ctrl);
9169 wpa_ctrl_close(ctrl);
9170 send_resp(dut, conn, SIGMA_ERROR,
9171 "ErrorCode,Failed to start registrar");
9172 return 0;
9173 }
9174
9175 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
9176 dut->er_oper_performed = 1;
9177
9178 return wps_connection_event(dut, conn, ctrl, intf, 0);
9179}
9180
9181
9182static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
9183 struct sigma_conn *conn,
9184 struct sigma_cmd *cmd)
9185{
9186 struct wpa_ctrl *ctrl;
9187 const char *intf = get_param(cmd, "Interface");
9188 const char *bssid = get_param(cmd, "Bssid");
9189 char buf[100];
9190
9191 if (!bssid) {
9192 send_resp(dut, conn, SIGMA_ERROR,
9193 "ErrorCode,Missing Bssid argument");
9194 return 0;
9195 }
9196
9197 ctrl = open_wpa_mon(intf);
9198 if (ctrl == NULL) {
9199 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9200 "wpa_supplicant monitor connection");
9201 return -2;
9202 }
9203
9204 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
9205
9206 if (wpa_command(intf, buf) < 0) {
9207 wpa_ctrl_detach(ctrl);
9208 wpa_ctrl_close(ctrl);
9209 send_resp(dut, conn, SIGMA_ERROR,
9210 "ErrorCode,Failed to start registrar");
9211 return 0;
9212 }
9213
9214 return wps_connection_event(dut, conn, ctrl, intf, 0);
9215}
9216
9217
vamsi krishna9b144002017-09-20 13:28:13 +05309218static int cmd_start_wps_registration(struct sigma_dut *dut,
9219 struct sigma_conn *conn,
9220 struct sigma_cmd *cmd)
9221{
9222 struct wpa_ctrl *ctrl;
9223 const char *intf = get_param(cmd, "Interface");
9224 const char *role, *method;
9225 int res;
9226 char buf[256];
9227 const char *events[] = {
9228 "CTRL-EVENT-CONNECTED",
9229 "WPS-OVERLAP-DETECTED",
9230 "WPS-TIMEOUT",
9231 "WPS-FAIL",
9232 NULL
9233 };
9234
9235 ctrl = open_wpa_mon(intf);
9236 if (!ctrl) {
9237 sigma_dut_print(dut, DUT_MSG_ERROR,
9238 "Failed to open wpa_supplicant monitor connection");
9239 return -2;
9240 }
9241
9242 role = get_param(cmd, "WpsRole");
9243 if (!role) {
9244 send_resp(dut, conn, SIGMA_INVALID,
9245 "ErrorCode,WpsRole not provided");
9246 goto fail;
9247 }
9248
9249 if (strcasecmp(role, "Enrollee") == 0) {
9250 method = get_param(cmd, "WpsConfigMethod");
9251 if (!method) {
9252 send_resp(dut, conn, SIGMA_INVALID,
9253 "ErrorCode,WpsConfigMethod not provided");
9254 goto fail;
9255 }
9256 if (strcasecmp(method, "PBC") == 0) {
9257 if (wpa_command(intf, "WPS_PBC") < 0) {
9258 send_resp(dut, conn, SIGMA_ERROR,
9259 "ErrorCode,Failed to enable PBC");
9260 goto fail;
9261 }
9262 } else {
9263 /* TODO: PIN method */
9264 send_resp(dut, conn, SIGMA_ERROR,
9265 "ErrorCode,Unsupported WpsConfigMethod value");
9266 goto fail;
9267 }
9268 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
9269 if (res < 0) {
9270 send_resp(dut, conn, SIGMA_ERROR,
9271 "ErrorCode,WPS connection did not complete");
9272 goto fail;
9273 }
9274 if (strstr(buf, "WPS-TIMEOUT")) {
9275 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
9276 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
9277 send_resp(dut, conn, SIGMA_ERROR,
9278 "ErrorCode,OverlapSession");
9279 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
9280 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
9281 } else {
9282 send_resp(dut, conn, SIGMA_ERROR,
9283 "ErrorCode,WPS operation failed");
9284 }
9285 } else {
9286 /* TODO: Registrar role */
9287 send_resp(dut, conn, SIGMA_ERROR,
9288 "ErrorCode,Unsupported WpsRole value");
9289 }
9290
9291fail:
9292 wpa_ctrl_detach(ctrl);
9293 wpa_ctrl_close(ctrl);
9294 return 0;
9295}
9296
9297
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009298static int req_intf(struct sigma_cmd *cmd)
9299{
9300 return get_param(cmd, "interface") == NULL ? -1 : 0;
9301}
9302
9303
9304void sta_register_cmds(void)
9305{
9306 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
9307 cmd_sta_get_ip_config);
9308 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
9309 cmd_sta_set_ip_config);
9310 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
9311 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
9312 cmd_sta_get_mac_address);
9313 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
9314 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
9315 cmd_sta_verify_ip_connection);
9316 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
9317 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
9318 cmd_sta_set_encryption);
9319 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
9320 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
9321 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
9322 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
9323 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
9324 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
9325 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
9326 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
9327 cmd_sta_set_eapakaprime);
9328 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
9329 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
9330 /* TODO: sta_set_ibss */
9331 /* TODO: sta_set_mode */
9332 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
9333 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
9334 /* TODO: sta_up_load */
9335 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
9336 cmd_sta_preset_testparameters);
9337 /* TODO: sta_set_system */
9338 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
9339 /* TODO: sta_set_rifs_test */
9340 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
9341 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
9342 /* TODO: sta_send_coexist_mgmt */
9343 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
9344 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
9345 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
9346 sigma_dut_reg_cmd("sta_reset_default", req_intf,
9347 cmd_sta_reset_default);
9348 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
9349 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
9350 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
9351 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
9352 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
9353 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
9354 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
9355 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
9356 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
9357 cmd_sta_hs2_associate);
9358 sigma_dut_reg_cmd("sta_add_credential", req_intf,
9359 cmd_sta_add_credential);
9360 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +02009361 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009362 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
9363 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
9364 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
9365 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
9366 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
9367 cmd_sta_wps_connect_pw_token);
9368 sigma_dut_reg_cmd("sta_exec_action", req_intf, cmd_sta_exec_action);
9369 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
9370 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
vamsi krishna9b144002017-09-20 13:28:13 +05309371 sigma_dut_reg_cmd("start_wps_registration", req_intf,
9372 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009373}