blob: 978fb93264d9210023195c09c70c0c87521b2d7d [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>
Jouni Malinen82905202018-04-29 17:20:10 +030013#include <sys/wait.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014#ifdef __linux__
Lior Davidcc88b562017-01-03 18:52:09 +020015#include <regex.h>
16#include <dirent.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017#include <sys/time.h>
18#include <netpacket/packet.h>
19#include <linux/if_ether.h>
20#ifdef ANDROID
21#include <cutils/properties.h>
22#include <android/log.h>
23#include "keystore_get.h"
24#else /* ANDROID */
25#include <ifaddrs.h>
26#endif /* ANDROID */
27#include <netdb.h>
28#endif /* __linux__ */
29#ifdef __QNXNTO__
30#include <net/if_dl.h>
31#endif /* __QNXNTO__ */
32#include "wpa_ctrl.h"
33#include "wpa_helpers.h"
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070034#include "miracast.h"
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070035#include "qca-vendor_copy.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020036
37/* Temporary files for sta_send_addba */
38#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
39#define VI_QOS_FILE "/tmp/vi-qos.txt"
40#define VI_QOS_REFFILE "/etc/vi-qos.txt"
41
42/*
43 * MTU for Ethernet need to take into account 8-byte SNAP header
44 * to be added when encapsulating Ethernet frame into 802.11
45 */
46#ifndef IEEE80211_MAX_DATA_LEN_DMG
47#define IEEE80211_MAX_DATA_LEN_DMG 7920
48#endif
49#ifndef IEEE80211_SNAP_LEN_DMG
50#define IEEE80211_SNAP_LEN_DMG 8
51#endif
52
Ashwini Patil00402582017-04-13 12:29:39 +053053#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053054#define NEIGHBOR_REPORT_SIZE 1000
55#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
56#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053057
Jouni Malinencd4e3c32015-10-29 12:39:56 +020058extern char *sigma_wpas_ctrl;
59extern char *sigma_cert_path;
60extern enum driver_type wifi_chip_type;
61extern char *sigma_radio_ifname[];
62
Lior David0fe101e2017-03-09 16:09:50 +020063#ifdef __linux__
64#define WIL_WMI_MAX_PAYLOAD 248
65#define WIL_WMI_BF_TRIG_CMDID 0x83a
66
67struct wil_wmi_header {
68 uint8_t mid;
69 uint8_t reserved;
70 uint16_t cmd;
71 uint32_t ts;
72} __attribute__((packed));
73
74enum wil_wmi_bf_trig_type {
75 WIL_WMI_SLS,
76 WIL_WMI_BRP_RX,
77 WIL_WMI_BRP_TX,
78};
79
80struct wil_wmi_bf_trig_cmd {
81 /* enum wil_wmi_bf_trig_type */
82 uint32_t bf_type;
83 /* cid when type == WMI_BRP_RX */
84 uint32_t sta_id;
85 uint32_t reserved;
86 /* mac address when type = WIL_WMI_SLS */
87 uint8_t dest_mac[6];
88} __attribute__((packed));
89#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020090
91#ifdef ANDROID
92
93static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
94
95#define ANDROID_KEYSTORE_GET 'g'
96#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
97
98static int android_keystore_get(char cmd, const char *key, unsigned char *val)
99{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200100 /* Android 4.3 changed keystore design, so need to use keystore_get() */
101#ifndef KEYSTORE_MESSAGE_SIZE
102#define KEYSTORE_MESSAGE_SIZE 65535
103#endif /* KEYSTORE_MESSAGE_SIZE */
104
105 ssize_t len;
106 uint8_t *value = NULL;
107
108 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
109 "keystore command '%c' key '%s' --> keystore_get",
110 cmd, key);
111
112 len = keystore_get(key, strlen(key), &value);
113 if (len < 0) {
114 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
115 "keystore_get() failed");
116 return -1;
117 }
118
119 if (len > KEYSTORE_MESSAGE_SIZE)
120 len = KEYSTORE_MESSAGE_SIZE;
121 memcpy(val, value, len);
122 free(value);
123 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200124}
125#endif /* ANDROID */
126
127
128int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
129{
130#ifdef __linux__
131 char buf[100];
132
133 if (wifi_chip_type == DRIVER_WCN) {
134 if (enabled) {
135 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 906");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530136 if (system(buf) != 0)
137 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200138 } else {
139 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 905");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530140 if (system(buf) != 0)
141 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200142 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 912");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530143 if (system(buf) != 0)
144 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200145 }
146
147 return 0;
148 }
149
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530150set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200151 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
152 intf, enabled ? "on" : "off");
153 if (system(buf) != 0) {
154 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
155 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530156 if (system(buf) != 0) {
157 sigma_dut_print(dut, DUT_MSG_ERROR,
158 "Failed to set power save %s",
159 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200160 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530161 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200162 }
163
164 return 0;
165#else /* __linux__ */
166 return -1;
167#endif /* __linux__ */
168}
169
170
Lior Davidcc88b562017-01-03 18:52:09 +0200171#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200172
Lior Davidcc88b562017-01-03 18:52:09 +0200173static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
174 size_t len)
175{
176 DIR *dir, *wil_dir;
177 struct dirent *entry;
178 int ret = -1;
179 const char *root_path = "/sys/kernel/debug/ieee80211";
180
181 dir = opendir(root_path);
182 if (!dir)
183 return -2;
184
185 while ((entry = readdir(dir))) {
186 if (strcmp(entry->d_name, ".") == 0 ||
187 strcmp(entry->d_name, "..") == 0)
188 continue;
189
190 if (snprintf(path, len, "%s/%s/wil6210",
191 root_path, entry->d_name) >= (int) len) {
192 ret = -3;
193 break;
194 }
195
196 wil_dir = opendir(path);
197 if (wil_dir) {
198 closedir(wil_dir);
199 ret = 0;
200 break;
201 }
202 }
203
204 closedir(dir);
205 return ret;
206}
Lior David0fe101e2017-03-09 16:09:50 +0200207
208
209static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
210 void *payload, uint16_t length)
211{
212 struct {
213 struct wil_wmi_header hdr;
214 char payload[WIL_WMI_MAX_PAYLOAD];
215 } __attribute__((packed)) cmd;
216 char buf[128], fname[128];
217 size_t towrite, written;
218 FILE *f;
219
220 if (length > WIL_WMI_MAX_PAYLOAD) {
221 sigma_dut_print(dut, DUT_MSG_ERROR,
222 "payload too large(%u, max %u)",
223 length, WIL_WMI_MAX_PAYLOAD);
224 return -1;
225 }
226
227 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
228 cmd.hdr.cmd = command;
229 memcpy(cmd.payload, payload, length);
230
231 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
232 sigma_dut_print(dut, DUT_MSG_ERROR,
233 "failed to get wil6210 debugfs dir");
234 return -1;
235 }
236
237 snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
238 f = fopen(fname, "wb");
239 if (!f) {
240 sigma_dut_print(dut, DUT_MSG_ERROR,
241 "failed to open: %s", fname);
242 return -1;
243 }
244
245 towrite = sizeof(cmd.hdr) + length;
246 written = fwrite(&cmd, 1, towrite, f);
247 fclose(f);
248 if (written != towrite) {
249 sigma_dut_print(dut, DUT_MSG_ERROR,
250 "failed to send wmi %u", command);
251 return -1;
252 }
253
254 return 0;
255}
256
257
258static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
259 const char *pattern, unsigned int *field)
260{
261 char buf[128], fname[128];
262 FILE *f;
263 regex_t re;
264 regmatch_t m[2];
265 int rc, ret = -1;
266
267 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
268 sigma_dut_print(dut, DUT_MSG_ERROR,
269 "failed to get wil6210 debugfs dir");
270 return -1;
271 }
272
273 snprintf(fname, sizeof(fname), "%s/stations", buf);
274 f = fopen(fname, "r");
275 if (!f) {
276 sigma_dut_print(dut, DUT_MSG_ERROR,
277 "failed to open: %s", fname);
278 return -1;
279 }
280
281 if (regcomp(&re, pattern, REG_EXTENDED)) {
282 sigma_dut_print(dut, DUT_MSG_ERROR,
283 "regcomp failed: %s", pattern);
284 goto out;
285 }
286
287 /*
288 * find the entry for the mac address
289 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
290 */
291 while (fgets(buf, sizeof(buf), f)) {
292 if (strcasestr(buf, bssid)) {
293 /* extract the field (CID/AID/state) */
294 rc = regexec(&re, buf, 2, m, 0);
295 if (!rc && (m[1].rm_so >= 0)) {
296 buf[m[1].rm_eo] = 0;
297 *field = atoi(&buf[m[1].rm_so]);
298 ret = 0;
299 break;
300 }
301 }
302 }
303
304 regfree(&re);
305 if (ret)
306 sigma_dut_print(dut, DUT_MSG_ERROR,
307 "could not extract field");
308
309out:
310 fclose(f);
311
312 return ret;
313}
314
315
316static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
317 unsigned int *cid)
318{
319 const char *pattern = "\\[([0-9]+)\\]";
320
321 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
322}
323
324
325static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
326 int l_rx)
327{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700328 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200329 unsigned int cid;
330
Rakesh Sunki556237d2017-03-30 14:49:31 -0700331 memset(&cmd, 0, sizeof(cmd));
332
Lior David0fe101e2017-03-09 16:09:50 +0200333 if (wil6210_get_cid(dut, mac, &cid))
334 return -1;
335
336 cmd.bf_type = WIL_WMI_BRP_RX;
337 cmd.sta_id = cid;
338 /* training length (l_rx) is ignored, FW always uses length 16 */
339 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
340 &cmd, sizeof(cmd));
341}
342
343
344static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
345{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700346 struct wil_wmi_bf_trig_cmd cmd;
347
348 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200349
350 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
351 return -1;
352
353 cmd.bf_type = WIL_WMI_SLS;
354 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
355 &cmd, sizeof(cmd));
356}
357
Lior Davidcc88b562017-01-03 18:52:09 +0200358#endif /* __linux__ */
359
360
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200361static void static_ip_file(int proto, const char *addr, const char *mask,
362 const char *gw)
363{
364 if (proto) {
365 FILE *f = fopen("static-ip", "w");
366 if (f) {
367 fprintf(f, "%d %s %s %s\n", proto, addr,
368 mask ? mask : "N/A",
369 gw ? gw : "N/A");
370 fclose(f);
371 }
372 } else {
373 unlink("static-ip");
374 }
375}
376
377
378static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
379 const char *ssid)
380{
381#ifdef __linux__
382 char buf[100];
383
384 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
385 intf, ssid);
386 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
387
388 if (system(buf) != 0) {
389 sigma_dut_print(dut, DUT_MSG_ERROR,
390 "iwpriv neighbor request failed");
391 return -1;
392 }
393
394 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
395
396 return 0;
397#else /* __linux__ */
398 return -1;
399#endif /* __linux__ */
400}
401
402
403static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530404 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200405{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530406 const char *val;
407 int reason_code = 0;
408 char buf[1024];
409
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200410 /*
411 * In the earlier builds we used WNM_QUERY and in later
412 * builds used WNM_BSS_QUERY.
413 */
414
Ashwini Patil5acd7382017-04-13 15:55:04 +0530415 val = get_param(cmd, "BTMQuery_Reason_Code");
416 if (val)
417 reason_code = atoi(val);
418
419 val = get_param(cmd, "Cand_List");
420 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
421 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
422 dut->btm_query_cand_list);
423 free(dut->btm_query_cand_list);
424 dut->btm_query_cand_list = NULL;
425 } else {
426 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
427 }
428
429 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200430 sigma_dut_print(dut, DUT_MSG_ERROR,
431 "transition management query failed");
432 return -1;
433 }
434
435 sigma_dut_print(dut, DUT_MSG_DEBUG,
436 "transition management query sent");
437
438 return 0;
439}
440
441
442int is_ip_addr(const char *str)
443{
444 const char *pos = str;
445 struct in_addr addr;
446
447 while (*pos) {
448 if (*pos != '.' && (*pos < '0' || *pos > '9'))
449 return 0;
450 pos++;
451 }
452
453 return inet_aton(str, &addr);
454}
455
456
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200457int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
458 size_t buf_len)
459{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530460 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200461 char ip[16], mask[15], dns[16], sec_dns[16];
462 int is_dhcp = 0;
463 int s;
464#ifdef ANDROID
465 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530466#else /* ANDROID */
467 FILE *f;
468#ifdef __linux__
469 const char *str_ps;
470#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200471#endif /* ANDROID */
472
473 ip[0] = '\0';
474 mask[0] = '\0';
475 dns[0] = '\0';
476 sec_dns[0] = '\0';
477
478 s = socket(PF_INET, SOCK_DGRAM, 0);
479 if (s >= 0) {
480 struct ifreq ifr;
481 struct sockaddr_in saddr;
482
483 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700484 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200485 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
486 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
487 "%s IP address: %s",
488 ifname, strerror(errno));
489 } else {
490 memcpy(&saddr, &ifr.ifr_addr,
491 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700492 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200493 }
494
495 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
496 memcpy(&saddr, &ifr.ifr_addr,
497 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700498 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200499 }
500 close(s);
501 }
502
503#ifdef ANDROID
504 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
505 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
506 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
507 if (property_get(tmp, prop, NULL) != 0 &&
508 strcmp(prop, "ok") == 0) {
509 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
510 ifname);
511 if (property_get(tmp, prop, NULL) != 0 &&
512 strcmp(ip, prop) == 0)
513 is_dhcp = 1;
514 }
515 }
516
517 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700518 if (property_get(tmp, prop, NULL) != 0)
519 strlcpy(dns, prop, sizeof(dns));
520 else if (property_get("net.dns1", prop, NULL) != 0)
521 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200522
523 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700524 if (property_get(tmp, prop, NULL) != 0)
525 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200526#else /* ANDROID */
527#ifdef __linux__
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530528 if (get_driver_type() == DRIVER_OPENWRT)
529 str_ps = "ps -w";
530 else
531 str_ps = "ps ax";
532 snprintf(tmp, sizeof(tmp),
533 "%s | grep dhclient | grep -v grep | grep -q %s",
534 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200535 if (system(tmp) == 0)
536 is_dhcp = 1;
537 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530538 snprintf(tmp, sizeof(tmp),
539 "%s | grep udhcpc | grep -v grep | grep -q %s",
540 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200541 if (system(tmp) == 0)
542 is_dhcp = 1;
543 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530544 snprintf(tmp, sizeof(tmp),
545 "%s | grep dhcpcd | grep -v grep | grep -q %s",
546 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200547 if (system(tmp) == 0)
548 is_dhcp = 1;
549 }
550 }
551#endif /* __linux__ */
552
553 f = fopen("/etc/resolv.conf", "r");
554 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +0530555 char *pos, *pos2;
556
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200557 while (fgets(tmp, sizeof(tmp), f)) {
558 if (strncmp(tmp, "nameserver", 10) != 0)
559 continue;
560 pos = tmp + 10;
561 while (*pos == ' ' || *pos == '\t')
562 pos++;
563 pos2 = pos;
564 while (*pos2) {
565 if (*pos2 == '\n' || *pos2 == '\r') {
566 *pos2 = '\0';
567 break;
568 }
569 pos2++;
570 }
Peng Xub8fc5cc2017-05-10 17:27:28 -0700571 if (!dns[0])
572 strlcpy(dns, pos, sizeof(dns));
573 else if (!sec_dns[0])
574 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200575 }
576 fclose(f);
577 }
578#endif /* ANDROID */
579
580 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
581 is_dhcp, ip, mask, dns);
582 buf[buf_len - 1] = '\0';
583
584 return 0;
585}
586
587
588
589
590int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
591 size_t buf_len)
592{
593#ifdef __linux__
594#ifdef ANDROID
595 char cmd[200], result[1000], *pos, *end;
596 FILE *f;
597 size_t len;
598
599 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
600 f = popen(cmd, "r");
601 if (f == NULL)
602 return -1;
603 len = fread(result, 1, sizeof(result) - 1, f);
604 pclose(f);
605 if (len == 0)
606 return -1;
607 result[len] = '\0';
608 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
609
610 pos = strstr(result, "inet6 ");
611 if (pos == NULL)
612 return -1;
613 pos += 6;
614 end = strchr(pos, ' ');
615 if (end)
616 *end = '\0';
617 end = strchr(pos, '/');
618 if (end)
619 *end = '\0';
620 snprintf(buf, buf_len, "ip,%s", pos);
621 buf[buf_len - 1] = '\0';
622 return 0;
623#else /* ANDROID */
624 struct ifaddrs *ifaddr, *ifa;
625 int res, found = 0;
626 char host[NI_MAXHOST];
627
628 if (getifaddrs(&ifaddr) < 0) {
629 perror("getifaddrs");
630 return -1;
631 }
632
633 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
634 if (strcasecmp(ifname, ifa->ifa_name) != 0)
635 continue;
636 if (ifa->ifa_addr == NULL ||
637 ifa->ifa_addr->sa_family != AF_INET6)
638 continue;
639
640 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
641 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
642 if (res != 0) {
643 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
644 gai_strerror(res));
645 continue;
646 }
647 if (strncmp(host, "fe80::", 6) == 0)
648 continue; /* skip link-local */
649
650 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
651 found = 1;
652 break;
653 }
654
655 freeifaddrs(ifaddr);
656
657 if (found) {
658 char *pos;
659 pos = strchr(host, '%');
660 if (pos)
661 *pos = '\0';
662 snprintf(buf, buf_len, "ip,%s", host);
663 buf[buf_len - 1] = '\0';
664 return 0;
665 }
666
667#endif /* ANDROID */
668#endif /* __linux__ */
669 return -1;
670}
671
672
673static int cmd_sta_get_ip_config(struct sigma_dut *dut,
674 struct sigma_conn *conn,
675 struct sigma_cmd *cmd)
676{
677 const char *intf = get_param(cmd, "Interface");
678 const char *ifname;
679 char buf[200];
680 const char *val;
681 int type = 1;
682
683 if (intf == NULL)
684 return -1;
685
686 if (strcmp(intf, get_main_ifname()) == 0)
687 ifname = get_station_ifname();
688 else
689 ifname = intf;
690
691 /*
692 * UCC may assume the IP address to be available immediately after
693 * association without trying to run sta_get_ip_config multiple times.
694 * Sigma CAPI does not specify this command as a block command that
695 * would wait for the address to become available, but to pass tests
696 * more reliably, it looks like such a wait may be needed here.
697 */
698 if (wait_ip_addr(dut, ifname, 15) < 0) {
699 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
700 "for sta_get_ip_config");
701 /*
702 * Try to continue anyway since many UCC tests do not really
703 * care about the return value from here..
704 */
705 }
706
707 val = get_param(cmd, "Type");
708 if (val)
709 type = atoi(val);
710 if (type == 2 || dut->last_set_ip_config_ipv6) {
711 int i;
712
713 /*
714 * Since we do not have proper wait for IPv6 addresses, use a
715 * fixed two second delay here as a workaround for UCC script
716 * assuming IPv6 address is available when this command returns.
717 * Some scripts did not use Type,2 properly for IPv6, so include
718 * also the cases where the previous sta_set_ip_config indicated
719 * use of IPv6.
720 */
721 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
722 for (i = 0; i < 10; i++) {
723 sleep(1);
724 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
725 {
726 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
727 send_resp(dut, conn, SIGMA_COMPLETE, buf);
728#ifdef ANDROID
729 sigma_dut_print(dut, DUT_MSG_INFO,
730 "Adding IPv6 rule on Android");
731 add_ipv6_rule(dut, intf);
732#endif /* ANDROID */
733
734 return 0;
735 }
736 }
737 }
738 if (type == 1) {
739 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
740 return -2;
741 } else if (type == 2) {
742 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
743 return -2;
744 } else {
745 send_resp(dut, conn, SIGMA_ERROR,
746 "errorCode,Unsupported address type");
747 return 0;
748 }
749
750 send_resp(dut, conn, SIGMA_COMPLETE, buf);
751 return 0;
752}
753
754
755static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
756{
757#ifdef __linux__
758 char buf[200];
759 char path[128];
760 struct stat s;
761
762#ifdef ANDROID
763 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
764#else /* ANDROID */
765 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
766#endif /* ANDROID */
767 if (stat(path, &s) == 0) {
768 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
769 sigma_dut_print(dut, DUT_MSG_INFO,
770 "Kill previous DHCP client: %s", buf);
771 if (system(buf) != 0)
772 sigma_dut_print(dut, DUT_MSG_INFO,
773 "Failed to kill DHCP client");
774 unlink(path);
775 sleep(1);
776 } else {
777 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
778
779 if (stat(path, &s) == 0) {
780 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
781 sigma_dut_print(dut, DUT_MSG_INFO,
782 "Kill previous DHCP client: %s", buf);
783 if (system(buf) != 0)
784 sigma_dut_print(dut, DUT_MSG_INFO,
785 "Failed to kill DHCP client");
786 unlink(path);
787 sleep(1);
788 }
789 }
790#endif /* __linux__ */
791}
792
793
794static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
795{
796#ifdef __linux__
797 char buf[200];
798
799#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +0530800 if (access("/system/bin/dhcpcd", F_OK) != -1) {
801 snprintf(buf, sizeof(buf),
802 "/system/bin/dhcpcd -b %s", ifname);
803 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
804 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
805 } else {
806 sigma_dut_print(dut, DUT_MSG_ERROR,
807 "DHCP client program missing");
808 return 0;
809 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200810#else /* ANDROID */
811 snprintf(buf, sizeof(buf),
812 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
813 ifname, ifname);
814#endif /* ANDROID */
815 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
816 if (system(buf) != 0) {
817 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
818 if (system(buf) != 0) {
819 sigma_dut_print(dut, DUT_MSG_INFO,
820 "Failed to start DHCP client");
821#ifndef ANDROID
822 return -1;
823#endif /* ANDROID */
824 }
825 }
826#endif /* __linux__ */
827
828 return 0;
829}
830
831
832static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
833{
834#ifdef __linux__
835 char buf[200];
836
837 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
838 if (system(buf) != 0) {
839 sigma_dut_print(dut, DUT_MSG_INFO,
840 "Failed to clear IP addresses");
841 return -1;
842 }
843#endif /* __linux__ */
844
845 return 0;
846}
847
848
849#ifdef ANDROID
850static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
851{
852 char cmd[200], *result, *pos;
853 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530854 int tableid;
855 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200856
857 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
858 ifname);
859 fp = popen(cmd, "r");
860 if (fp == NULL)
861 return -1;
862
863 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530864 if (result == NULL) {
865 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200866 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530867 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200868
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530869 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200870 fclose(fp);
871
872 if (len == 0) {
873 free(result);
874 return -1;
875 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530876 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200877
878 pos = strstr(result, "table ");
879 if (pos == NULL) {
880 free(result);
881 return -1;
882 }
883
884 pos += strlen("table ");
885 tableid = atoi(pos);
886 if (tableid != 0) {
887 if (system("ip -6 rule del prio 22000") != 0) {
888 /* ignore any error */
889 }
890 snprintf(cmd, sizeof(cmd),
891 "ip -6 rule add from all lookup %d prio 22000",
892 tableid);
893 if (system(cmd) != 0) {
894 sigma_dut_print(dut, DUT_MSG_INFO,
895 "Failed to run %s", cmd);
896 free(result);
897 return -1;
898 }
899 } else {
900 sigma_dut_print(dut, DUT_MSG_INFO,
901 "No Valid Table Id found %s", pos);
902 free(result);
903 return -1;
904 }
905 free(result);
906
907 return 0;
908}
909#endif /* ANDROID */
910
911
Ankita Bajaj1bde7942018-01-09 19:15:01 +0530912int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
913 const char *ip, const char *mask)
914{
915 char buf[200];
916
917 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
918 ifname, ip, mask);
919 return system(buf) == 0;
920}
921
922
923int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
924{
925 char buf[200];
926
927 if (!is_ip_addr(gw)) {
928 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
929 return -1;
930 }
931
932 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
933 if (!dut->no_ip_addr_set && system(buf) != 0) {
934 snprintf(buf, sizeof(buf), "ip ro re default via %s",
935 gw);
936 if (system(buf) != 0)
937 return 0;
938 }
939
940 return 1;
941}
942
943
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200944static int cmd_sta_set_ip_config(struct sigma_dut *dut,
945 struct sigma_conn *conn,
946 struct sigma_cmd *cmd)
947{
948 const char *intf = get_param(cmd, "Interface");
949 const char *ifname;
950 char buf[200];
951 const char *val, *ip, *mask, *gw;
952 int type = 1;
953
954 if (intf == NULL)
955 return -1;
956
957 if (strcmp(intf, get_main_ifname()) == 0)
958 ifname = get_station_ifname();
959 else
960 ifname = intf;
961
962 if (if_nametoindex(ifname) == 0) {
963 send_resp(dut, conn, SIGMA_ERROR,
964 "ErrorCode,Unknown interface");
965 return 0;
966 }
967
968 val = get_param(cmd, "Type");
969 if (val) {
970 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +0530971 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200972 send_resp(dut, conn, SIGMA_ERROR,
973 "ErrorCode,Unsupported address type");
974 return 0;
975 }
976 }
977
978 dut->last_set_ip_config_ipv6 = 0;
979
980 val = get_param(cmd, "dhcp");
981 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
982 static_ip_file(0, NULL, NULL, NULL);
983#ifdef __linux__
984 if (type == 2) {
985 dut->last_set_ip_config_ipv6 = 1;
986 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
987 "stateless address autoconfiguration");
988#ifdef ANDROID
989 /*
990 * This sleep is required as the assignment in case of
991 * Android is taking time and is done by the kernel.
992 * The subsequent ping for IPv6 is impacting HS20 test
993 * case.
994 */
995 sleep(2);
996 add_ipv6_rule(dut, intf);
997#endif /* ANDROID */
998 /* Assume this happens by default */
999 return 1;
1000 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301001 if (type != 3) {
1002 kill_dhcp_client(dut, ifname);
1003 if (start_dhcp_client(dut, ifname) < 0)
1004 return -2;
1005 } else {
1006 sigma_dut_print(dut, DUT_MSG_DEBUG,
1007 "Using FILS HLP DHCPv4 Rapid Commit");
1008 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001009
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001010 return 1;
1011#endif /* __linux__ */
1012 return -2;
1013 }
1014
1015 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301016 if (!ip) {
1017 send_resp(dut, conn, SIGMA_INVALID,
1018 "ErrorCode,Missing IP address");
1019 return 0;
1020 }
1021
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001022 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301023 if (!mask) {
1024 send_resp(dut, conn, SIGMA_INVALID,
1025 "ErrorCode,Missing subnet mask");
1026 return 0;
1027 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001028
1029 if (type == 2) {
1030 int net = atoi(mask);
1031
1032 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1033 return -1;
1034
1035 if (dut->no_ip_addr_set) {
1036 snprintf(buf, sizeof(buf),
1037 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1038 ifname);
1039 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1040 if (system(buf) != 0) {
1041 sigma_dut_print(dut, DUT_MSG_DEBUG,
1042 "Failed to disable IPv6 address before association");
1043 }
1044 } else {
1045 snprintf(buf, sizeof(buf),
1046 "ip -6 addr del %s/%s dev %s",
1047 ip, mask, ifname);
1048 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1049 if (system(buf) != 0) {
1050 /*
1051 * This command may fail if the address being
1052 * deleted does not exist. Inaction here is
1053 * intentional.
1054 */
1055 }
1056
1057 snprintf(buf, sizeof(buf),
1058 "ip -6 addr add %s/%s dev %s",
1059 ip, mask, ifname);
1060 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1061 if (system(buf) != 0) {
1062 send_resp(dut, conn, SIGMA_ERROR,
1063 "ErrorCode,Failed to set IPv6 address");
1064 return 0;
1065 }
1066 }
1067
1068 dut->last_set_ip_config_ipv6 = 1;
1069 static_ip_file(6, ip, mask, NULL);
1070 return 1;
1071 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301072 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001073 return -1;
1074 }
1075
1076 kill_dhcp_client(dut, ifname);
1077
1078 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301079 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001080 send_resp(dut, conn, SIGMA_ERROR,
1081 "ErrorCode,Failed to set IP address");
1082 return 0;
1083 }
1084 }
1085
1086 gw = get_param(cmd, "defaultGateway");
1087 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301088 if (set_ipv4_gw(dut, gw) < 1) {
1089 send_resp(dut, conn, SIGMA_ERROR,
1090 "ErrorCode,Failed to set default gateway");
1091 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001092 }
1093 }
1094
1095 val = get_param(cmd, "primary-dns");
1096 if (val) {
1097 /* TODO */
1098 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1099 "setting", val);
1100 }
1101
1102 val = get_param(cmd, "secondary-dns");
1103 if (val) {
1104 /* TODO */
1105 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1106 "setting", val);
1107 }
1108
1109 static_ip_file(4, ip, mask, gw);
1110
1111 return 1;
1112}
1113
1114
1115static int cmd_sta_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
1116 struct sigma_cmd *cmd)
1117{
1118 /* const char *intf = get_param(cmd, "Interface"); */
1119 /* TODO: could report more details here */
1120 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1121 return 0;
1122}
1123
1124
1125static int cmd_sta_get_mac_address(struct sigma_dut *dut,
1126 struct sigma_conn *conn,
1127 struct sigma_cmd *cmd)
1128{
1129 /* const char *intf = get_param(cmd, "Interface"); */
1130 char addr[20], resp[50];
1131
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301132 if (dut->dev_role == DEVROLE_STA_CFON)
1133 return sta_cfon_get_mac_address(dut, conn, cmd);
1134
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001135 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
1136 < 0)
1137 return -2;
1138
1139 snprintf(resp, sizeof(resp), "mac,%s", addr);
1140 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1141 return 0;
1142}
1143
1144
1145static int cmd_sta_is_connected(struct sigma_dut *dut, struct sigma_conn *conn,
1146 struct sigma_cmd *cmd)
1147{
1148 /* const char *intf = get_param(cmd, "Interface"); */
1149 int connected = 0;
1150 char result[32];
1151 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
1152 sizeof(result)) < 0) {
1153 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get interface "
1154 "%s status", get_station_ifname());
1155 return -2;
1156 }
1157
1158 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1159 if (strncmp(result, "COMPLETED", 9) == 0)
1160 connected = 1;
1161
1162 if (connected)
1163 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1164 else
1165 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1166
1167 return 0;
1168}
1169
1170
1171static int cmd_sta_verify_ip_connection(struct sigma_dut *dut,
1172 struct sigma_conn *conn,
1173 struct sigma_cmd *cmd)
1174{
1175 /* const char *intf = get_param(cmd, "Interface"); */
1176 const char *dst, *timeout;
1177 int wait_time = 90;
1178 char buf[100];
1179 int res;
1180
1181 dst = get_param(cmd, "destination");
1182 if (dst == NULL || !is_ip_addr(dst))
1183 return -1;
1184
1185 timeout = get_param(cmd, "timeout");
1186 if (timeout) {
1187 wait_time = atoi(timeout);
1188 if (wait_time < 1)
1189 wait_time = 1;
1190 }
1191
1192 /* TODO: force renewal of IP lease if DHCP is enabled */
1193
1194 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1195 res = system(buf);
1196 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1197 if (res == 0)
1198 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1199 else if (res == 256)
1200 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1201 else
1202 return -2;
1203
1204 return 0;
1205}
1206
1207
1208static int cmd_sta_get_bssid(struct sigma_dut *dut, struct sigma_conn *conn,
1209 struct sigma_cmd *cmd)
1210{
1211 /* const char *intf = get_param(cmd, "Interface"); */
1212 char bssid[20], resp[50];
1213
1214 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
1215 < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001216 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001217
1218 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1219 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1220 return 0;
1221}
1222
1223
1224#ifdef __SAMSUNG__
1225static int add_use_network(const char *ifname)
1226{
1227 char buf[100];
1228
1229 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1230 wpa_command(ifname, buf);
1231 return 0;
1232}
1233#endif /* __SAMSUNG__ */
1234
1235
1236static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1237 const char *ifname, struct sigma_cmd *cmd)
1238{
1239 const char *ssid = get_param(cmd, "ssid");
1240 int id;
1241 const char *val;
1242
1243 if (ssid == NULL)
1244 return -1;
1245
1246 start_sta_mode(dut);
1247
1248#ifdef __SAMSUNG__
1249 add_use_network(ifname);
1250#endif /* __SAMSUNG__ */
1251
1252 id = add_network(ifname);
1253 if (id < 0)
1254 return -2;
1255 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1256
1257 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1258 return -2;
1259
1260 dut->infra_network_id = id;
1261 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1262
1263 val = get_param(cmd, "program");
1264 if (!val)
1265 val = get_param(cmd, "prog");
1266 if (val && strcasecmp(val, "hs2") == 0) {
1267 char buf[100];
1268 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1269 wpa_command(ifname, buf);
1270
1271 val = get_param(cmd, "prefer");
1272 if (val && atoi(val) > 0)
1273 set_network(ifname, id, "priority", "1");
1274 }
1275
1276 return id;
1277}
1278
1279
1280static int cmd_sta_set_encryption(struct sigma_dut *dut,
1281 struct sigma_conn *conn,
1282 struct sigma_cmd *cmd)
1283{
1284 const char *intf = get_param(cmd, "Interface");
1285 const char *ssid = get_param(cmd, "ssid");
1286 const char *type = get_param(cmd, "encpType");
1287 const char *ifname;
1288 char buf[200];
1289 int id;
1290
1291 if (intf == NULL || ssid == NULL)
1292 return -1;
1293
1294 if (strcmp(intf, get_main_ifname()) == 0)
1295 ifname = get_station_ifname();
1296 else
1297 ifname = intf;
1298
1299 id = add_network_common(dut, conn, ifname, cmd);
1300 if (id < 0)
1301 return id;
1302
1303 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1304 return -2;
1305
1306 if (type && strcasecmp(type, "wep") == 0) {
1307 const char *val;
1308 int i;
1309
1310 val = get_param(cmd, "activeKey");
1311 if (val) {
1312 int keyid;
1313 keyid = atoi(val);
1314 if (keyid < 1 || keyid > 4)
1315 return -1;
1316 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1317 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1318 return -2;
1319 }
1320
1321 for (i = 0; i < 4; i++) {
1322 snprintf(buf, sizeof(buf), "key%d", i + 1);
1323 val = get_param(cmd, buf);
1324 if (val == NULL)
1325 continue;
1326 snprintf(buf, sizeof(buf), "wep_key%d", i);
1327 if (set_network(ifname, id, buf, val) < 0)
1328 return -2;
1329 }
1330 }
1331
1332 return 1;
1333}
1334
1335
1336static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1337 const char *ifname, struct sigma_cmd *cmd)
1338{
1339 const char *val;
1340 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001341 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001342 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301343 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001344
1345 id = add_network_common(dut, conn, ifname, cmd);
1346 if (id < 0)
1347 return id;
1348
Jouni Malinen47dcc952017-10-09 16:43:24 +03001349 val = get_param(cmd, "Type");
1350 owe = val && strcasecmp(val, "OWE") == 0;
1351
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001352 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001353 if (!val && owe)
1354 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001355 if (val == NULL) {
1356 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Missing keyMgmtType");
1357 return 0;
1358 }
1359 if (strcasecmp(val, "wpa") == 0 ||
1360 strcasecmp(val, "wpa-psk") == 0) {
1361 if (set_network(ifname, id, "proto", "WPA") < 0)
1362 return -2;
1363 } else if (strcasecmp(val, "wpa2") == 0 ||
1364 strcasecmp(val, "wpa2-psk") == 0 ||
1365 strcasecmp(val, "wpa2-ft") == 0 ||
1366 strcasecmp(val, "wpa2-sha256") == 0) {
1367 if (set_network(ifname, id, "proto", "WPA2") < 0)
1368 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301369 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1370 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001371 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1372 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001373 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301374 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001375 if (set_network(ifname, id, "proto", "WPA2") < 0)
1376 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001377 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001378 } else {
1379 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1380 return 0;
1381 }
1382
1383 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001384 if (val) {
1385 cipher_set = 1;
1386 if (strcasecmp(val, "tkip") == 0) {
1387 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1388 return -2;
1389 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1390 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1391 return -2;
1392 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1393 if (set_network(ifname, id, "pairwise",
1394 "CCMP TKIP") < 0)
1395 return -2;
1396 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1397 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1398 return -2;
1399 if (set_network(ifname, id, "group", "GCMP") < 0)
1400 return -2;
1401 } else {
1402 send_resp(dut, conn, SIGMA_ERROR,
1403 "errorCode,Unrecognized encpType value");
1404 return 0;
1405 }
1406 }
1407
1408 val = get_param(cmd, "PairwiseCipher");
1409 if (val) {
1410 cipher_set = 1;
1411 /* TODO: Support space separated list */
1412 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1413 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1414 return -2;
1415 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1416 if (set_network(ifname, id, "pairwise",
1417 "CCMP-256") < 0)
1418 return -2;
1419 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1420 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1421 return -2;
1422 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1423 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1424 return -2;
1425 } else {
1426 send_resp(dut, conn, SIGMA_ERROR,
1427 "errorCode,Unrecognized PairwiseCipher value");
1428 return 0;
1429 }
1430 }
1431
Jouni Malinen47dcc952017-10-09 16:43:24 +03001432 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001433 send_resp(dut, conn, SIGMA_ERROR,
1434 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001435 return 0;
1436 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001437
1438 val = get_param(cmd, "GroupCipher");
1439 if (val) {
1440 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1441 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1442 return -2;
1443 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1444 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1445 return -2;
1446 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1447 if (set_network(ifname, id, "group", "GCMP") < 0)
1448 return -2;
1449 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1450 if (set_network(ifname, id, "group", "CCMP") < 0)
1451 return -2;
1452 } else {
1453 send_resp(dut, conn, SIGMA_ERROR,
1454 "errorCode,Unrecognized GroupCipher value");
1455 return 0;
1456 }
1457 }
1458
Jouni Malinen7b239522017-09-14 21:37:18 +03001459 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001460 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001461 const char *cipher;
1462
1463 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1464 cipher = "BIP-GMAC-256";
1465 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1466 cipher = "BIP-CMAC-256";
1467 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1468 cipher = "BIP-GMAC-128";
1469 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1470 cipher = "AES-128-CMAC";
1471 } else {
1472 send_resp(dut, conn, SIGMA_INVALID,
1473 "errorCode,Unsupported GroupMgntCipher");
1474 return 0;
1475 }
1476 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1477 send_resp(dut, conn, SIGMA_INVALID,
1478 "errorCode,Failed to set GroupMgntCipher");
1479 return 0;
1480 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001481 }
1482
1483 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301484
1485 if (dut->program == PROGRAM_OCE) {
1486 dut->sta_pmf = STA_PMF_OPTIONAL;
1487 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1488 return -2;
1489 }
1490
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001491 val = get_param(cmd, "PMF");
1492 if (val) {
1493 if (strcasecmp(val, "Required") == 0 ||
1494 strcasecmp(val, "Forced_Required") == 0) {
1495 dut->sta_pmf = STA_PMF_REQUIRED;
1496 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1497 return -2;
1498 } else if (strcasecmp(val, "Optional") == 0) {
1499 dut->sta_pmf = STA_PMF_OPTIONAL;
1500 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1501 return -2;
1502 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08001503 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001504 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);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002236 if (strcasecmp(type, "wep") == 0)
2237 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002238
2239 send_resp(dut, conn, SIGMA_ERROR,
2240 "ErrorCode,Unsupported Type value");
2241 return 0;
2242}
2243
2244
2245int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2246{
2247#ifdef __linux__
2248 /* special handling for ath6kl */
2249 char path[128], fname[128], *pos;
2250 ssize_t res;
2251 FILE *f;
2252
2253 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", intf);
2254 res = readlink(path, path, sizeof(path));
2255 if (res < 0)
2256 return 0; /* not ath6kl */
2257
2258 if (res >= (int) sizeof(path))
2259 res = sizeof(path) - 1;
2260 path[res] = '\0';
2261 pos = strrchr(path, '/');
2262 if (pos == NULL)
2263 pos = path;
2264 else
2265 pos++;
2266 snprintf(fname, sizeof(fname),
2267 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2268 "create_qos", pos);
2269 if (!file_exists(fname))
2270 return 0; /* not ath6kl */
2271
2272 if (uapsd) {
2273 f = fopen(fname, "w");
2274 if (f == NULL)
2275 return -1;
2276
2277 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2278 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2279 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2280 "20000 0\n");
2281 fclose(f);
2282 } else {
2283 snprintf(fname, sizeof(fname),
2284 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2285 "delete_qos", pos);
2286
2287 f = fopen(fname, "w");
2288 if (f == NULL)
2289 return -1;
2290
2291 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2292 fprintf(f, "2 4\n");
2293 fclose(f);
2294 }
2295#endif /* __linux__ */
2296
2297 return 0;
2298}
2299
2300
2301static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
2302 struct sigma_cmd *cmd)
2303{
2304 const char *intf = get_param(cmd, "Interface");
2305 /* const char *ssid = get_param(cmd, "ssid"); */
2306 const char *val;
2307 int max_sp_len = 4;
2308 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2309 char buf[100];
2310 int ret1, ret2;
2311
2312 val = get_param(cmd, "maxSPLength");
2313 if (val) {
2314 max_sp_len = atoi(val);
2315 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2316 max_sp_len != 4)
2317 return -1;
2318 }
2319
2320 val = get_param(cmd, "acBE");
2321 if (val)
2322 ac_be = atoi(val);
2323
2324 val = get_param(cmd, "acBK");
2325 if (val)
2326 ac_bk = atoi(val);
2327
2328 val = get_param(cmd, "acVI");
2329 if (val)
2330 ac_vi = atoi(val);
2331
2332 val = get_param(cmd, "acVO");
2333 if (val)
2334 ac_vo = atoi(val);
2335
2336 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2337
2338 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2339 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2340 ret1 = wpa_command(intf, buf);
2341
2342 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2343 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2344 ret2 = wpa_command(intf, buf);
2345
2346 if (ret1 && ret2) {
2347 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2348 "UAPSD parameters.");
2349 return -2;
2350 }
2351
2352 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2353 send_resp(dut, conn, SIGMA_ERROR,
2354 "ErrorCode,Failed to set ath6kl QoS parameters");
2355 return 0;
2356 }
2357
2358 return 1;
2359}
2360
2361
2362static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
2363 struct sigma_cmd *cmd)
2364{
2365 char buf[1000];
2366 const char *intf = get_param(cmd, "Interface");
2367 const char *grp = get_param(cmd, "Group");
2368 const char *act = get_param(cmd, "Action");
2369 const char *tid = get_param(cmd, "Tid");
2370 const char *dir = get_param(cmd, "Direction");
2371 const char *psb = get_param(cmd, "Psb");
2372 const char *up = get_param(cmd, "Up");
2373 const char *fixed = get_param(cmd, "Fixed");
2374 const char *size = get_param(cmd, "Size");
2375 const char *msize = get_param(cmd, "Maxsize");
2376 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2377 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2378 const char *inact = get_param(cmd, "Inactivity");
2379 const char *sus = get_param(cmd, "Suspension");
2380 const char *mindr = get_param(cmd, "Mindatarate");
2381 const char *meandr = get_param(cmd, "Meandatarate");
2382 const char *peakdr = get_param(cmd, "Peakdatarate");
2383 const char *phyrate = get_param(cmd, "Phyrate");
2384 const char *burstsize = get_param(cmd, "Burstsize");
2385 const char *sba = get_param(cmd, "Sba");
2386 int direction;
2387 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002388 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002389 int fixed_int;
2390 int psb_ts;
2391
2392 if (intf == NULL || grp == NULL || act == NULL )
2393 return -1;
2394
2395 if (strcasecmp(act, "addts") == 0) {
2396 if (tid == NULL || dir == NULL || psb == NULL ||
2397 up == NULL || fixed == NULL || size == NULL)
2398 return -1;
2399
2400 /*
2401 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
2402 * possible values, but WMM-AC and V-E test scripts use "UP,
2403 * "DOWN", and "BIDI".
2404 */
2405 if (strcasecmp(dir, "uplink") == 0 ||
2406 strcasecmp(dir, "up") == 0) {
2407 direction = 0;
2408 } else if (strcasecmp(dir, "downlink") == 0 ||
2409 strcasecmp(dir, "down") == 0) {
2410 direction = 1;
2411 } else if (strcasecmp(dir, "bidi") == 0) {
2412 direction = 2;
2413 } else {
2414 sigma_dut_print(dut, DUT_MSG_ERROR,
2415 "Direction %s not supported", dir);
2416 return -1;
2417 }
2418
2419 if (strcasecmp(psb, "legacy") == 0) {
2420 psb_ts = 0;
2421 } else if (strcasecmp(psb, "uapsd") == 0) {
2422 psb_ts = 1;
2423 } else {
2424 sigma_dut_print(dut, DUT_MSG_ERROR,
2425 "PSB %s not supported", psb);
2426 return -1;
2427 }
2428
2429 if (atoi(tid) < 0 || atoi(tid) > 7) {
2430 sigma_dut_print(dut, DUT_MSG_ERROR,
2431 "TID %s not supported", tid);
2432 return -1;
2433 }
2434
2435 if (strcasecmp(fixed, "true") == 0) {
2436 fixed_int = 1;
2437 } else {
2438 fixed_int = 0;
2439 }
2440
Peng Xu93319622017-10-04 17:58:16 -07002441 if (sba)
2442 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002443
2444 dut->dialog_token++;
2445 handle = 7000 + dut->dialog_token;
2446
2447 /*
2448 * size: convert to hex
2449 * maxsi: convert to hex
2450 * mindr: convert to hex
2451 * meandr: convert to hex
2452 * peakdr: convert to hex
2453 * burstsize: convert to hex
2454 * phyrate: convert to hex
2455 * sba: convert to hex with modification
2456 * minsi: convert to integer
2457 * sus: convert to integer
2458 * inact: convert to integer
2459 * maxsi: convert to integer
2460 */
2461
2462 /*
2463 * The Nominal MSDU Size field is 2 octets long and contains an
2464 * unsigned integer that specifies the nominal size, in octets,
2465 * of MSDUs belonging to the traffic under this traffic
2466 * specification and is defined in Figure 16. If the Fixed
2467 * subfield is set to 1, then the size of the MSDU is fixed and
2468 * is indicated by the Size Subfield. If the Fixed subfield is
2469 * set to 0, then the size of the MSDU might not be fixed and
2470 * the Size indicates the nominal MSDU size.
2471 *
2472 * The Surplus Bandwidth Allowance Factor field is 2 octets long
2473 * and specifies the excess allocation of time (and bandwidth)
2474 * over and above the stated rates required to transport an MSDU
2475 * belonging to the traffic in this TSPEC. This field is
2476 * represented as an unsigned binary number with an implicit
2477 * binary point after the leftmost 3 bits. For example, an SBA
2478 * of 1.75 is represented as 0x3800. This field is included to
2479 * account for retransmissions. As such, the value of this field
2480 * must be greater than unity.
2481 */
2482
2483 snprintf(buf, sizeof(buf),
2484 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
2485 " 0x%X 0x%X 0x%X"
2486 " 0x%X 0x%X 0x%X"
2487 " 0x%X %d %d %d %d"
2488 " %d %d",
2489 intf, handle, tid, direction, psb_ts, up,
2490 (unsigned int) ((fixed_int << 15) | atoi(size)),
2491 msize ? atoi(msize) : 0,
2492 mindr ? atoi(mindr) : 0,
2493 meandr ? atoi(meandr) : 0,
2494 peakdr ? atoi(peakdr) : 0,
2495 burstsize ? atoi(burstsize) : 0,
2496 phyrate ? atoi(phyrate) : 0,
2497 sba ? ((unsigned int) (((int) sba_fv << 13) |
2498 (int)((sba_fv - (int) sba_fv) *
2499 8192))) : 0,
2500 minsi ? atoi(minsi) : 0,
2501 sus ? atoi(sus) : 0,
2502 0, 0,
2503 inact ? atoi(inact) : 0,
2504 maxsi ? atoi(maxsi) : 0);
2505
2506 if (system(buf) != 0) {
2507 sigma_dut_print(dut, DUT_MSG_ERROR,
2508 "iwpriv addtspec request failed");
2509 send_resp(dut, conn, SIGMA_ERROR,
2510 "errorCode,Failed to execute addTspec command");
2511 return 0;
2512 }
2513
2514 sigma_dut_print(dut, DUT_MSG_INFO,
2515 "iwpriv addtspec request send");
2516
2517 /* Mapping handle to a TID */
2518 dut->tid_to_handle[atoi(tid)] = handle;
2519 } else if (strcasecmp(act, "delts") == 0) {
2520 if (tid == NULL)
2521 return -1;
2522
2523 if (atoi(tid) < 0 || atoi(tid) > 7) {
2524 sigma_dut_print(dut, DUT_MSG_ERROR,
2525 "TID %s not supported", tid);
2526 send_resp(dut, conn, SIGMA_ERROR,
2527 "errorCode,Unsupported TID");
2528 return 0;
2529 }
2530
2531 handle = dut->tid_to_handle[atoi(tid)];
2532
2533 if (handle < 7000 || handle > 7255) {
2534 /* Invalid handle ie no mapping for that TID */
2535 sigma_dut_print(dut, DUT_MSG_ERROR,
2536 "handle-> %d not found", handle);
2537 }
2538
2539 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
2540 intf, handle);
2541
2542 if (system(buf) != 0) {
2543 sigma_dut_print(dut, DUT_MSG_ERROR,
2544 "iwpriv deltspec request failed");
2545 send_resp(dut, conn, SIGMA_ERROR,
2546 "errorCode,Failed to execute delTspec command");
2547 return 0;
2548 }
2549
2550 sigma_dut_print(dut, DUT_MSG_INFO,
2551 "iwpriv deltspec request send");
2552
2553 dut->tid_to_handle[atoi(tid)] = 0;
2554 } else {
2555 sigma_dut_print(dut, DUT_MSG_ERROR,
2556 "Action type %s not supported", act);
2557 send_resp(dut, conn, SIGMA_ERROR,
2558 "errorCode,Unsupported Action");
2559 return 0;
2560 }
2561
2562 return 1;
2563}
2564
2565
vamsi krishna52e16f92017-08-29 12:37:34 +05302566static int find_network(struct sigma_dut *dut, const char *ssid)
2567{
2568 char list[4096];
2569 char *pos;
2570
2571 sigma_dut_print(dut, DUT_MSG_DEBUG,
2572 "Search for profile based on SSID: '%s'", ssid);
2573 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
2574 list, sizeof(list)) < 0)
2575 return -1;
2576 pos = strstr(list, ssid);
2577 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
2578 return -1;
2579
2580 while (pos > list && pos[-1] != '\n')
2581 pos--;
2582 dut->infra_network_id = atoi(pos);
2583 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
2584 return 0;
2585}
2586
2587
Sunil Dutt44595082018-02-12 19:41:45 +05302588#ifdef NL80211_SUPPORT
2589static int sta_config_rsnie(struct sigma_dut *dut, int val)
2590{
2591 struct nl_msg *msg;
2592 int ret;
2593 struct nlattr *params;
2594 int ifindex;
2595
2596 ifindex = if_nametoindex("wlan0");
2597 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
2598 NL80211_CMD_VENDOR)) ||
2599 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
2600 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
2601 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
2602 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
2603 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
2604 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
2605 sigma_dut_print(dut, DUT_MSG_ERROR,
2606 "%s: err in adding vendor_cmd and vendor_data",
2607 __func__);
2608 nlmsg_free(msg);
2609 return -1;
2610 }
2611 nla_nest_end(msg, params);
2612
2613 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
2614 if (ret) {
2615 sigma_dut_print(dut, DUT_MSG_ERROR,
2616 "%s: err in send_and_recv_msgs, ret=%d",
2617 __func__, ret);
2618 return ret;
2619 }
2620
2621 return 0;
2622}
2623#endif /* NL80211_SUPPORT */
2624
2625
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002626static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
2627 struct sigma_cmd *cmd)
2628{
2629 /* const char *intf = get_param(cmd, "Interface"); */
2630 const char *ssid = get_param(cmd, "ssid");
2631 const char *wps_param = get_param(cmd, "WPS");
2632 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03002633 const char *chan = get_param(cmd, "channel");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002634 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03002635 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002636
2637 if (ssid == NULL)
2638 return -1;
2639
Jouni Malinen3c367e82017-06-23 17:01:47 +03002640 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05302641#ifdef NL80211_SUPPORT
2642 if (get_driver_type() == DRIVER_WCN) {
2643 sta_config_rsnie(dut, 1);
2644 dut->config_rsnie = 1;
2645 }
2646#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03002647 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
2648 dut->rsne_override);
2649 if (wpa_command(get_station_ifname(), buf) < 0) {
2650 send_resp(dut, conn, SIGMA_ERROR,
2651 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
2652 return 0;
2653 }
2654 }
2655
Jouni Malinen68143132017-09-02 02:34:08 +03002656 if (dut->sae_commit_override) {
2657 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
2658 dut->sae_commit_override);
2659 if (wpa_command(get_station_ifname(), buf) < 0) {
2660 send_resp(dut, conn, SIGMA_ERROR,
2661 "ErrorCode,Failed to set SAE commit override");
2662 return 0;
2663 }
2664 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05302665#ifdef ANDROID
2666 if (dut->fils_hlp)
2667 process_fils_hlp(dut);
2668#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03002669
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002670 if (wps_param &&
2671 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
2672 wps = 1;
2673
2674 if (wps) {
2675 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
2676 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
2677 "parameters not yet set");
2678 return 0;
2679 }
2680 if (dut->wps_method == WFA_CS_WPS_PBC) {
2681 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
2682 return -2;
2683 } else {
2684 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
2685 dut->wps_pin);
2686 if (wpa_command(get_station_ifname(), buf) < 0)
2687 return -2;
2688 }
2689 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05302690 if (strcmp(ssid, dut->infra_ssid) == 0) {
2691 sigma_dut_print(dut, DUT_MSG_DEBUG,
2692 "sta_associate for the most recently added network");
2693 } else if (find_network(dut, ssid) < 0) {
2694 sigma_dut_print(dut, DUT_MSG_DEBUG,
2695 "sta_associate for a previously stored network profile");
2696 send_resp(dut, conn, SIGMA_ERROR,
2697 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002698 return 0;
2699 }
2700
2701 if (bssid &&
2702 set_network(get_station_ifname(), dut->infra_network_id,
2703 "bssid", bssid) < 0) {
2704 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2705 "Invalid bssid argument");
2706 return 0;
2707 }
2708
Jouni Malinen46a19b62017-06-23 14:31:27 +03002709 extra[0] = '\0';
2710 if (chan)
2711 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02002712 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03002713 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
2714 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002715 if (wpa_command(get_station_ifname(), buf) < 0) {
2716 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
2717 "network id %d on %s",
2718 dut->infra_network_id,
2719 get_station_ifname());
2720 return -2;
2721 }
2722 }
2723
2724 return 1;
2725}
2726
2727
2728static int run_hs20_osu(struct sigma_dut *dut, const char *params)
2729{
2730 char buf[500], cmd[200];
2731 int res;
2732
2733 /* Use hs20-osu-client file at the current dir, if found; otherwise use
2734 * default path */
2735 res = snprintf(cmd, sizeof(cmd),
2736 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
2737 file_exists("./hs20-osu-client") ?
2738 "./hs20-osu-client" : "hs20-osu-client",
2739 sigma_wpas_ctrl,
2740 dut->summary_log ? "-s " : "",
2741 dut->summary_log ? dut->summary_log : "");
2742 if (res < 0 || res >= (int) sizeof(cmd))
2743 return -1;
2744
2745 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
2746 if (res < 0 || res >= (int) sizeof(buf))
2747 return -1;
2748 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
2749
2750 if (system(buf) != 0) {
2751 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
2752 return -1;
2753 }
2754 sigma_dut_print(dut, DUT_MSG_DEBUG,
2755 "Completed hs20-osu-client operation");
2756
2757 return 0;
2758}
2759
2760
2761static int download_ppsmo(struct sigma_dut *dut,
2762 struct sigma_conn *conn,
2763 const char *intf,
2764 struct sigma_cmd *cmd)
2765{
2766 const char *name, *path, *val;
2767 char url[500], buf[600], fbuf[100];
2768 char *fqdn = NULL;
2769
2770 name = get_param(cmd, "FileName");
2771 path = get_param(cmd, "FilePath");
2772 if (name == NULL || path == NULL)
2773 return -1;
2774
2775 if (strcasecmp(path, "VendorSpecific") == 0) {
2776 snprintf(url, sizeof(url), "PPS/%s", name);
2777 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
2778 "from the device (%s)", url);
2779 if (!file_exists(url)) {
2780 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2781 "PPS MO file does not exist");
2782 return 0;
2783 }
2784 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
2785 if (system(buf) != 0) {
2786 send_resp(dut, conn, SIGMA_ERROR,
2787 "errorCode,Failed to copy PPS MO");
2788 return 0;
2789 }
2790 } else if (strncasecmp(path, "http:", 5) != 0 &&
2791 strncasecmp(path, "https:", 6) != 0) {
2792 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2793 "Unsupported FilePath value");
2794 return 0;
2795 } else {
2796 snprintf(url, sizeof(url), "%s/%s", path, name);
2797 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
2798 url);
2799 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
2800 remove("pps-tnds.xml");
2801 if (system(buf) != 0) {
2802 send_resp(dut, conn, SIGMA_ERROR,
2803 "errorCode,Failed to download PPS MO");
2804 return 0;
2805 }
2806 }
2807
2808 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
2809 send_resp(dut, conn, SIGMA_ERROR,
2810 "errorCode,Failed to parse downloaded PPSMO");
2811 return 0;
2812 }
2813 unlink("pps-tnds.xml");
2814
2815 val = get_param(cmd, "managementTreeURI");
2816 if (val) {
2817 const char *pos, *end;
2818 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
2819 val);
2820 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
2821 send_resp(dut, conn, SIGMA_ERROR,
2822 "errorCode,Invalid managementTreeURI prefix");
2823 return 0;
2824 }
2825 pos = val + 8;
2826 end = strchr(pos, '/');
2827 if (end == NULL ||
2828 strcmp(end, "/PerProviderSubscription") != 0) {
2829 send_resp(dut, conn, SIGMA_ERROR,
2830 "errorCode,Invalid managementTreeURI postfix");
2831 return 0;
2832 }
2833 if (end - pos >= (int) sizeof(fbuf)) {
2834 send_resp(dut, conn, SIGMA_ERROR,
2835 "errorCode,Too long FQDN in managementTreeURI");
2836 return 0;
2837 }
2838 memcpy(fbuf, pos, end - pos);
2839 fbuf[end - pos] = '\0';
2840 fqdn = fbuf;
2841 sigma_dut_print(dut, DUT_MSG_INFO,
2842 "FQDN from managementTreeURI: %s", fqdn);
2843 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
2844 FILE *f = fopen("pps-fqdn", "r");
2845 if (f) {
2846 if (fgets(fbuf, sizeof(fbuf), f)) {
2847 fbuf[sizeof(fbuf) - 1] = '\0';
2848 fqdn = fbuf;
2849 sigma_dut_print(dut, DUT_MSG_DEBUG,
2850 "Use FQDN %s", fqdn);
2851 }
2852 fclose(f);
2853 }
2854 }
2855
2856 if (fqdn == NULL) {
2857 send_resp(dut, conn, SIGMA_ERROR,
2858 "errorCode,No FQDN specified");
2859 return 0;
2860 }
2861
2862 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2863 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
2864 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2865
2866 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
2867 if (rename("pps.xml", buf) < 0) {
2868 send_resp(dut, conn, SIGMA_ERROR,
2869 "errorCode,Could not move PPS MO");
2870 return 0;
2871 }
2872
2873 if (strcasecmp(path, "VendorSpecific") == 0) {
2874 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
2875 fqdn);
2876 if (system(buf)) {
2877 send_resp(dut, conn, SIGMA_ERROR,
2878 "errorCode,Failed to copy OSU CA cert");
2879 return 0;
2880 }
2881
2882 snprintf(buf, sizeof(buf),
2883 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
2884 fqdn);
2885 if (system(buf)) {
2886 send_resp(dut, conn, SIGMA_ERROR,
2887 "errorCode,Failed to copy AAA CA cert");
2888 return 0;
2889 }
2890 } else {
2891 snprintf(buf, sizeof(buf),
2892 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
2893 fqdn, fqdn);
2894 if (run_hs20_osu(dut, buf) < 0) {
2895 send_resp(dut, conn, SIGMA_ERROR,
2896 "errorCode,Failed to download OSU CA cert");
2897 return 0;
2898 }
2899
2900 snprintf(buf, sizeof(buf),
2901 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
2902 fqdn, fqdn);
2903 if (run_hs20_osu(dut, buf) < 0) {
2904 sigma_dut_print(dut, DUT_MSG_INFO,
2905 "Failed to download AAA CA cert");
2906 }
2907 }
2908
2909 if (file_exists("next-client-cert.pem")) {
2910 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
2911 if (rename("next-client-cert.pem", buf) < 0) {
2912 send_resp(dut, conn, SIGMA_ERROR,
2913 "errorCode,Could not move client certificate");
2914 return 0;
2915 }
2916 }
2917
2918 if (file_exists("next-client-key.pem")) {
2919 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
2920 if (rename("next-client-key.pem", buf) < 0) {
2921 send_resp(dut, conn, SIGMA_ERROR,
2922 "errorCode,Could not move client key");
2923 return 0;
2924 }
2925 }
2926
2927 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
2928 if (run_hs20_osu(dut, buf) < 0) {
2929 send_resp(dut, conn, SIGMA_ERROR,
2930 "errorCode,Failed to configure credential from "
2931 "PPSMO");
2932 return 0;
2933 }
2934
2935 return 1;
2936}
2937
2938
2939static int download_cert(struct sigma_dut *dut,
2940 struct sigma_conn *conn,
2941 const char *intf,
2942 struct sigma_cmd *cmd)
2943{
2944 const char *name, *path;
2945 char url[500], buf[600];
2946
2947 name = get_param(cmd, "FileName");
2948 path = get_param(cmd, "FilePath");
2949 if (name == NULL || path == NULL)
2950 return -1;
2951
2952 if (strcasecmp(path, "VendorSpecific") == 0) {
2953 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
2954 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2955 "certificate from the device (%s)", url);
2956 if (!file_exists(url)) {
2957 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2958 "certificate file does not exist");
2959 return 0;
2960 }
2961 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
2962 if (system(buf) != 0) {
2963 send_resp(dut, conn, SIGMA_ERROR,
2964 "errorCode,Failed to copy client "
2965 "certificate");
2966 return 0;
2967 }
2968
2969 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
2970 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2971 "private key from the device (%s)", url);
2972 if (!file_exists(url)) {
2973 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2974 "private key file does not exist");
2975 return 0;
2976 }
2977 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
2978 if (system(buf) != 0) {
2979 send_resp(dut, conn, SIGMA_ERROR,
2980 "errorCode,Failed to copy client key");
2981 return 0;
2982 }
2983 } else if (strncasecmp(path, "http:", 5) != 0 &&
2984 strncasecmp(path, "https:", 6) != 0) {
2985 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2986 "Unsupported FilePath value");
2987 return 0;
2988 } else {
2989 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
2990 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
2991 "certificate/key from %s", url);
2992 snprintf(buf, sizeof(buf),
2993 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
2994 if (system(buf) != 0) {
2995 send_resp(dut, conn, SIGMA_ERROR,
2996 "errorCode,Failed to download client "
2997 "certificate");
2998 return 0;
2999 }
3000
3001 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3002 {
3003 send_resp(dut, conn, SIGMA_ERROR,
3004 "errorCode,Failed to copy client key");
3005 return 0;
3006 }
3007 }
3008
3009 return 1;
3010}
3011
3012
3013static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3014 struct sigma_conn *conn,
3015 const char *intf,
3016 struct sigma_cmd *cmd)
3017{
3018 const char *val;
3019
3020 val = get_param(cmd, "FileType");
3021 if (val && strcasecmp(val, "PPSMO") == 0)
3022 return download_ppsmo(dut, conn, intf, cmd);
3023 if (val && strcasecmp(val, "CERT") == 0)
3024 return download_cert(dut, conn, intf, cmd);
3025 if (val) {
3026 send_resp(dut, conn, SIGMA_ERROR,
3027 "ErrorCode,Unsupported FileType");
3028 return 0;
3029 }
3030
3031 return 1;
3032}
3033
3034
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303035static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3036 struct sigma_conn *conn,
3037 const char *intf,
3038 struct sigma_cmd *cmd)
3039{
3040 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303041 char buf[1000];
3042 char text[20];
3043 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303044
3045 val = get_param(cmd, "OCESupport");
3046 if (val && strcasecmp(val, "Disable") == 0) {
3047 if (wpa_command(intf, "SET oce 0") < 0) {
3048 send_resp(dut, conn, SIGMA_ERROR,
3049 "ErrorCode,Failed to disable OCE");
3050 return 0;
3051 }
3052 } else if (val && strcasecmp(val, "Enable") == 0) {
3053 if (wpa_command(intf, "SET oce 1") < 0) {
3054 send_resp(dut, conn, SIGMA_ERROR,
3055 "ErrorCode,Failed to enable OCE");
3056 return 0;
3057 }
3058 }
3059
vamsi krishnaa2799492017-12-05 14:28:01 +05303060 val = get_param(cmd, "FILScap");
3061 if (val && (atoi(val) == 1)) {
3062 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3063 send_resp(dut, conn, SIGMA_ERROR,
3064 "ErrorCode,Failed to enable FILS");
3065 return 0;
3066 }
3067 } else if (val && (atoi(val) == 0)) {
3068 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3069 send_resp(dut, conn, SIGMA_ERROR,
3070 "ErrorCode,Failed to disable FILS");
3071 return 0;
3072 }
3073 }
3074
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303075 val = get_param(cmd, "FILSHLP");
3076 if (val && strcasecmp(val, "Enable") == 0) {
3077 if (get_wpa_status(get_station_ifname(), "address", text,
3078 sizeof(text)) < 0)
3079 return -2;
3080 hwaddr_aton(text, addr);
3081 snprintf(buf, sizeof(buf),
3082 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3083 "080045100140000040004011399e00000000ffffffff00440043"
3084 "012cb30001010600fd4f46410000000000000000000000000000"
3085 "000000000000"
3086 "%02x%02x%02x%02x%02x%02x"
3087 "0000000000000000000000000000000000000000000000000000"
3088 "0000000000000000000000000000000000000000000000000000"
3089 "0000000000000000000000000000000000000000000000000000"
3090 "0000000000000000000000000000000000000000000000000000"
3091 "0000000000000000000000000000000000000000000000000000"
3092 "0000000000000000000000000000000000000000000000000000"
3093 "0000000000000000000000000000000000000000000000000000"
3094 "0000000000000000000000000000000000000000638253633501"
3095 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3096 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3097 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3098 if (wpa_command(intf, buf)) {
3099 send_resp(dut, conn, SIGMA_ERROR,
3100 "ErrorCode,Failed to add HLP");
3101 return 0;
3102 }
3103 dut->fils_hlp = 1;
3104 }
3105
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303106 return 1;
3107}
3108
3109
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003110static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3111 const char *val)
3112{
3113 int counter = 0;
3114 char token[50];
3115 char *result;
3116 char buf[100];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303117 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003118
Peng Xub8fc5cc2017-05-10 17:27:28 -07003119 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003120 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303121 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003122 while (result) {
3123 if (strcmp(result, "disable") == 0) {
3124 snprintf(buf, sizeof(buf),
3125 "iwpriv %s noackpolicy %d 1 0",
3126 intf, counter);
3127 } else {
3128 snprintf(buf, sizeof(buf),
3129 "iwpriv %s noackpolicy %d 1 1",
3130 intf, counter);
3131 }
3132 if (system(buf) != 0) {
3133 sigma_dut_print(dut, DUT_MSG_ERROR,
3134 "iwpriv noackpolicy failed");
3135 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303136 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003137 counter++;
3138 }
3139}
3140
3141
3142static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3143 const char *val)
3144{
3145 char buf[100];
3146
3147 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3148 if (system(buf) != 0) {
3149 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3150 }
3151}
3152
3153
3154static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3155 const char *val)
3156{
3157 char buf[100];
3158
3159 if (strcasecmp(val, "off") == 0) {
3160 snprintf(buf, sizeof(buf), "iwpriv %s wmm 0", intf);
3161 if (system(buf) != 0) {
3162 sigma_dut_print(dut, DUT_MSG_ERROR,
3163 "Failed to turn off WMM");
3164 }
3165 }
3166}
3167
3168
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003169static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3170 const char *val)
3171{
3172#ifdef NL80211_SUPPORT
3173 struct nl_msg *msg;
3174 int ret = 0;
3175 struct nlattr *params;
3176 int ifindex;
3177 int wmmenable = 1;
3178
3179 if (val &&
3180 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3181 wmmenable = 0;
3182
3183 ifindex = if_nametoindex(intf);
3184 if (ifindex == 0) {
3185 sigma_dut_print(dut, DUT_MSG_ERROR,
3186 "%s: Index for interface %s failed",
3187 __func__, intf);
3188 return -1;
3189 }
3190
3191 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3192 NL80211_CMD_VENDOR)) ||
3193 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3194 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3195 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3196 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3197 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3198 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
3199 wmmenable)) {
3200 sigma_dut_print(dut, DUT_MSG_ERROR,
3201 "%s: err in adding vendor_cmd and vendor_data",
3202 __func__);
3203 nlmsg_free(msg);
3204 return -1;
3205 }
3206 nla_nest_end(msg, params);
3207
3208 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3209 if (ret) {
3210 sigma_dut_print(dut, DUT_MSG_ERROR,
3211 "%s: err in send_and_recv_msgs, ret=%d",
3212 __func__, ret);
3213 }
3214 return ret;
3215#else /* NL80211_SUPPORT */
3216 sigma_dut_print(dut, DUT_MSG_ERROR,
3217 "WMM cannot be changed without NL80211_SUPPORT defined");
3218 return -1;
3219#endif /* NL80211_SUPPORT */
3220}
3221
3222
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003223static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3224 const char *val)
3225{
3226 char buf[100];
3227 int sgi20;
3228
3229 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3230
3231 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi20);
3232 if (system(buf) != 0)
3233 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv shortgi failed");
3234}
3235
3236
3237static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3238 const char *val)
3239{
3240 char buf[100];
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303241 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003242
3243 /* Disable Tx Beam forming when using a fixed rate */
3244 ath_disable_txbf(dut, intf);
3245
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303246 v = atoi(val);
3247 if (v < 0 || v > 32) {
3248 sigma_dut_print(dut, DUT_MSG_ERROR,
3249 "Invalid Fixed MCS rate: %d", v);
3250 return;
3251 }
3252 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003253
3254 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0x%x",
3255 intf, rate_code);
3256 if (system(buf) != 0) {
3257 sigma_dut_print(dut, DUT_MSG_ERROR,
3258 "iwpriv set11NRates failed");
3259 }
3260
3261 /* Channel width gets messed up, fix this */
3262 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d", intf, dut->chwidth);
3263 if (system(buf) != 0)
3264 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
3265}
3266
3267
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08003268static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3269 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003270{
3271 char buf[60];
3272
3273 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3274 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3275 else
3276 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3277
3278 if (system(buf) != 0)
3279 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3280}
3281
3282
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003283static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3284 int ampdu)
3285{
3286 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003287 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003288
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003289 if (ampdu)
3290 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003291 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3292 if (system(buf) != 0) {
3293 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3294 return -1;
3295 }
3296
3297 return 0;
3298}
3299
3300
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003301static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3302 const char *val)
3303{
3304 char buf[60];
3305
3306 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3307 if (system(buf) != 0) {
3308 sigma_dut_print(dut, DUT_MSG_ERROR,
3309 "iwpriv tx_stbc failed");
3310 }
3311
3312 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3313 if (system(buf) != 0) {
3314 sigma_dut_print(dut, DUT_MSG_ERROR,
3315 "iwpriv rx_stbc failed");
3316 }
3317}
3318
3319
3320static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3321 const char *val)
3322{
3323 char buf[60];
3324
Peng Xucc317ed2017-05-18 16:44:37 -07003325 if (strcmp(val, "160") == 0) {
3326 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3327 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003328 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3329 } else if (strcmp(val, "40") == 0) {
3330 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3331 } else if (strcmp(val, "20") == 0) {
3332 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3333 } else if (strcasecmp(val, "Auto") == 0) {
3334 buf[0] = '\0';
3335 } else {
3336 sigma_dut_print(dut, DUT_MSG_ERROR,
3337 "WIDTH/CTS_WIDTH value not supported");
3338 return -1;
3339 }
3340
3341 if (buf[0] != '\0' && system(buf) != 0) {
3342 sigma_dut_print(dut, DUT_MSG_ERROR,
3343 "Failed to set WIDTH/CTS_WIDTH");
3344 return -1;
3345 }
3346
3347 return 0;
3348}
3349
3350
3351int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3352 const char *intf, const char *val)
3353{
3354 char buf[60];
3355
3356 if (strcasecmp(val, "Auto") == 0) {
3357 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3358 dut->chwidth = 0;
3359 } else if (strcasecmp(val, "20") == 0) {
3360 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3361 dut->chwidth = 0;
3362 } else if (strcasecmp(val, "40") == 0) {
3363 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
3364 dut->chwidth = 1;
3365 } else if (strcasecmp(val, "80") == 0) {
3366 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
3367 dut->chwidth = 2;
3368 } else if (strcasecmp(val, "160") == 0) {
3369 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 3", intf);
3370 dut->chwidth = 3;
3371 } else {
3372 send_resp(dut, conn, SIGMA_ERROR,
3373 "ErrorCode,WIDTH not supported");
3374 return -1;
3375 }
3376
3377 if (system(buf) != 0) {
3378 sigma_dut_print(dut, DUT_MSG_ERROR,
3379 "iwpriv chwidth failed");
3380 }
3381
3382 return 0;
3383}
3384
3385
3386static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3387 const char *val)
3388{
3389 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07003390 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003391
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003392 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003393 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003394 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003395 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003396 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003397 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003398 } else {
3399 sigma_dut_print(dut, DUT_MSG_ERROR,
3400 "SP_STREAM value not supported");
3401 return -1;
3402 }
3403
3404 if (system(buf) != 0) {
3405 sigma_dut_print(dut, DUT_MSG_ERROR,
3406 "Failed to set SP_STREAM");
3407 return -1;
3408 }
3409
Arif Hussainac6c5112018-05-25 17:34:00 -07003410 dut->sta_nss = sta_nss;
3411
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003412 return 0;
3413}
3414
3415
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303416static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3417 const char *val)
3418{
3419 char buf[60];
3420
3421 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3422 if (system(buf) != 0)
3423 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
3424
3425 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3426 if (system(buf) != 0)
3427 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
3428}
3429
3430
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303431static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
3432 struct sigma_conn *conn,
3433 const char *intf, int capa)
3434{
3435 char buf[32];
3436
3437 if (capa > 0 && capa < 4) {
3438 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
3439 if (wpa_command(intf, buf) < 0) {
3440 send_resp(dut, conn, SIGMA_ERROR,
3441 "ErrorCode, Failed to set cellular data capability");
3442 return 0;
3443 }
3444 return 1;
3445 }
3446
3447 sigma_dut_print(dut, DUT_MSG_ERROR,
3448 "Invalid Cellular data capability: %d", capa);
3449 send_resp(dut, conn, SIGMA_INVALID,
3450 "ErrorCode,Invalid cellular data capability");
3451 return 0;
3452}
3453
3454
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303455static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
3456 const char *intf, const char *val)
3457{
3458 if (strcasecmp(val, "Disable") == 0) {
3459 if (wpa_command(intf, "SET roaming 0") < 0) {
3460 send_resp(dut, conn, SIGMA_ERROR,
3461 "ErrorCode,Failed to disable roaming");
3462 return 0;
3463 }
3464 return 1;
3465 }
3466
3467 if (strcasecmp(val, "Enable") == 0) {
3468 if (wpa_command(intf, "SET roaming 1") < 0) {
3469 send_resp(dut, conn, SIGMA_ERROR,
3470 "ErrorCode,Failed to enable roaming");
3471 return 0;
3472 }
3473 return 1;
3474 }
3475
3476 sigma_dut_print(dut, DUT_MSG_ERROR,
3477 "Invalid value provided for roaming: %s", val);
3478 send_resp(dut, conn, SIGMA_INVALID,
3479 "ErrorCode,Unknown value provided for Roaming");
3480 return 0;
3481}
3482
3483
Ashwini Patila75de5a2017-04-13 16:35:05 +05303484static int mbo_set_assoc_disallow(struct sigma_dut *dut,
3485 struct sigma_conn *conn,
3486 const char *intf, const char *val)
3487{
3488 if (strcasecmp(val, "Disable") == 0) {
3489 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
3490 send_resp(dut, conn, SIGMA_ERROR,
3491 "ErrorCode,Failed to disable Assoc_disallow");
3492 return 0;
3493 }
3494 return 1;
3495 }
3496
3497 if (strcasecmp(val, "Enable") == 0) {
3498 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
3499 send_resp(dut, conn, SIGMA_ERROR,
3500 "ErrorCode,Failed to enable Assoc_disallow");
3501 return 0;
3502 }
3503 return 1;
3504 }
3505
3506 sigma_dut_print(dut, DUT_MSG_ERROR,
3507 "Invalid value provided for Assoc_disallow: %s", val);
3508 send_resp(dut, conn, SIGMA_INVALID,
3509 "ErrorCode,Unknown value provided for Assoc_disallow");
3510 return 0;
3511}
3512
3513
Ashwini Patilc63161e2017-04-13 16:30:23 +05303514static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
3515 const char *intf, const char *val)
3516{
3517 if (strcasecmp(val, "Reject") == 0) {
3518 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
3519 send_resp(dut, conn, SIGMA_ERROR,
3520 "ErrorCode,Failed to Reject BTM Request");
3521 return 0;
3522 }
3523 return 1;
3524 }
3525
3526 if (strcasecmp(val, "Accept") == 0) {
3527 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
3528 send_resp(dut, conn, SIGMA_ERROR,
3529 "ErrorCode,Failed to Accept BTM Request");
3530 return 0;
3531 }
3532 return 1;
3533 }
3534
3535 sigma_dut_print(dut, DUT_MSG_ERROR,
3536 "Invalid value provided for BSS_Transition: %s", val);
3537 send_resp(dut, conn, SIGMA_INVALID,
3538 "ErrorCode,Unknown value provided for BSS_Transition");
3539 return 0;
3540}
3541
3542
Ashwini Patil00402582017-04-13 12:29:39 +05303543static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
3544 struct sigma_conn *conn,
3545 const char *intf,
3546 struct sigma_cmd *cmd)
3547{
3548 const char *ch, *pref, *op_class, *reason;
3549 char buf[120];
3550 int len, ret;
3551
3552 pref = get_param(cmd, "Ch_Pref");
3553 if (!pref)
3554 return 1;
3555
3556 if (strcasecmp(pref, "clear") == 0) {
3557 free(dut->non_pref_ch_list);
3558 dut->non_pref_ch_list = NULL;
3559 } else {
3560 op_class = get_param(cmd, "Ch_Op_Class");
3561 if (!op_class) {
3562 send_resp(dut, conn, SIGMA_INVALID,
3563 "ErrorCode,Ch_Op_Class not provided");
3564 return 0;
3565 }
3566
3567 ch = get_param(cmd, "Ch_Pref_Num");
3568 if (!ch) {
3569 send_resp(dut, conn, SIGMA_INVALID,
3570 "ErrorCode,Ch_Pref_Num not provided");
3571 return 0;
3572 }
3573
3574 reason = get_param(cmd, "Ch_Reason_Code");
3575 if (!reason) {
3576 send_resp(dut, conn, SIGMA_INVALID,
3577 "ErrorCode,Ch_Reason_Code not provided");
3578 return 0;
3579 }
3580
3581 if (!dut->non_pref_ch_list) {
3582 dut->non_pref_ch_list =
3583 calloc(1, NON_PREF_CH_LIST_SIZE);
3584 if (!dut->non_pref_ch_list) {
3585 send_resp(dut, conn, SIGMA_ERROR,
3586 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
3587 return 0;
3588 }
3589 }
3590 len = strlen(dut->non_pref_ch_list);
3591 ret = snprintf(dut->non_pref_ch_list + len,
3592 NON_PREF_CH_LIST_SIZE - len,
3593 " %s:%s:%s:%s", op_class, ch, pref, reason);
3594 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
3595 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
3596 dut->non_pref_ch_list);
3597 } else {
3598 sigma_dut_print(dut, DUT_MSG_ERROR,
3599 "snprintf failed for non_pref_list, ret = %d",
3600 ret);
3601 send_resp(dut, conn, SIGMA_ERROR,
3602 "ErrorCode,snprintf failed");
3603 free(dut->non_pref_ch_list);
3604 dut->non_pref_ch_list = NULL;
3605 return 0;
3606 }
3607 }
3608
3609 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
3610 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
3611 if (ret < 0 || ret >= (int) sizeof(buf)) {
3612 sigma_dut_print(dut, DUT_MSG_DEBUG,
3613 "snprintf failed for set non_pref_chan, ret: %d",
3614 ret);
3615 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
3616 return 0;
3617 }
3618
3619 if (wpa_command(intf, buf) < 0) {
3620 send_resp(dut, conn, SIGMA_ERROR,
3621 "ErrorCode,Failed to set non-preferred channel list");
3622 return 0;
3623 }
3624
3625 return 1;
3626}
3627
3628
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003629#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003630
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003631static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
3632 enum he_fragmentation_val frag)
3633{
3634 struct nl_msg *msg;
3635 int ret = 0;
3636 struct nlattr *params;
3637 int ifindex;
3638
3639 ifindex = if_nametoindex(intf);
3640 if (ifindex == 0) {
3641 sigma_dut_print(dut, DUT_MSG_ERROR,
3642 "%s: Index for interface %s failed",
3643 __func__, intf);
3644 return -1;
3645 }
3646
3647 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3648 NL80211_CMD_VENDOR)) ||
3649 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3650 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3651 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3652 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3653 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3654 nla_put_u8(msg,
3655 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
3656 frag)) {
3657 sigma_dut_print(dut, DUT_MSG_ERROR,
3658 "%s: err in adding vendor_cmd and vendor_data",
3659 __func__);
3660 nlmsg_free(msg);
3661 return -1;
3662 }
3663 nla_nest_end(msg, params);
3664
3665 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3666 if (ret) {
3667 sigma_dut_print(dut, DUT_MSG_ERROR,
3668 "%s: err in send_and_recv_msgs, ret=%d",
3669 __func__, ret);
3670 }
3671 return ret;
3672}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003673
3674
Subhani Shaik8e7a3052018-04-24 14:03:00 -07003675static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
3676 enum qca_wlan_he_ltf_cfg ltf)
3677{
3678 struct nl_msg *msg;
3679 int ret = 0;
3680 struct nlattr *params;
3681 int ifindex;
3682
3683 ifindex = if_nametoindex(intf);
3684 if (ifindex == 0) {
3685 sigma_dut_print(dut, DUT_MSG_ERROR,
3686 "%s: Index for interface %s failed",
3687 __func__, intf);
3688 return -1;
3689 }
3690
3691 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3692 NL80211_CMD_VENDOR)) ||
3693 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3694 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3695 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3696 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3697 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3698 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
3699 ltf)) {
3700 sigma_dut_print(dut, DUT_MSG_ERROR,
3701 "%s: err in adding vendor_cmd and vendor_data",
3702 __func__);
3703 nlmsg_free(msg);
3704 return -1;
3705 }
3706 nla_nest_end(msg, params);
3707
3708 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3709 if (ret) {
3710 sigma_dut_print(dut, DUT_MSG_ERROR,
3711 "%s: err in send_and_recv_msgs, ret=%d",
3712 __func__, ret);
3713 }
3714 return ret;
3715}
3716
3717
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003718static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
3719 int noack, enum qca_wlan_ac_type ac)
3720{
3721 struct nl_msg *msg;
3722 int ret = 0;
3723 struct nlattr *params;
3724 int ifindex;
3725
3726 ifindex = if_nametoindex(intf);
3727 if (ifindex == 0) {
3728 sigma_dut_print(dut, DUT_MSG_ERROR,
3729 "%s: Index for interface %s failed",
3730 __func__, intf);
3731 return -1;
3732 }
3733
3734 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3735 NL80211_CMD_VENDOR)) ||
3736 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3737 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3738 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3739 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3740 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3741 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
3742 noack) ||
3743 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
3744 ac)) {
3745 sigma_dut_print(dut, DUT_MSG_ERROR,
3746 "%s: err in adding vendor_cmd and vendor_data",
3747 __func__);
3748 nlmsg_free(msg);
3749 return -1;
3750 }
3751 nla_nest_end(msg, params);
3752
3753 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3754 if (ret) {
3755 sigma_dut_print(dut, DUT_MSG_ERROR,
3756 "%s: err in send_and_recv_msgs, ret=%d",
3757 __func__, ret);
3758 }
3759 return ret;
3760}
3761
3762
3763static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
3764 const char *val)
3765{
3766 int noack, ret;
3767 char token[100];
3768 char *result;
3769 char *saveptr;
3770 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
3771
3772 strlcpy(token, val, sizeof(token));
3773 token[sizeof(token) - 1] = '\0';
3774 result = strtok_r(token, ":", &saveptr);
3775 while (result) {
3776 noack = strcasecmp(result, "Disable") != 0;
3777 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
3778 if (ret) {
3779 sigma_dut_print(dut, DUT_MSG_ERROR,
3780 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
3781 ac, ret);
3782 }
3783 result = strtok_r(NULL, ":", &saveptr);
3784 ac++;
3785 }
3786}
3787
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003788#endif /* NL80211_SUPPORT */
3789
3790
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003791static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
3792 struct sigma_conn *conn,
3793 struct sigma_cmd *cmd)
3794{
3795 const char *intf = get_param(cmd, "Interface");
3796 const char *val;
3797
3798 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03003799 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
3800 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003801 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
3802 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003803
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07003804 if (val && strcasecmp(val, "LOC") == 0)
3805 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
3806
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003807#ifdef ANDROID_NAN
3808 if (val && strcasecmp(val, "NAN") == 0)
3809 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
3810#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07003811#ifdef MIRACAST
3812 if (val && (strcasecmp(val, "WFD") == 0 ||
3813 strcasecmp(val, "DisplayR2") == 0))
3814 return miracast_preset_testparameters(dut, conn, cmd);
3815#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003816
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303817 if (val && strcasecmp(val, "MBO") == 0) {
3818 val = get_param(cmd, "Cellular_Data_Cap");
3819 if (val &&
3820 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
3821 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05303822
3823 val = get_param(cmd, "Ch_Pref");
3824 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
3825 return 0;
3826
Ashwini Patilc63161e2017-04-13 16:30:23 +05303827 val = get_param(cmd, "BSS_Transition");
3828 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
3829 return 0;
3830
Ashwini Patila75de5a2017-04-13 16:35:05 +05303831 val = get_param(cmd, "Assoc_Disallow");
3832 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
3833 return 0;
3834
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303835 val = get_param(cmd, "Roaming");
3836 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
3837 return 0;
3838
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303839 return 1;
3840 }
3841
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303842 if (val && strcasecmp(val, "OCE") == 0)
3843 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
3844
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003845#if 0
3846 val = get_param(cmd, "Supplicant");
3847 if (val && strcasecmp(val, "Default") != 0) {
3848 send_resp(dut, conn, SIGMA_ERROR,
3849 "ErrorCode,Only default(Vendor) supplicant "
3850 "supported");
3851 return 0;
3852 }
3853#endif
3854
3855 val = get_param(cmd, "RTS");
3856 if (val) {
3857 switch (get_driver_type()) {
3858 case DRIVER_ATHEROS:
3859 ath_sta_set_rts(dut, intf, val);
3860 break;
3861 default:
3862#if 0
3863 send_resp(dut, conn, SIGMA_ERROR,
3864 "ErrorCode,Setting RTS not supported");
3865 return 0;
3866#else
3867 sigma_dut_print(dut, DUT_MSG_DEBUG,
3868 "Setting RTS not supported");
3869 break;
3870#endif
3871 }
3872 }
3873
3874#if 0
3875 val = get_param(cmd, "FRGMNT");
3876 if (val) {
3877 /* TODO */
3878 send_resp(dut, conn, SIGMA_ERROR,
3879 "ErrorCode,Setting FRGMNT not supported");
3880 return 0;
3881 }
3882#endif
3883
3884#if 0
3885 val = get_param(cmd, "Preamble");
3886 if (val) {
3887 /* TODO: Long/Short */
3888 send_resp(dut, conn, SIGMA_ERROR,
3889 "ErrorCode,Setting Preamble not supported");
3890 return 0;
3891 }
3892#endif
3893
3894 val = get_param(cmd, "Mode");
3895 if (val) {
3896 if (strcmp(val, "11b") == 0 ||
3897 strcmp(val, "11g") == 0 ||
3898 strcmp(val, "11a") == 0 ||
3899 strcmp(val, "11n") == 0 ||
3900 strcmp(val, "11ng") == 0 ||
3901 strcmp(val, "11nl") == 0 ||
3902 strcmp(val, "11nl(nabg)") == 0 ||
3903 strcmp(val, "AC") == 0 ||
3904 strcmp(val, "11AC") == 0 ||
3905 strcmp(val, "11ac") == 0 ||
3906 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08003907 strcmp(val, "11an") == 0 ||
3908 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003909 /* STA supports all modes by default */
3910 } else {
3911 send_resp(dut, conn, SIGMA_ERROR,
3912 "ErrorCode,Setting Mode not supported");
3913 return 0;
3914 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08003915
3916 /* Change the mode only in case of testbed for HE program
3917 * and for 11a and 11g modes only. */
3918 if (dut->program == PROGRAM_HE &&
3919 dut->device_type == STA_testbed) {
3920 int phymode;
3921 char buf[60];
3922
3923 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08003924 phymode = 1; /* IEEE80211_MODE_11A */
3925 } else if (strcmp(val, "11g") == 0) {
3926 phymode = 3; /* IEEE80211_MODE_11G */
3927 } else if (strcmp(val, "11b") == 0) {
3928 phymode = 2; /* IEEE80211_MODE_11B */
3929 } else if (strcmp(val, "11n") == 0 ||
3930 strcmp(val, "11nl") == 0 ||
3931 strcmp(val, "11nl(nabg)") == 0) {
3932 phymode = 22; /* IEEE80211_MODE_11AGN */
3933 } else if (strcmp(val, "11ng") == 0) {
3934 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
3935 } else if (strcmp(val, "AC") == 0 ||
3936 strcasecmp(val, "11AC") == 0) {
3937 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
3938 } else if (strcmp(val, "11na") == 0 ||
3939 strcasecmp(val, "11an") == 0) {
3940 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
3941 } else if (strcmp(val, "11ax") == 0) {
3942 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08003943 } else {
3944 sigma_dut_print(dut, DUT_MSG_DEBUG,
3945 "Ignoring mode change for mode: %s",
3946 val);
3947 phymode = -1;
3948 }
3949 if (phymode != -1) {
3950 snprintf(buf, sizeof(buf),
3951 "iwpriv %s setphymode %d",
3952 intf, phymode);
3953 if (system(buf) != 0) {
3954 sigma_dut_print(dut, DUT_MSG_ERROR,
3955 "iwpriv setting of phymode failed");
3956 }
3957 }
3958 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003959 }
3960
3961 val = get_param(cmd, "wmm");
3962 if (val) {
3963 switch (get_driver_type()) {
3964 case DRIVER_ATHEROS:
3965 ath_sta_set_wmm(dut, intf, val);
3966 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003967 case DRIVER_WCN:
3968 wcn_sta_set_wmm(dut, intf, val);
3969 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003970 default:
3971 sigma_dut_print(dut, DUT_MSG_DEBUG,
3972 "Setting wmm not supported");
3973 break;
3974 }
3975 }
3976
3977 val = get_param(cmd, "Powersave");
3978 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08003979 char buf[60];
3980
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003981 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08003982 if (get_driver_type() == DRIVER_WCN) {
3983 snprintf(buf, sizeof(buf),
3984 "iwpriv %s setPower 2", intf);
3985 if (system(buf) != 0) {
3986 sigma_dut_print(dut, DUT_MSG_ERROR,
3987 "iwpriv setPower 2 failed");
3988 return 0;
3989 }
3990 }
3991
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003992 if (wpa_command(get_station_ifname(),
3993 "P2P_SET ps 0") < 0)
3994 return -2;
3995 /* Make sure test modes are disabled */
3996 wpa_command(get_station_ifname(), "P2P_SET ps 98");
3997 wpa_command(get_station_ifname(), "P2P_SET ps 96");
3998 } else if (strcmp(val, "1") == 0 ||
3999 strcasecmp(val, "PSPoll") == 0 ||
4000 strcasecmp(val, "on") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004001 if (get_driver_type() == DRIVER_WCN) {
4002 snprintf(buf, sizeof(buf),
4003 "iwpriv %s setPower 1", intf);
4004 if (system(buf) != 0) {
4005 sigma_dut_print(dut, DUT_MSG_ERROR,
4006 "iwpriv setPower 1 failed");
4007 return 0;
4008 }
4009 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004010 /* Disable default power save mode */
4011 wpa_command(get_station_ifname(), "P2P_SET ps 0");
4012 /* Enable PS-Poll test mode */
4013 if (wpa_command(get_station_ifname(),
4014 "P2P_SET ps 97") < 0 ||
4015 wpa_command(get_station_ifname(),
4016 "P2P_SET ps 99") < 0)
4017 return -2;
4018 } else if (strcmp(val, "2") == 0 ||
4019 strcasecmp(val, "Fast") == 0) {
4020 /* TODO */
4021 send_resp(dut, conn, SIGMA_ERROR,
4022 "ErrorCode,Powersave=Fast not supported");
4023 return 0;
4024 } else if (strcmp(val, "3") == 0 ||
4025 strcasecmp(val, "PSNonPoll") == 0) {
4026 /* Make sure test modes are disabled */
4027 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4028 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4029
4030 /* Enable default power save mode */
4031 if (wpa_command(get_station_ifname(),
4032 "P2P_SET ps 1") < 0)
4033 return -2;
4034 } else
4035 return -1;
4036 }
4037
4038 val = get_param(cmd, "NoAck");
4039 if (val) {
4040 switch (get_driver_type()) {
4041 case DRIVER_ATHEROS:
4042 ath_sta_set_noack(dut, intf, val);
4043 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004044#ifdef NL80211_SUPPORT
4045 case DRIVER_WCN:
4046 wcn_sta_set_noack(dut, intf, val);
4047 break;
4048#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004049 default:
4050 send_resp(dut, conn, SIGMA_ERROR,
4051 "ErrorCode,Setting NoAck not supported");
4052 return 0;
4053 }
4054 }
4055
4056 val = get_param(cmd, "IgnoreChswitchProhibit");
4057 if (val) {
4058 /* TODO: Enabled/disabled */
4059 if (strcasecmp(val, "Enabled") == 0) {
4060 send_resp(dut, conn, SIGMA_ERROR,
4061 "ErrorCode,Enabling IgnoreChswitchProhibit "
4062 "not supported");
4063 return 0;
4064 }
4065 }
4066
4067 val = get_param(cmd, "TDLS");
4068 if (val) {
4069 if (strcasecmp(val, "Disabled") == 0) {
4070 if (wpa_command(intf, "SET tdls_disabled 1")) {
4071 send_resp(dut, conn, SIGMA_ERROR,
4072 "ErrorCode,Failed to disable TDLS");
4073 return 0;
4074 }
4075 } else if (strcasecmp(val, "Enabled") == 0) {
4076 if (wpa_command(intf, "SET tdls_disabled 0")) {
4077 send_resp(dut, conn, SIGMA_ERROR,
4078 "ErrorCode,Failed to enable TDLS");
4079 return 0;
4080 }
4081 } else {
4082 send_resp(dut, conn, SIGMA_ERROR,
4083 "ErrorCode,Unsupported TDLS value");
4084 return 0;
4085 }
4086 }
4087
4088 val = get_param(cmd, "TDLSmode");
4089 if (val) {
4090 if (strcasecmp(val, "Default") == 0) {
4091 wpa_command(intf, "SET tdls_testing 0");
4092 } else if (strcasecmp(val, "APProhibit") == 0) {
4093 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4094 send_resp(dut, conn, SIGMA_ERROR,
4095 "ErrorCode,Failed to enable ignore "
4096 "APProhibit TDLS mode");
4097 return 0;
4098 }
4099 } else if (strcasecmp(val, "HiLoMac") == 0) {
4100 /* STA should respond with TDLS setup req for a TDLS
4101 * setup req */
4102 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4103 send_resp(dut, conn, SIGMA_ERROR,
4104 "ErrorCode,Failed to enable HiLoMac "
4105 "TDLS mode");
4106 return 0;
4107 }
4108 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4109 /*
4110 * Since all security modes are enabled by default when
4111 * Sigma control is used, there is no need to do
4112 * anything here.
4113 */
4114 } else if (strcasecmp(val, "ExistLink") == 0) {
4115 /*
4116 * Since we allow new TDLS Setup Request even if there
4117 * is an existing link, nothing needs to be done for
4118 * this.
4119 */
4120 } else {
4121 /* TODO:
4122 * ExistLink: STA should send TDLS setup req even if
4123 * direct link already exists
4124 */
4125 send_resp(dut, conn, SIGMA_ERROR,
4126 "ErrorCode,Unsupported TDLSmode value");
4127 return 0;
4128 }
4129 }
4130
4131 val = get_param(cmd, "FakePubKey");
4132 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4133 send_resp(dut, conn, SIGMA_ERROR,
4134 "ErrorCode,Failed to enable FakePubKey");
4135 return 0;
4136 }
4137
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004138#ifdef NL80211_SUPPORT
4139 val = get_param(cmd, "FrgmntSupport");
4140 if (val) {
4141 if (strcasecmp(val, "Enable") == 0) {
4142 if (sta_set_he_fragmentation(dut, intf,
4143 HE_FRAG_LEVEL1)) {
4144 send_resp(dut, conn, SIGMA_ERROR,
4145 "ErrorCode,Failed to enable HE Fragmentation");
4146 return 0;
4147 }
4148 } else if (strcasecmp(val, "Disable") == 0) {
4149 if (sta_set_he_fragmentation(dut, intf,
4150 HE_FRAG_DISABLE)) {
4151 send_resp(dut, conn, SIGMA_ERROR,
4152 "ErrorCode,Failed to disable HE Fragmentation");
4153 return 0;
4154 }
4155 }
4156 }
4157#endif /* NL80211_SUPPORT */
4158
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004159 return 1;
4160}
4161
4162
4163static const char * ath_get_radio_name(const char *radio_name)
4164{
4165 if (radio_name == NULL)
4166 return "wifi0";
4167 if (strcmp(radio_name, "wifi1") == 0)
4168 return "wifi1";
4169 if (strcmp(radio_name, "wifi2") == 0)
4170 return "wifi2";
4171 return "wifi0";
4172}
4173
4174
4175static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
4176 const char *val)
4177{
4178 char buf[60];
4179 unsigned int vht_mcsmap = 0;
4180 int txchainmask = 0;
4181 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4182
4183 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4184 if (dut->testbed_flag_txsp == 1) {
4185 vht_mcsmap = 0xfffc;
4186 dut->testbed_flag_txsp = 0;
4187 } else {
4188 vht_mcsmap = 0xfffe;
4189 }
4190 txchainmask = 1;
4191 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4192 if (dut->testbed_flag_txsp == 1) {
4193 vht_mcsmap = 0xfff0;
4194 dut->testbed_flag_txsp = 0;
4195 } else {
4196 vht_mcsmap = 0xfffa;
4197 }
4198 txchainmask = 3;
4199 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4200 if (dut->testbed_flag_txsp == 1) {
4201 vht_mcsmap = 0xffc0;
4202 dut->testbed_flag_txsp = 0;
4203 } else {
4204 vht_mcsmap = 0xffea;
4205 }
4206 txchainmask = 7;
4207 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4208 if (dut->testbed_flag_txsp == 1) {
4209 vht_mcsmap = 0xff00;
4210 dut->testbed_flag_txsp = 0;
4211 } else {
4212 vht_mcsmap = 0xffaa;
4213 }
4214 txchainmask = 15;
4215 } else {
4216 if (dut->testbed_flag_txsp == 1) {
4217 vht_mcsmap = 0xffc0;
4218 dut->testbed_flag_txsp = 0;
4219 } else {
4220 vht_mcsmap = 0xffea;
4221 }
4222 }
4223
4224 if (txchainmask) {
4225 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
4226 basedev, txchainmask);
4227 if (system(buf) != 0) {
4228 sigma_dut_print(dut, DUT_MSG_ERROR,
4229 "iwpriv txchainmask failed");
4230 }
4231 }
4232
4233 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4234 intf, vht_mcsmap);
4235 if (system(buf) != 0) {
4236 sigma_dut_print(dut, DUT_MSG_ERROR,
4237 "iwpriv %s vht_mcsmap 0x%04x failed",
4238 intf, vht_mcsmap);
4239 }
4240}
4241
4242
4243static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
4244 const char *val)
4245{
4246 char buf[60];
4247 unsigned int vht_mcsmap = 0;
4248 int rxchainmask = 0;
4249 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4250
4251 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4252 if (dut->testbed_flag_rxsp == 1) {
4253 vht_mcsmap = 0xfffc;
4254 dut->testbed_flag_rxsp = 0;
4255 } else {
4256 vht_mcsmap = 0xfffe;
4257 }
4258 rxchainmask = 1;
4259 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4260 if (dut->testbed_flag_rxsp == 1) {
4261 vht_mcsmap = 0xfff0;
4262 dut->testbed_flag_rxsp = 0;
4263 } else {
4264 vht_mcsmap = 0xfffa;
4265 }
4266 rxchainmask = 3;
4267 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4268 if (dut->testbed_flag_rxsp == 1) {
4269 vht_mcsmap = 0xffc0;
4270 dut->testbed_flag_rxsp = 0;
4271 } else {
4272 vht_mcsmap = 0xffea;
4273 }
4274 rxchainmask = 7;
4275 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4276 if (dut->testbed_flag_rxsp == 1) {
4277 vht_mcsmap = 0xff00;
4278 dut->testbed_flag_rxsp = 0;
4279 } else {
4280 vht_mcsmap = 0xffaa;
4281 }
4282 rxchainmask = 15;
4283 } else {
4284 if (dut->testbed_flag_rxsp == 1) {
4285 vht_mcsmap = 0xffc0;
4286 dut->testbed_flag_rxsp = 0;
4287 } else {
4288 vht_mcsmap = 0xffea;
4289 }
4290 }
4291
4292 if (rxchainmask) {
4293 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
4294 basedev, rxchainmask);
4295 if (system(buf) != 0) {
4296 sigma_dut_print(dut, DUT_MSG_ERROR,
4297 "iwpriv rxchainmask failed");
4298 }
4299 }
4300
4301 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4302 intf, vht_mcsmap);
4303 if (system(buf) != 0) {
4304 sigma_dut_print(dut, DUT_MSG_ERROR,
4305 "iwpriv %s vht_mcsmap 0x%04x",
4306 intf, vht_mcsmap);
4307 }
4308}
4309
4310
4311void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
4312{
4313 if (strcasecmp(val, "enable") == 0) {
4314 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
4315 != 0) {
4316 sigma_dut_print(dut, DUT_MSG_ERROR,
4317 "Disable BB_VHTSIGB_CRC_CALC failed");
4318 }
4319
4320 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
4321 != 0) {
4322 sigma_dut_print(dut, DUT_MSG_ERROR,
4323 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4324 }
4325 } else {
4326 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4327 != 0) {
4328 sigma_dut_print(dut, DUT_MSG_ERROR,
4329 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4330 }
4331
4332 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4333 != 0) {
4334 sigma_dut_print(dut, DUT_MSG_ERROR,
4335 "Enable BB_VHTSIGB_CRC_CALC failed");
4336 }
4337 }
4338}
4339
4340
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004341static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
4342 const char *val)
4343{
4344 char buf[60];
4345
4346 if (strcmp(val, "20") == 0) {
4347 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
4348 dut->chwidth = 0;
4349 } else if (strcmp(val, "40") == 0) {
4350 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
4351 dut->chwidth = 1;
4352 } else if (strcmp(val, "80") == 0) {
4353 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
4354 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05304355 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004356 buf[0] = '\0';
4357 } else {
4358 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
4359 val);
4360 return -1;
4361 }
4362
4363 if (buf[0] != '\0' && system(buf) != 0) {
4364 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
4365 return -1;
4366 }
4367
4368 return 0;
4369}
4370
4371
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004372static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
4373 const char *intf, int addbareject)
4374{
4375#ifdef NL80211_SUPPORT
4376 struct nl_msg *msg;
4377 int ret = 0;
4378 struct nlattr *params;
4379 int ifindex;
4380
4381 ifindex = if_nametoindex(intf);
4382 if (ifindex == 0) {
4383 sigma_dut_print(dut, DUT_MSG_ERROR,
4384 "%s: Index for interface %s failed",
4385 __func__, intf);
4386 return -1;
4387 }
4388
4389 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4390 NL80211_CMD_VENDOR)) ||
4391 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4392 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4393 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4394 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4395 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4396 nla_put_u8(msg,
4397 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
4398 !addbareject)) {
4399 sigma_dut_print(dut, DUT_MSG_ERROR,
4400 "%s: err in adding vendor_cmd and vendor_data",
4401 __func__);
4402 nlmsg_free(msg);
4403 return -1;
4404 }
4405 nla_nest_end(msg, params);
4406
4407 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4408 if (ret) {
4409 sigma_dut_print(dut, DUT_MSG_ERROR,
4410 "%s: err in send_and_recv_msgs, ret=%d",
4411 __func__, ret);
4412 }
4413 return ret;
4414#else /* NL80211_SUPPORT */
4415 sigma_dut_print(dut, DUT_MSG_ERROR,
4416 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
4417 return -1;
4418#endif /* NL80211_SUPPORT */
4419}
4420
4421
4422static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
4423 int addbareject)
4424{
4425 int ret;
4426
4427 switch (get_driver_type()) {
4428 case DRIVER_WCN:
4429 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
4430 if (ret) {
4431 sigma_dut_print(dut, DUT_MSG_ERROR,
4432 "nlvendor_sta_set_addba_reject failed, ret:%d",
4433 ret);
4434 return ret;
4435 }
4436 break;
4437 default:
4438 sigma_dut_print(dut, DUT_MSG_ERROR,
4439 "errorCode,Unsupported ADDBA_REJECT with the current driver");
4440 ret = -1;
4441 break;
4442 }
4443
4444 return ret;
4445}
4446
4447
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004448static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
4449 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004450{
4451#ifdef NL80211_SUPPORT
4452 struct nl_msg *msg;
4453 int ret = 0;
4454 struct nlattr *params;
4455 int ifindex;
4456
4457 ifindex = if_nametoindex(intf);
4458 if (ifindex == 0) {
4459 sigma_dut_print(dut, DUT_MSG_ERROR,
4460 "%s: Index for interface %s failed",
4461 __func__, intf);
4462 return -1;
4463 }
4464
4465 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4466 NL80211_CMD_VENDOR)) ||
4467 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4468 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4469 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4470 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4471 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4472 nla_put_u8(msg,
4473 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004474 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004475 sigma_dut_print(dut, DUT_MSG_ERROR,
4476 "%s: err in adding vendor_cmd and vendor_data",
4477 __func__);
4478 nlmsg_free(msg);
4479 return -1;
4480 }
4481 nla_nest_end(msg, params);
4482
4483 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4484 if (ret) {
4485 sigma_dut_print(dut, DUT_MSG_ERROR,
4486 "%s: err in send_and_recv_msgs, ret=%d",
4487 __func__, ret);
4488 }
4489 return ret;
4490#else /* NL80211_SUPPORT */
4491 sigma_dut_print(dut, DUT_MSG_ERROR,
4492 "Disable addba not possible without NL80211_SUPPORT defined");
4493 return -1;
4494#endif /* NL80211_SUPPORT */
4495}
4496
4497
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004498static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
4499 struct sigma_conn *conn,
4500 struct sigma_cmd *cmd)
4501{
4502 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004503 int ampdu = -1, addbareject = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004504 char buf[30];
4505
4506 val = get_param(cmd, "40_INTOLERANT");
4507 if (val) {
4508 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4509 /* TODO: iwpriv ht40intol through wpa_supplicant */
4510 send_resp(dut, conn, SIGMA_ERROR,
4511 "ErrorCode,40_INTOLERANT not supported");
4512 return 0;
4513 }
4514 }
4515
4516 val = get_param(cmd, "ADDBA_REJECT");
4517 if (val) {
4518 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4519 /* reject any ADDBA with status "decline" */
4520 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004521 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004522 } else {
4523 /* accept ADDBA */
4524 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004525 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004526 }
4527 }
4528
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004529 if (addbareject >= 0 &&
4530 sta_set_addba_reject(dut, intf, addbareject) < 0) {
4531 send_resp(dut, conn, SIGMA_ERROR,
4532 "ErrorCode,set addba_reject failed");
4533 return 0;
4534 }
4535
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004536 val = get_param(cmd, "AMPDU");
4537 if (val) {
4538 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4539 /* enable AMPDU Aggregation */
4540 if (ampdu == 0) {
4541 send_resp(dut, conn, SIGMA_ERROR,
4542 "ErrorCode,Mismatch in "
4543 "addba_reject/ampdu - "
4544 "not supported");
4545 return 0;
4546 }
4547 ampdu = 1;
4548 } else {
4549 /* disable AMPDU Aggregation */
4550 if (ampdu == 1) {
4551 send_resp(dut, conn, SIGMA_ERROR,
4552 "ErrorCode,Mismatch in "
4553 "addba_reject/ampdu - "
4554 "not supported");
4555 return 0;
4556 }
4557 ampdu = 0;
4558 }
4559 }
4560
4561 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004562 int ret;
4563
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004564 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
4565 ampdu ? "Enabling" : "Disabling");
4566 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004567 if (wpa_command(intf, buf) < 0 &&
4568 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004569 send_resp(dut, conn, SIGMA_ERROR,
4570 "ErrorCode,set aggr failed");
4571 return 0;
4572 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004573
4574 if (ampdu == 0) {
4575 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004576 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004577 if (ret) {
4578 sigma_dut_print(dut, DUT_MSG_ERROR,
4579 "Failed to disable addba, ret:%d",
4580 ret);
4581 }
4582 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004583 }
4584
4585 val = get_param(cmd, "AMSDU");
4586 if (val) {
4587 switch (get_driver_type()) {
4588 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004589 case DRIVER_WCN:
4590 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004591 break;
4592 default:
4593 if (strcmp(val, "1") == 0 ||
4594 strcasecmp(val, "Enable") == 0) {
4595 /* Enable AMSDU Aggregation */
4596 send_resp(dut, conn, SIGMA_ERROR,
4597 "ErrorCode,AMSDU aggregation not supported");
4598 return 0;
4599 }
4600 break;
4601 }
4602 }
4603
4604 val = get_param(cmd, "STBC_RX");
4605 if (val) {
4606 switch (get_driver_type()) {
4607 case DRIVER_ATHEROS:
4608 ath_sta_set_stbc(dut, intf, val);
4609 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304610 case DRIVER_WCN:
4611 wcn_sta_set_stbc(dut, intf, val);
4612 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004613 default:
4614 send_resp(dut, conn, SIGMA_ERROR,
4615 "ErrorCode,STBC_RX not supported");
4616 return 0;
4617 }
4618 }
4619
4620 val = get_param(cmd, "WIDTH");
4621 if (val) {
4622 switch (get_driver_type()) {
4623 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004624 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004625 send_resp(dut, conn, SIGMA_ERROR,
4626 "ErrorCode,Failed to set WIDTH");
4627 return 0;
4628 }
4629 break;
4630 case DRIVER_ATHEROS:
4631 if (ath_set_width(dut, conn, intf, val) < 0)
4632 return 0;
4633 break;
4634 default:
4635 sigma_dut_print(dut, DUT_MSG_ERROR,
4636 "Setting WIDTH not supported");
4637 break;
4638 }
4639 }
4640
4641 val = get_param(cmd, "SMPS");
4642 if (val) {
4643 /* TODO: Dynamic/0, Static/1, No Limit/2 */
4644 send_resp(dut, conn, SIGMA_ERROR,
4645 "ErrorCode,SMPS not supported");
4646 return 0;
4647 }
4648
4649 val = get_param(cmd, "TXSP_STREAM");
4650 if (val) {
4651 switch (get_driver_type()) {
4652 case DRIVER_WCN:
4653 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4654 send_resp(dut, conn, SIGMA_ERROR,
4655 "ErrorCode,Failed to set TXSP_STREAM");
4656 return 0;
4657 }
4658 break;
4659 case DRIVER_ATHEROS:
4660 ath_sta_set_txsp_stream(dut, intf, val);
4661 break;
4662 default:
4663 sigma_dut_print(dut, DUT_MSG_ERROR,
4664 "Setting TXSP_STREAM not supported");
4665 break;
4666 }
4667 }
4668
4669 val = get_param(cmd, "RXSP_STREAM");
4670 if (val) {
4671 switch (get_driver_type()) {
4672 case DRIVER_WCN:
4673 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4674 send_resp(dut, conn, SIGMA_ERROR,
4675 "ErrorCode,Failed to set RXSP_STREAM");
4676 return 0;
4677 }
4678 break;
4679 case DRIVER_ATHEROS:
4680 ath_sta_set_rxsp_stream(dut, intf, val);
4681 break;
4682 default:
4683 sigma_dut_print(dut, DUT_MSG_ERROR,
4684 "Setting RXSP_STREAM not supported");
4685 break;
4686 }
4687 }
4688
4689 val = get_param(cmd, "DYN_BW_SGNL");
4690 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004691 switch (get_driver_type()) {
4692 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08004693 if (strcasecmp(val, "enable") == 0) {
4694 snprintf(buf, sizeof(buf),
4695 "iwpriv %s cwmenable 1", intf);
4696 if (system(buf) != 0) {
4697 sigma_dut_print(dut, DUT_MSG_ERROR,
4698 "iwpriv cwmenable 1 failed");
4699 return 0;
4700 }
4701 } else if (strcasecmp(val, "disable") == 0) {
4702 snprintf(buf, sizeof(buf),
4703 "iwpriv %s cwmenable 0", intf);
4704 if (system(buf) != 0) {
4705 sigma_dut_print(dut, DUT_MSG_ERROR,
4706 "iwpriv cwmenable 0 failed");
4707 return 0;
4708 }
4709 } else {
4710 sigma_dut_print(dut, DUT_MSG_ERROR,
4711 "Unsupported DYN_BW_SGL");
4712 }
4713
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004714 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4715 if (system(buf) != 0) {
4716 sigma_dut_print(dut, DUT_MSG_ERROR,
4717 "Failed to set cts_cbw in DYN_BW_SGNL");
4718 return 0;
4719 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004720 break;
4721 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004722 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004723 ath_config_dyn_bw_sig(dut, intf, val);
4724 break;
4725 default:
4726 sigma_dut_print(dut, DUT_MSG_ERROR,
4727 "Failed to set DYN_BW_SGNL");
4728 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004729 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004730 }
4731
4732 val = get_param(cmd, "RTS_FORCE");
4733 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004734 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004735 if (strcasecmp(val, "Enable") == 0) {
4736 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004737 if (system(buf) != 0) {
4738 sigma_dut_print(dut, DUT_MSG_ERROR,
4739 "Failed to set RTS_FORCE 64");
4740 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08004741 snprintf(buf, sizeof(buf),
4742 "wifitool %s beeliner_fw_test 100 1", intf);
4743 if (system(buf) != 0) {
4744 sigma_dut_print(dut, DUT_MSG_ERROR,
4745 "wifitool beeliner_fw_test 100 1 failed");
4746 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004747 } else if (strcasecmp(val, "Disable") == 0) {
4748 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
4749 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004750 if (system(buf) != 0) {
4751 sigma_dut_print(dut, DUT_MSG_ERROR,
4752 "Failed to set RTS_FORCE 2347");
4753 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004754 } else {
4755 send_resp(dut, conn, SIGMA_ERROR,
4756 "ErrorCode,RTS_FORCE value not supported");
4757 return 0;
4758 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004759 }
4760
4761 val = get_param(cmd, "CTS_WIDTH");
4762 if (val) {
4763 switch (get_driver_type()) {
4764 case DRIVER_WCN:
4765 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
4766 send_resp(dut, conn, SIGMA_ERROR,
4767 "ErrorCode,Failed to set CTS_WIDTH");
4768 return 0;
4769 }
4770 break;
4771 case DRIVER_ATHEROS:
4772 ath_set_cts_width(dut, intf, val);
4773 break;
4774 default:
4775 sigma_dut_print(dut, DUT_MSG_ERROR,
4776 "Setting CTS_WIDTH not supported");
4777 break;
4778 }
4779 }
4780
4781 val = get_param(cmd, "BW_SGNL");
4782 if (val) {
4783 if (strcasecmp(val, "Enable") == 0) {
4784 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1",
4785 intf);
4786 } else if (strcasecmp(val, "Disable") == 0) {
4787 /* TODO: Disable */
4788 buf[0] = '\0';
4789 } else {
4790 send_resp(dut, conn, SIGMA_ERROR,
4791 "ErrorCode,BW_SGNL value not supported");
4792 return 0;
4793 }
4794
4795 if (buf[0] != '\0' && system(buf) != 0) {
4796 sigma_dut_print(dut, DUT_MSG_ERROR,
4797 "Failed to set BW_SGNL");
4798 }
4799 }
4800
4801 val = get_param(cmd, "Band");
4802 if (val) {
4803 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
4804 /* STA supports all bands by default */
4805 } else {
4806 send_resp(dut, conn, SIGMA_ERROR,
4807 "ErrorCode,Unsupported Band");
4808 return 0;
4809 }
4810 }
4811
4812 val = get_param(cmd, "zero_crc");
4813 if (val) {
4814 switch (get_driver_type()) {
4815 case DRIVER_ATHEROS:
4816 ath_set_zero_crc(dut, val);
4817 break;
4818 default:
4819 break;
4820 }
4821 }
4822
4823 return 1;
4824}
4825
4826
4827static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
4828 struct sigma_cmd *cmd)
4829{
4830 const char *val;
4831 char buf[100];
4832
4833 val = get_param(cmd, "MSDUSize");
4834 if (val) {
4835 int mtu;
4836
4837 dut->amsdu_size = atoi(val);
4838 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
4839 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
4840 sigma_dut_print(dut, DUT_MSG_ERROR,
4841 "MSDUSize %d is above max %d or below min %d",
4842 dut->amsdu_size,
4843 IEEE80211_MAX_DATA_LEN_DMG,
4844 IEEE80211_SNAP_LEN_DMG);
4845 dut->amsdu_size = 0;
4846 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4847 }
4848
4849 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
4850 sigma_dut_print(dut, DUT_MSG_DEBUG,
4851 "Setting amsdu_size to %d", mtu);
4852 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
4853 get_station_ifname(), mtu);
4854
4855 if (system(buf) != 0) {
4856 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
4857 buf);
4858 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4859 }
4860 }
4861
4862 val = get_param(cmd, "BAckRcvBuf");
4863 if (val) {
4864 dut->back_rcv_buf = atoi(val);
4865 if (dut->back_rcv_buf == 0) {
4866 sigma_dut_print(dut, DUT_MSG_ERROR,
4867 "Failed to convert %s or value is 0",
4868 val);
4869 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4870 }
4871
4872 sigma_dut_print(dut, DUT_MSG_DEBUG,
4873 "Setting BAckRcvBuf to %s", val);
4874 }
4875
4876 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
4877}
4878
4879
4880static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
4881 struct sigma_cmd *cmd)
4882{
4883 int net_id;
4884 char *ifname;
4885 const char *val;
4886 char buf[100];
4887
4888 dut->mode = SIGMA_MODE_STATION;
4889 ifname = get_main_ifname();
4890 if (wpa_command(ifname, "PING") != 0) {
4891 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
4892 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4893 }
4894
4895 wpa_command(ifname, "FLUSH");
4896 net_id = add_network_common(dut, conn, ifname, cmd);
4897 if (net_id < 0) {
4898 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
4899 return net_id;
4900 }
4901
4902 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
4903 if (set_network(ifname, net_id, "mode", "2") < 0) {
4904 sigma_dut_print(dut, DUT_MSG_ERROR,
4905 "Failed to set supplicant network mode");
4906 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4907 }
4908
4909 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02004910 "Supplicant set network with mode 2. network_id %d",
4911 net_id);
4912
4913 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
4914 sigma_dut_print(dut, DUT_MSG_INFO,
4915 "Failed to set supplicant to WPS ENABLE");
4916 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4917 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004918
4919 val = get_param(cmd, "Security");
4920 if (val && strcasecmp(val, "OPEN") == 0) {
4921 dut->ap_key_mgmt = AP_OPEN;
4922 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
4923 sigma_dut_print(dut, DUT_MSG_ERROR,
4924 "Failed to set supplicant to %s security",
4925 val);
4926 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4927 }
4928 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
4929 dut->ap_key_mgmt = AP_WPA2_PSK;
4930 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
4931 sigma_dut_print(dut, DUT_MSG_ERROR,
4932 "Failed to set supplicant to %s security",
4933 val);
4934 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4935 }
4936
4937 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
4938 sigma_dut_print(dut, DUT_MSG_ERROR,
4939 "Failed to set supplicant to proto RSN");
4940 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4941 }
4942 } else if (val) {
4943 sigma_dut_print(dut, DUT_MSG_ERROR,
4944 "Requested Security %s is not supported on 60GHz",
4945 val);
4946 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
4947 }
4948
4949 val = get_param(cmd, "Encrypt");
4950 if (val && strcasecmp(val, "AES-GCMP") == 0) {
4951 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
4952 sigma_dut_print(dut, DUT_MSG_ERROR,
4953 "Failed to set supplicant to pairwise GCMP");
4954 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4955 }
4956 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
4957 sigma_dut_print(dut, DUT_MSG_ERROR,
4958 "Failed to set supplicant to group GCMP");
4959 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4960 }
4961 } else if (val) {
4962 sigma_dut_print(dut, DUT_MSG_ERROR,
4963 "Requested Encrypt %s is not supported on 60 GHz",
4964 val);
4965 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
4966 }
4967
4968 val = get_param(cmd, "PSK");
4969 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
4970 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
4971 val);
4972 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4973 }
4974
4975 /* Convert 60G channel to freq */
4976 switch (dut->ap_channel) {
4977 case 1:
4978 val = "58320";
4979 break;
4980 case 2:
4981 val = "60480";
4982 break;
4983 case 3:
4984 val = "62640";
4985 break;
4986 default:
4987 sigma_dut_print(dut, DUT_MSG_ERROR,
4988 "Failed to configure channel %d. Not supported",
4989 dut->ap_channel);
4990 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4991 }
4992
4993 if (set_network(ifname, net_id, "frequency", val) < 0) {
4994 sigma_dut_print(dut, DUT_MSG_ERROR,
4995 "Failed to set supplicant network frequency");
4996 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4997 }
4998
4999 sigma_dut_print(dut, DUT_MSG_DEBUG,
5000 "Supplicant set network with frequency");
5001
5002 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5003 if (wpa_command(ifname, buf) < 0) {
5004 sigma_dut_print(dut, DUT_MSG_INFO,
5005 "Failed to select network id %d on %s",
5006 net_id, ifname);
5007 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5008 }
5009
5010 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5011
5012 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
5013}
5014
5015
Lior David67543f52017-01-03 19:04:22 +02005016static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
5017{
5018 char buf[128], fname[128];
5019 FILE *f;
5020
5021 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
5022 sigma_dut_print(dut, DUT_MSG_ERROR,
5023 "failed to get wil6210 debugfs dir");
5024 return -1;
5025 }
5026
5027 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5028 f = fopen(fname, "w");
5029 if (!f) {
5030 sigma_dut_print(dut, DUT_MSG_ERROR,
5031 "failed to open: %s", fname);
5032 return -1;
5033 }
5034
5035 fprintf(f, "%d\n", abft_len);
5036 fclose(f);
5037
5038 return 0;
5039}
5040
5041
5042static int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5043 int abft_len)
5044{
5045 switch (get_driver_type()) {
5046 case DRIVER_WIL6210:
5047 return wil6210_set_abft_len(dut, abft_len);
5048 default:
5049 sigma_dut_print(dut, DUT_MSG_ERROR,
5050 "set abft_len not supported");
5051 return -1;
5052 }
5053}
5054
5055
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005056static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5057 struct sigma_cmd *cmd)
5058{
5059 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005060 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005061
5062 if (dut->dev_role != DEVROLE_PCP) {
5063 send_resp(dut, conn, SIGMA_INVALID,
5064 "ErrorCode,Invalid DevRole");
5065 return 0;
5066 }
5067
5068 val = get_param(cmd, "SSID");
5069 if (val) {
5070 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5071 send_resp(dut, conn, SIGMA_INVALID,
5072 "ErrorCode,Invalid SSID");
5073 return -1;
5074 }
5075
Peng Xub8fc5cc2017-05-10 17:27:28 -07005076 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005077 }
5078
5079 val = get_param(cmd, "CHANNEL");
5080 if (val) {
5081 const char *pos;
5082
5083 dut->ap_channel = atoi(val);
5084 pos = strchr(val, ';');
5085 if (pos) {
5086 pos++;
5087 dut->ap_channel_1 = atoi(pos);
5088 }
5089 }
5090
5091 switch (dut->ap_channel) {
5092 case 1:
5093 case 2:
5094 case 3:
5095 break;
5096 default:
5097 sigma_dut_print(dut, DUT_MSG_ERROR,
5098 "Channel %d is not supported", dut->ap_channel);
5099 send_resp(dut, conn, SIGMA_ERROR,
5100 "Requested channel is not supported");
5101 return -1;
5102 }
5103
5104 val = get_param(cmd, "BCNINT");
5105 if (val)
5106 dut->ap_bcnint = atoi(val);
5107
5108
5109 val = get_param(cmd, "ExtSchIE");
5110 if (val) {
5111 send_resp(dut, conn, SIGMA_ERROR,
5112 "ErrorCode,ExtSchIE is not supported yet");
5113 return -1;
5114 }
5115
5116 val = get_param(cmd, "AllocType");
5117 if (val) {
5118 send_resp(dut, conn, SIGMA_ERROR,
5119 "ErrorCode,AllocType is not supported yet");
5120 return -1;
5121 }
5122
5123 val = get_param(cmd, "PercentBI");
5124 if (val) {
5125 send_resp(dut, conn, SIGMA_ERROR,
5126 "ErrorCode,PercentBI is not supported yet");
5127 return -1;
5128 }
5129
5130 val = get_param(cmd, "CBAPOnly");
5131 if (val) {
5132 send_resp(dut, conn, SIGMA_ERROR,
5133 "ErrorCode,CBAPOnly is not supported yet");
5134 return -1;
5135 }
5136
5137 val = get_param(cmd, "AMPDU");
5138 if (val) {
5139 if (strcasecmp(val, "Enable") == 0)
5140 dut->ap_ampdu = 1;
5141 else if (strcasecmp(val, "Disable") == 0)
5142 dut->ap_ampdu = 2;
5143 else {
5144 send_resp(dut, conn, SIGMA_ERROR,
5145 "ErrorCode,AMPDU value is not Enable nor Disabled");
5146 return -1;
5147 }
5148 }
5149
5150 val = get_param(cmd, "AMSDU");
5151 if (val) {
5152 if (strcasecmp(val, "Enable") == 0)
5153 dut->ap_amsdu = 1;
5154 else if (strcasecmp(val, "Disable") == 0)
5155 dut->ap_amsdu = 2;
5156 }
5157
5158 val = get_param(cmd, "NumMSDU");
5159 if (val) {
5160 send_resp(dut, conn, SIGMA_ERROR,
5161 "ErrorCode, NumMSDU is not supported yet");
5162 return -1;
5163 }
5164
5165 val = get_param(cmd, "ABFTLRang");
5166 if (val) {
5167 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02005168 "ABFTLRang parameter %s", val);
5169 if (strcmp(val, "Gt1") == 0)
5170 abft_len = 2; /* 2 slots in this case */
5171 }
5172
5173 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
5174 send_resp(dut, conn, SIGMA_ERROR,
5175 "ErrorCode, Can't set ABFT length");
5176 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005177 }
5178
5179 if (sta_pcp_start(dut, conn, cmd) < 0) {
5180 send_resp(dut, conn, SIGMA_ERROR,
5181 "ErrorCode, Can't start PCP role");
5182 return -1;
5183 }
5184
5185 return sta_set_60g_common(dut, conn, cmd);
5186}
5187
5188
5189static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
5190 struct sigma_cmd *cmd)
5191{
5192 const char *val = get_param(cmd, "DiscoveryMode");
5193
5194 if (dut->dev_role != DEVROLE_STA) {
5195 send_resp(dut, conn, SIGMA_INVALID,
5196 "ErrorCode,Invalid DevRole");
5197 return 0;
5198 }
5199
5200 if (val) {
5201 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
5202 /* Ignore Discovery mode till Driver expose API. */
5203#if 0
5204 if (strcasecmp(val, "1") == 0) {
5205 send_resp(dut, conn, SIGMA_INVALID,
5206 "ErrorCode,DiscoveryMode 1 not supported");
5207 return 0;
5208 }
5209
5210 if (strcasecmp(val, "0") == 0) {
5211 /* OK */
5212 } else {
5213 send_resp(dut, conn, SIGMA_INVALID,
5214 "ErrorCode,DiscoveryMode not supported");
5215 return 0;
5216 }
5217#endif
5218 }
5219
5220 if (start_sta_mode(dut) != 0)
5221 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5222 return sta_set_60g_common(dut, conn, cmd);
5223}
5224
5225
5226static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
5227 struct sigma_cmd *cmd)
5228{
5229 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02005230 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05305231
Jouni Malinened77e672018-01-10 16:45:13 +02005232 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08005233 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02005234 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05305235 wpa_command(intf, "DISCONNECT");
5236 return 1;
5237 }
5238
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005239 disconnect_station(dut);
5240 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
5241 * due to cached results. */
5242 wpa_command(intf, "SET ignore_old_scan_res 1");
5243 wpa_command(intf, "BSS_FLUSH");
5244 return 1;
5245}
5246
5247
5248static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
5249 struct sigma_cmd *cmd)
5250{
5251 const char *intf = get_param(cmd, "Interface");
5252 const char *bssid = get_param(cmd, "bssid");
5253 const char *val = get_param(cmd, "CHANNEL");
5254 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305255 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05305256 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005257 int res;
5258 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05305259 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05305260 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005261
5262 if (bssid == NULL) {
5263 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
5264 "argument");
5265 return 0;
5266 }
5267
5268 if (val)
5269 chan = atoi(val);
5270
5271 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
5272 /* The current network may be from sta_associate or
5273 * sta_hs2_associate
5274 */
5275 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
5276 0 ||
5277 set_network(intf, 0, "bssid", bssid) < 0)
5278 return -2;
5279 }
5280
5281 ctrl = open_wpa_mon(intf);
5282 if (ctrl == NULL) {
5283 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
5284 "wpa_supplicant monitor connection");
5285 return -1;
5286 }
5287
Sunil Duttd30ce092018-01-11 23:56:29 +05305288 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
5289 sizeof(result)) < 0 ||
5290 strncmp(result, "COMPLETED", 9) != 0) {
5291 sigma_dut_print(dut, DUT_MSG_DEBUG,
5292 "sta_reassoc: Not connected");
5293 fastreassoc = 0;
5294 }
5295
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305296 if (dut->rsne_override) {
5297#ifdef NL80211_SUPPORT
5298 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
5299 sta_config_rsnie(dut, 1);
5300 dut->config_rsnie = 1;
5301 }
5302#endif /* NL80211_SUPPORT */
5303 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
5304 dut->rsne_override);
5305 if (wpa_command(intf, buf) < 0) {
5306 send_resp(dut, conn, SIGMA_ERROR,
5307 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
5308 return 0;
5309 }
5310 }
5311
Sunil Duttd30ce092018-01-11 23:56:29 +05305312 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005313#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305314 if (chan) {
5315 unsigned int freq;
5316
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02005317 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305318 if (!freq) {
5319 sigma_dut_print(dut, DUT_MSG_ERROR,
5320 "Invalid channel number provided: %d",
5321 chan);
5322 send_resp(dut, conn, SIGMA_INVALID,
5323 "ErrorCode,Invalid channel number");
5324 goto close_mon_conn;
5325 }
5326 res = snprintf(buf, sizeof(buf),
5327 "SCAN TYPE=ONLY freq=%d", freq);
5328 } else {
5329 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
5330 }
5331 if (res < 0 || res >= (int) sizeof(buf)) {
5332 send_resp(dut, conn, SIGMA_ERROR,
5333 "ErrorCode,snprintf failed");
5334 goto close_mon_conn;
5335 }
5336 if (wpa_command(intf, buf) < 0) {
5337 sigma_dut_print(dut, DUT_MSG_INFO,
5338 "Failed to start scan");
5339 send_resp(dut, conn, SIGMA_ERROR,
5340 "ErrorCode,scan failed");
5341 goto close_mon_conn;
5342 }
5343
5344 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
5345 buf, sizeof(buf));
5346 if (res < 0) {
5347 sigma_dut_print(dut, DUT_MSG_INFO,
5348 "Scan did not complete");
5349 send_resp(dut, conn, SIGMA_ERROR,
5350 "ErrorCode,scan did not complete");
5351 goto close_mon_conn;
5352 }
5353
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005354 if (set_network(intf, dut->infra_network_id, "bssid", "any")
5355 < 0) {
5356 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
5357 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305358 status = -2;
5359 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005360 }
5361 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
5362 bssid, chan);
5363 if (res > 0 && res < (int) sizeof(buf))
5364 res = wpa_command(intf, buf);
5365
5366 if (res < 0 || res >= (int) sizeof(buf)) {
5367 send_resp(dut, conn, SIGMA_ERROR,
5368 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305369 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005370 }
5371#else /* ANDROID */
5372 sigma_dut_print(dut, DUT_MSG_DEBUG,
5373 "Reassoc using iwpriv - skip chan=%d info",
5374 chan);
5375 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
5376 if (system(buf) != 0) {
5377 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05305378 status = -2;
5379 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005380 }
5381#endif /* ANDROID */
5382 sigma_dut_print(dut, DUT_MSG_INFO,
5383 "sta_reassoc: Run %s successful", buf);
5384 } else if (wpa_command(intf, "REASSOCIATE")) {
5385 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
5386 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05305387 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005388 }
5389
5390 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
5391 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05305392 if (res < 0) {
5393 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
5394 status = -1;
5395 goto close_mon_conn;
5396 }
5397 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005398
Ashwini Patil467efef2017-05-25 12:18:27 +05305399close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005400 wpa_ctrl_detach(ctrl);
5401 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05305402 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005403}
5404
5405
5406static void hs2_clear_credentials(const char *intf)
5407{
5408 wpa_command(intf, "REMOVE_CRED all");
5409}
5410
5411
Lior Davidcc88b562017-01-03 18:52:09 +02005412#ifdef __linux__
5413static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
5414 unsigned int *aid)
5415{
Lior David0fe101e2017-03-09 16:09:50 +02005416 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02005417
Lior David0fe101e2017-03-09 16:09:50 +02005418 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02005419}
5420#endif /* __linux__ */
5421
5422
5423static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
5424 unsigned int *aid)
5425{
5426 switch (get_driver_type()) {
5427#ifdef __linux__
5428 case DRIVER_WIL6210:
5429 return wil6210_get_aid(dut, bssid, aid);
5430#endif /* __linux__ */
5431 default:
5432 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
5433 return -1;
5434 }
5435}
5436
5437
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005438static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
5439 struct sigma_cmd *cmd)
5440{
5441 char buf[MAX_CMD_LEN];
5442 char bss_list[MAX_CMD_LEN];
5443 const char *parameter = get_param(cmd, "Parameter");
5444
5445 if (parameter == NULL)
5446 return -1;
5447
Lior Davidcc88b562017-01-03 18:52:09 +02005448 if (strcasecmp(parameter, "AID") == 0) {
5449 unsigned int aid = 0;
5450 char bssid[20];
5451
5452 if (get_wpa_status(get_station_ifname(), "bssid",
5453 bssid, sizeof(bssid)) < 0) {
5454 sigma_dut_print(dut, DUT_MSG_ERROR,
5455 "could not get bssid");
5456 return -2;
5457 }
5458
5459 if (sta_get_aid_60g(dut, bssid, &aid))
5460 return -2;
5461
5462 snprintf(buf, sizeof(buf), "aid,%d", aid);
5463 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
5464 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5465 return 0;
5466 }
5467
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005468 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
5469 char *bss_line;
5470 char *bss_id = NULL;
5471 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305472 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005473
5474 if (ifname == NULL) {
5475 sigma_dut_print(dut, DUT_MSG_INFO,
5476 "For get DiscoveredDevList need Interface name.");
5477 return -1;
5478 }
5479
5480 /*
5481 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
5482 * of BSSIDs in "bssid=<BSSID>\n"
5483 */
5484 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
5485 bss_list,
5486 sizeof(bss_list)) < 0) {
5487 sigma_dut_print(dut, DUT_MSG_ERROR,
5488 "Failed to get bss list");
5489 return -1;
5490 }
5491
5492 sigma_dut_print(dut, DUT_MSG_DEBUG,
5493 "bss list for ifname:%s is:%s",
5494 ifname, bss_list);
5495
5496 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305497 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005498 while (bss_line) {
5499 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
5500 bss_id) {
5501 int len;
5502
5503 len = snprintf(buf + strlen(buf),
5504 sizeof(buf) - strlen(buf),
5505 ",%s", bss_id);
5506 free(bss_id);
5507 bss_id = NULL;
5508 if (len < 0) {
5509 sigma_dut_print(dut,
5510 DUT_MSG_ERROR,
5511 "Failed to read BSSID");
5512 send_resp(dut, conn, SIGMA_ERROR,
5513 "ErrorCode,Failed to read BSS ID");
5514 return 0;
5515 }
5516
5517 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
5518 sigma_dut_print(dut,
5519 DUT_MSG_ERROR,
5520 "Response buf too small for list");
5521 send_resp(dut, conn,
5522 SIGMA_ERROR,
5523 "ErrorCode,Response buf too small for list");
5524 return 0;
5525 }
5526 }
5527
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305528 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005529 }
5530
5531 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
5532 buf);
5533 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5534 return 0;
5535 }
5536
5537 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5538 return 0;
5539}
5540
5541
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07005542static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
5543 struct sigma_cmd *cmd)
5544{
5545 char buf[MAX_CMD_LEN];
5546 const char *parameter = get_param(cmd, "Parameter");
5547
5548 if (!parameter)
5549 return -1;
5550
5551 if (strcasecmp(parameter, "RSSI") == 0) {
5552 char rssi[10];
5553
5554 if (get_wpa_signal_poll(dut, get_station_ifname(), "RSSI",
5555 rssi, sizeof(rssi)) < 0) {
5556 sigma_dut_print(dut, DUT_MSG_ERROR,
5557 "Could not get RSSI");
5558 return -2;
5559 }
5560
5561 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
5562 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
5563 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5564 return 0;
5565 }
5566
5567 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5568 return 0;
5569}
5570
5571
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005572static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
5573 struct sigma_cmd *cmd)
5574{
5575 const char *program = get_param(cmd, "Program");
5576
5577 if (program == NULL)
5578 return -1;
5579
5580 if (strcasecmp(program, "P2PNFC") == 0)
5581 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
5582
5583 if (strcasecmp(program, "60ghz") == 0)
5584 return sta_get_parameter_60g(dut, conn, cmd);
5585
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07005586 if (strcasecmp(program, "he") == 0)
5587 return sta_get_parameter_he(dut, conn, cmd);
5588
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005589#ifdef ANDROID_NAN
5590 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07005591 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005592#endif /* ANDROID_NAN */
5593
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005594#ifdef MIRACAST
5595 if (strcasecmp(program, "WFD") == 0 ||
5596 strcasecmp(program, "DisplayR2") == 0)
5597 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
5598#endif /* MIRACAST */
5599
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005600 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5601 return 0;
5602}
5603
5604
5605static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
5606 const char *type)
5607{
5608 char buf[100];
5609
5610 if (dut->program == PROGRAM_VHT) {
5611 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5612 if (system(buf) != 0) {
5613 sigma_dut_print(dut, DUT_MSG_ERROR,
5614 "iwpriv %s chwidth failed", intf);
5615 }
5616
5617 snprintf(buf, sizeof(buf), "iwpriv %s mode 11ACVHT80", intf);
5618 if (system(buf) != 0) {
5619 sigma_dut_print(dut, DUT_MSG_ERROR,
5620 "iwpriv %s mode 11ACVHT80 failed",
5621 intf);
5622 }
5623
5624 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs -1", intf);
5625 if (system(buf) != 0) {
5626 sigma_dut_print(dut, DUT_MSG_ERROR,
5627 "iwpriv %s vhtmcs -1 failed", intf);
5628 }
5629 }
5630
5631 if (dut->program == PROGRAM_HT) {
5632 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5633 if (system(buf) != 0) {
5634 sigma_dut_print(dut, DUT_MSG_ERROR,
5635 "iwpriv %s chwidth failed", intf);
5636 }
5637
5638 snprintf(buf, sizeof(buf), "iwpriv %s mode 11naht40", intf);
5639 if (system(buf) != 0) {
5640 sigma_dut_print(dut, DUT_MSG_ERROR,
5641 "iwpriv %s mode 11naht40 failed",
5642 intf);
5643 }
5644
5645 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0", intf);
5646 if (system(buf) != 0) {
5647 sigma_dut_print(dut, DUT_MSG_ERROR,
5648 "iwpriv set11NRates failed");
5649 }
5650 }
5651
5652 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
5653 snprintf(buf, sizeof(buf), "iwpriv %s powersave 0", intf);
5654 if (system(buf) != 0) {
5655 sigma_dut_print(dut, DUT_MSG_ERROR,
5656 "disabling powersave failed");
5657 }
5658
5659 /* Reset CTS width */
5660 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
5661 intf);
5662 if (system(buf) != 0) {
5663 sigma_dut_print(dut, DUT_MSG_ERROR,
5664 "wifitool %s beeliner_fw_test 54 0 failed",
5665 intf);
5666 }
5667
5668 /* Enable Dynamic Bandwidth signalling by default */
5669 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", intf);
5670 if (system(buf) != 0) {
5671 sigma_dut_print(dut, DUT_MSG_ERROR,
5672 "iwpriv %s cwmenable 1 failed", intf);
5673 }
5674
5675 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
5676 if (system(buf) != 0) {
5677 sigma_dut_print(dut, DUT_MSG_ERROR,
5678 "iwpriv rts failed");
5679 }
5680 }
5681
5682 if (type && strcasecmp(type, "Testbed") == 0) {
5683 dut->testbed_flag_txsp = 1;
5684 dut->testbed_flag_rxsp = 1;
5685 /* STA has to set spatial stream to 2 per Appendix H */
5686 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0xfff0", intf);
5687 if (system(buf) != 0) {
5688 sigma_dut_print(dut, DUT_MSG_ERROR,
5689 "iwpriv vht_mcsmap failed");
5690 }
5691
5692 /* Disable LDPC per Appendix H */
5693 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", intf);
5694 if (system(buf) != 0) {
5695 sigma_dut_print(dut, DUT_MSG_ERROR,
5696 "iwpriv %s ldpc 0 failed", intf);
5697 }
5698
5699 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5700 if (system(buf) != 0) {
5701 sigma_dut_print(dut, DUT_MSG_ERROR,
5702 "iwpriv amsdu failed");
5703 }
5704
5705 /* TODO: Disable STBC 2x1 transmit and receive */
5706 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", intf);
5707 if (system(buf) != 0) {
5708 sigma_dut_print(dut, DUT_MSG_ERROR,
5709 "Disable tx_stbc 0 failed");
5710 }
5711
5712 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc 0", intf);
5713 if (system(buf) != 0) {
5714 sigma_dut_print(dut, DUT_MSG_ERROR,
5715 "Disable rx_stbc 0 failed");
5716 }
5717
5718 /* STA has to disable Short GI per Appendix H */
5719 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 0", intf);
5720 if (system(buf) != 0) {
5721 sigma_dut_print(dut, DUT_MSG_ERROR,
5722 "iwpriv %s shortgi 0 failed", intf);
5723 }
5724 }
5725
5726 if (type && strcasecmp(type, "DUT") == 0) {
5727 snprintf(buf, sizeof(buf), "iwpriv %s nss 3", intf);
5728 if (system(buf) != 0) {
5729 sigma_dut_print(dut, DUT_MSG_ERROR,
5730 "iwpriv %s nss 3 failed", intf);
5731 }
Arif Hussainac6c5112018-05-25 17:34:00 -07005732 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005733
5734 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 1", intf);
5735 if (system(buf) != 0) {
5736 sigma_dut_print(dut, DUT_MSG_ERROR,
5737 "iwpriv %s shortgi 1 failed", intf);
5738 }
5739 }
5740}
5741
5742
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08005743#ifdef NL80211_SUPPORT
5744static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
5745 enum he_mcs_config mcs)
5746{
5747 struct nl_msg *msg;
5748 int ret = 0;
5749 struct nlattr *params;
5750 int ifindex;
5751
5752 ifindex = if_nametoindex(intf);
5753 if (ifindex == 0) {
5754 sigma_dut_print(dut, DUT_MSG_ERROR,
5755 "%s: Index for interface %s failed",
5756 __func__, intf);
5757 return -1;
5758 }
5759
5760 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5761 NL80211_CMD_VENDOR)) ||
5762 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5763 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5764 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5765 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5766 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5767 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
5768 mcs)) {
5769 sigma_dut_print(dut, DUT_MSG_ERROR,
5770 "%s: err in adding vendor_cmd and vendor_data",
5771 __func__);
5772 nlmsg_free(msg);
5773 return -1;
5774 }
5775 nla_nest_end(msg, params);
5776
5777 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5778 if (ret) {
5779 sigma_dut_print(dut, DUT_MSG_ERROR,
5780 "%s: err in send_and_recv_msgs, ret=%d",
5781 __func__, ret);
5782 }
5783 return ret;
5784}
5785#endif /* NL80211_SUPPORT */
5786
5787
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07005788static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
5789 const char *intf, int enable)
5790{
5791#ifdef NL80211_SUPPORT
5792 struct nl_msg *msg;
5793 int ret = 0;
5794 struct nlattr *params;
5795 int ifindex;
5796
5797 ifindex = if_nametoindex(intf);
5798 if (ifindex == 0) {
5799 sigma_dut_print(dut, DUT_MSG_ERROR,
5800 "%s: Index for interface %s failed",
5801 __func__, intf);
5802 return -1;
5803 }
5804
5805 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5806 NL80211_CMD_VENDOR)) ||
5807 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5808 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5809 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5810 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5811 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5812 nla_put_u8(msg,
5813 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
5814 enable)) {
5815 sigma_dut_print(dut, DUT_MSG_ERROR,
5816 "%s: err in adding vendor_cmd and vendor_data",
5817 __func__);
5818 nlmsg_free(msg);
5819 return -1;
5820 }
5821 nla_nest_end(msg, params);
5822
5823 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5824 if (ret) {
5825 sigma_dut_print(dut, DUT_MSG_ERROR,
5826 "%s: err in send_and_recv_msgs, ret=%d",
5827 __func__, ret);
5828 }
5829 return ret;
5830#else /* NL80211_SUPPORT */
5831 sigma_dut_print(dut, DUT_MSG_ERROR,
5832 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
5833 return -1;
5834#endif /* NL80211_SUPPORT */
5835}
5836
5837
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08005838static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
5839 const char *intf, int enable)
5840{
5841#ifdef NL80211_SUPPORT
5842 struct nl_msg *msg;
5843 int ret = 0;
5844 struct nlattr *params;
5845 int ifindex;
5846
5847 ifindex = if_nametoindex(intf);
5848 if (ifindex == 0) {
5849 sigma_dut_print(dut, DUT_MSG_ERROR,
5850 "%s: Index for interface %s failed",
5851 __func__, intf);
5852 return -1;
5853 }
5854
5855 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5856 NL80211_CMD_VENDOR)) ||
5857 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5858 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5859 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5860 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5861 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5862 nla_put_u8(msg,
5863 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
5864 enable)) {
5865 sigma_dut_print(dut, DUT_MSG_ERROR,
5866 "%s: err in adding vendor_cmd and vendor_data",
5867 __func__);
5868 nlmsg_free(msg);
5869 return -1;
5870 }
5871 nla_nest_end(msg, params);
5872
5873 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5874 if (ret) {
5875 sigma_dut_print(dut, DUT_MSG_ERROR,
5876 "%s: err in send_and_recv_msgs, ret=%d",
5877 __func__, ret);
5878 }
5879 return ret;
5880#else /* NL80211_SUPPORT */
5881 sigma_dut_print(dut, DUT_MSG_ERROR,
5882 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
5883 return -1;
5884#endif /* NL80211_SUPPORT */
5885}
5886
5887
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08005888static int sta_set_addba_buf_size(struct sigma_dut *dut,
5889 const char *intf, int bufsize)
5890{
5891#ifdef NL80211_SUPPORT
5892 struct nl_msg *msg;
5893 int ret = 0;
5894 struct nlattr *params;
5895 int ifindex;
5896
5897 ifindex = if_nametoindex(intf);
5898 if (ifindex == 0) {
5899 sigma_dut_print(dut, DUT_MSG_ERROR,
5900 "%s: Index for interface %s failed",
5901 __func__, intf);
5902 return -1;
5903 }
5904
5905 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5906 NL80211_CMD_VENDOR)) ||
5907 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5908 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5909 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5910 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5911 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07005912 nla_put_u16(msg,
5913 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
5914 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08005915 sigma_dut_print(dut, DUT_MSG_ERROR,
5916 "%s: err in adding vendor_cmd and vendor_data",
5917 __func__);
5918 nlmsg_free(msg);
5919 return -1;
5920 }
5921 nla_nest_end(msg, params);
5922
5923 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5924 if (ret) {
5925 sigma_dut_print(dut, DUT_MSG_ERROR,
5926 "%s: err in send_and_recv_msgs, ret=%d",
5927 __func__, ret);
5928 }
5929 return ret;
5930#else /* NL80211_SUPPORT */
5931 sigma_dut_print(dut, DUT_MSG_ERROR,
5932 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
5933 return -1;
5934#endif /* NL80211_SUPPORT */
5935}
5936
5937
Arif Hussain8d5b27b2018-05-14 14:31:03 -07005938static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
5939 int enable)
5940{
5941#ifdef NL80211_SUPPORT
5942 struct nl_msg *msg;
5943 int ret = 0;
5944 struct nlattr *params;
5945 int ifindex;
5946
5947 ifindex = if_nametoindex(intf);
5948 if (ifindex == 0) {
5949 sigma_dut_print(dut, DUT_MSG_ERROR,
5950 "%s: Index for interface %s failed",
5951 __func__, intf);
5952 return -1;
5953 }
5954
5955 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5956 NL80211_CMD_VENDOR)) ||
5957 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5958 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5959 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5960 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5961 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5962 nla_put_u8(msg,
5963 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
5964 enable)) {
5965 sigma_dut_print(dut, DUT_MSG_ERROR,
5966 "%s: err in adding vendor_cmd and vendor_data",
5967 __func__);
5968 nlmsg_free(msg);
5969 return -1;
5970 }
5971 nla_nest_end(msg, params);
5972
5973 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5974 if (ret) {
5975 sigma_dut_print(dut, DUT_MSG_ERROR,
5976 "%s: err in send_and_recv_msgs, ret=%d",
5977 __func__, ret);
5978 }
5979 return ret;
5980#else /* NL80211_SUPPORT */
5981 sigma_dut_print(dut, DUT_MSG_ERROR,
5982 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
5983 return -1;
5984#endif /* NL80211_SUPPORT */
5985}
5986
5987
Arif Hussain9765f7d2018-07-03 08:28:26 -07005988static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
5989 int val)
5990{
5991#ifdef NL80211_SUPPORT
5992 struct nl_msg *msg;
5993 int ret = 0;
5994 struct nlattr *params;
5995 int ifindex;
5996
5997 ifindex = if_nametoindex(intf);
5998 if (ifindex == 0) {
5999 sigma_dut_print(dut, DUT_MSG_ERROR,
6000 "%s: Index for interface %s failed, val:%d",
6001 __func__, intf, val);
6002 return -1;
6003 }
6004
6005 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6006 NL80211_CMD_VENDOR)) ||
6007 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6008 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6009 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6010 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6011 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6012 nla_put_u8(msg,
6013 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
6014 val)) {
6015 sigma_dut_print(dut, DUT_MSG_ERROR,
6016 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6017 __func__, val);
6018 nlmsg_free(msg);
6019 return -1;
6020 }
6021 nla_nest_end(msg, params);
6022
6023 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6024 if (ret) {
6025 sigma_dut_print(dut, DUT_MSG_ERROR,
6026 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6027 __func__, ret, val);
6028 }
6029 return ret;
6030#else /* NL80211_SUPPORT */
6031 sigma_dut_print(dut, DUT_MSG_ERROR,
6032 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
6033 return -1;
6034#endif /* NL80211_SUPPORT */
6035}
6036
6037
Arif Hussain68d23f52018-07-11 13:39:08 -07006038#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006039static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
6040 enum qca_wlan_he_mac_padding_dur val)
6041{
Arif Hussain68d23f52018-07-11 13:39:08 -07006042 struct nl_msg *msg;
6043 int ret = 0;
6044 struct nlattr *params;
6045 int ifindex;
6046
6047 ifindex = if_nametoindex(intf);
6048 if (ifindex == 0) {
6049 sigma_dut_print(dut, DUT_MSG_ERROR,
6050 "%s: Index for interface %s failed, val:%d",
6051 __func__, intf, val);
6052 return -1;
6053 }
6054
6055 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6056 NL80211_CMD_VENDOR)) ||
6057 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6058 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6059 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6060 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6061 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6062 nla_put_u8(msg,
6063 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
6064 val)) {
6065 sigma_dut_print(dut, DUT_MSG_ERROR,
6066 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6067 __func__, val);
6068 nlmsg_free(msg);
6069 return -1;
6070 }
6071 nla_nest_end(msg, params);
6072
6073 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6074 if (ret) {
6075 sigma_dut_print(dut, DUT_MSG_ERROR,
6076 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6077 __func__, ret, val);
6078 }
6079 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07006080}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006081#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07006082
6083
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006084static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
6085 int val)
6086{
6087#ifdef NL80211_SUPPORT
6088 struct nl_msg *msg;
6089 int ret = 0;
6090 struct nlattr *params;
6091 int ifindex;
6092
6093 ifindex = if_nametoindex(intf);
6094 if (ifindex == 0) {
6095 sigma_dut_print(dut, DUT_MSG_ERROR,
6096 "%s: Index for interface %s failed, val:%d",
6097 __func__, intf, val);
6098 return -1;
6099 }
6100
6101 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6102 NL80211_CMD_VENDOR)) ||
6103 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6104 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6105 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6106 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6107 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6108 nla_put_u8(msg,
6109 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
6110 val)) {
6111 sigma_dut_print(dut, DUT_MSG_ERROR,
6112 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6113 __func__, val);
6114 nlmsg_free(msg);
6115 return -1;
6116 }
6117 nla_nest_end(msg, params);
6118
6119 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6120 if (ret) {
6121 sigma_dut_print(dut, DUT_MSG_ERROR,
6122 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6123 __func__, ret, val);
6124 }
6125 return ret;
6126#else /* NL80211_SUPPORT */
6127 sigma_dut_print(dut, DUT_MSG_ERROR,
6128 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
6129 return -1;
6130#endif /* NL80211_SUPPORT */
6131}
6132
6133
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006134static int sta_set_he_om_ctrl_nss(struct sigma_dut *dut, const char *intf,
6135 int val)
6136{
6137#ifdef NL80211_SUPPORT
6138 struct nl_msg *msg;
6139 int ret = 0;
6140 struct nlattr *params;
6141 int ifindex;
6142
6143 ifindex = if_nametoindex(intf);
6144 if (ifindex == 0) {
6145 sigma_dut_print(dut, DUT_MSG_ERROR,
6146 "%s: Index for interface %s failed, val:%d",
6147 __func__, intf, val);
6148 return -1;
6149 }
6150
6151 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6152 NL80211_CMD_VENDOR)) ||
6153 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6154 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6155 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6156 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6157 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6158 nla_put_u8(msg,
6159 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS,
6160 val)) {
6161 sigma_dut_print(dut, DUT_MSG_ERROR,
6162 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6163 __func__, val);
6164 nlmsg_free(msg);
6165 return -1;
6166 }
6167 nla_nest_end(msg, params);
6168
6169 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6170 if (ret) {
6171 sigma_dut_print(dut, DUT_MSG_ERROR,
6172 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6173 __func__, ret, val);
6174 }
6175 return ret;
6176#else /* NL80211_SUPPORT */
6177 sigma_dut_print(dut, DUT_MSG_ERROR,
6178 "OM CTRL NSS cannot be set without NL80211_SUPPORT defined");
6179 return -1;
6180#endif /* NL80211_SUPPORT */
6181}
6182
6183
6184static int sta_set_he_om_ctrl_bw(struct sigma_dut *dut, const char *intf,
6185 enum qca_wlan_he_om_ctrl_ch_bw val)
6186{
6187#ifdef NL80211_SUPPORT
6188 struct nl_msg *msg;
6189 int ret = 0;
6190 struct nlattr *params;
6191 int ifindex;
6192
6193 ifindex = if_nametoindex(intf);
6194 if (ifindex == 0) {
6195 sigma_dut_print(dut, DUT_MSG_ERROR,
6196 "%s: Index for interface %s failed, val:%d",
6197 __func__, intf, val);
6198 return -1;
6199 }
6200
6201 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6202 NL80211_CMD_VENDOR)) ||
6203 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6204 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6205 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6206 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6207 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6208 nla_put_u8(msg,
6209 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW,
6210 val)) {
6211 sigma_dut_print(dut, DUT_MSG_ERROR,
6212 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6213 __func__, val);
6214 nlmsg_free(msg);
6215 return -1;
6216 }
6217 nla_nest_end(msg, params);
6218
6219 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6220 if (ret) {
6221 sigma_dut_print(dut, DUT_MSG_ERROR,
6222 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6223 __func__, ret, val);
6224 }
6225 return ret;
6226#else /* NL80211_SUPPORT */
6227 sigma_dut_print(dut, DUT_MSG_ERROR,
6228 "OM CTRL BW cannot be set without NL80211_SUPPORT defined");
6229 return -1;
6230#endif /* NL80211_SUPPORT */
6231}
6232
6233
6234#ifdef NL80211_SUPPORT
6235static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
6236{
6237 struct nl_msg *msg;
6238 int ret = 0;
6239 struct nlattr *params;
6240 int ifindex;
6241
6242 ifindex = if_nametoindex(intf);
6243 if (ifindex == 0) {
6244 sigma_dut_print(dut, DUT_MSG_ERROR,
6245 "%s: Index for interface %s failed",
6246 __func__, intf);
6247 return -1;
6248 }
6249
6250 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6251 NL80211_CMD_VENDOR)) ||
6252 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6253 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6254 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6255 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6256 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6257 nla_put_flag(msg,
6258 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
6259 sigma_dut_print(dut, DUT_MSG_ERROR,
6260 "%s: err in adding vendor_cmd and vendor_data",
6261 __func__);
6262 nlmsg_free(msg);
6263 return -1;
6264 }
6265 nla_nest_end(msg, params);
6266
6267 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6268 if (ret) {
6269 sigma_dut_print(dut, DUT_MSG_ERROR,
6270 "%s: err in send_and_recv_msgs, ret=%d",
6271 __func__, ret);
6272 }
6273 return ret;
6274}
6275#endif /* NL80211_SUPPORT */
6276
6277
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006278static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
6279 int val)
6280{
6281#ifdef NL80211_SUPPORT
6282 struct nl_msg *msg;
6283 int ret = 0;
6284 struct nlattr *params;
6285 int ifindex;
6286
6287 ifindex = if_nametoindex(intf);
6288 if (ifindex == 0) {
6289 sigma_dut_print(dut, DUT_MSG_ERROR,
6290 "%s: Index for interface %s failed, val:%d",
6291 __func__, intf, val);
6292 return -1;
6293 }
6294
6295 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6296 NL80211_CMD_VENDOR)) ||
6297 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6298 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6299 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6300 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6301 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6302 nla_put_u8(msg,
6303 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
6304 val)) {
6305 sigma_dut_print(dut, DUT_MSG_ERROR,
6306 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6307 __func__, val);
6308 nlmsg_free(msg);
6309 return -1;
6310 }
6311 nla_nest_end(msg, params);
6312
6313 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6314 if (ret) {
6315 sigma_dut_print(dut, DUT_MSG_ERROR,
6316 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6317 __func__, ret, val);
6318 }
6319 return ret;
6320#else /* NL80211_SUPPORT */
6321 sigma_dut_print(dut, DUT_MSG_ERROR,
6322 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
6323 return -1;
6324#endif /* NL80211_SUPPORT */
6325}
6326
6327
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006328static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
6329 int val)
6330{
6331#ifdef NL80211_SUPPORT
6332 struct nl_msg *msg;
6333 int ret = 0;
6334 struct nlattr *params;
6335 int ifindex;
6336
6337 ifindex = if_nametoindex(intf);
6338 if (ifindex == 0) {
6339 sigma_dut_print(dut, DUT_MSG_ERROR,
6340 "%s: Index for interface %s failed, val:%d",
6341 __func__, intf, val);
6342 return -1;
6343 }
6344
6345 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6346 NL80211_CMD_VENDOR)) ||
6347 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6348 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6349 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6350 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6351 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6352 nla_put_u8(msg,
6353 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
6354 val)) {
6355 sigma_dut_print(dut, DUT_MSG_ERROR,
6356 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6357 __func__, val);
6358 nlmsg_free(msg);
6359 return -1;
6360 }
6361 nla_nest_end(msg, params);
6362
6363 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6364 if (ret) {
6365 sigma_dut_print(dut, DUT_MSG_ERROR,
6366 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6367 __func__, ret, val);
6368 }
6369 return ret;
6370#else /* NL80211_SUPPORT */
6371 sigma_dut_print(dut, DUT_MSG_ERROR,
6372 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
6373 return -1;
6374#endif /* NL80211_SUPPORT */
6375}
6376
6377
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006378static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
6379 const char *type)
6380{
6381 char buf[60];
6382
6383 if (dut->program == PROGRAM_HE) {
6384 /* resetting phymode to auto in case of HE program */
6385 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
6386 if (system(buf) != 0) {
6387 sigma_dut_print(dut, DUT_MSG_ERROR,
6388 "iwpriv %s setphymode failed", intf);
6389 }
6390
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07006391 /* reset the rate to Auto rate */
6392 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
6393 intf);
6394 if (system(buf) != 0) {
6395 sigma_dut_print(dut, DUT_MSG_ERROR,
6396 "iwpriv %s set_11ax_rate 0xff failed",
6397 intf);
6398 }
6399
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07006400 /* reset the LDPC setting */
6401 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
6402 if (system(buf) != 0) {
6403 sigma_dut_print(dut, DUT_MSG_ERROR,
6404 "iwpriv %s ldpc 1 failed", intf);
6405 }
6406
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006407 /* reset the power save setting */
6408 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
6409 if (system(buf) != 0) {
6410 sigma_dut_print(dut, DUT_MSG_ERROR,
6411 "iwpriv %s setPower 2 failed", intf);
6412 }
6413
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006414 /* remove all network profiles */
6415 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006416
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006417 /* Configure ADDBA Req/Rsp buffer size to be 64 */
6418 sta_set_addba_buf_size(dut, intf, 64);
6419
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08006420#ifdef NL80211_SUPPORT
6421 /* Disable noackpolicy for all AC */
6422 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
6423 sigma_dut_print(dut, DUT_MSG_ERROR,
6424 "Disable of noackpolicy for all AC failed");
6425 }
6426#endif /* NL80211_SUPPORT */
6427
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08006428 /* Enable WMM by default */
6429 if (wcn_sta_set_wmm(dut, intf, "on")) {
6430 sigma_dut_print(dut, DUT_MSG_ERROR,
6431 "Enable of WMM in sta_reset_default_wcn failed");
6432 }
6433
6434 /* Disable ADDBA_REJECT by default */
6435 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
6436 sigma_dut_print(dut, DUT_MSG_ERROR,
6437 "Disable of addba_reject in sta_reset_default_wcn failed");
6438 }
6439
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006440 /* Enable sending of ADDBA by default */
6441 if (nlvendor_config_send_addba(dut, intf, 1)) {
6442 sigma_dut_print(dut, DUT_MSG_ERROR,
6443 "Enable sending of ADDBA in sta_reset_default_wcn failed");
6444 }
6445
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08006446 /* Enable AMPDU by default */
6447 iwpriv_sta_set_ampdu(dut, intf, 1);
6448
Subhani Shaik8e7a3052018-04-24 14:03:00 -07006449#ifdef NL80211_SUPPORT
6450 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
6451 sigma_dut_print(dut, DUT_MSG_ERROR,
6452 "Set LTF config to default in sta_reset_default_wcn failed");
6453 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07006454
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08006455 /* set the beamformee NSTS(maximum number of
6456 * space-time streams) to default DUT config
6457 */
6458 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07006459 sigma_dut_print(dut, DUT_MSG_ERROR,
6460 "Failed to set BeamformeeSTS");
6461 }
Arif Hussain68d23f52018-07-11 13:39:08 -07006462
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006463 if (sta_set_mac_padding_duration(
6464 dut, intf,
6465 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07006466 sigma_dut_print(dut, DUT_MSG_ERROR,
6467 "Failed to set MAC padding duration");
6468 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006469
6470 if (sta_set_mu_edca_override(dut, intf, 0)) {
6471 sigma_dut_print(dut, DUT_MSG_ERROR,
6472 "ErrorCode,Failed to set MU EDCA override disable");
6473 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006474
6475 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
6476 sigma_dut_print(dut, DUT_MSG_ERROR,
6477 "Failed to set OM ctrl supp");
6478 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006479
6480 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
6481 sigma_dut_print(dut, DUT_MSG_ERROR,
6482 "Failed to set Tx SU PPDU enable");
6483 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006484
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006485 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
6486 sigma_dut_print(dut, DUT_MSG_ERROR,
6487 "failed to send TB PPDU Tx cfg");
6488 }
6489
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006490 if (sta_set_he_om_ctrl_reset(dut, intf)) {
6491 sigma_dut_print(dut, DUT_MSG_ERROR,
6492 "Failed to set OM ctrl reset");
6493 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07006494#endif /* NL80211_SUPPORT */
6495
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006496 if (sta_set_tx_beamformee(dut, intf, 1)) {
6497 sigma_dut_print(dut, DUT_MSG_ERROR,
6498 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
6499 }
6500
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006501 /* Set nss to 1 and MCS 0-7 in case of testbed */
6502 if (type && strcasecmp(type, "Testbed") == 0) {
6503#ifdef NL80211_SUPPORT
6504 int ret;
6505#endif /* NL80211_SUPPORT */
6506
6507 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
6508 if (system(buf) != 0) {
6509 sigma_dut_print(dut, DUT_MSG_ERROR,
6510 "iwpriv %s nss failed", intf);
6511 }
6512
6513#ifdef NL80211_SUPPORT
6514 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
6515 if (ret) {
6516 sigma_dut_print(dut, DUT_MSG_ERROR,
6517 "Setting of MCS failed, ret:%d",
6518 ret);
6519 }
6520#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08006521
6522 /* Disable STBC as default */
6523 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006524
6525 /* Disable AMSDU as default */
6526 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08006527
6528#ifdef NL80211_SUPPORT
6529 /* HE fragmentation default off */
6530 if (sta_set_he_fragmentation(dut, intf,
6531 HE_FRAG_DISABLE)) {
6532 sigma_dut_print(dut, DUT_MSG_ERROR,
6533 "Setting of HE fragmentation failed");
6534 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08006535
6536 /* set the beamformee NSTS(maximum number of
6537 * space-time streams) to default testbed config
6538 */
6539 if (sta_set_beamformee_sts(dut, intf, 3)) {
6540 sigma_dut_print(dut, DUT_MSG_ERROR,
6541 "Failed to set BeamformeeSTS");
6542 }
6543
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08006544#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006545
6546 /* Enable WEP/TKIP with HE capability in testbed */
6547 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
6548 sigma_dut_print(dut, DUT_MSG_ERROR,
6549 "Enabling HE config with WEP/TKIP failed");
6550 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006551 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006552
6553 /* Defaults in case of DUT */
6554 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07006555 /* Enable STBC by default */
6556 wcn_sta_set_stbc(dut, intf, "1");
6557
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006558 /* set nss to 2 */
6559 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
6560 if (system(buf) != 0) {
6561 sigma_dut_print(dut, DUT_MSG_ERROR,
6562 "iwpriv %s nss 2 failed", intf);
6563 }
Arif Hussainac6c5112018-05-25 17:34:00 -07006564 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006565
6566#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07006567 /* Set HE_MCS to 0-11 */
6568 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006569 sigma_dut_print(dut, DUT_MSG_ERROR,
6570 "Setting of MCS failed");
6571 }
6572#endif /* NL80211_SUPPORT */
6573
6574 /* Disable WEP/TKIP with HE capability in DUT */
6575 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
6576 sigma_dut_print(dut, DUT_MSG_ERROR,
6577 "Enabling HE config with WEP/TKIP failed");
6578 }
6579 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006580 }
6581}
6582
6583
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006584static int cmd_sta_reset_default(struct sigma_dut *dut,
6585 struct sigma_conn *conn,
6586 struct sigma_cmd *cmd)
6587{
6588 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
6589 struct sigma_cmd *cmd);
6590 const char *intf = get_param(cmd, "Interface");
6591 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006592 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05306593 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006594
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006595 if (!program)
6596 program = get_param(cmd, "prog");
6597 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006598 dut->device_type = STA_unknown;
6599 type = get_param(cmd, "type");
6600 if (type && strcasecmp(type, "Testbed") == 0)
6601 dut->device_type = STA_testbed;
6602 if (type && strcasecmp(type, "DUT") == 0)
6603 dut->device_type = STA_dut;
6604
6605 if (dut->program == PROGRAM_TDLS) {
6606 /* Clear TDLS testing mode */
6607 wpa_command(intf, "SET tdls_disabled 0");
6608 wpa_command(intf, "SET tdls_testing 0");
6609 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05306610 if (get_driver_type() == DRIVER_WCN) {
6611 /* Enable the WCN driver in TDLS Explicit trigger mode
6612 */
6613 wpa_command(intf, "SET tdls_external_control 0");
6614 wpa_command(intf, "SET tdls_trigger_control 0");
6615 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006616 }
6617
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006618#ifdef MIRACAST
6619 if (dut->program == PROGRAM_WFD ||
6620 dut->program == PROGRAM_DISPLAYR2)
6621 miracast_sta_reset_default(dut, conn, cmd);
6622#endif /* MIRACAST */
6623
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006624 switch (get_driver_type()) {
6625 case DRIVER_ATHEROS:
6626 sta_reset_default_ath(dut, intf, type);
6627 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006628 case DRIVER_WCN:
6629 sta_reset_default_wcn(dut, intf, type);
6630 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006631 default:
6632 break;
6633 }
6634
6635#ifdef ANDROID_NAN
6636 if (dut->program == PROGRAM_NAN)
6637 nan_cmd_sta_reset_default(dut, conn, cmd);
6638#endif /* ANDROID_NAN */
6639
Jouni Malinenba630452018-06-22 11:49:59 +03006640 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006641 unlink("SP/wi-fi.org/pps.xml");
6642 if (system("rm -r SP/*") != 0) {
6643 }
6644 unlink("next-client-cert.pem");
6645 unlink("next-client-key.pem");
6646 }
6647
6648 if (dut->program == PROGRAM_60GHZ) {
6649 const char *dev_role = get_param(cmd, "DevRole");
6650
6651 if (!dev_role) {
6652 send_resp(dut, conn, SIGMA_ERROR,
6653 "errorCode,Missing DevRole argument");
6654 return 0;
6655 }
6656
6657 if (strcasecmp(dev_role, "STA") == 0)
6658 dut->dev_role = DEVROLE_STA;
6659 else if (strcasecmp(dev_role, "PCP") == 0)
6660 dut->dev_role = DEVROLE_PCP;
6661 else {
6662 send_resp(dut, conn, SIGMA_ERROR,
6663 "errorCode,Unknown DevRole");
6664 return 0;
6665 }
6666
6667 if (dut->device_type == STA_unknown) {
6668 sigma_dut_print(dut, DUT_MSG_ERROR,
6669 "Device type is not STA testbed or DUT");
6670 send_resp(dut, conn, SIGMA_ERROR,
6671 "errorCode,Unknown device type");
6672 return 0;
6673 }
6674 }
6675
6676 wpa_command(intf, "WPS_ER_STOP");
6677 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05306678 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006679 wpa_command(intf, "SET radio_disabled 0");
6680
6681 if (dut->tmp_mac_addr && dut->set_macaddr) {
6682 dut->tmp_mac_addr = 0;
6683 if (system(dut->set_macaddr) != 0) {
6684 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
6685 "temporary MAC address");
6686 }
6687 }
6688
6689 set_ps(intf, dut, 0);
6690
Jouni Malinenba630452018-06-22 11:49:59 +03006691 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
6692 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006693 wpa_command(intf, "SET interworking 1");
6694 wpa_command(intf, "SET hs20 1");
6695 }
6696
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08006697 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03006698 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08006699 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006700 wpa_command(intf, "SET pmf 1");
6701 } else {
6702 wpa_command(intf, "SET pmf 0");
6703 }
6704
6705 hs2_clear_credentials(intf);
6706 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
6707 wpa_command(intf, "SET access_network_type 15");
6708
6709 static_ip_file(0, NULL, NULL, NULL);
6710 kill_dhcp_client(dut, intf);
6711 clear_ip_addr(dut, intf);
6712
6713 dut->er_oper_performed = 0;
6714 dut->er_oper_bssid[0] = '\0';
6715
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07006716 if (dut->program == PROGRAM_LOC) {
6717 /* Disable Interworking by default */
6718 wpa_command(get_station_ifname(), "SET interworking 0");
6719 }
6720
Ashwini Patil00402582017-04-13 12:29:39 +05306721 if (dut->program == PROGRAM_MBO) {
6722 free(dut->non_pref_ch_list);
6723 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05306724 free(dut->btm_query_cand_list);
6725 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05306726 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05306727 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05306728 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306729 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05306730 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05306731 }
6732
Jouni Malinen3c367e82017-06-23 17:01:47 +03006733 free(dut->rsne_override);
6734 dut->rsne_override = NULL;
6735
Jouni Malinen68143132017-09-02 02:34:08 +03006736 free(dut->sae_commit_override);
6737 dut->sae_commit_override = NULL;
6738
Jouni Malinend86e5822017-08-29 03:55:32 +03006739 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02006740 free(dut->dpp_peer_uri);
6741 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02006742 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02006743 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03006744
Jouni Malinenfac9cad2017-10-10 18:35:55 +03006745 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
6746
vamsi krishnaa2799492017-12-05 14:28:01 +05306747 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306748 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05306749 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05306750 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
6751 dut->fils_hlp = 0;
6752#ifdef ANDROID
6753 hlp_thread_cleanup(dut);
6754#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05306755 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306756
Sunil Dutt076081f2018-02-05 19:45:50 +05306757#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05306758 if (get_driver_type() == DRIVER_WCN &&
6759 dut->config_rsnie == 1) {
6760 dut->config_rsnie = 0;
6761 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05306762 }
6763#endif /* NL80211_SUPPORT */
6764
Sunil Duttfebf8a82018-02-09 18:50:13 +05306765 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
6766 dut->dev_role = DEVROLE_STA_CFON;
6767 return sta_cfon_reset_default(dut, conn, cmd);
6768 }
6769
Jouni Malinen439352d2018-09-13 03:42:23 +03006770 wpa_command(intf, "SET setband AUTO");
6771
Sunil Duttfebf8a82018-02-09 18:50:13 +05306772 if (dut->program != PROGRAM_VHT)
6773 return cmd_sta_p2p_reset(dut, conn, cmd);
6774
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08006775 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006776}
6777
6778
6779static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
6780 struct sigma_cmd *cmd)
6781{
6782 const char *program = get_param(cmd, "Program");
6783
6784 if (program == NULL)
6785 return -1;
6786#ifdef ANDROID_NAN
6787 if (strcasecmp(program, "NAN") == 0)
6788 return nan_cmd_sta_get_events(dut, conn, cmd);
6789#endif /* ANDROID_NAN */
6790 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6791 return 0;
6792}
6793
6794
Jouni Malinen82905202018-04-29 17:20:10 +03006795static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
6796 struct sigma_cmd *cmd)
6797{
6798 const char *url = get_param(cmd, "url");
6799 const char *method = get_param(cmd, "method");
6800 pid_t pid;
6801 int status;
6802
6803 if (!url || !method)
6804 return -1;
6805
6806 /* TODO: Add support for method,post */
6807 if (strcasecmp(method, "get") != 0) {
6808 send_resp(dut, conn, SIGMA_ERROR,
6809 "ErrorCode,Unsupported method");
6810 return 0;
6811 }
6812
6813 pid = fork();
6814 if (pid < 0) {
6815 perror("fork");
6816 return -1;
6817 }
6818
6819 if (pid == 0) {
6820 char * argv[5] = { "wget", "-O", "/dev/null",
6821 (char *) url, NULL };
6822
6823 execv("/usr/bin/wget", argv);
6824 perror("execv");
6825 exit(0);
6826 return -1;
6827 }
6828
6829 if (waitpid(pid, &status, 0) < 0) {
6830 perror("waitpid");
6831 return -1;
6832 }
6833
6834 if (WIFEXITED(status)) {
6835 const char *errmsg;
6836
6837 if (WEXITSTATUS(status) == 0)
6838 return 1;
6839 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
6840 WEXITSTATUS(status));
6841 switch (WEXITSTATUS(status)) {
6842 case 4:
6843 errmsg = "errmsg,Network failure";
6844 break;
6845 case 8:
6846 errmsg = "errmsg,Server issued an error response";
6847 break;
6848 default:
6849 errmsg = "errmsg,Unknown failure from wget";
6850 break;
6851 }
6852 send_resp(dut, conn, SIGMA_ERROR, errmsg);
6853 return 0;
6854 }
6855
6856 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
6857 return 0;
6858}
6859
6860
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006861static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
6862 struct sigma_cmd *cmd)
6863{
6864 const char *program = get_param(cmd, "Prog");
6865
Jouni Malinen82905202018-04-29 17:20:10 +03006866 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006867 return -1;
6868#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03006869 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006870 return nan_cmd_sta_exec_action(dut, conn, cmd);
6871#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03006872
6873 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07006874 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03006875
6876 if (get_param(cmd, "url"))
6877 return sta_exec_action_url(dut, conn, cmd);
6878
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006879 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6880 return 0;
6881}
6882
6883
6884static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
6885 struct sigma_cmd *cmd)
6886{
6887 const char *intf = get_param(cmd, "Interface");
6888 const char *val, *mcs32, *rate;
6889
6890 val = get_param(cmd, "GREENFIELD");
6891 if (val) {
6892 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6893 /* Enable GD */
6894 send_resp(dut, conn, SIGMA_ERROR,
6895 "ErrorCode,GF not supported");
6896 return 0;
6897 }
6898 }
6899
6900 val = get_param(cmd, "SGI20");
6901 if (val) {
6902 switch (get_driver_type()) {
6903 case DRIVER_ATHEROS:
6904 ath_sta_set_sgi(dut, intf, val);
6905 break;
6906 default:
6907 send_resp(dut, conn, SIGMA_ERROR,
6908 "ErrorCode,SGI20 not supported");
6909 return 0;
6910 }
6911 }
6912
6913 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
6914 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
6915 if (mcs32 && rate) {
6916 /* TODO */
6917 send_resp(dut, conn, SIGMA_ERROR,
6918 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
6919 return 0;
6920 } else if (mcs32 && !rate) {
6921 /* TODO */
6922 send_resp(dut, conn, SIGMA_ERROR,
6923 "ErrorCode,MCS32 not supported");
6924 return 0;
6925 } else if (!mcs32 && rate) {
6926 switch (get_driver_type()) {
6927 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08006928 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006929 ath_sta_set_11nrates(dut, intf, rate);
6930 break;
6931 default:
6932 send_resp(dut, conn, SIGMA_ERROR,
6933 "ErrorCode,MCS32_FIXEDRATE not supported");
6934 return 0;
6935 }
6936 }
6937
6938 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
6939}
6940
6941
Arif Hussain7b47d2d2018-05-09 10:44:02 -07006942static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
6943 int mcs_config)
6944{
6945#ifdef NL80211_SUPPORT
6946 int ret;
6947
6948 switch (mcs_config) {
6949 case HE_80_MCS0_7:
6950 case HE_80_MCS0_9:
6951 case HE_80_MCS0_11:
6952 ret = sta_set_he_mcs(dut, intf, mcs_config);
6953 if (ret) {
6954 sigma_dut_print(dut, DUT_MSG_ERROR,
6955 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
6956 mcs_config, ret);
6957 }
6958 break;
6959 default:
6960 sigma_dut_print(dut, DUT_MSG_ERROR,
6961 "cmd_set_max_he_mcs: Invalid mcs %d",
6962 mcs_config);
6963 break;
6964 }
6965#else /* NL80211_SUPPORT */
6966 sigma_dut_print(dut, DUT_MSG_ERROR,
6967 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
6968#endif /* NL80211_SUPPORT */
6969}
6970
6971
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006972static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
6973 struct sigma_conn *conn,
6974 struct sigma_cmd *cmd)
6975{
6976 const char *intf = get_param(cmd, "Interface");
6977 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07006978 const char *program;
Arif Hussaind13d6952018-07-02 16:23:47 -07006979 char buf[60];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006980 int tkip = -1;
6981 int wep = -1;
6982
Arif Hussaina37e9552018-06-20 17:05:59 -07006983 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006984 val = get_param(cmd, "SGI80");
6985 if (val) {
6986 int sgi80;
6987
6988 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
6989 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi80);
6990 if (system(buf) != 0) {
6991 sigma_dut_print(dut, DUT_MSG_ERROR,
6992 "iwpriv shortgi failed");
6993 }
6994 }
6995
6996 val = get_param(cmd, "TxBF");
6997 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07006998 switch (get_driver_type()) {
6999 case DRIVER_WCN:
7000 if (sta_set_tx_beamformee(dut, intf, 1)) {
7001 send_resp(dut, conn, SIGMA_ERROR,
7002 "ErrorCode,Failed to set TX beamformee enable");
7003 return 0;
7004 }
7005 break;
7006 case DRIVER_ATHEROS:
7007 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 1",
7008 intf);
7009 if (system(buf) != 0) {
7010 send_resp(dut, conn, SIGMA_ERROR,
7011 "ErrorCode,Setting vhtsubfee failed");
7012 return 0;
7013 }
7014
7015 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 1",
7016 intf);
7017 if (system(buf) != 0) {
7018 send_resp(dut, conn, SIGMA_ERROR,
7019 "ErrorCode,Setting vhtsubfer failed");
7020 return 0;
7021 }
7022 break;
7023 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007024 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007025 "Unsupported driver type");
7026 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007027 }
7028 }
7029
7030 val = get_param(cmd, "MU_TxBF");
7031 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
7032 switch (get_driver_type()) {
7033 case DRIVER_ATHEROS:
7034 ath_sta_set_txsp_stream(dut, intf, "1SS");
7035 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Sunil Duttae9e5d12018-06-29 11:50:47 +05307036 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 1",
7037 intf);
7038 if (system(buf) != 0) {
7039 sigma_dut_print(dut, DUT_MSG_ERROR,
7040 "iwpriv vhtmubfee failed");
7041 }
7042 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 1",
7043 intf);
7044 if (system(buf) != 0) {
7045 sigma_dut_print(dut, DUT_MSG_ERROR,
7046 "iwpriv vhtmubfer failed");
7047 }
7048 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007049 case DRIVER_WCN:
7050 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
7051 send_resp(dut, conn, SIGMA_ERROR,
7052 "ErrorCode,Failed to set RX/TXSP_STREAM");
7053 return 0;
7054 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05307055 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007056 default:
7057 sigma_dut_print(dut, DUT_MSG_ERROR,
7058 "Setting SP_STREAM not supported");
7059 break;
7060 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007061 }
7062
7063 val = get_param(cmd, "LDPC");
7064 if (val) {
7065 int ldpc;
7066
7067 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7068 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, ldpc);
7069 if (system(buf) != 0) {
7070 sigma_dut_print(dut, DUT_MSG_ERROR,
7071 "iwpriv ldpc failed");
7072 }
7073 }
7074
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08007075 val = get_param(cmd, "BCC");
7076 if (val) {
7077 int bcc;
7078
7079 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7080 /* use LDPC iwpriv itself to set bcc coding, bcc coding
7081 * is mutually exclusive to bcc */
7082 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, !bcc);
7083 if (system(buf) != 0) {
7084 sigma_dut_print(dut, DUT_MSG_ERROR,
7085 "Enabling/Disabling of BCC failed");
7086 }
7087 }
7088
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007089 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
7090 if (val && dut->sta_nss == 1)
7091 cmd_set_max_he_mcs(dut, intf, atoi(val));
7092
7093 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
7094 if (val && dut->sta_nss == 2)
7095 cmd_set_max_he_mcs(dut, intf, atoi(val));
7096
Arif Hussainac6c5112018-05-25 17:34:00 -07007097 val = get_param(cmd, "MCS_FixedRate");
7098 if (val) {
7099#ifdef NL80211_SUPPORT
7100 int mcs, ratecode = 0;
7101 enum he_mcs_config mcs_config;
7102 int ret;
7103
7104 ratecode = (0x07 & dut->sta_nss) << 5;
7105 mcs = atoi(val);
7106 /* Add the MCS to the ratecode */
7107 if (mcs >= 0 && mcs <= 11) {
7108 ratecode += mcs;
7109 if (dut->device_type == STA_testbed &&
7110 mcs > 7 && mcs <= 11) {
7111 if (mcs <= 9)
7112 mcs_config = HE_80_MCS0_9;
7113 else
7114 mcs_config = HE_80_MCS0_11;
7115 ret = sta_set_he_mcs(dut, intf, mcs_config);
7116 if (ret) {
7117 sigma_dut_print(dut, DUT_MSG_ERROR,
7118 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
7119 mcs, mcs_config, ret);
7120 }
7121 }
7122 snprintf(buf, sizeof(buf),
7123 "iwpriv %s set_11ax_rate 0x%03x",
7124 intf, ratecode);
7125 if (system(buf) != 0) {
7126 sigma_dut_print(dut, DUT_MSG_ERROR,
7127 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
7128 ratecode);
7129 }
7130 } else {
7131 sigma_dut_print(dut, DUT_MSG_ERROR,
7132 "MCS_FixedRate: HE MCS %d not supported",
7133 mcs);
7134 }
7135#else /* NL80211_SUPPORT */
7136 sigma_dut_print(dut, DUT_MSG_ERROR,
7137 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
7138#endif /* NL80211_SUPPORT */
7139 }
7140
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007141 val = get_param(cmd, "opt_md_notif_ie");
7142 if (val) {
7143 char *result = NULL;
7144 char delim[] = ";";
7145 char token[30];
7146 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307147 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007148
Peng Xub8fc5cc2017-05-10 17:27:28 -07007149 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307150 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007151
7152 /* Extract the NSS information */
7153 if (result) {
7154 value = atoi(result);
7155 switch (value) {
7156 case 1:
7157 config_val = 1;
7158 break;
7159 case 2:
7160 config_val = 3;
7161 break;
7162 case 3:
7163 config_val = 7;
7164 break;
7165 case 4:
7166 config_val = 15;
7167 break;
7168 default:
7169 config_val = 3;
7170 break;
7171 }
7172
7173 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
7174 intf, config_val);
7175 if (system(buf) != 0) {
7176 sigma_dut_print(dut, DUT_MSG_ERROR,
7177 "iwpriv rxchainmask failed");
7178 }
7179
7180 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
7181 intf, config_val);
7182 if (system(buf) != 0) {
7183 sigma_dut_print(dut, DUT_MSG_ERROR,
7184 "iwpriv txchainmask failed");
7185 }
7186 }
7187
7188 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307189 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007190 if (result) {
7191 value = atoi(result);
7192 switch (value) {
7193 case 20:
7194 config_val = 0;
7195 break;
7196 case 40:
7197 config_val = 1;
7198 break;
7199 case 80:
7200 config_val = 2;
7201 break;
7202 case 160:
7203 config_val = 3;
7204 break;
7205 default:
7206 config_val = 2;
7207 break;
7208 }
7209
7210 dut->chwidth = config_val;
7211
7212 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
7213 intf, config_val);
7214 if (system(buf) != 0) {
7215 sigma_dut_print(dut, DUT_MSG_ERROR,
7216 "iwpriv chwidth failed");
7217 }
7218 }
7219
7220 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", intf);
7221 if (system(buf) != 0) {
7222 sigma_dut_print(dut, DUT_MSG_ERROR,
7223 "iwpriv opmode_notify failed");
7224 }
7225 }
7226
7227 val = get_param(cmd, "nss_mcs_cap");
7228 if (val) {
7229 int nss, mcs;
7230 char token[20];
7231 char *result = NULL;
7232 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307233 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007234
Peng Xub8fc5cc2017-05-10 17:27:28 -07007235 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307236 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307237 if (!result) {
7238 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007239 "NSS not specified");
7240 send_resp(dut, conn, SIGMA_ERROR,
7241 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307242 return 0;
7243 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007244 nss = atoi(result);
7245
7246 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
7247 if (system(buf) != 0) {
7248 sigma_dut_print(dut, DUT_MSG_ERROR,
7249 "iwpriv nss failed");
7250 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007251 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007252
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307253 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007254 if (result == NULL) {
7255 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007256 "MCS not specified");
7257 send_resp(dut, conn, SIGMA_ERROR,
7258 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007259 return 0;
7260 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307261 result = strtok_r(result, "-", &saveptr);
7262 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307263 if (!result) {
7264 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007265 "MCS not specified");
7266 send_resp(dut, conn, SIGMA_ERROR,
7267 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307268 return 0;
7269 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007270 mcs = atoi(result);
7271
Arif Hussaina37e9552018-06-20 17:05:59 -07007272 if (program && strcasecmp(program, "HE") == 0) {
7273#ifdef NL80211_SUPPORT
7274 enum he_mcs_config mcs_config;
7275 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007276
Arif Hussaina37e9552018-06-20 17:05:59 -07007277 if (mcs >= 0 && mcs <= 7) {
7278 mcs_config = HE_80_MCS0_7;
7279 } else if (mcs > 7 && mcs <= 9) {
7280 mcs_config = HE_80_MCS0_9;
7281 } else if (mcs > 9 && mcs <= 11) {
7282 mcs_config = HE_80_MCS0_11;
7283 } else {
7284 sigma_dut_print(dut, DUT_MSG_ERROR,
7285 "nss_mcs_cap: HE: Invalid mcs: %d",
7286 mcs);
7287 send_resp(dut, conn, SIGMA_ERROR,
7288 "errorCode,Invalid MCS");
7289 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007290 }
Arif Hussaina37e9552018-06-20 17:05:59 -07007291
7292 ret = sta_set_he_mcs(dut, intf, mcs_config);
7293 if (ret) {
7294 sigma_dut_print(dut, DUT_MSG_ERROR,
7295 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
7296 mcs_config, ret);
7297 send_resp(dut, conn, SIGMA_ERROR,
7298 "errorCode,Failed to set MCS");
7299 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007300 }
Arif Hussaina37e9552018-06-20 17:05:59 -07007301#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007302 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007303 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
7304#endif /* NL80211_SUPPORT */
7305 } else {
7306 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
7307 intf, mcs);
7308 if (system(buf) != 0) {
7309 sigma_dut_print(dut, DUT_MSG_ERROR,
7310 "iwpriv mcs failed");
7311 }
7312
7313 switch (nss) {
7314 case 1:
7315 switch (mcs) {
7316 case 7:
7317 vht_mcsmap = 0xfffc;
7318 break;
7319 case 8:
7320 vht_mcsmap = 0xfffd;
7321 break;
7322 case 9:
7323 vht_mcsmap = 0xfffe;
7324 break;
7325 default:
7326 vht_mcsmap = 0xfffe;
7327 break;
7328 }
7329 break;
7330 case 2:
7331 switch (mcs) {
7332 case 7:
7333 vht_mcsmap = 0xfff0;
7334 break;
7335 case 8:
7336 vht_mcsmap = 0xfff5;
7337 break;
7338 case 9:
7339 vht_mcsmap = 0xfffa;
7340 break;
7341 default:
7342 vht_mcsmap = 0xfffa;
7343 break;
7344 }
7345 break;
7346 case 3:
7347 switch (mcs) {
7348 case 7:
7349 vht_mcsmap = 0xffc0;
7350 break;
7351 case 8:
7352 vht_mcsmap = 0xffd5;
7353 break;
7354 case 9:
7355 vht_mcsmap = 0xffea;
7356 break;
7357 default:
7358 vht_mcsmap = 0xffea;
7359 break;
7360 }
7361 break;
7362 default:
7363 vht_mcsmap = 0xffea;
7364 break;
7365 }
7366 snprintf(buf, sizeof(buf),
7367 "iwpriv %s vht_mcsmap 0x%04x",
7368 intf, vht_mcsmap);
7369 if (system(buf) != 0) {
7370 sigma_dut_print(dut, DUT_MSG_ERROR,
7371 "iwpriv vht_mcsmap failed");
7372 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007373 }
7374 }
7375
7376 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
7377
7378 val = get_param(cmd, "Vht_tkip");
7379 if (val)
7380 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7381
7382 val = get_param(cmd, "Vht_wep");
7383 if (val)
7384 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7385
7386 if (tkip != -1 || wep != -1) {
7387 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
7388 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1",
7389 intf);
7390 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
7391 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 0",
7392 intf);
7393 } else {
7394 sigma_dut_print(dut, DUT_MSG_ERROR,
7395 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
7396 return 0;
7397 }
7398
7399 if (system(buf) != 0) {
7400 sigma_dut_print(dut, DUT_MSG_ERROR,
7401 "iwpriv htweptkip failed");
7402 }
7403 }
7404
Arif Hussain55f00da2018-07-03 08:28:26 -07007405 val = get_param(cmd, "txBandwidth");
7406 if (val) {
7407 switch (get_driver_type()) {
7408 case DRIVER_WCN:
7409 if (wcn_sta_set_width(dut, intf, val) < 0) {
7410 send_resp(dut, conn, SIGMA_ERROR,
7411 "ErrorCode,Failed to set txBandwidth");
7412 return 0;
7413 }
7414 break;
7415 case DRIVER_ATHEROS:
7416 if (ath_set_width(dut, conn, intf, val) < 0) {
7417 send_resp(dut, conn, SIGMA_ERROR,
7418 "ErrorCode,Failed to set txBandwidth");
7419 return 0;
7420 }
7421 break;
7422 default:
7423 sigma_dut_print(dut, DUT_MSG_ERROR,
7424 "Setting txBandwidth not supported");
7425 break;
7426 }
7427 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007428
Arif Hussain9765f7d2018-07-03 08:28:26 -07007429 val = get_param(cmd, "BeamformeeSTS");
7430 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07007431 if (sta_set_tx_beamformee(dut, intf, 1)) {
7432 send_resp(dut, conn, SIGMA_ERROR,
7433 "ErrorCode,Failed to set TX beamformee enable");
7434 return 0;
7435 }
7436
Arif Hussain9765f7d2018-07-03 08:28:26 -07007437 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
7438 send_resp(dut, conn, SIGMA_ERROR,
7439 "ErrorCode,Failed to set BeamformeeSTS");
7440 return 0;
7441 }
7442 }
7443
Arif Hussain68d23f52018-07-11 13:39:08 -07007444 val = get_param(cmd, "Trig_MAC_Padding_Dur");
7445 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007446#ifdef NL80211_SUPPORT
7447 enum qca_wlan_he_mac_padding_dur set_val;
7448
7449 switch (atoi(val)) {
7450 case 16:
7451 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
7452 break;
7453 case 8:
7454 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
7455 break;
7456 default:
7457 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
7458 break;
7459 }
7460 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007461 send_resp(dut, conn, SIGMA_ERROR,
7462 "ErrorCode,Failed to set MAC padding duration");
7463 return 0;
7464 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007465#else /* NL80211_SUPPORT */
7466 sigma_dut_print(dut, DUT_MSG_ERROR,
7467 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
7468#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007469 }
7470
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007471 val = get_param(cmd, "MU_EDCA");
7472 if (val && (strcasecmp(val, "Override") == 0)) {
7473 if (sta_set_mu_edca_override(dut, intf, 1)) {
7474 send_resp(dut, conn, SIGMA_ERROR,
7475 "ErrorCode,Failed to set MU EDCA override");
7476 return 0;
7477 }
7478 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07007479
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007480 val = get_param(cmd, "OMControl");
7481 if (val) {
7482 int set_val = 1;
7483
7484 if (strcasecmp(val, "Enable") == 0)
7485 set_val = 1;
7486 else if (strcasecmp(val, "Disable") == 0)
7487 set_val = 0;
7488
7489 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
7490 send_resp(dut, conn, SIGMA_ERROR,
7491 "ErrorCode,Failed to set OM ctrl supp");
7492 return 0;
7493 }
7494 }
7495
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07007496 val = get_param(cmd, "ADDBAResp_BufSize");
7497 if (val) {
7498 int buf_size;
7499
7500 if (strcasecmp(val, "gt64") == 0)
7501 buf_size = 256;
7502 else
7503 buf_size = 64;
7504 if (get_driver_type() == DRIVER_WCN &&
7505 sta_set_addba_buf_size(dut, intf, buf_size)) {
7506 send_resp(dut, conn, SIGMA_ERROR,
7507 "ErrorCode,set addbaresp_buff_size failed");
7508 return 0;
7509 }
7510 }
7511
7512 val = get_param(cmd, "ADDBAReq_BufSize");
7513 if (val) {
7514 int buf_size;
7515
7516 if (strcasecmp(val, "gt64") == 0)
7517 buf_size = 256;
7518 else
7519 buf_size = 64;
7520 if (get_driver_type() == DRIVER_WCN &&
7521 sta_set_addba_buf_size(dut, intf, buf_size)) {
7522 send_resp(dut, conn, SIGMA_ERROR,
7523 "ErrorCode,set addbareq_buff_size failed");
7524 return 0;
7525 }
7526 }
7527
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007528 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7529}
7530
7531
7532static int sta_set_wireless_60g(struct sigma_dut *dut,
7533 struct sigma_conn *conn,
7534 struct sigma_cmd *cmd)
7535{
7536 const char *dev_role = get_param(cmd, "DevRole");
7537
7538 if (!dev_role) {
7539 send_resp(dut, conn, SIGMA_INVALID,
7540 "ErrorCode,DevRole not specified");
7541 return 0;
7542 }
7543
7544 if (strcasecmp(dev_role, "PCP") == 0)
7545 return sta_set_60g_pcp(dut, conn, cmd);
7546 if (strcasecmp(dev_role, "STA") == 0)
7547 return sta_set_60g_sta(dut, conn, cmd);
7548 send_resp(dut, conn, SIGMA_INVALID,
7549 "ErrorCode,DevRole not supported");
7550 return 0;
7551}
7552
7553
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307554static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
7555 struct sigma_cmd *cmd)
7556{
7557 int status;
7558 const char *intf = get_param(cmd, "Interface");
7559 const char *val = get_param(cmd, "DevRole");
7560
7561 if (val && strcasecmp(val, "STA-CFON") == 0) {
7562 status = sta_cfon_set_wireless(dut, conn, cmd);
7563 if (status)
7564 return status;
7565 }
7566 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7567}
7568
7569
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007570static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
7571 struct sigma_cmd *cmd)
7572{
7573 const char *val;
7574
7575 val = get_param(cmd, "Program");
7576 if (val) {
7577 if (strcasecmp(val, "11n") == 0)
7578 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08007579 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007580 return cmd_sta_set_wireless_vht(dut, conn, cmd);
7581 if (strcasecmp(val, "60ghz") == 0)
7582 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307583 if (strcasecmp(val, "OCE") == 0)
7584 return sta_set_wireless_oce(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007585 send_resp(dut, conn, SIGMA_ERROR,
7586 "ErrorCode,Program value not supported");
7587 } else {
7588 send_resp(dut, conn, SIGMA_ERROR,
7589 "ErrorCode,Program argument not available");
7590 }
7591
7592 return 0;
7593}
7594
7595
7596static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
7597 int tid)
7598{
7599 char buf[100];
7600 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
7601
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05307602 if (tid < 0 ||
7603 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
7604 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
7605 return;
7606 }
7607
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007608 /*
7609 * Two ways to ensure that addba request with a
7610 * non zero TID could be sent out. EV 117296
7611 */
7612 snprintf(buf, sizeof(buf),
7613 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
7614 tid);
7615 if (system(buf) != 0) {
7616 sigma_dut_print(dut, DUT_MSG_ERROR,
7617 "Ping did not send out");
7618 }
7619
7620 snprintf(buf, sizeof(buf),
7621 "iwconfig %s | grep Access | awk '{print $6}' > %s",
7622 intf, VI_QOS_TMP_FILE);
7623 if (system(buf) != 0)
7624 return;
7625
7626 snprintf(buf, sizeof(buf),
7627 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
7628 intf, VI_QOS_TMP_FILE);
7629 if (system(buf) != 0)
7630 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
7631
7632 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
7633 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
7634 if (system(buf) != 0) {
7635 sigma_dut_print(dut, DUT_MSG_ERROR,
7636 "VI_QOS_TEMP_FILE generation error failed");
7637 }
7638 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
7639 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
7640 if (system(buf) != 0) {
7641 sigma_dut_print(dut, DUT_MSG_ERROR,
7642 "VI_QOS_FILE generation failed");
7643 }
7644
7645 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
7646 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
7647 if (system(buf) != 0) {
7648 sigma_dut_print(dut, DUT_MSG_ERROR,
7649 "VI_QOS_FILE generation failed");
7650 }
7651
7652 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
7653 if (system(buf) != 0) {
7654 }
7655}
7656
7657
7658static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
7659 struct sigma_cmd *cmd)
7660{
7661 const char *intf = get_param(cmd, "Interface");
7662 const char *val;
7663 int tid = 0;
7664 char buf[100];
7665
7666 val = get_param(cmd, "TID");
7667 if (val) {
7668 tid = atoi(val);
7669 if (tid)
7670 ath_sta_inject_frame(dut, intf, tid);
7671 }
7672
7673 /* Command sequence for ADDBA request on Peregrine based devices */
7674 snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", intf);
7675 if (system(buf) != 0) {
7676 sigma_dut_print(dut, DUT_MSG_ERROR,
7677 "iwpriv setaddbaoper failed");
7678 }
7679
7680 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
7681 if (system(buf) != 0) {
7682 sigma_dut_print(dut, DUT_MSG_ERROR,
7683 "wifitool senddelba failed");
7684 }
7685
7686 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
7687 if (system(buf) != 0) {
7688 sigma_dut_print(dut, DUT_MSG_ERROR,
7689 "wifitool sendaddba failed");
7690 }
7691
7692 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
7693
7694 return 1;
7695}
7696
7697
Lior David9981b512017-01-20 13:16:40 +02007698#ifdef __linux__
7699
7700static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
7701 int agg_size)
7702{
7703 char dir[128], buf[128];
7704 FILE *f;
7705 regex_t re;
7706 regmatch_t m[2];
7707 int rc, ret = -1, vring_id, found;
7708
7709 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
7710 sigma_dut_print(dut, DUT_MSG_ERROR,
7711 "failed to get wil6210 debugfs dir");
7712 return -1;
7713 }
7714
7715 snprintf(buf, sizeof(buf), "%s/vrings", dir);
7716 f = fopen(buf, "r");
7717 if (!f) {
7718 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02007719 /* newer wil6210 driver renamed file to "rings" */
7720 snprintf(buf, sizeof(buf), "%s/rings", dir);
7721 f = fopen(buf, "r");
7722 if (!f) {
7723 sigma_dut_print(dut, DUT_MSG_ERROR,
7724 "failed to open: %s", buf);
7725 return -1;
7726 }
Lior David9981b512017-01-20 13:16:40 +02007727 }
7728
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02007729 /* can be either VRING tx... or RING... */
7730 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02007731 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
7732 goto out;
7733 }
7734
7735 /* find TX VRING for the mac address */
7736 found = 0;
7737 while (fgets(buf, sizeof(buf), f)) {
7738 if (strcasestr(buf, dest_mac)) {
7739 found = 1;
7740 break;
7741 }
7742 }
7743
7744 if (!found) {
7745 sigma_dut_print(dut, DUT_MSG_ERROR,
7746 "no TX VRING for %s", dest_mac);
7747 goto out;
7748 }
7749
7750 /* extract VRING ID, "VRING tx_<id> = {" */
7751 if (!fgets(buf, sizeof(buf), f)) {
7752 sigma_dut_print(dut, DUT_MSG_ERROR,
7753 "no VRING start line for %s", dest_mac);
7754 goto out;
7755 }
7756
7757 rc = regexec(&re, buf, 2, m, 0);
7758 regfree(&re);
7759 if (rc || m[1].rm_so < 0) {
7760 sigma_dut_print(dut, DUT_MSG_ERROR,
7761 "no VRING TX ID for %s", dest_mac);
7762 goto out;
7763 }
7764 buf[m[1].rm_eo] = 0;
7765 vring_id = atoi(&buf[m[1].rm_so]);
7766
7767 /* send the addba command */
7768 fclose(f);
7769 snprintf(buf, sizeof(buf), "%s/back", dir);
7770 f = fopen(buf, "w");
7771 if (!f) {
7772 sigma_dut_print(dut, DUT_MSG_ERROR,
7773 "failed to open: %s", buf);
7774 return -1;
7775 }
7776
7777 fprintf(f, "add %d %d\n", vring_id, agg_size);
7778
7779 ret = 0;
7780
7781out:
7782 fclose(f);
7783
7784 return ret;
7785}
7786
7787
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007788static int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7789 struct sigma_cmd *cmd)
7790{
7791 const char *val;
7792 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007793
7794 val = get_param(cmd, "TID");
7795 if (val) {
7796 tid = atoi(val);
7797 if (tid != 0) {
7798 sigma_dut_print(dut, DUT_MSG_ERROR,
7799 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
7800 tid);
7801 }
7802 }
7803
7804 val = get_param(cmd, "Dest_mac");
7805 if (!val) {
7806 sigma_dut_print(dut, DUT_MSG_ERROR,
7807 "Currently not supporting addba for 60G without Dest_mac");
7808 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
7809 }
7810
Lior David9981b512017-01-20 13:16:40 +02007811 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007812 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007813
7814 return 1;
7815}
7816
Lior David9981b512017-01-20 13:16:40 +02007817#endif /* __linux__ */
7818
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007819
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007820static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
7821 struct sigma_cmd *cmd)
7822{
7823#ifdef NL80211_SUPPORT
7824 const char *intf = get_param(cmd, "Interface");
7825 const char *val;
7826 int tid = -1;
7827 int bufsize = 64;
7828 struct nl_msg *msg;
7829 int ret = 0;
7830 struct nlattr *params;
7831 int ifindex;
7832
7833 val = get_param(cmd, "TID");
7834 if (val)
7835 tid = atoi(val);
7836
7837 if (tid == -1) {
7838 send_resp(dut, conn, SIGMA_ERROR,
7839 "ErrorCode,sta_send_addba tid invalid");
7840 return 0;
7841 }
7842
7843 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
7844
7845 ifindex = if_nametoindex(intf);
7846 if (ifindex == 0) {
7847 sigma_dut_print(dut, DUT_MSG_ERROR,
7848 "%s: Index for interface %s failed",
7849 __func__, intf);
7850 send_resp(dut, conn, SIGMA_ERROR,
7851 "ErrorCode,sta_send_addba interface invalid");
7852 return 0;
7853 }
7854
7855 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7856 NL80211_CMD_VENDOR)) ||
7857 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7858 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7859 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7860 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7861 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7862 nla_put_u8(msg,
7863 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
7864 QCA_WLAN_ADD_BA) ||
7865 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
7866 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07007867 nla_put_u16(msg,
7868 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
7869 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007870 sigma_dut_print(dut, DUT_MSG_ERROR,
7871 "%s: err in adding vendor_cmd and vendor_data",
7872 __func__);
7873 nlmsg_free(msg);
7874 send_resp(dut, conn, SIGMA_ERROR,
7875 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
7876 return 0;
7877 }
7878 nla_nest_end(msg, params);
7879
7880 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7881 if (ret) {
7882 sigma_dut_print(dut, DUT_MSG_ERROR,
7883 "%s: err in send_and_recv_msgs, ret=%d",
7884 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05307885 if (ret == -EOPNOTSUPP)
7886 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007887 send_resp(dut, conn, SIGMA_ERROR,
7888 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
7889 return 0;
7890 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007891#else /* NL80211_SUPPORT */
7892 sigma_dut_print(dut, DUT_MSG_ERROR,
7893 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007894#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05307895
7896 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007897}
7898
7899
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007900static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
7901 struct sigma_cmd *cmd)
7902{
7903 switch (get_driver_type()) {
7904 case DRIVER_ATHEROS:
7905 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007906 case DRIVER_WCN:
7907 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02007908#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007909 case DRIVER_WIL6210:
7910 return send_addba_60g(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02007911#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007912 default:
7913 /*
7914 * There is no driver specific implementation for other drivers.
7915 * Ignore the command and report COMPLETE since the following
7916 * throughput test operation will end up sending ADDBA anyway.
7917 */
7918 return 1;
7919 }
7920}
7921
7922
7923int inject_eth_frame(int s, const void *data, size_t len,
7924 unsigned short ethtype, char *dst, char *src)
7925{
7926 struct iovec iov[4] = {
7927 {
7928 .iov_base = dst,
7929 .iov_len = ETH_ALEN,
7930 },
7931 {
7932 .iov_base = src,
7933 .iov_len = ETH_ALEN,
7934 },
7935 {
7936 .iov_base = &ethtype,
7937 .iov_len = sizeof(unsigned short),
7938 },
7939 {
7940 .iov_base = (void *) data,
7941 .iov_len = len,
7942 }
7943 };
7944 struct msghdr msg = {
7945 .msg_name = NULL,
7946 .msg_namelen = 0,
7947 .msg_iov = iov,
7948 .msg_iovlen = 4,
7949 .msg_control = NULL,
7950 .msg_controllen = 0,
7951 .msg_flags = 0,
7952 };
7953
7954 return sendmsg(s, &msg, 0);
7955}
7956
7957#if defined(__linux__) || defined(__QNXNTO__)
7958
7959int inject_frame(int s, const void *data, size_t len, int encrypt)
7960{
7961#define IEEE80211_RADIOTAP_F_WEP 0x04
7962#define IEEE80211_RADIOTAP_F_FRAG 0x08
7963 unsigned char rtap_hdr[] = {
7964 0x00, 0x00, /* radiotap version */
7965 0x0e, 0x00, /* radiotap length */
7966 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
7967 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
7968 0x00, /* padding */
7969 0x00, 0x00, /* RX and TX flags to indicate that */
7970 0x00, 0x00, /* this is the injected frame directly */
7971 };
7972 struct iovec iov[2] = {
7973 {
7974 .iov_base = &rtap_hdr,
7975 .iov_len = sizeof(rtap_hdr),
7976 },
7977 {
7978 .iov_base = (void *) data,
7979 .iov_len = len,
7980 }
7981 };
7982 struct msghdr msg = {
7983 .msg_name = NULL,
7984 .msg_namelen = 0,
7985 .msg_iov = iov,
7986 .msg_iovlen = 2,
7987 .msg_control = NULL,
7988 .msg_controllen = 0,
7989 .msg_flags = 0,
7990 };
7991
7992 if (encrypt)
7993 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
7994
7995 return sendmsg(s, &msg, 0);
7996}
7997
7998
7999int open_monitor(const char *ifname)
8000{
8001#ifdef __QNXNTO__
8002 struct sockaddr_dl ll;
8003 int s;
8004
8005 memset(&ll, 0, sizeof(ll));
8006 ll.sdl_family = AF_LINK;
8007 ll.sdl_index = if_nametoindex(ifname);
8008 if (ll.sdl_index == 0) {
8009 perror("if_nametoindex");
8010 return -1;
8011 }
8012 s = socket(PF_INET, SOCK_RAW, 0);
8013#else /* __QNXNTO__ */
8014 struct sockaddr_ll ll;
8015 int s;
8016
8017 memset(&ll, 0, sizeof(ll));
8018 ll.sll_family = AF_PACKET;
8019 ll.sll_ifindex = if_nametoindex(ifname);
8020 if (ll.sll_ifindex == 0) {
8021 perror("if_nametoindex");
8022 return -1;
8023 }
8024 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
8025#endif /* __QNXNTO__ */
8026 if (s < 0) {
8027 perror("socket[PF_PACKET,SOCK_RAW]");
8028 return -1;
8029 }
8030
8031 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
8032 perror("monitor socket bind");
8033 close(s);
8034 return -1;
8035 }
8036
8037 return s;
8038}
8039
8040
8041static int hex2num(char c)
8042{
8043 if (c >= '0' && c <= '9')
8044 return c - '0';
8045 if (c >= 'a' && c <= 'f')
8046 return c - 'a' + 10;
8047 if (c >= 'A' && c <= 'F')
8048 return c - 'A' + 10;
8049 return -1;
8050}
8051
8052
8053int hwaddr_aton(const char *txt, unsigned char *addr)
8054{
8055 int i;
8056
8057 for (i = 0; i < 6; i++) {
8058 int a, b;
8059
8060 a = hex2num(*txt++);
8061 if (a < 0)
8062 return -1;
8063 b = hex2num(*txt++);
8064 if (b < 0)
8065 return -1;
8066 *addr++ = (a << 4) | b;
8067 if (i < 5 && *txt++ != ':')
8068 return -1;
8069 }
8070
8071 return 0;
8072}
8073
8074#endif /* defined(__linux__) || defined(__QNXNTO__) */
8075
8076enum send_frame_type {
8077 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
8078};
8079enum send_frame_protection {
8080 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
8081};
8082
8083
8084static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
8085 enum send_frame_type frame,
8086 enum send_frame_protection protected,
8087 const char *dest)
8088{
8089#ifdef __linux__
8090 unsigned char buf[1000], *pos;
8091 int s, res;
8092 char bssid[20], addr[20];
8093 char result[32], ssid[100];
8094 size_t ssid_len;
8095
8096 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
8097 sizeof(result)) < 0 ||
8098 strncmp(result, "COMPLETED", 9) != 0) {
8099 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
8100 return 0;
8101 }
8102
8103 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
8104 < 0) {
8105 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8106 "current BSSID");
8107 return 0;
8108 }
8109
8110 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
8111 < 0) {
8112 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8113 "own MAC address");
8114 return 0;
8115 }
8116
8117 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
8118 < 0) {
8119 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8120 "current SSID");
8121 return 0;
8122 }
8123 ssid_len = strlen(ssid);
8124
8125 pos = buf;
8126
8127 /* Frame Control */
8128 switch (frame) {
8129 case DISASSOC:
8130 *pos++ = 0xa0;
8131 break;
8132 case DEAUTH:
8133 *pos++ = 0xc0;
8134 break;
8135 case SAQUERY:
8136 *pos++ = 0xd0;
8137 break;
8138 case AUTH:
8139 *pos++ = 0xb0;
8140 break;
8141 case ASSOCREQ:
8142 *pos++ = 0x00;
8143 break;
8144 case REASSOCREQ:
8145 *pos++ = 0x20;
8146 break;
8147 case DLS_REQ:
8148 *pos++ = 0xd0;
8149 break;
8150 }
8151
8152 if (protected == INCORRECT_KEY)
8153 *pos++ = 0x40; /* Set Protected field to 1 */
8154 else
8155 *pos++ = 0x00;
8156
8157 /* Duration */
8158 *pos++ = 0x00;
8159 *pos++ = 0x00;
8160
8161 /* addr1 = DA (current AP) */
8162 hwaddr_aton(bssid, pos);
8163 pos += 6;
8164 /* addr2 = SA (own address) */
8165 hwaddr_aton(addr, pos);
8166 pos += 6;
8167 /* addr3 = BSSID (current AP) */
8168 hwaddr_aton(bssid, pos);
8169 pos += 6;
8170
8171 /* Seq# (to be filled by driver/mac80211) */
8172 *pos++ = 0x00;
8173 *pos++ = 0x00;
8174
8175 if (protected == INCORRECT_KEY) {
8176 /* CCMP parameters */
8177 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
8178 pos += 8;
8179 }
8180
8181 if (protected == INCORRECT_KEY) {
8182 switch (frame) {
8183 case DEAUTH:
8184 /* Reason code (encrypted) */
8185 memcpy(pos, "\xa7\x39", 2);
8186 pos += 2;
8187 break;
8188 case DISASSOC:
8189 /* Reason code (encrypted) */
8190 memcpy(pos, "\xa7\x39", 2);
8191 pos += 2;
8192 break;
8193 case SAQUERY:
8194 /* Category|Action|TransID (encrypted) */
8195 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
8196 pos += 4;
8197 break;
8198 default:
8199 return -1;
8200 }
8201
8202 /* CCMP MIC */
8203 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
8204 pos += 8;
8205 } else {
8206 switch (frame) {
8207 case DEAUTH:
8208 /* reason code = 8 */
8209 *pos++ = 0x08;
8210 *pos++ = 0x00;
8211 break;
8212 case DISASSOC:
8213 /* reason code = 8 */
8214 *pos++ = 0x08;
8215 *pos++ = 0x00;
8216 break;
8217 case SAQUERY:
8218 /* Category - SA Query */
8219 *pos++ = 0x08;
8220 /* SA query Action - Request */
8221 *pos++ = 0x00;
8222 /* Transaction ID */
8223 *pos++ = 0x12;
8224 *pos++ = 0x34;
8225 break;
8226 case AUTH:
8227 /* Auth Alg (Open) */
8228 *pos++ = 0x00;
8229 *pos++ = 0x00;
8230 /* Seq# */
8231 *pos++ = 0x01;
8232 *pos++ = 0x00;
8233 /* Status code */
8234 *pos++ = 0x00;
8235 *pos++ = 0x00;
8236 break;
8237 case ASSOCREQ:
8238 /* Capability Information */
8239 *pos++ = 0x31;
8240 *pos++ = 0x04;
8241 /* Listen Interval */
8242 *pos++ = 0x0a;
8243 *pos++ = 0x00;
8244 /* SSID */
8245 *pos++ = 0x00;
8246 *pos++ = ssid_len;
8247 memcpy(pos, ssid, ssid_len);
8248 pos += ssid_len;
8249 /* Supported Rates */
8250 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
8251 10);
8252 pos += 10;
8253 /* Extended Supported Rates */
8254 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
8255 pos += 6;
8256 /* RSN */
8257 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
8258 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
8259 "\x00\x00\x00\x00\x0f\xac\x06", 28);
8260 pos += 28;
8261 break;
8262 case REASSOCREQ:
8263 /* Capability Information */
8264 *pos++ = 0x31;
8265 *pos++ = 0x04;
8266 /* Listen Interval */
8267 *pos++ = 0x0a;
8268 *pos++ = 0x00;
8269 /* Current AP */
8270 hwaddr_aton(bssid, pos);
8271 pos += 6;
8272 /* SSID */
8273 *pos++ = 0x00;
8274 *pos++ = ssid_len;
8275 memcpy(pos, ssid, ssid_len);
8276 pos += ssid_len;
8277 /* Supported Rates */
8278 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
8279 10);
8280 pos += 10;
8281 /* Extended Supported Rates */
8282 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
8283 pos += 6;
8284 /* RSN */
8285 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
8286 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
8287 "\x00\x00\x00\x00\x0f\xac\x06", 28);
8288 pos += 28;
8289 break;
8290 case DLS_REQ:
8291 /* Category - DLS */
8292 *pos++ = 0x02;
8293 /* DLS Action - Request */
8294 *pos++ = 0x00;
8295 /* Destination MACAddress */
8296 if (dest)
8297 hwaddr_aton(dest, pos);
8298 else
8299 memset(pos, 0, 6);
8300 pos += 6;
8301 /* Source MACAddress */
8302 hwaddr_aton(addr, pos);
8303 pos += 6;
8304 /* Capability Information */
8305 *pos++ = 0x10; /* Privacy */
8306 *pos++ = 0x06; /* QoS */
8307 /* DLS Timeout Value */
8308 *pos++ = 0x00;
8309 *pos++ = 0x01;
8310 /* Supported rates */
8311 *pos++ = 0x01;
8312 *pos++ = 0x08;
8313 *pos++ = 0x0c; /* 6 Mbps */
8314 *pos++ = 0x12; /* 9 Mbps */
8315 *pos++ = 0x18; /* 12 Mbps */
8316 *pos++ = 0x24; /* 18 Mbps */
8317 *pos++ = 0x30; /* 24 Mbps */
8318 *pos++ = 0x48; /* 36 Mbps */
8319 *pos++ = 0x60; /* 48 Mbps */
8320 *pos++ = 0x6c; /* 54 Mbps */
8321 /* TODO: Extended Supported Rates */
8322 /* TODO: HT Capabilities */
8323 break;
8324 }
8325 }
8326
8327 s = open_monitor("sigmadut");
8328 if (s < 0) {
8329 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
8330 "monitor socket");
8331 return 0;
8332 }
8333
8334 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
8335 if (res < 0) {
8336 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
8337 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308338 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008339 return 0;
8340 }
8341 if (res < pos - buf) {
8342 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
8343 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308344 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008345 return 0;
8346 }
8347
8348 close(s);
8349
8350 return 1;
8351#else /* __linux__ */
8352 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
8353 "yet supported");
8354 return 0;
8355#endif /* __linux__ */
8356}
8357
8358
8359static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
8360 struct sigma_conn *conn,
8361 struct sigma_cmd *cmd)
8362{
8363 const char *intf = get_param(cmd, "Interface");
8364 const char *sta, *val;
8365 unsigned char addr[ETH_ALEN];
8366 char buf[100];
8367
8368 sta = get_param(cmd, "peer");
8369 if (sta == NULL)
8370 sta = get_param(cmd, "station");
8371 if (sta == NULL) {
8372 send_resp(dut, conn, SIGMA_ERROR,
8373 "ErrorCode,Missing peer address");
8374 return 0;
8375 }
8376 if (hwaddr_aton(sta, addr) < 0) {
8377 send_resp(dut, conn, SIGMA_ERROR,
8378 "ErrorCode,Invalid peer address");
8379 return 0;
8380 }
8381
8382 val = get_param(cmd, "type");
8383 if (val == NULL)
8384 return -1;
8385
8386 if (strcasecmp(val, "DISCOVERY") == 0) {
8387 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
8388 if (wpa_command(intf, buf) < 0) {
8389 send_resp(dut, conn, SIGMA_ERROR,
8390 "ErrorCode,Failed to send TDLS discovery");
8391 return 0;
8392 }
8393 return 1;
8394 }
8395
8396 if (strcasecmp(val, "SETUP") == 0) {
8397 int status = 0, timeout = 0;
8398
8399 val = get_param(cmd, "Status");
8400 if (val)
8401 status = atoi(val);
8402
8403 val = get_param(cmd, "Timeout");
8404 if (val)
8405 timeout = atoi(val);
8406
8407 if (status != 0 && status != 37) {
8408 send_resp(dut, conn, SIGMA_ERROR,
8409 "ErrorCode,Unsupported status value");
8410 return 0;
8411 }
8412
8413 if (timeout != 0 && timeout != 301) {
8414 send_resp(dut, conn, SIGMA_ERROR,
8415 "ErrorCode,Unsupported timeout value");
8416 return 0;
8417 }
8418
8419 if (status && timeout) {
8420 send_resp(dut, conn, SIGMA_ERROR,
8421 "ErrorCode,Unsupported timeout+status "
8422 "combination");
8423 return 0;
8424 }
8425
8426 if (status == 37 &&
8427 wpa_command(intf, "SET tdls_testing 0x200")) {
8428 send_resp(dut, conn, SIGMA_ERROR,
8429 "ErrorCode,Failed to enable "
8430 "decline setup response test mode");
8431 return 0;
8432 }
8433
8434 if (timeout == 301) {
8435 int res;
8436 if (dut->no_tpk_expiration)
8437 res = wpa_command(intf,
8438 "SET tdls_testing 0x108");
8439 else
8440 res = wpa_command(intf,
8441 "SET tdls_testing 0x8");
8442 if (res) {
8443 send_resp(dut, conn, SIGMA_ERROR,
8444 "ErrorCode,Failed to set short TPK "
8445 "lifetime");
8446 return 0;
8447 }
8448 }
8449
8450 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
8451 if (wpa_command(intf, buf) < 0) {
8452 send_resp(dut, conn, SIGMA_ERROR,
8453 "ErrorCode,Failed to send TDLS setup");
8454 return 0;
8455 }
8456 return 1;
8457 }
8458
8459 if (strcasecmp(val, "TEARDOWN") == 0) {
8460 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
8461 if (wpa_command(intf, buf) < 0) {
8462 send_resp(dut, conn, SIGMA_ERROR,
8463 "ErrorCode,Failed to send TDLS teardown");
8464 return 0;
8465 }
8466 return 1;
8467 }
8468
8469 send_resp(dut, conn, SIGMA_ERROR,
8470 "ErrorCode,Unsupported TDLS frame");
8471 return 0;
8472}
8473
8474
8475static int sta_ap_known(const char *ifname, const char *bssid)
8476{
8477 char buf[4096];
8478
Jouni Malinendd32f192018-09-15 02:55:19 +03008479 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008480 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
8481 return 0;
8482 if (strncmp(buf, "id=", 3) != 0)
8483 return 0;
8484 return 1;
8485}
8486
8487
8488static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
8489 const char *bssid)
8490{
8491 int res;
8492 struct wpa_ctrl *ctrl;
8493 char buf[256];
8494
8495 if (sta_ap_known(ifname, bssid))
8496 return 0;
8497 sigma_dut_print(dut, DUT_MSG_DEBUG,
8498 "AP not in BSS table - start scan");
8499
8500 ctrl = open_wpa_mon(ifname);
8501 if (ctrl == NULL) {
8502 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
8503 "wpa_supplicant monitor connection");
8504 return -1;
8505 }
8506
8507 if (wpa_command(ifname, "SCAN") < 0) {
8508 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
8509 wpa_ctrl_detach(ctrl);
8510 wpa_ctrl_close(ctrl);
8511 return -1;
8512 }
8513
8514 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
8515 buf, sizeof(buf));
8516
8517 wpa_ctrl_detach(ctrl);
8518 wpa_ctrl_close(ctrl);
8519
8520 if (res < 0) {
8521 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
8522 return -1;
8523 }
8524
8525 if (sta_ap_known(ifname, bssid))
8526 return 0;
8527 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
8528 return -1;
8529}
8530
8531
8532static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
8533 struct sigma_conn *conn,
8534 struct sigma_cmd *cmd,
8535 const char *intf)
8536{
8537 char buf[200];
8538
8539 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
8540 if (system(buf) != 0) {
8541 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
8542 "ndsend");
8543 return 0;
8544 }
8545
8546 return 1;
8547}
8548
8549
8550static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
8551 struct sigma_conn *conn,
8552 struct sigma_cmd *cmd,
8553 const char *intf)
8554{
8555 char buf[200];
8556 const char *ip = get_param(cmd, "SenderIP");
8557
Peng Xu26b356d2017-10-04 17:58:16 -07008558 if (!ip)
8559 return 0;
8560
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008561 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
8562 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8563 if (system(buf) == 0) {
8564 sigma_dut_print(dut, DUT_MSG_INFO,
8565 "Neighbor Solicitation got a response "
8566 "for %s@%s", ip, intf);
8567 }
8568
8569 return 1;
8570}
8571
8572
8573static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
8574 struct sigma_conn *conn,
8575 struct sigma_cmd *cmd,
8576 const char *ifname)
8577{
8578 char buf[200];
8579 const char *ip = get_param(cmd, "SenderIP");
8580
8581 if (ip == NULL) {
8582 send_resp(dut, conn, SIGMA_ERROR,
8583 "ErrorCode,Missing SenderIP parameter");
8584 return 0;
8585 }
8586 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
8587 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8588 if (system(buf) != 0) {
8589 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
8590 "for %s@%s", ip, ifname);
8591 }
8592
8593 return 1;
8594}
8595
8596
8597static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
8598 struct sigma_conn *conn,
8599 struct sigma_cmd *cmd,
8600 const char *ifname)
8601{
8602 char buf[200];
8603 char ip[16];
8604 int s;
Peng Xub3756882017-10-04 14:39:09 -07008605 struct ifreq ifr;
8606 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008607
8608 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07008609 if (s < 0) {
8610 perror("socket");
8611 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008612 }
8613
Peng Xub3756882017-10-04 14:39:09 -07008614 memset(&ifr, 0, sizeof(ifr));
8615 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
8616 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
8617 sigma_dut_print(dut, DUT_MSG_INFO,
8618 "Failed to get %s IP address: %s",
8619 ifname, strerror(errno));
8620 close(s);
8621 return -1;
8622 }
8623 close(s);
8624
8625 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
8626 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
8627
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008628 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
8629 ip);
8630 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8631 if (system(buf) != 0) {
8632 }
8633
8634 return 1;
8635}
8636
8637
8638static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
8639 struct sigma_conn *conn,
8640 struct sigma_cmd *cmd,
8641 const char *ifname)
8642{
8643 char buf[200], addr[20];
8644 char dst[ETH_ALEN], src[ETH_ALEN];
8645 short ethtype = htons(ETH_P_ARP);
8646 char *pos;
8647 int s, res;
8648 const char *val;
8649 struct sockaddr_in taddr;
8650
8651 val = get_param(cmd, "dest");
8652 if (val)
8653 hwaddr_aton(val, (unsigned char *) dst);
8654
8655 val = get_param(cmd, "DestIP");
8656 if (val)
8657 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07008658 else
8659 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008660
8661 if (get_wpa_status(get_station_ifname(), "address", addr,
8662 sizeof(addr)) < 0)
8663 return -2;
8664 hwaddr_aton(addr, (unsigned char *) src);
8665
8666 pos = buf;
8667 *pos++ = 0x00;
8668 *pos++ = 0x01;
8669 *pos++ = 0x08;
8670 *pos++ = 0x00;
8671 *pos++ = 0x06;
8672 *pos++ = 0x04;
8673 *pos++ = 0x00;
8674 *pos++ = 0x02;
8675 memcpy(pos, src, ETH_ALEN);
8676 pos += ETH_ALEN;
8677 memcpy(pos, &taddr.sin_addr, 4);
8678 pos += 4;
8679 memcpy(pos, dst, ETH_ALEN);
8680 pos += ETH_ALEN;
8681 memcpy(pos, &taddr.sin_addr, 4);
8682 pos += 4;
8683
8684 s = open_monitor(get_station_ifname());
8685 if (s < 0) {
8686 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
8687 "monitor socket");
8688 return 0;
8689 }
8690
8691 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
8692 if (res < 0) {
8693 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
8694 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308695 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008696 return 0;
8697 }
8698
8699 close(s);
8700
8701 return 1;
8702}
8703
8704
8705static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
8706 struct sigma_conn *conn,
8707 struct sigma_cmd *cmd,
8708 const char *intf, const char *dest)
8709{
8710 char buf[100];
8711
8712 if (if_nametoindex("sigmadut") == 0) {
8713 snprintf(buf, sizeof(buf),
8714 "iw dev %s interface add sigmadut type monitor",
8715 get_station_ifname());
8716 if (system(buf) != 0 ||
8717 if_nametoindex("sigmadut") == 0) {
8718 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
8719 "monitor interface with '%s'", buf);
8720 return -2;
8721 }
8722 }
8723
8724 if (system("ifconfig sigmadut up") != 0) {
8725 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
8726 "monitor interface up");
8727 return -2;
8728 }
8729
8730 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
8731}
8732
8733
8734static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
8735 struct sigma_conn *conn,
8736 struct sigma_cmd *cmd)
8737{
8738 const char *intf = get_param(cmd, "Interface");
8739 const char *dest = get_param(cmd, "Dest");
8740 const char *type = get_param(cmd, "FrameName");
8741 const char *val;
8742 char buf[200], *pos, *end;
8743 int count, count2;
8744
8745 if (type == NULL)
8746 type = get_param(cmd, "Type");
8747
8748 if (intf == NULL || dest == NULL || type == NULL)
8749 return -1;
8750
8751 if (strcasecmp(type, "NeighAdv") == 0)
8752 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
8753
8754 if (strcasecmp(type, "NeighSolicitReq") == 0)
8755 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
8756
8757 if (strcasecmp(type, "ARPProbe") == 0)
8758 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
8759
8760 if (strcasecmp(type, "ARPAnnounce") == 0)
8761 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
8762
8763 if (strcasecmp(type, "ARPReply") == 0)
8764 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
8765
8766 if (strcasecmp(type, "DLS-request") == 0 ||
8767 strcasecmp(type, "DLSrequest") == 0)
8768 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
8769 dest);
8770
8771 if (strcasecmp(type, "ANQPQuery") != 0 &&
8772 strcasecmp(type, "Query") != 0) {
8773 send_resp(dut, conn, SIGMA_ERROR,
8774 "ErrorCode,Unsupported HS 2.0 send frame type");
8775 return 0;
8776 }
8777
8778 if (sta_scan_ap(dut, intf, dest) < 0) {
8779 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
8780 "the requested AP");
8781 return 0;
8782 }
8783
8784 pos = buf;
8785 end = buf + sizeof(buf);
8786 count = 0;
8787 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
8788
8789 val = get_param(cmd, "ANQP_CAP_LIST");
8790 if (val && atoi(val)) {
8791 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
8792 count++;
8793 }
8794
8795 val = get_param(cmd, "VENUE_NAME");
8796 if (val && atoi(val)) {
8797 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
8798 count++;
8799 }
8800
8801 val = get_param(cmd, "NETWORK_AUTH_TYPE");
8802 if (val && atoi(val)) {
8803 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
8804 count++;
8805 }
8806
8807 val = get_param(cmd, "ROAMING_CONS");
8808 if (val && atoi(val)) {
8809 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
8810 count++;
8811 }
8812
8813 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
8814 if (val && atoi(val)) {
8815 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
8816 count++;
8817 }
8818
8819 val = get_param(cmd, "NAI_REALM_LIST");
8820 if (val && atoi(val)) {
8821 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
8822 count++;
8823 }
8824
8825 val = get_param(cmd, "3GPP_INFO");
8826 if (val && atoi(val)) {
8827 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
8828 count++;
8829 }
8830
8831 val = get_param(cmd, "DOMAIN_LIST");
8832 if (val && atoi(val)) {
8833 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
8834 count++;
8835 }
8836
Jouni Malinen34cf9532018-04-29 19:26:33 +03008837 val = get_param(cmd, "Venue_URL");
8838 if (val && atoi(val)) {
8839 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
8840 count++;
8841 }
8842
Jouni Malinend3bca5d2018-04-29 17:25:23 +03008843 val = get_param(cmd, "Advice_Of_Charge");
8844 if (val && atoi(val)) {
8845 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
8846 count++;
8847 }
8848
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008849 if (count && wpa_command(intf, buf)) {
8850 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
8851 return 0;
8852 }
8853
8854 pos = buf;
8855 end = buf + sizeof(buf);
8856 count2 = 0;
8857 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
8858
8859 val = get_param(cmd, "HS_CAP_LIST");
8860 if (val && atoi(val)) {
8861 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
8862 count2++;
8863 }
8864
8865 val = get_param(cmd, "OPER_NAME");
8866 if (val && atoi(val)) {
8867 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
8868 count2++;
8869 }
8870
8871 val = get_param(cmd, "WAN_METRICS");
8872 if (!val)
8873 val = get_param(cmd, "WAN_MAT");
8874 if (!val)
8875 val = get_param(cmd, "WAN_MET");
8876 if (val && atoi(val)) {
8877 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
8878 count2++;
8879 }
8880
8881 val = get_param(cmd, "CONNECTION_CAPABILITY");
8882 if (val && atoi(val)) {
8883 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
8884 count2++;
8885 }
8886
8887 val = get_param(cmd, "OP_CLASS");
8888 if (val && atoi(val)) {
8889 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
8890 count2++;
8891 }
8892
8893 val = get_param(cmd, "OSU_PROVIDER_LIST");
8894 if (val && atoi(val)) {
8895 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
8896 count2++;
8897 }
8898
Jouni Malinenf67afec2018-04-29 19:24:58 +03008899 val = get_param(cmd, "OPER_ICON_METADATA");
8900 if (!val)
8901 val = get_param(cmd, "OPERATOR_ICON_METADATA");
8902 if (val && atoi(val)) {
8903 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
8904 count2++;
8905 }
8906
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008907 if (count && count2) {
8908 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
8909 "second query");
8910 sleep(1);
8911 }
8912
8913 if (count2 && wpa_command(intf, buf)) {
8914 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
8915 "failed");
8916 return 0;
8917 }
8918
8919 val = get_param(cmd, "NAI_HOME_REALM_LIST");
8920 if (val) {
8921 if (count || count2) {
8922 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
8923 "sending out second query");
8924 sleep(1);
8925 }
8926
8927 if (strcmp(val, "1") == 0)
8928 val = "mail.example.com";
8929 snprintf(buf, end - pos,
8930 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
8931 dest, val);
8932 if (wpa_command(intf, buf)) {
8933 send_resp(dut, conn, SIGMA_ERROR,
8934 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
8935 "failed");
8936 return 0;
8937 }
8938 }
8939
8940 val = get_param(cmd, "ICON_REQUEST");
8941 if (val) {
8942 if (count || count2) {
8943 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
8944 "sending out second query");
8945 sleep(1);
8946 }
8947
8948 snprintf(buf, end - pos,
8949 "HS20_ICON_REQUEST %s %s", dest, val);
8950 if (wpa_command(intf, buf)) {
8951 send_resp(dut, conn, SIGMA_ERROR,
8952 "ErrorCode,HS20_ICON_REQUEST failed");
8953 return 0;
8954 }
8955 }
8956
8957 return 1;
8958}
8959
8960
8961static int ath_sta_send_frame_vht(struct sigma_dut *dut,
8962 struct sigma_conn *conn,
8963 struct sigma_cmd *cmd)
8964{
8965 const char *val;
8966 char *ifname;
8967 char buf[100];
8968 int chwidth, nss;
8969
8970 val = get_param(cmd, "framename");
8971 if (!val)
8972 return -1;
8973 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
8974
8975 /* Command sequence to generate Op mode notification */
8976 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
8977 ifname = get_station_ifname();
8978
8979 /* Disable STBC */
8980 snprintf(buf, sizeof(buf),
8981 "iwpriv %s tx_stbc 0", ifname);
8982 if (system(buf) != 0) {
8983 sigma_dut_print(dut, DUT_MSG_ERROR,
8984 "iwpriv tx_stbc 0 failed!");
8985 }
8986
8987 /* Extract Channel width */
8988 val = get_param(cmd, "Channel_width");
8989 if (val) {
8990 switch (atoi(val)) {
8991 case 20:
8992 chwidth = 0;
8993 break;
8994 case 40:
8995 chwidth = 1;
8996 break;
8997 case 80:
8998 chwidth = 2;
8999 break;
9000 case 160:
9001 chwidth = 3;
9002 break;
9003 default:
9004 chwidth = 2;
9005 break;
9006 }
9007
9008 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
9009 ifname, chwidth);
9010 if (system(buf) != 0) {
9011 sigma_dut_print(dut, DUT_MSG_ERROR,
9012 "iwpriv chwidth failed!");
9013 }
9014 }
9015
9016 /* Extract NSS */
9017 val = get_param(cmd, "NSS");
9018 if (val) {
9019 switch (atoi(val)) {
9020 case 1:
9021 nss = 1;
9022 break;
9023 case 2:
9024 nss = 3;
9025 break;
9026 case 3:
9027 nss = 7;
9028 break;
9029 default:
9030 /* We do not support NSS > 3 */
9031 nss = 3;
9032 break;
9033 }
9034 snprintf(buf, sizeof(buf),
9035 "iwpriv %s rxchainmask %d", ifname, nss);
9036 if (system(buf) != 0) {
9037 sigma_dut_print(dut, DUT_MSG_ERROR,
9038 "iwpriv rxchainmask failed!");
9039 }
9040 }
9041
9042 /* Opmode notify */
9043 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
9044 if (system(buf) != 0) {
9045 sigma_dut_print(dut, DUT_MSG_ERROR,
9046 "iwpriv opmode_notify failed!");
9047 } else {
9048 sigma_dut_print(dut, DUT_MSG_INFO,
9049 "Sent out the notify frame!");
9050 }
9051 }
9052
9053 return 1;
9054}
9055
9056
9057static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
9058 struct sigma_conn *conn,
9059 struct sigma_cmd *cmd)
9060{
9061 switch (get_driver_type()) {
9062 case DRIVER_ATHEROS:
9063 return ath_sta_send_frame_vht(dut, conn, cmd);
9064 default:
9065 send_resp(dut, conn, SIGMA_ERROR,
9066 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
9067 return 0;
9068 }
9069}
9070
9071
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009072static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
9073 struct sigma_cmd *cmd)
9074{
9075 const char *val;
9076 const char *intf = get_param(cmd, "Interface");
9077
9078 val = get_param(cmd, "framename");
9079 if (!val)
9080 return -1;
9081 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9082
9083 /* Command sequence to generate Op mode notification */
9084 if (val && strcasecmp(val, "action") == 0) {
9085 val = get_param(cmd, "PPDUTxType");
9086 if (val && strcasecmp(val, "TB") == 0) {
9087 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
9088 sigma_dut_print(dut, DUT_MSG_ERROR,
9089 "failed to send TB PPDU Tx cfg");
9090 send_resp(dut, conn, SIGMA_ERROR,
9091 "ErrorCode,set TB PPDU Tx cfg failed");
9092 return 0;
9093 }
9094 return 1;
9095 }
9096
9097 sigma_dut_print(dut, DUT_MSG_ERROR,
9098 "Action Tx type is not defined");
9099 }
9100
9101 return 1;
9102}
9103
9104
9105static int cmd_sta_send_frame_he(struct sigma_dut *dut,
9106 struct sigma_conn *conn,
9107 struct sigma_cmd *cmd)
9108{
9109 switch (get_driver_type()) {
9110 case DRIVER_WCN:
9111 return wcn_sta_send_frame_he(dut, conn, cmd);
9112 default:
9113 send_resp(dut, conn, SIGMA_ERROR,
9114 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
9115 return 0;
9116 }
9117}
9118
9119
Lior David0fe101e2017-03-09 16:09:50 +02009120#ifdef __linux__
9121int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9122 struct sigma_cmd *cmd)
9123{
9124 const char *frame_name = get_param(cmd, "framename");
9125 const char *mac = get_param(cmd, "dest_mac");
9126
9127 if (!frame_name || !mac) {
9128 sigma_dut_print(dut, DUT_MSG_ERROR,
9129 "framename and dest_mac must be provided");
9130 return -1;
9131 }
9132
9133 if (strcasecmp(frame_name, "brp") == 0) {
9134 const char *l_rx = get_param(cmd, "L-RX");
9135 int l_rx_i;
9136
9137 if (!l_rx) {
9138 sigma_dut_print(dut, DUT_MSG_ERROR,
9139 "L-RX must be provided");
9140 return -1;
9141 }
9142 l_rx_i = atoi(l_rx);
9143
9144 sigma_dut_print(dut, DUT_MSG_INFO,
9145 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
9146 mac, l_rx);
9147 if (l_rx_i != 16) {
9148 sigma_dut_print(dut, DUT_MSG_ERROR,
9149 "unsupported L-RX: %s", l_rx);
9150 return -1;
9151 }
9152
9153 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
9154 return -1;
9155 } else if (strcasecmp(frame_name, "ssw") == 0) {
9156 sigma_dut_print(dut, DUT_MSG_INFO,
9157 "dev_send_frame: SLS, dest_mac %s", mac);
9158 if (wil6210_send_sls(dut, mac))
9159 return -1;
9160 } else {
9161 sigma_dut_print(dut, DUT_MSG_ERROR,
9162 "unsupported frame type: %s", frame_name);
9163 return -1;
9164 }
9165
9166 return 1;
9167}
9168#endif /* __linux__ */
9169
9170
9171static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
9172 struct sigma_conn *conn,
9173 struct sigma_cmd *cmd)
9174{
9175 switch (get_driver_type()) {
9176#ifdef __linux__
9177 case DRIVER_WIL6210:
9178 return wil6210_send_frame_60g(dut, conn, cmd);
9179#endif /* __linux__ */
9180 default:
9181 send_resp(dut, conn, SIGMA_ERROR,
9182 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
9183 return 0;
9184 }
9185}
9186
9187
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309188static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
9189 const char *intf, struct sigma_cmd *cmd)
9190{
9191 const char *val, *addr;
9192 char buf[100];
9193
9194 addr = get_param(cmd, "DestMac");
9195 if (!addr) {
9196 send_resp(dut, conn, SIGMA_INVALID,
9197 "ErrorCode,AP MAC address is missing");
9198 return 0;
9199 }
9200
9201 val = get_param(cmd, "ANQPQuery_ID");
9202 if (!val) {
9203 send_resp(dut, conn, SIGMA_INVALID,
9204 "ErrorCode,Missing ANQPQuery_ID");
9205 return 0;
9206 }
9207
9208 if (strcasecmp(val, "NeighborReportReq") == 0) {
9209 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
9210 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
9211 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
9212 } else {
9213 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
9214 val);
9215 send_resp(dut, conn, SIGMA_INVALID,
9216 "ErrorCode,Invalid ANQPQuery_ID");
9217 return 0;
9218 }
9219
Ashwini Patild174f2c2017-04-13 16:49:46 +05309220 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
9221 * (Address3 = Wildcard BSSID when sent to not-associated AP;
9222 * if associated, AP BSSID).
9223 */
9224 if (wpa_command(intf, "SET gas_address3 1") < 0) {
9225 send_resp(dut, conn, SIGMA_ERROR,
9226 "ErrorCode,Failed to set gas_address3");
9227 return 0;
9228 }
9229
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309230 if (wpa_command(intf, buf) < 0) {
9231 send_resp(dut, conn, SIGMA_ERROR,
9232 "ErrorCode,Failed to send ANQP query");
9233 return 0;
9234 }
9235
9236 return 1;
9237}
9238
9239
9240static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
9241 struct sigma_conn *conn,
9242 const char *intf,
9243 struct sigma_cmd *cmd)
9244{
9245 const char *val = get_param(cmd, "FrameName");
9246
9247 if (val && strcasecmp(val, "ANQPQuery") == 0)
9248 return mbo_send_anqp_query(dut, conn, intf, cmd);
9249
9250 return 2;
9251}
9252
9253
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009254int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9255 struct sigma_cmd *cmd)
9256{
9257 const char *intf = get_param(cmd, "Interface");
9258 const char *val;
9259 enum send_frame_type frame;
9260 enum send_frame_protection protected;
9261 char buf[100];
9262 unsigned char addr[ETH_ALEN];
9263 int res;
9264
9265 val = get_param(cmd, "program");
9266 if (val == NULL)
9267 val = get_param(cmd, "frame");
9268 if (val && strcasecmp(val, "TDLS") == 0)
9269 return cmd_sta_send_frame_tdls(dut, conn, cmd);
9270 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +03009271 strcasecmp(val, "HS2-R2") == 0 ||
9272 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009273 return cmd_sta_send_frame_hs2(dut, conn, cmd);
9274 if (val && strcasecmp(val, "VHT") == 0)
9275 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009276 if (val && strcasecmp(val, "HE") == 0)
9277 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009278 if (val && strcasecmp(val, "LOC") == 0)
9279 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +02009280 if (val && strcasecmp(val, "60GHz") == 0)
9281 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309282 if (val && strcasecmp(val, "MBO") == 0) {
9283 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
9284 if (res != 2)
9285 return res;
9286 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009287
9288 val = get_param(cmd, "TD_DISC");
9289 if (val) {
9290 if (hwaddr_aton(val, addr) < 0)
9291 return -1;
9292 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
9293 if (wpa_command(intf, buf) < 0) {
9294 send_resp(dut, conn, SIGMA_ERROR,
9295 "ErrorCode,Failed to send TDLS discovery");
9296 return 0;
9297 }
9298 return 1;
9299 }
9300
9301 val = get_param(cmd, "TD_Setup");
9302 if (val) {
9303 if (hwaddr_aton(val, addr) < 0)
9304 return -1;
9305 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
9306 if (wpa_command(intf, buf) < 0) {
9307 send_resp(dut, conn, SIGMA_ERROR,
9308 "ErrorCode,Failed to start TDLS setup");
9309 return 0;
9310 }
9311 return 1;
9312 }
9313
9314 val = get_param(cmd, "TD_TearDown");
9315 if (val) {
9316 if (hwaddr_aton(val, addr) < 0)
9317 return -1;
9318 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
9319 if (wpa_command(intf, buf) < 0) {
9320 send_resp(dut, conn, SIGMA_ERROR,
9321 "ErrorCode,Failed to tear down TDLS link");
9322 return 0;
9323 }
9324 return 1;
9325 }
9326
9327 val = get_param(cmd, "TD_ChannelSwitch");
9328 if (val) {
9329 /* TODO */
9330 send_resp(dut, conn, SIGMA_ERROR,
9331 "ErrorCode,TD_ChannelSwitch not yet supported");
9332 return 0;
9333 }
9334
9335 val = get_param(cmd, "TD_NF");
9336 if (val) {
9337 /* TODO */
9338 send_resp(dut, conn, SIGMA_ERROR,
9339 "ErrorCode,TD_NF not yet supported");
9340 return 0;
9341 }
9342
9343 val = get_param(cmd, "PMFFrameType");
9344 if (val == NULL)
9345 val = get_param(cmd, "FrameName");
9346 if (val == NULL)
9347 val = get_param(cmd, "Type");
9348 if (val == NULL)
9349 return -1;
9350 if (strcasecmp(val, "disassoc") == 0)
9351 frame = DISASSOC;
9352 else if (strcasecmp(val, "deauth") == 0)
9353 frame = DEAUTH;
9354 else if (strcasecmp(val, "saquery") == 0)
9355 frame = SAQUERY;
9356 else if (strcasecmp(val, "auth") == 0)
9357 frame = AUTH;
9358 else if (strcasecmp(val, "assocreq") == 0)
9359 frame = ASSOCREQ;
9360 else if (strcasecmp(val, "reassocreq") == 0)
9361 frame = REASSOCREQ;
9362 else if (strcasecmp(val, "neigreq") == 0) {
9363 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
9364
9365 val = get_param(cmd, "ssid");
9366 if (val == NULL)
9367 return -1;
9368
9369 res = send_neighbor_request(dut, intf, val);
9370 if (res) {
9371 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9372 "Failed to send neighbor report request");
9373 return 0;
9374 }
9375
9376 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309377 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
9378 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009379 sigma_dut_print(dut, DUT_MSG_DEBUG,
9380 "Got Transition Management Query");
9381
Ashwini Patil5acd7382017-04-13 15:55:04 +05309382 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009383 if (res) {
9384 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9385 "Failed to send Transition Management Query");
9386 return 0;
9387 }
9388
9389 return 1;
9390 } else {
9391 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9392 "PMFFrameType");
9393 return 0;
9394 }
9395
9396 val = get_param(cmd, "PMFProtected");
9397 if (val == NULL)
9398 val = get_param(cmd, "Protected");
9399 if (val == NULL)
9400 return -1;
9401 if (strcasecmp(val, "Correct-key") == 0 ||
9402 strcasecmp(val, "CorrectKey") == 0)
9403 protected = CORRECT_KEY;
9404 else if (strcasecmp(val, "IncorrectKey") == 0)
9405 protected = INCORRECT_KEY;
9406 else if (strcasecmp(val, "Unprotected") == 0)
9407 protected = UNPROTECTED;
9408 else {
9409 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9410 "PMFProtected");
9411 return 0;
9412 }
9413
9414 if (protected != UNPROTECTED &&
9415 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
9416 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
9417 "PMFProtected for auth/assocreq/reassocreq");
9418 return 0;
9419 }
9420
9421 if (if_nametoindex("sigmadut") == 0) {
9422 snprintf(buf, sizeof(buf),
9423 "iw dev %s interface add sigmadut type monitor",
9424 get_station_ifname());
9425 if (system(buf) != 0 ||
9426 if_nametoindex("sigmadut") == 0) {
9427 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9428 "monitor interface with '%s'", buf);
9429 return -2;
9430 }
9431 }
9432
9433 if (system("ifconfig sigmadut up") != 0) {
9434 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9435 "monitor interface up");
9436 return -2;
9437 }
9438
9439 return sta_inject_frame(dut, conn, frame, protected, NULL);
9440}
9441
9442
9443static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
9444 struct sigma_conn *conn,
9445 struct sigma_cmd *cmd,
9446 const char *ifname)
9447{
9448 char buf[200];
9449 const char *val;
9450
9451 val = get_param(cmd, "ClearARP");
9452 if (val && atoi(val) == 1) {
9453 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
9454 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9455 if (system(buf) != 0) {
9456 send_resp(dut, conn, SIGMA_ERROR,
9457 "errorCode,Failed to clear ARP cache");
9458 return 0;
9459 }
9460 }
9461
9462 return 1;
9463}
9464
9465
9466int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
9467 struct sigma_cmd *cmd)
9468{
9469 const char *intf = get_param(cmd, "Interface");
9470 const char *val;
9471
9472 if (intf == NULL)
9473 return -1;
9474
9475 val = get_param(cmd, "program");
9476 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +03009477 strcasecmp(val, "HS2-R2") == 0 ||
9478 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009479 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
9480
9481 return -1;
9482}
9483
9484
9485static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
9486 struct sigma_cmd *cmd)
9487{
9488 const char *intf = get_param(cmd, "Interface");
9489 const char *mac = get_param(cmd, "MAC");
9490
9491 if (intf == NULL || mac == NULL)
9492 return -1;
9493
9494 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
9495 "interface %s to %s", intf, mac);
9496
9497 if (dut->set_macaddr) {
9498 char buf[128];
9499 int res;
9500 if (strcasecmp(mac, "default") == 0) {
9501 res = snprintf(buf, sizeof(buf), "%s",
9502 dut->set_macaddr);
9503 dut->tmp_mac_addr = 0;
9504 } else {
9505 res = snprintf(buf, sizeof(buf), "%s %s",
9506 dut->set_macaddr, mac);
9507 dut->tmp_mac_addr = 1;
9508 }
9509 if (res < 0 || res >= (int) sizeof(buf))
9510 return -1;
9511 if (system(buf) != 0) {
9512 send_resp(dut, conn, SIGMA_ERROR,
9513 "errorCode,Failed to set MAC "
9514 "address");
9515 return 0;
9516 }
9517 return 1;
9518 }
9519
9520 if (strcasecmp(mac, "default") == 0)
9521 return 1;
9522
9523 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9524 "command");
9525 return 0;
9526}
9527
9528
9529static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
9530 struct sigma_conn *conn, const char *intf,
9531 int val)
9532{
9533 char buf[200];
9534 int res;
9535
9536 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
9537 intf, val);
9538 if (res < 0 || res >= (int) sizeof(buf))
9539 return -1;
9540 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9541 if (system(buf) != 0) {
9542 send_resp(dut, conn, SIGMA_ERROR,
9543 "errorCode,Failed to configure offchannel mode");
9544 return 0;
9545 }
9546
9547 return 1;
9548}
9549
9550
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009551static int off_chan_val(enum sec_ch_offset off)
9552{
9553 switch (off) {
9554 case SEC_CH_NO:
9555 return 0;
9556 case SEC_CH_40ABOVE:
9557 return 40;
9558 case SEC_CH_40BELOW:
9559 return -40;
9560 }
9561
9562 return 0;
9563}
9564
9565
9566static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
9567 const char *intf, int off_ch_num,
9568 enum sec_ch_offset sec)
9569{
9570 char buf[200];
9571 int res;
9572
9573 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
9574 intf, off_ch_num);
9575 if (res < 0 || res >= (int) sizeof(buf))
9576 return -1;
9577 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9578 if (system(buf) != 0) {
9579 send_resp(dut, conn, SIGMA_ERROR,
9580 "errorCode,Failed to set offchan");
9581 return 0;
9582 }
9583
9584 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
9585 intf, off_chan_val(sec));
9586 if (res < 0 || res >= (int) sizeof(buf))
9587 return -1;
9588 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9589 if (system(buf) != 0) {
9590 send_resp(dut, conn, SIGMA_ERROR,
9591 "errorCode,Failed to set sec chan offset");
9592 return 0;
9593 }
9594
9595 return 1;
9596}
9597
9598
9599static int tdls_set_offchannel_offset(struct sigma_dut *dut,
9600 struct sigma_conn *conn,
9601 const char *intf, int off_ch_num,
9602 enum sec_ch_offset sec)
9603{
9604 char buf[200];
9605 int res;
9606
9607 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
9608 off_ch_num);
9609 if (res < 0 || res >= (int) sizeof(buf))
9610 return -1;
9611 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9612
9613 if (wpa_command(intf, buf) < 0) {
9614 send_resp(dut, conn, SIGMA_ERROR,
9615 "ErrorCode,Failed to set offchan");
9616 return 0;
9617 }
9618 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
9619 off_chan_val(sec));
9620 if (res < 0 || res >= (int) sizeof(buf))
9621 return -1;
9622
9623 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9624
9625 if (wpa_command(intf, buf) < 0) {
9626 send_resp(dut, conn, SIGMA_ERROR,
9627 "ErrorCode,Failed to set sec chan offset");
9628 return 0;
9629 }
9630
9631 return 1;
9632}
9633
9634
9635static int tdls_set_offchannel_mode(struct sigma_dut *dut,
9636 struct sigma_conn *conn,
9637 const char *intf, int val)
9638{
9639 char buf[200];
9640 int res;
9641
9642 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
9643 val);
9644 if (res < 0 || res >= (int) sizeof(buf))
9645 return -1;
9646 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9647
9648 if (wpa_command(intf, buf) < 0) {
9649 send_resp(dut, conn, SIGMA_ERROR,
9650 "ErrorCode,Failed to configure offchannel mode");
9651 return 0;
9652 }
9653
9654 return 1;
9655}
9656
9657
9658static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
9659 struct sigma_conn *conn,
9660 struct sigma_cmd *cmd)
9661{
9662 const char *val;
9663 enum {
9664 CHSM_NOT_SET,
9665 CHSM_ENABLE,
9666 CHSM_DISABLE,
9667 CHSM_REJREQ,
9668 CHSM_UNSOLRESP
9669 } chsm = CHSM_NOT_SET;
9670 int off_ch_num = -1;
9671 enum sec_ch_offset sec_ch = SEC_CH_NO;
9672 int res;
9673
9674 val = get_param(cmd, "Uapsd");
9675 if (val) {
9676 char buf[100];
9677 if (strcasecmp(val, "Enable") == 0)
9678 snprintf(buf, sizeof(buf), "SET ps 99");
9679 else if (strcasecmp(val, "Disable") == 0)
9680 snprintf(buf, sizeof(buf), "SET ps 98");
9681 else {
9682 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9683 "Unsupported uapsd parameter value");
9684 return 0;
9685 }
9686 if (wpa_command(intf, buf)) {
9687 send_resp(dut, conn, SIGMA_ERROR,
9688 "ErrorCode,Failed to change U-APSD "
9689 "powersave mode");
9690 return 0;
9691 }
9692 }
9693
9694 val = get_param(cmd, "TPKTIMER");
9695 if (val && strcasecmp(val, "DISABLE") == 0) {
9696 if (wpa_command(intf, "SET tdls_testing 0x100")) {
9697 send_resp(dut, conn, SIGMA_ERROR,
9698 "ErrorCode,Failed to enable no TPK "
9699 "expiration test mode");
9700 return 0;
9701 }
9702 dut->no_tpk_expiration = 1;
9703 }
9704
9705 val = get_param(cmd, "ChSwitchMode");
9706 if (val) {
9707 if (strcasecmp(val, "Enable") == 0 ||
9708 strcasecmp(val, "Initiate") == 0)
9709 chsm = CHSM_ENABLE;
9710 else if (strcasecmp(val, "Disable") == 0 ||
9711 strcasecmp(val, "passive") == 0)
9712 chsm = CHSM_DISABLE;
9713 else if (strcasecmp(val, "RejReq") == 0)
9714 chsm = CHSM_REJREQ;
9715 else if (strcasecmp(val, "UnSolResp") == 0)
9716 chsm = CHSM_UNSOLRESP;
9717 else {
9718 send_resp(dut, conn, SIGMA_ERROR,
9719 "ErrorCode,Unknown ChSwitchMode value");
9720 return 0;
9721 }
9722 }
9723
9724 val = get_param(cmd, "OffChNum");
9725 if (val) {
9726 off_ch_num = atoi(val);
9727 if (off_ch_num == 0) {
9728 send_resp(dut, conn, SIGMA_ERROR,
9729 "ErrorCode,Invalid OffChNum");
9730 return 0;
9731 }
9732 }
9733
9734 val = get_param(cmd, "SecChOffset");
9735 if (val) {
9736 if (strcmp(val, "20") == 0)
9737 sec_ch = SEC_CH_NO;
9738 else if (strcasecmp(val, "40above") == 0)
9739 sec_ch = SEC_CH_40ABOVE;
9740 else if (strcasecmp(val, "40below") == 0)
9741 sec_ch = SEC_CH_40BELOW;
9742 else {
9743 send_resp(dut, conn, SIGMA_ERROR,
9744 "ErrorCode,Unknown SecChOffset value");
9745 return 0;
9746 }
9747 }
9748
9749 if (chsm == CHSM_NOT_SET) {
9750 /* no offchannel changes requested */
9751 return 1;
9752 }
9753
9754 if (strcmp(intf, get_main_ifname()) != 0 &&
9755 strcmp(intf, get_station_ifname()) != 0) {
9756 send_resp(dut, conn, SIGMA_ERROR,
9757 "ErrorCode,Unknown interface");
9758 return 0;
9759 }
9760
9761 switch (chsm) {
9762 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +03009763 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009764 break;
9765 case CHSM_ENABLE:
9766 if (off_ch_num < 0) {
9767 send_resp(dut, conn, SIGMA_ERROR,
9768 "ErrorCode,Missing OffChNum argument");
9769 return 0;
9770 }
9771 if (wifi_chip_type == DRIVER_WCN) {
9772 res = tdls_set_offchannel_offset(dut, conn, intf,
9773 off_ch_num, sec_ch);
9774 } else {
9775 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
9776 sec_ch);
9777 }
9778 if (res != 1)
9779 return res;
9780 if (wifi_chip_type == DRIVER_WCN)
9781 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
9782 else
9783 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
9784 break;
9785 case CHSM_DISABLE:
9786 if (wifi_chip_type == DRIVER_WCN)
9787 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
9788 else
9789 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
9790 break;
9791 case CHSM_REJREQ:
9792 if (wifi_chip_type == DRIVER_WCN)
9793 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
9794 else
9795 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
9796 break;
9797 case CHSM_UNSOLRESP:
9798 if (off_ch_num < 0) {
9799 send_resp(dut, conn, SIGMA_ERROR,
9800 "ErrorCode,Missing OffChNum argument");
9801 return 0;
9802 }
9803 if (wifi_chip_type == DRIVER_WCN) {
9804 res = tdls_set_offchannel_offset(dut, conn, intf,
9805 off_ch_num, sec_ch);
9806 } else {
9807 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
9808 sec_ch);
9809 }
9810 if (res != 1)
9811 return res;
9812 if (wifi_chip_type == DRIVER_WCN)
9813 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
9814 else
9815 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
9816 break;
9817 }
9818
9819 return res;
9820}
9821
9822
9823static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
9824 struct sigma_conn *conn,
9825 struct sigma_cmd *cmd)
9826{
9827 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +05309828 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009829
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08009830 novap_reset(dut, intf);
9831
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009832 val = get_param(cmd, "nss_mcs_opt");
9833 if (val) {
9834 /* String (nss_operating_mode; mcs_operating_mode) */
9835 int nss, mcs;
9836 char buf[50];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309837 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009838
9839 token = strdup(val);
9840 if (!token)
9841 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309842 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05309843 if (!result) {
9844 sigma_dut_print(dut, DUT_MSG_ERROR,
9845 "VHT NSS not specified");
9846 goto failed;
9847 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009848 if (strcasecmp(result, "def") != 0) {
9849 nss = atoi(result);
9850 if (nss == 4)
9851 ath_disable_txbf(dut, intf);
9852 snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
9853 intf, nss);
9854 if (system(buf) != 0) {
9855 sigma_dut_print(dut, DUT_MSG_ERROR,
9856 "iwpriv nss failed");
9857 goto failed;
9858 }
9859 }
9860
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309861 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05309862 if (!result) {
9863 sigma_dut_print(dut, DUT_MSG_ERROR,
9864 "VHT MCS not specified");
9865 goto failed;
9866 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009867 if (strcasecmp(result, "def") == 0) {
9868 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0",
9869 intf);
9870 if (system(buf) != 0) {
9871 sigma_dut_print(dut, DUT_MSG_ERROR,
9872 "iwpriv set11NRates failed");
9873 goto failed;
9874 }
9875
9876 } else {
9877 mcs = atoi(result);
9878 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
9879 intf, mcs);
9880 if (system(buf) != 0) {
9881 sigma_dut_print(dut, DUT_MSG_ERROR,
9882 "iwpriv vhtmcs failed");
9883 goto failed;
9884 }
9885 }
9886 /* Channel width gets messed up, fix this */
9887 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
9888 intf, dut->chwidth);
9889 if (system(buf) != 0) {
9890 sigma_dut_print(dut, DUT_MSG_ERROR,
9891 "iwpriv chwidth failed");
9892 }
9893 }
9894
Srikanth Marepalli5415acf2018-08-27 12:53:11 +05309895 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009896 return 1;
9897failed:
9898 free(token);
9899 return 0;
9900}
9901
9902
9903static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
9904 struct sigma_conn *conn,
9905 struct sigma_cmd *cmd)
9906{
9907 switch (get_driver_type()) {
9908 case DRIVER_ATHEROS:
9909 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
9910 default:
9911 send_resp(dut, conn, SIGMA_ERROR,
9912 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
9913 return 0;
9914 }
9915}
9916
9917
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009918static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
9919 struct sigma_conn *conn,
9920 struct sigma_cmd *cmd)
9921{
9922 const char *val;
9923 char *token = NULL, *result;
9924 char buf[60];
9925
9926 val = get_param(cmd, "nss_mcs_opt");
9927 if (val) {
9928 /* String (nss_operating_mode; mcs_operating_mode) */
9929 int nss, mcs, ratecode;
9930 char *saveptr;
9931
9932 token = strdup(val);
9933 if (!token)
9934 return -2;
9935
9936 result = strtok_r(token, ";", &saveptr);
9937 if (!result) {
9938 sigma_dut_print(dut, DUT_MSG_ERROR,
9939 "HE NSS not specified");
9940 goto failed;
9941 }
9942 nss = 1;
9943 if (strcasecmp(result, "def") != 0)
9944 nss = atoi(result);
9945
9946 result = strtok_r(NULL, ";", &saveptr);
9947 if (!result) {
9948 sigma_dut_print(dut, DUT_MSG_ERROR,
9949 "HE MCS not specified");
9950 goto failed;
9951 }
9952 mcs = 7;
9953 if (strcasecmp(result, "def") != 0)
9954 mcs = atoi(result);
9955
Arif Hussain557bf412018-05-25 17:29:36 -07009956 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009957 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -07009958 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009959 } else if (nss > 2) {
9960 sigma_dut_print(dut, DUT_MSG_ERROR,
9961 "HE NSS %d not supported", nss);
9962 goto failed;
9963 }
9964
Arif Hussain557bf412018-05-25 17:29:36 -07009965 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
9966 if (system(buf) != 0) {
9967 sigma_dut_print(dut, DUT_MSG_ERROR,
9968 "nss_mcs_opt: iwpriv %s nss %d failed",
9969 intf, nss);
9970 goto failed;
9971 }
Arif Hussainac6c5112018-05-25 17:34:00 -07009972 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -07009973
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009974 /* Add the MCS to the ratecode */
9975 if (mcs >= 0 && mcs <= 11) {
9976 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -07009977#ifdef NL80211_SUPPORT
9978 if (dut->device_type == STA_testbed) {
9979 enum he_mcs_config mcs_config;
9980 int ret;
9981
9982 if (mcs <= 7)
9983 mcs_config = HE_80_MCS0_7;
9984 else if (mcs <= 9)
9985 mcs_config = HE_80_MCS0_9;
9986 else
9987 mcs_config = HE_80_MCS0_11;
9988 ret = sta_set_he_mcs(dut, intf, mcs_config);
9989 if (ret) {
9990 sigma_dut_print(dut, DUT_MSG_ERROR,
9991 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
9992 mcs, mcs_config, ret);
9993 goto failed;
9994 }
9995 }
9996#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -08009997 } else {
9998 sigma_dut_print(dut, DUT_MSG_ERROR,
9999 "HE MCS %d not supported", mcs);
10000 goto failed;
10001 }
10002 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
10003 intf, ratecode);
10004 if (system(buf) != 0) {
10005 sigma_dut_print(dut, DUT_MSG_ERROR,
10006 "iwpriv setting of 11ax rates failed");
10007 goto failed;
10008 }
10009 free(token);
10010 }
10011
10012 val = get_param(cmd, "GI");
10013 if (val) {
10014 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010015 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010016 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010017 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
10018 intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010019 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010020 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
10021 intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010022 } else {
10023 send_resp(dut, conn, SIGMA_ERROR,
10024 "errorCode,GI value not supported");
10025 return 0;
10026 }
10027 if (system(buf) != 0) {
10028 send_resp(dut, conn, SIGMA_ERROR,
10029 "errorCode,Failed to set shortgi");
10030 return 0;
10031 }
10032 }
10033
Subhani Shaik8e7a3052018-04-24 14:03:00 -070010034 val = get_param(cmd, "LTF");
10035 if (val) {
10036#ifdef NL80211_SUPPORT
10037 if (strcmp(val, "3.2") == 0) {
10038 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
10039 } if (strcmp(val, "6.4") == 0) {
10040 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
10041 } else if (strcmp(val, "12.8") == 0) {
10042 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
10043 } else {
10044 send_resp(dut, conn, SIGMA_ERROR,
10045 "errorCode, LTF value not supported");
10046 return 0;
10047 }
10048#else /* NL80211_SUPPORT */
10049 sigma_dut_print(dut, DUT_MSG_ERROR,
10050 "LTF cannot be set without NL80211_SUPPORT defined");
10051 return -2;
10052#endif /* NL80211_SUPPORT */
10053 }
10054
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070010055 val = get_param(cmd, "TxSUPPDU");
10056 if (val) {
10057 int set_val = 1;
10058
10059 if (strcasecmp(val, "Enable") == 0)
10060 set_val = 1;
10061 else if (strcasecmp(val, "Disable") == 0)
10062 set_val = 0;
10063
10064 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
10065 send_resp(dut, conn, SIGMA_ERROR,
10066 "ErrorCode,Failed to set Tx SU PPDU config");
10067 return 0;
10068 }
10069 }
10070
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070010071 val = get_param(cmd, "OMCtrl_RxNSS");
10072 if (val) {
10073 /*
10074 * OMCtrl_RxNSS uses the IEEE 802.11 standard values for Nss,
10075 * i.e., 0 for 1Nss, 1 for Nss 2, etc. The driver checks for
10076 * the actual Nss value hence add 1 to the set value.
10077 */
10078 int set_val = atoi(val) + 1;
10079
10080 if (sta_set_he_om_ctrl_nss(dut, intf, set_val)) {
10081 send_resp(dut, conn, SIGMA_ERROR,
10082 "ErrorCode,Failed to set OM ctrl NSS config");
10083 return 0;
10084 }
10085 }
10086
10087 val = get_param(cmd, "OMCtrl_ChnlWidth");
10088 if (val) {
10089 int set_val = atoi(val);
10090
10091 if (sta_set_he_om_ctrl_bw(dut, intf,
10092 (enum qca_wlan_he_om_ctrl_ch_bw)
10093 set_val)) {
10094 send_resp(dut, conn, SIGMA_ERROR,
10095 "ErrorCode,Failed to set OM ctrl BW config");
10096 return 0;
10097 }
10098 }
10099
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010100 return 1;
10101
10102failed:
10103 free(token);
10104 return -2;
10105}
10106
10107
10108static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
10109 struct sigma_conn *conn,
10110 struct sigma_cmd *cmd)
10111{
10112 switch (get_driver_type()) {
10113 case DRIVER_WCN:
10114 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
10115 default:
10116 send_resp(dut, conn, SIGMA_ERROR,
10117 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
10118 return 0;
10119 }
10120}
10121
10122
Ashwini Patil5acd7382017-04-13 15:55:04 +053010123static int btm_query_candidate_list(struct sigma_dut *dut,
10124 struct sigma_conn *conn,
10125 struct sigma_cmd *cmd)
10126{
10127 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
10128 int len, ret;
10129 char buf[10];
10130
10131 /*
10132 * Neighbor Report elements format:
10133 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
10134 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
10135 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
10136 */
10137
10138 bssid = get_param(cmd, "Nebor_BSSID");
10139 if (!bssid) {
10140 send_resp(dut, conn, SIGMA_INVALID,
10141 "errorCode,Nebor_BSSID is missing");
10142 return 0;
10143 }
10144
10145 info = get_param(cmd, "Nebor_Bssid_Info");
10146 if (!info) {
10147 sigma_dut_print(dut, DUT_MSG_INFO,
10148 "Using default value for Nebor_Bssid_Info: %s",
10149 DEFAULT_NEIGHBOR_BSSID_INFO);
10150 info = DEFAULT_NEIGHBOR_BSSID_INFO;
10151 }
10152
10153 op_class = get_param(cmd, "Nebor_Op_Class");
10154 if (!op_class) {
10155 send_resp(dut, conn, SIGMA_INVALID,
10156 "errorCode,Nebor_Op_Class is missing");
10157 return 0;
10158 }
10159
10160 ch = get_param(cmd, "Nebor_Op_Ch");
10161 if (!ch) {
10162 send_resp(dut, conn, SIGMA_INVALID,
10163 "errorCode,Nebor_Op_Ch is missing");
10164 return 0;
10165 }
10166
10167 phy_type = get_param(cmd, "Nebor_Phy_Type");
10168 if (!phy_type) {
10169 sigma_dut_print(dut, DUT_MSG_INFO,
10170 "Using default value for Nebor_Phy_Type: %s",
10171 DEFAULT_NEIGHBOR_PHY_TYPE);
10172 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
10173 }
10174
10175 /* Parse optional subelements */
10176 buf[0] = '\0';
10177 pref = get_param(cmd, "Nebor_Pref");
10178 if (pref) {
10179 /* hexdump for preferrence subelement */
10180 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
10181 if (ret < 0 || ret >= (int) sizeof(buf)) {
10182 sigma_dut_print(dut, DUT_MSG_ERROR,
10183 "snprintf failed for optional subelement ret: %d",
10184 ret);
10185 send_resp(dut, conn, SIGMA_ERROR,
10186 "errorCode,snprintf failed for subelement");
10187 return 0;
10188 }
10189 }
10190
10191 if (!dut->btm_query_cand_list) {
10192 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
10193 if (!dut->btm_query_cand_list) {
10194 send_resp(dut, conn, SIGMA_ERROR,
10195 "errorCode,Failed to allocate memory for btm_query_cand_list");
10196 return 0;
10197 }
10198 }
10199
10200 len = strlen(dut->btm_query_cand_list);
10201 ret = snprintf(dut->btm_query_cand_list + len,
10202 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
10203 bssid, info, op_class, ch, phy_type, buf);
10204 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
10205 sigma_dut_print(dut, DUT_MSG_ERROR,
10206 "snprintf failed for neighbor report list ret: %d",
10207 ret);
10208 send_resp(dut, conn, SIGMA_ERROR,
10209 "errorCode,snprintf failed for neighbor report");
10210 free(dut->btm_query_cand_list);
10211 dut->btm_query_cand_list = NULL;
10212 return 0;
10213 }
10214
10215 return 1;
10216}
10217
10218
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010219static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
10220 struct sigma_cmd *cmd)
10221{
10222 const char *intf = get_param(cmd, "Interface");
10223 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010224 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010225
10226 if (intf == NULL || prog == NULL)
10227 return -1;
10228
Ashwini Patil5acd7382017-04-13 15:55:04 +053010229 /* BSS Transition candidate list for BTM query */
10230 val = get_param(cmd, "Nebor_BSSID");
10231 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
10232 return 0;
10233
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010234 if (strcasecmp(prog, "TDLS") == 0)
10235 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
10236
10237 if (strcasecmp(prog, "VHT") == 0)
10238 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
10239
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010240 if (strcasecmp(prog, "HE") == 0)
10241 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
10242
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010243 if (strcasecmp(prog, "MBO") == 0) {
10244 val = get_param(cmd, "Cellular_Data_Cap");
10245 if (val &&
10246 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
10247 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053010248
10249 val = get_param(cmd, "Ch_Pref");
10250 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
10251 return 0;
10252
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010253 return 1;
10254 }
10255
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010256 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
10257 return 0;
10258}
10259
10260
10261static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
10262 struct sigma_cmd *cmd)
10263{
10264 const char *intf = get_param(cmd, "Interface");
10265 const char *mode = get_param(cmd, "Mode");
10266 int res;
10267
10268 if (intf == NULL || mode == NULL)
10269 return -1;
10270
10271 if (strcasecmp(mode, "On") == 0)
10272 res = wpa_command(intf, "SET radio_disabled 0");
10273 else if (strcasecmp(mode, "Off") == 0)
10274 res = wpa_command(intf, "SET radio_disabled 1");
10275 else
10276 return -1;
10277
10278 if (res) {
10279 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
10280 "radio mode");
10281 return 0;
10282 }
10283
10284 return 1;
10285}
10286
10287
10288static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
10289 struct sigma_cmd *cmd)
10290{
10291 const char *intf = get_param(cmd, "Interface");
10292 const char *mode = get_param(cmd, "Mode");
10293 int res;
10294
10295 if (intf == NULL || mode == NULL)
10296 return -1;
10297
10298 if (strcasecmp(mode, "On") == 0)
10299 res = set_ps(intf, dut, 1);
10300 else if (strcasecmp(mode, "Off") == 0)
10301 res = set_ps(intf, dut, 0);
10302 else
10303 return -1;
10304
10305 if (res) {
10306 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
10307 "power save mode");
10308 return 0;
10309 }
10310
10311 return 1;
10312}
10313
10314
10315static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
10316 struct sigma_cmd *cmd)
10317{
10318 const char *intf = get_param(cmd, "Interface");
10319 const char *val, *bssid;
10320 int res;
10321 char *buf;
10322 size_t buf_len;
10323
10324 val = get_param(cmd, "BSSID_FILTER");
10325 if (val == NULL)
10326 return -1;
10327
10328 bssid = get_param(cmd, "BSSID_List");
10329 if (atoi(val) == 0 || bssid == NULL) {
10330 /* Disable BSSID filter */
10331 if (wpa_command(intf, "SET bssid_filter ")) {
10332 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
10333 "to disable BSSID filter");
10334 return 0;
10335 }
10336
10337 return 1;
10338 }
10339
10340 buf_len = 100 + strlen(bssid);
10341 buf = malloc(buf_len);
10342 if (buf == NULL)
10343 return -1;
10344
10345 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
10346 res = wpa_command(intf, buf);
10347 free(buf);
10348 if (res) {
10349 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
10350 "BSSID filter");
10351 return 0;
10352 }
10353
10354 return 1;
10355}
10356
10357
10358static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
10359 struct sigma_cmd *cmd)
10360{
10361 const char *intf = get_param(cmd, "Interface");
10362 const char *val;
10363
10364 /* TODO: ARP */
10365
10366 val = get_param(cmd, "HS2_CACHE_PROFILE");
10367 if (val && strcasecmp(val, "All") == 0)
10368 hs2_clear_credentials(intf);
10369
10370 return 1;
10371}
10372
10373
10374static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
10375 struct sigma_cmd *cmd)
10376{
10377 const char *intf = get_param(cmd, "Interface");
10378 const char *key_type = get_param(cmd, "KeyType");
10379 char buf[100], resp[200];
10380
10381 if (key_type == NULL)
10382 return -1;
10383
10384 if (strcasecmp(key_type, "GTK") == 0) {
10385 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
10386 strncmp(buf, "FAIL", 4) == 0) {
10387 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10388 "not fetch current GTK");
10389 return 0;
10390 }
10391 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
10392 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10393 return 0;
10394 } else {
10395 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10396 "KeyType");
10397 return 0;
10398 }
10399
10400 return 1;
10401}
10402
10403
10404static int hs2_set_policy(struct sigma_dut *dut)
10405{
10406#ifdef ANDROID
10407 system("ip rule del prio 23000");
10408 if (system("ip rule add from all lookup main prio 23000") != 0) {
10409 sigma_dut_print(dut, DUT_MSG_ERROR,
10410 "Failed to run:ip rule add from all lookup main prio");
10411 return -1;
10412 }
10413 if (system("ip route flush cache") != 0) {
10414 sigma_dut_print(dut, DUT_MSG_ERROR,
10415 "Failed to run ip route flush cache");
10416 return -1;
10417 }
10418 return 1;
10419#else /* ANDROID */
10420 return 0;
10421#endif /* ANDROID */
10422}
10423
10424
10425static int cmd_sta_hs2_associate(struct sigma_dut *dut,
10426 struct sigma_conn *conn,
10427 struct sigma_cmd *cmd)
10428{
10429 const char *intf = get_param(cmd, "Interface");
10430 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030010431 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010432 struct wpa_ctrl *ctrl;
10433 int res;
10434 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
10435 int tries = 0;
10436 int ignore_blacklist = 0;
10437 const char *events[] = {
10438 "CTRL-EVENT-CONNECTED",
10439 "INTERWORKING-BLACKLISTED",
10440 "INTERWORKING-NO-MATCH",
10441 NULL
10442 };
10443
10444 start_sta_mode(dut);
10445
Jouni Malinen439352d2018-09-13 03:42:23 +030010446 if (band) {
10447 if (strcmp(band, "2.4") == 0) {
10448 wpa_command(intf, "SET setband 2G");
10449 } else if (strcmp(band, "5") == 0) {
10450 wpa_command(intf, "SET setband 5G");
10451 } else {
10452 send_resp(dut, conn, SIGMA_ERROR,
10453 "errorCode,Unsupported band");
10454 return 0;
10455 }
10456 }
10457
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010458 blacklisted[0] = '\0';
10459 if (val && atoi(val))
10460 ignore_blacklist = 1;
10461
10462try_again:
10463 ctrl = open_wpa_mon(intf);
10464 if (ctrl == NULL) {
10465 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
10466 "wpa_supplicant monitor connection");
10467 return -2;
10468 }
10469
10470 tries++;
10471 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
10472 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
10473 "Interworking connection");
10474 wpa_ctrl_detach(ctrl);
10475 wpa_ctrl_close(ctrl);
10476 return 0;
10477 }
10478
10479 buf[0] = '\0';
10480 while (1) {
10481 char *pos;
10482 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
10483 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
10484 if (!pos)
10485 break;
10486 pos += 25;
10487 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
10488 pos);
10489 if (!blacklisted[0])
10490 memcpy(blacklisted, pos, strlen(pos) + 1);
10491 }
10492
10493 if (ignore_blacklist && blacklisted[0]) {
10494 char *end;
10495 end = strchr(blacklisted, ' ');
10496 if (end)
10497 *end = '\0';
10498 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
10499 blacklisted);
10500 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
10501 blacklisted);
10502 if (wpa_command(intf, buf)) {
10503 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
10504 wpa_ctrl_detach(ctrl);
10505 wpa_ctrl_close(ctrl);
10506 return 0;
10507 }
10508 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
10509 buf, sizeof(buf));
10510 }
10511
10512 wpa_ctrl_detach(ctrl);
10513 wpa_ctrl_close(ctrl);
10514
10515 if (res < 0) {
10516 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
10517 "connect");
10518 return 0;
10519 }
10520
10521 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
10522 strstr(buf, "INTERWORKING-BLACKLISTED")) {
10523 if (tries < 2) {
10524 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
10525 goto try_again;
10526 }
10527 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
10528 "matching credentials found");
10529 return 0;
10530 }
10531
10532 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
10533 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
10534 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
10535 "get current BSSID/SSID");
10536 return 0;
10537 }
10538
10539 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
10540 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10541 hs2_set_policy(dut);
10542 return 0;
10543}
10544
10545
Jouni Malinenb639f1c2018-09-13 02:39:46 +030010546static int cmd_sta_hs2_venue_info(struct sigma_dut *dut,
10547 struct sigma_conn *conn,
10548 struct sigma_cmd *cmd)
10549{
10550 const char *intf = get_param(cmd, "Interface");
10551 const char *display = get_param(cmd, "Display");
10552 struct wpa_ctrl *ctrl;
10553 char buf[300], params[400], *pos;
10554 char bssid[20];
10555 int info_avail = 0;
10556 unsigned int old_timeout;
10557 int res;
10558
10559 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
10560 send_resp(dut, conn, SIGMA_ERROR,
10561 "ErrorCode,Could not get current BSSID");
10562 return 0;
10563 }
10564 ctrl = open_wpa_mon(intf);
10565 if (!ctrl) {
10566 sigma_dut_print(dut, DUT_MSG_ERROR,
10567 "Failed to open wpa_supplicant monitor connection");
10568 return -2;
10569 }
10570
10571 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
10572 wpa_command(intf, buf);
10573
10574 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
10575 if (res < 0) {
10576 send_resp(dut, conn, SIGMA_ERROR,
10577 "ErrorCode,Could not complete GAS query");
10578 goto fail;
10579 }
10580
10581 old_timeout = dut->default_timeout;
10582 dut->default_timeout = 2;
10583 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
10584 dut->default_timeout = old_timeout;
10585 if (res < 0)
10586 goto done;
10587 pos = strchr(buf, ' ');
10588 if (!pos)
10589 goto done;
10590 pos++;
10591 pos = strchr(pos, ' ');
10592 if (!pos)
10593 goto done;
10594 pos++;
10595 info_avail = 1;
10596 snprintf(params, sizeof(params), "browser %s", pos);
10597
10598 if (display && strcasecmp(display, "Yes") == 0) {
10599 pid_t pid;
10600
10601 pid = fork();
10602 if (pid < 0) {
10603 perror("fork");
10604 return -1;
10605 }
10606
10607 if (pid == 0) {
10608 run_hs20_osu(dut, params);
10609 exit(0);
10610 }
10611 }
10612
10613done:
10614 snprintf(buf, sizeof(buf), "Info_available,%s",
10615 info_avail ? "Yes" : "No");
10616 send_resp(dut, conn, SIGMA_COMPLETE, buf);
10617fail:
10618 wpa_ctrl_detach(ctrl);
10619 wpa_ctrl_close(ctrl);
10620 return 0;
10621}
10622
10623
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010624static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
10625 struct sigma_conn *conn,
10626 const char *ifname,
10627 struct sigma_cmd *cmd)
10628{
10629 const char *val;
10630 int id;
10631
10632 id = add_cred(ifname);
10633 if (id < 0)
10634 return -2;
10635 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
10636
10637 val = get_param(cmd, "prefer");
10638 if (val && atoi(val) > 0)
10639 set_cred(ifname, id, "priority", "1");
10640
10641 val = get_param(cmd, "REALM");
10642 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
10643 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10644 "realm");
10645 return 0;
10646 }
10647
10648 val = get_param(cmd, "HOME_FQDN");
10649 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
10650 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10651 "home_fqdn");
10652 return 0;
10653 }
10654
10655 val = get_param(cmd, "Username");
10656 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
10657 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10658 "username");
10659 return 0;
10660 }
10661
10662 val = get_param(cmd, "Password");
10663 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
10664 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10665 "password");
10666 return 0;
10667 }
10668
10669 val = get_param(cmd, "ROOT_CA");
10670 if (val) {
10671 char fname[200];
10672 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
10673#ifdef __linux__
10674 if (!file_exists(fname)) {
10675 char msg[300];
10676 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
10677 "file (%s) not found", fname);
10678 send_resp(dut, conn, SIGMA_ERROR, msg);
10679 return 0;
10680 }
10681#endif /* __linux__ */
10682 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
10683 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10684 "not set root CA");
10685 return 0;
10686 }
10687 }
10688
10689 return 1;
10690}
10691
10692
10693static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
10694{
10695 FILE *in, *out;
10696 char buf[500];
10697 int found = 0;
10698
10699 in = fopen("devdetail.xml", "r");
10700 if (in == NULL)
10701 return -1;
10702 out = fopen("devdetail.xml.tmp", "w");
10703 if (out == NULL) {
10704 fclose(in);
10705 return -1;
10706 }
10707
10708 while (fgets(buf, sizeof(buf), in)) {
10709 char *pos = strstr(buf, "<IMSI>");
10710 if (pos) {
10711 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
10712 imsi);
10713 pos += 6;
10714 *pos = '\0';
10715 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
10716 found++;
10717 } else {
10718 fprintf(out, "%s", buf);
10719 }
10720 }
10721
10722 fclose(out);
10723 fclose(in);
10724 if (found)
10725 rename("devdetail.xml.tmp", "devdetail.xml");
10726 else
10727 unlink("devdetail.xml.tmp");
10728
10729 return 0;
10730}
10731
10732
10733static int sta_add_credential_sim(struct sigma_dut *dut,
10734 struct sigma_conn *conn,
10735 const char *ifname, struct sigma_cmd *cmd)
10736{
10737 const char *val, *imsi = NULL;
10738 int id;
10739 char buf[200];
10740 int res;
10741 const char *pos;
10742 size_t mnc_len;
10743 char plmn_mcc[4];
10744 char plmn_mnc[4];
10745
10746 id = add_cred(ifname);
10747 if (id < 0)
10748 return -2;
10749 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
10750
10751 val = get_param(cmd, "prefer");
10752 if (val && atoi(val) > 0)
10753 set_cred(ifname, id, "priority", "1");
10754
10755 val = get_param(cmd, "PLMN_MCC");
10756 if (val == NULL) {
10757 send_resp(dut, conn, SIGMA_ERROR,
10758 "errorCode,Missing PLMN_MCC");
10759 return 0;
10760 }
10761 if (strlen(val) != 3) {
10762 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
10763 return 0;
10764 }
10765 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
10766
10767 val = get_param(cmd, "PLMN_MNC");
10768 if (val == NULL) {
10769 send_resp(dut, conn, SIGMA_ERROR,
10770 "errorCode,Missing PLMN_MNC");
10771 return 0;
10772 }
10773 if (strlen(val) != 2 && strlen(val) != 3) {
10774 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
10775 return 0;
10776 }
10777 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
10778
10779 val = get_param(cmd, "IMSI");
10780 if (val == NULL) {
10781 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
10782 "IMSI");
10783 return 0;
10784 }
10785
10786 imsi = pos = val;
10787
10788 if (strncmp(plmn_mcc, pos, 3) != 0) {
10789 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
10790 return 0;
10791 }
10792 pos += 3;
10793
10794 mnc_len = strlen(plmn_mnc);
10795 if (mnc_len < 2) {
10796 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
10797 return 0;
10798 }
10799
10800 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
10801 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
10802 return 0;
10803 }
10804 pos += mnc_len;
10805
10806 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
10807 if (res < 0 || res >= (int) sizeof(buf))
10808 return -1;
10809 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
10810 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10811 "not set IMSI");
10812 return 0;
10813 }
10814
10815 val = get_param(cmd, "Password");
10816 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
10817 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10818 "not set password");
10819 return 0;
10820 }
10821
Jouni Malinenba630452018-06-22 11:49:59 +030010822 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010823 /*
10824 * Set provisioning_sp for the test cases where SIM/USIM
10825 * provisioning is used.
10826 */
10827 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
10828 "wi-fi.org") < 0) {
10829 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10830 "not set provisioning_sp");
10831 return 0;
10832 }
10833
10834 update_devdetail_imsi(dut, imsi);
10835 }
10836
10837 return 1;
10838}
10839
10840
10841static int sta_add_credential_cert(struct sigma_dut *dut,
10842 struct sigma_conn *conn,
10843 const char *ifname,
10844 struct sigma_cmd *cmd)
10845{
10846 const char *val;
10847 int id;
10848
10849 id = add_cred(ifname);
10850 if (id < 0)
10851 return -2;
10852 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
10853
10854 val = get_param(cmd, "prefer");
10855 if (val && atoi(val) > 0)
10856 set_cred(ifname, id, "priority", "1");
10857
10858 val = get_param(cmd, "REALM");
10859 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
10860 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10861 "realm");
10862 return 0;
10863 }
10864
10865 val = get_param(cmd, "HOME_FQDN");
10866 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
10867 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10868 "home_fqdn");
10869 return 0;
10870 }
10871
10872 val = get_param(cmd, "Username");
10873 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
10874 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10875 "username");
10876 return 0;
10877 }
10878
10879 val = get_param(cmd, "clientCertificate");
10880 if (val) {
10881 char fname[200];
10882 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
10883#ifdef __linux__
10884 if (!file_exists(fname)) {
10885 char msg[300];
10886 snprintf(msg, sizeof(msg),
10887 "ErrorCode,clientCertificate "
10888 "file (%s) not found", fname);
10889 send_resp(dut, conn, SIGMA_ERROR, msg);
10890 return 0;
10891 }
10892#endif /* __linux__ */
10893 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
10894 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10895 "not set client_cert");
10896 return 0;
10897 }
10898 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
10899 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10900 "not set private_key");
10901 return 0;
10902 }
10903 }
10904
10905 val = get_param(cmd, "ROOT_CA");
10906 if (val) {
10907 char fname[200];
10908 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
10909#ifdef __linux__
10910 if (!file_exists(fname)) {
10911 char msg[300];
10912 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
10913 "file (%s) not found", fname);
10914 send_resp(dut, conn, SIGMA_ERROR, msg);
10915 return 0;
10916 }
10917#endif /* __linux__ */
10918 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
10919 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10920 "not set root CA");
10921 return 0;
10922 }
10923 }
10924
10925 return 1;
10926}
10927
10928
10929static int cmd_sta_add_credential(struct sigma_dut *dut,
10930 struct sigma_conn *conn,
10931 struct sigma_cmd *cmd)
10932{
10933 const char *intf = get_param(cmd, "Interface");
10934 const char *type;
10935
10936 start_sta_mode(dut);
10937
10938 type = get_param(cmd, "Type");
10939 if (!type)
10940 return -1;
10941
10942 if (strcasecmp(type, "uname_pwd") == 0)
10943 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
10944
10945 if (strcasecmp(type, "sim") == 0)
10946 return sta_add_credential_sim(dut, conn, intf, cmd);
10947
10948 if (strcasecmp(type, "cert") == 0)
10949 return sta_add_credential_cert(dut, conn, intf, cmd);
10950
10951 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
10952 "type");
10953 return 0;
10954}
10955
10956
10957static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
10958 struct sigma_cmd *cmd)
10959{
10960 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053010961 const char *val, *bssid, *ssid;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010962 char buf[100];
vamsi krishna89ad8c62017-09-19 12:51:18 +053010963 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010964 int res;
10965
10966 val = get_param(cmd, "HESSID");
10967 if (val) {
10968 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
10969 if (res < 0 || res >= (int) sizeof(buf))
10970 return -1;
10971 wpa_command(intf, buf);
10972 }
10973
10974 val = get_param(cmd, "ACCS_NET_TYPE");
10975 if (val) {
10976 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
10977 val);
10978 if (res < 0 || res >= (int) sizeof(buf))
10979 return -1;
10980 wpa_command(intf, buf);
10981 }
10982
vamsi krishna89ad8c62017-09-19 12:51:18 +053010983 bssid = get_param(cmd, "Bssid");
10984 ssid = get_param(cmd, "Ssid");
10985
10986 if (ssid) {
10987 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
10988 send_resp(dut, conn, SIGMA_ERROR,
10989 "ErrorCode,Too long SSID");
10990 return 0;
10991 }
10992 ascii2hexstr(ssid, ssid_hex);
10993 }
10994
10995 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
10996 bssid ? " bssid=": "",
10997 bssid ? bssid : "",
10998 ssid ? " ssid " : "",
10999 ssid ? ssid_hex : "");
11000 if (res < 0 || res >= (int) sizeof(buf))
11001 return -1;
11002
11003 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011004 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
11005 "scan");
11006 return 0;
11007 }
11008
11009 return 1;
11010}
11011
11012
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020011013static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
11014 struct sigma_cmd *cmd)
11015{
11016 const char *intf = get_param(cmd, "Interface");
11017 const char *bssid;
11018 char buf[4096], *pos;
11019 int freq, chan;
11020 char *ssid;
11021 char resp[100];
11022 int res;
11023 struct wpa_ctrl *ctrl;
11024
11025 bssid = get_param(cmd, "BSSID");
11026 if (!bssid) {
11027 send_resp(dut, conn, SIGMA_INVALID,
11028 "errorCode,BSSID argument is missing");
11029 return 0;
11030 }
11031
11032 ctrl = open_wpa_mon(intf);
11033 if (!ctrl) {
11034 sigma_dut_print(dut, DUT_MSG_ERROR,
11035 "Failed to open wpa_supplicant monitor connection");
11036 return -1;
11037 }
11038
11039 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
11040 send_resp(dut, conn, SIGMA_ERROR,
11041 "errorCode,Could not start scan");
11042 wpa_ctrl_detach(ctrl);
11043 wpa_ctrl_close(ctrl);
11044 return 0;
11045 }
11046
11047 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
11048 buf, sizeof(buf));
11049
11050 wpa_ctrl_detach(ctrl);
11051 wpa_ctrl_close(ctrl);
11052
11053 if (res < 0) {
11054 send_resp(dut, conn, SIGMA_ERROR,
11055 "errorCode,Scan did not complete");
11056 return 0;
11057 }
11058
11059 snprintf(buf, sizeof(buf), "BSS %s", bssid);
11060 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
11061 strncmp(buf, "id=", 3) != 0) {
11062 send_resp(dut, conn, SIGMA_ERROR,
11063 "errorCode,Specified BSSID not found");
11064 return 0;
11065 }
11066
11067 pos = strstr(buf, "\nfreq=");
11068 if (!pos) {
11069 send_resp(dut, conn, SIGMA_ERROR,
11070 "errorCode,Channel not found");
11071 return 0;
11072 }
11073 freq = atoi(pos + 6);
11074 chan = freq_to_channel(freq);
11075
11076 pos = strstr(buf, "\nssid=");
11077 if (!pos) {
11078 send_resp(dut, conn, SIGMA_ERROR,
11079 "errorCode,SSID not found");
11080 return 0;
11081 }
11082 ssid = pos + 6;
11083 pos = strchr(ssid, '\n');
11084 if (pos)
11085 *pos = '\0';
11086 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
11087 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11088 return 0;
11089}
11090
11091
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011092static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
11093 struct sigma_cmd *cmd)
11094{
11095#ifdef __linux__
11096 struct timeval tv;
11097 struct tm tm;
11098 time_t t;
11099 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053011100 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011101
11102 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
11103
11104 memset(&tm, 0, sizeof(tm));
11105 val = get_param(cmd, "seconds");
11106 if (val)
11107 tm.tm_sec = atoi(val);
11108 val = get_param(cmd, "minutes");
11109 if (val)
11110 tm.tm_min = atoi(val);
11111 val = get_param(cmd, "hours");
11112 if (val)
11113 tm.tm_hour = atoi(val);
11114 val = get_param(cmd, "date");
11115 if (val)
11116 tm.tm_mday = atoi(val);
11117 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053011118 if (val) {
11119 v = atoi(val);
11120 if (v < 1 || v > 12) {
11121 send_resp(dut, conn, SIGMA_INVALID,
11122 "errorCode,Invalid month");
11123 return 0;
11124 }
11125 tm.tm_mon = v - 1;
11126 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011127 val = get_param(cmd, "year");
11128 if (val) {
11129 int year = atoi(val);
11130#ifdef ANDROID
11131 if (year > 2035)
11132 year = 2035; /* years beyond 2035 not supported */
11133#endif /* ANDROID */
11134 tm.tm_year = year - 1900;
11135 }
11136 t = mktime(&tm);
11137 if (t == (time_t) -1) {
11138 send_resp(dut, conn, SIGMA_ERROR,
11139 "errorCode,Invalid date or time");
11140 return 0;
11141 }
11142
11143 memset(&tv, 0, sizeof(tv));
11144 tv.tv_sec = t;
11145
11146 if (settimeofday(&tv, NULL) < 0) {
11147 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
11148 strerror(errno));
11149 send_resp(dut, conn, SIGMA_ERROR,
11150 "errorCode,Failed to set time");
11151 return 0;
11152 }
11153
11154 return 1;
11155#endif /* __linux__ */
11156
11157 return -1;
11158}
11159
11160
11161static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
11162 struct sigma_cmd *cmd)
11163{
11164 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011165 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011166 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011167 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011168 int res;
11169 struct wpa_ctrl *ctrl;
11170
11171 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011172 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011173
11174 val = get_param(cmd, "ProdESSAssoc");
11175 if (val)
11176 prod_ess_assoc = atoi(val);
11177
11178 kill_dhcp_client(dut, intf);
11179 if (start_dhcp_client(dut, intf) < 0)
11180 return -2;
11181
11182 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
11183 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
11184 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011185 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011186 prod_ess_assoc ? "" : "-N",
11187 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011188 name ? "'" : "",
11189 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
11190 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011191
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053011192 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011193 if (run_hs20_osu(dut, buf) < 0) {
11194 FILE *f;
11195
11196 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
11197
11198 f = fopen("hs20-osu-client.res", "r");
11199 if (f) {
11200 char resp[400], res[300], *pos;
11201 if (!fgets(res, sizeof(res), f))
11202 res[0] = '\0';
11203 pos = strchr(res, '\n');
11204 if (pos)
11205 *pos = '\0';
11206 fclose(f);
11207 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
11208 res);
11209 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
11210 if (system(resp) != 0) {
11211 }
11212 snprintf(resp, sizeof(resp),
11213 "SSID,,BSSID,,failureReason,%s", res);
11214 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11215 return 0;
11216 }
11217
11218 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11219 return 0;
11220 }
11221
11222 if (!prod_ess_assoc)
11223 goto report;
11224
11225 ctrl = open_wpa_mon(intf);
11226 if (ctrl == NULL) {
11227 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11228 "wpa_supplicant monitor connection");
11229 return -1;
11230 }
11231
11232 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
11233 buf, sizeof(buf));
11234
11235 wpa_ctrl_detach(ctrl);
11236 wpa_ctrl_close(ctrl);
11237
11238 if (res < 0) {
11239 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
11240 "network after OSU");
11241 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11242 return 0;
11243 }
11244
11245report:
11246 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
11247 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
11248 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
11249 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11250 return 0;
11251 }
11252
11253 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
11254 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011255 return 0;
11256}
11257
11258
11259static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
11260 struct sigma_cmd *cmd)
11261{
11262 const char *val;
11263 int timeout = 120;
11264
11265 val = get_param(cmd, "PolicyUpdate");
11266 if (val == NULL || atoi(val) == 0)
11267 return 1; /* No operation requested */
11268
11269 val = get_param(cmd, "Timeout");
11270 if (val)
11271 timeout = atoi(val);
11272
11273 if (timeout) {
11274 /* TODO: time out the command and return
11275 * PolicyUpdateStatus,TIMEOUT if needed. */
11276 }
11277
11278 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
11279 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
11280 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
11281 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
11282 return 0;
11283 }
11284
11285 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
11286 return 0;
11287}
11288
11289
11290static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
11291 struct sigma_cmd *cmd)
11292{
11293 struct wpa_ctrl *ctrl;
11294 const char *intf = get_param(cmd, "Interface");
11295 const char *bssid = get_param(cmd, "Bssid");
11296 const char *ssid = get_param(cmd, "SSID");
11297 const char *security = get_param(cmd, "Security");
11298 const char *passphrase = get_param(cmd, "Passphrase");
11299 const char *pin = get_param(cmd, "PIN");
11300 char buf[1000];
11301 char ssid_hex[200], passphrase_hex[200];
11302 const char *keymgmt, *cipher;
11303
11304 if (intf == NULL)
11305 intf = get_main_ifname();
11306
11307 if (!bssid) {
11308 send_resp(dut, conn, SIGMA_ERROR,
11309 "ErrorCode,Missing Bssid argument");
11310 return 0;
11311 }
11312
11313 if (!ssid) {
11314 send_resp(dut, conn, SIGMA_ERROR,
11315 "ErrorCode,Missing SSID argument");
11316 return 0;
11317 }
11318
11319 if (!security) {
11320 send_resp(dut, conn, SIGMA_ERROR,
11321 "ErrorCode,Missing Security argument");
11322 return 0;
11323 }
11324
11325 if (!passphrase) {
11326 send_resp(dut, conn, SIGMA_ERROR,
11327 "ErrorCode,Missing Passphrase argument");
11328 return 0;
11329 }
11330
11331 if (!pin) {
11332 send_resp(dut, conn, SIGMA_ERROR,
11333 "ErrorCode,Missing PIN argument");
11334 return 0;
11335 }
11336
vamsi krishna8c9c1562017-05-12 15:51:46 +053011337 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
11338 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011339 send_resp(dut, conn, SIGMA_ERROR,
11340 "ErrorCode,Too long SSID/passphrase");
11341 return 0;
11342 }
11343
11344 ctrl = open_wpa_mon(intf);
11345 if (ctrl == NULL) {
11346 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11347 "wpa_supplicant monitor connection");
11348 return -2;
11349 }
11350
11351 if (strcasecmp(security, "wpa2-psk") == 0) {
11352 keymgmt = "WPA2PSK";
11353 cipher = "CCMP";
11354 } else {
11355 wpa_ctrl_detach(ctrl);
11356 wpa_ctrl_close(ctrl);
11357 send_resp(dut, conn, SIGMA_ERROR,
11358 "ErrorCode,Unsupported Security value");
11359 return 0;
11360 }
11361
11362 ascii2hexstr(ssid, ssid_hex);
11363 ascii2hexstr(passphrase, passphrase_hex);
11364 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
11365 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
11366
11367 if (wpa_command(intf, buf) < 0) {
11368 wpa_ctrl_detach(ctrl);
11369 wpa_ctrl_close(ctrl);
11370 send_resp(dut, conn, SIGMA_ERROR,
11371 "ErrorCode,Failed to start registrar");
11372 return 0;
11373 }
11374
11375 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
11376 dut->er_oper_performed = 1;
11377
11378 return wps_connection_event(dut, conn, ctrl, intf, 0);
11379}
11380
11381
11382static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
11383 struct sigma_conn *conn,
11384 struct sigma_cmd *cmd)
11385{
11386 struct wpa_ctrl *ctrl;
11387 const char *intf = get_param(cmd, "Interface");
11388 const char *bssid = get_param(cmd, "Bssid");
11389 char buf[100];
11390
11391 if (!bssid) {
11392 send_resp(dut, conn, SIGMA_ERROR,
11393 "ErrorCode,Missing Bssid argument");
11394 return 0;
11395 }
11396
11397 ctrl = open_wpa_mon(intf);
11398 if (ctrl == NULL) {
11399 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11400 "wpa_supplicant monitor connection");
11401 return -2;
11402 }
11403
11404 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
11405
11406 if (wpa_command(intf, buf) < 0) {
11407 wpa_ctrl_detach(ctrl);
11408 wpa_ctrl_close(ctrl);
11409 send_resp(dut, conn, SIGMA_ERROR,
11410 "ErrorCode,Failed to start registrar");
11411 return 0;
11412 }
11413
11414 return wps_connection_event(dut, conn, ctrl, intf, 0);
11415}
11416
11417
vamsi krishna9b144002017-09-20 13:28:13 +053011418static int cmd_start_wps_registration(struct sigma_dut *dut,
11419 struct sigma_conn *conn,
11420 struct sigma_cmd *cmd)
11421{
11422 struct wpa_ctrl *ctrl;
11423 const char *intf = get_param(cmd, "Interface");
11424 const char *role, *method;
11425 int res;
11426 char buf[256];
11427 const char *events[] = {
11428 "CTRL-EVENT-CONNECTED",
11429 "WPS-OVERLAP-DETECTED",
11430 "WPS-TIMEOUT",
11431 "WPS-FAIL",
11432 NULL
11433 };
11434
11435 ctrl = open_wpa_mon(intf);
11436 if (!ctrl) {
11437 sigma_dut_print(dut, DUT_MSG_ERROR,
11438 "Failed to open wpa_supplicant monitor connection");
11439 return -2;
11440 }
11441
11442 role = get_param(cmd, "WpsRole");
11443 if (!role) {
11444 send_resp(dut, conn, SIGMA_INVALID,
11445 "ErrorCode,WpsRole not provided");
11446 goto fail;
11447 }
11448
11449 if (strcasecmp(role, "Enrollee") == 0) {
11450 method = get_param(cmd, "WpsConfigMethod");
11451 if (!method) {
11452 send_resp(dut, conn, SIGMA_INVALID,
11453 "ErrorCode,WpsConfigMethod not provided");
11454 goto fail;
11455 }
11456 if (strcasecmp(method, "PBC") == 0) {
11457 if (wpa_command(intf, "WPS_PBC") < 0) {
11458 send_resp(dut, conn, SIGMA_ERROR,
11459 "ErrorCode,Failed to enable PBC");
11460 goto fail;
11461 }
11462 } else {
11463 /* TODO: PIN method */
11464 send_resp(dut, conn, SIGMA_ERROR,
11465 "ErrorCode,Unsupported WpsConfigMethod value");
11466 goto fail;
11467 }
11468 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
11469 if (res < 0) {
11470 send_resp(dut, conn, SIGMA_ERROR,
11471 "ErrorCode,WPS connection did not complete");
11472 goto fail;
11473 }
11474 if (strstr(buf, "WPS-TIMEOUT")) {
11475 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
11476 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
11477 send_resp(dut, conn, SIGMA_ERROR,
11478 "ErrorCode,OverlapSession");
11479 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
11480 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
11481 } else {
11482 send_resp(dut, conn, SIGMA_ERROR,
11483 "ErrorCode,WPS operation failed");
11484 }
11485 } else {
11486 /* TODO: Registrar role */
11487 send_resp(dut, conn, SIGMA_ERROR,
11488 "ErrorCode,Unsupported WpsRole value");
11489 }
11490
11491fail:
11492 wpa_ctrl_detach(ctrl);
11493 wpa_ctrl_close(ctrl);
11494 return 0;
11495}
11496
11497
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011498static int req_intf(struct sigma_cmd *cmd)
11499{
11500 return get_param(cmd, "interface") == NULL ? -1 : 0;
11501}
11502
11503
11504void sta_register_cmds(void)
11505{
11506 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
11507 cmd_sta_get_ip_config);
11508 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
11509 cmd_sta_set_ip_config);
11510 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
11511 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
11512 cmd_sta_get_mac_address);
11513 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
11514 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
11515 cmd_sta_verify_ip_connection);
11516 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
11517 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
11518 cmd_sta_set_encryption);
11519 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
11520 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
11521 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
11522 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
11523 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
11524 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
11525 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
11526 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
11527 cmd_sta_set_eapakaprime);
11528 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
11529 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
11530 /* TODO: sta_set_ibss */
11531 /* TODO: sta_set_mode */
11532 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
11533 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
11534 /* TODO: sta_up_load */
11535 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
11536 cmd_sta_preset_testparameters);
11537 /* TODO: sta_set_system */
11538 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
11539 /* TODO: sta_set_rifs_test */
11540 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
11541 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
11542 /* TODO: sta_send_coexist_mgmt */
11543 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
11544 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
11545 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
11546 sigma_dut_reg_cmd("sta_reset_default", req_intf,
11547 cmd_sta_reset_default);
11548 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
11549 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
11550 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
11551 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
11552 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
11553 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
11554 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
11555 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
11556 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
11557 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030011558 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
11559 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011560 sigma_dut_reg_cmd("sta_add_credential", req_intf,
11561 cmd_sta_add_credential);
11562 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020011563 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011564 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
11565 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
11566 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
11567 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
11568 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
11569 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030011570 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011571 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
11572 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
vamsi krishna9b144002017-09-20 13:28:13 +053011573 sigma_dut_reg_cmd("start_wps_registration", req_intf,
11574 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011575}