blob: 437f2ed5b3d8031af275bbf5a04ac2153be82f72 [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
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003013static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3014 struct sigma_conn *conn,
3015 struct sigma_cmd *cmd)
3016{
3017 const char *val;
3018 const char *intf = get_param(cmd, "interface");
3019
3020 if (!intf)
3021 return -1;
3022
3023 val = get_param(cmd, "WscIEFragment");
3024 if (val && strcasecmp(val, "enable") == 0) {
3025 sigma_dut_print(dut, DUT_MSG_DEBUG,
3026 "Enable WSC IE fragmentation");
3027
3028 dut->wsc_fragment = 1;
3029 /* set long attributes to force fragmentation */
3030 if (wpa_command(intf, "SET device_name "
3031 WPS_LONG_DEVICE_NAME) < 0)
3032 return -2;
3033 if (wpa_command(intf, "SET manufacturer "
3034 WPS_LONG_MANUFACTURER) < 0)
3035 return -2;
3036 if (wpa_command(intf, "SET model_name "
3037 WPS_LONG_MODEL_NAME) < 0)
3038 return -2;
3039 if (wpa_command(intf, "SET model_number "
3040 WPS_LONG_MODEL_NUMBER) < 0)
3041 return -2;
3042 if (wpa_command(intf, "SET serial_number "
3043 WPS_LONG_SERIAL_NUMBER) < 0)
3044 return -2;
3045 }
3046
3047 return 1;
3048}
3049
3050
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003051static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3052 struct sigma_conn *conn,
3053 const char *intf,
3054 struct sigma_cmd *cmd)
3055{
3056 const char *val;
3057
3058 val = get_param(cmd, "FileType");
3059 if (val && strcasecmp(val, "PPSMO") == 0)
3060 return download_ppsmo(dut, conn, intf, cmd);
3061 if (val && strcasecmp(val, "CERT") == 0)
3062 return download_cert(dut, conn, intf, cmd);
3063 if (val) {
3064 send_resp(dut, conn, SIGMA_ERROR,
3065 "ErrorCode,Unsupported FileType");
3066 return 0;
3067 }
3068
3069 return 1;
3070}
3071
3072
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303073static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3074 struct sigma_conn *conn,
3075 const char *intf,
3076 struct sigma_cmd *cmd)
3077{
3078 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303079 char buf[1000];
3080 char text[20];
3081 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303082
3083 val = get_param(cmd, "OCESupport");
3084 if (val && strcasecmp(val, "Disable") == 0) {
3085 if (wpa_command(intf, "SET oce 0") < 0) {
3086 send_resp(dut, conn, SIGMA_ERROR,
3087 "ErrorCode,Failed to disable OCE");
3088 return 0;
3089 }
3090 } else if (val && strcasecmp(val, "Enable") == 0) {
3091 if (wpa_command(intf, "SET oce 1") < 0) {
3092 send_resp(dut, conn, SIGMA_ERROR,
3093 "ErrorCode,Failed to enable OCE");
3094 return 0;
3095 }
3096 }
3097
vamsi krishnaa2799492017-12-05 14:28:01 +05303098 val = get_param(cmd, "FILScap");
3099 if (val && (atoi(val) == 1)) {
3100 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3101 send_resp(dut, conn, SIGMA_ERROR,
3102 "ErrorCode,Failed to enable FILS");
3103 return 0;
3104 }
3105 } else if (val && (atoi(val) == 0)) {
3106 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3107 send_resp(dut, conn, SIGMA_ERROR,
3108 "ErrorCode,Failed to disable FILS");
3109 return 0;
3110 }
3111 }
3112
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303113 val = get_param(cmd, "FILSHLP");
3114 if (val && strcasecmp(val, "Enable") == 0) {
3115 if (get_wpa_status(get_station_ifname(), "address", text,
3116 sizeof(text)) < 0)
3117 return -2;
3118 hwaddr_aton(text, addr);
3119 snprintf(buf, sizeof(buf),
3120 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3121 "080045100140000040004011399e00000000ffffffff00440043"
3122 "012cb30001010600fd4f46410000000000000000000000000000"
3123 "000000000000"
3124 "%02x%02x%02x%02x%02x%02x"
3125 "0000000000000000000000000000000000000000000000000000"
3126 "0000000000000000000000000000000000000000000000000000"
3127 "0000000000000000000000000000000000000000000000000000"
3128 "0000000000000000000000000000000000000000000000000000"
3129 "0000000000000000000000000000000000000000000000000000"
3130 "0000000000000000000000000000000000000000000000000000"
3131 "0000000000000000000000000000000000000000000000000000"
3132 "0000000000000000000000000000000000000000638253633501"
3133 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3134 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3135 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3136 if (wpa_command(intf, buf)) {
3137 send_resp(dut, conn, SIGMA_ERROR,
3138 "ErrorCode,Failed to add HLP");
3139 return 0;
3140 }
3141 dut->fils_hlp = 1;
3142 }
3143
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303144 return 1;
3145}
3146
3147
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003148static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3149 const char *val)
3150{
3151 int counter = 0;
3152 char token[50];
3153 char *result;
3154 char buf[100];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303155 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003156
Peng Xub8fc5cc2017-05-10 17:27:28 -07003157 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003158 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303159 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003160 while (result) {
3161 if (strcmp(result, "disable") == 0) {
3162 snprintf(buf, sizeof(buf),
3163 "iwpriv %s noackpolicy %d 1 0",
3164 intf, counter);
3165 } else {
3166 snprintf(buf, sizeof(buf),
3167 "iwpriv %s noackpolicy %d 1 1",
3168 intf, counter);
3169 }
3170 if (system(buf) != 0) {
3171 sigma_dut_print(dut, DUT_MSG_ERROR,
3172 "iwpriv noackpolicy failed");
3173 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303174 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003175 counter++;
3176 }
3177}
3178
3179
3180static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3181 const char *val)
3182{
3183 char buf[100];
3184
3185 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3186 if (system(buf) != 0) {
3187 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3188 }
3189}
3190
3191
3192static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3193 const char *val)
3194{
3195 char buf[100];
3196
3197 if (strcasecmp(val, "off") == 0) {
3198 snprintf(buf, sizeof(buf), "iwpriv %s wmm 0", intf);
3199 if (system(buf) != 0) {
3200 sigma_dut_print(dut, DUT_MSG_ERROR,
3201 "Failed to turn off WMM");
3202 }
3203 }
3204}
3205
3206
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003207static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3208 const char *val)
3209{
3210#ifdef NL80211_SUPPORT
3211 struct nl_msg *msg;
3212 int ret = 0;
3213 struct nlattr *params;
3214 int ifindex;
3215 int wmmenable = 1;
3216
3217 if (val &&
3218 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3219 wmmenable = 0;
3220
3221 ifindex = if_nametoindex(intf);
3222 if (ifindex == 0) {
3223 sigma_dut_print(dut, DUT_MSG_ERROR,
3224 "%s: Index for interface %s failed",
3225 __func__, intf);
3226 return -1;
3227 }
3228
3229 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3230 NL80211_CMD_VENDOR)) ||
3231 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3232 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3233 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3234 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3235 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3236 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
3237 wmmenable)) {
3238 sigma_dut_print(dut, DUT_MSG_ERROR,
3239 "%s: err in adding vendor_cmd and vendor_data",
3240 __func__);
3241 nlmsg_free(msg);
3242 return -1;
3243 }
3244 nla_nest_end(msg, params);
3245
3246 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3247 if (ret) {
3248 sigma_dut_print(dut, DUT_MSG_ERROR,
3249 "%s: err in send_and_recv_msgs, ret=%d",
3250 __func__, ret);
3251 }
3252 return ret;
3253#else /* NL80211_SUPPORT */
3254 sigma_dut_print(dut, DUT_MSG_ERROR,
3255 "WMM cannot be changed without NL80211_SUPPORT defined");
3256 return -1;
3257#endif /* NL80211_SUPPORT */
3258}
3259
3260
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003261static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3262 const char *val)
3263{
3264 char buf[100];
3265 int sgi20;
3266
3267 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3268
3269 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi20);
3270 if (system(buf) != 0)
3271 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv shortgi failed");
3272}
3273
3274
3275static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3276 const char *val)
3277{
3278 char buf[100];
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303279 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003280
3281 /* Disable Tx Beam forming when using a fixed rate */
3282 ath_disable_txbf(dut, intf);
3283
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303284 v = atoi(val);
3285 if (v < 0 || v > 32) {
3286 sigma_dut_print(dut, DUT_MSG_ERROR,
3287 "Invalid Fixed MCS rate: %d", v);
3288 return;
3289 }
3290 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003291
3292 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0x%x",
3293 intf, rate_code);
3294 if (system(buf) != 0) {
3295 sigma_dut_print(dut, DUT_MSG_ERROR,
3296 "iwpriv set11NRates failed");
3297 }
3298
3299 /* Channel width gets messed up, fix this */
3300 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d", intf, dut->chwidth);
3301 if (system(buf) != 0)
3302 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
3303}
3304
3305
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08003306static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3307 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003308{
3309 char buf[60];
3310
3311 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3312 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3313 else
3314 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3315
3316 if (system(buf) != 0)
3317 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3318}
3319
3320
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003321static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3322 int ampdu)
3323{
3324 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003325 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003326
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003327 if (ampdu)
3328 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003329 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3330 if (system(buf) != 0) {
3331 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3332 return -1;
3333 }
3334
3335 return 0;
3336}
3337
3338
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003339static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3340 const char *val)
3341{
3342 char buf[60];
3343
3344 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3345 if (system(buf) != 0) {
3346 sigma_dut_print(dut, DUT_MSG_ERROR,
3347 "iwpriv tx_stbc failed");
3348 }
3349
3350 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3351 if (system(buf) != 0) {
3352 sigma_dut_print(dut, DUT_MSG_ERROR,
3353 "iwpriv rx_stbc failed");
3354 }
3355}
3356
3357
3358static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3359 const char *val)
3360{
3361 char buf[60];
3362
Peng Xucc317ed2017-05-18 16:44:37 -07003363 if (strcmp(val, "160") == 0) {
3364 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3365 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003366 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3367 } else if (strcmp(val, "40") == 0) {
3368 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3369 } else if (strcmp(val, "20") == 0) {
3370 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3371 } else if (strcasecmp(val, "Auto") == 0) {
3372 buf[0] = '\0';
3373 } else {
3374 sigma_dut_print(dut, DUT_MSG_ERROR,
3375 "WIDTH/CTS_WIDTH value not supported");
3376 return -1;
3377 }
3378
3379 if (buf[0] != '\0' && system(buf) != 0) {
3380 sigma_dut_print(dut, DUT_MSG_ERROR,
3381 "Failed to set WIDTH/CTS_WIDTH");
3382 return -1;
3383 }
3384
3385 return 0;
3386}
3387
3388
3389int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3390 const char *intf, const char *val)
3391{
3392 char buf[60];
3393
3394 if (strcasecmp(val, "Auto") == 0) {
3395 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3396 dut->chwidth = 0;
3397 } else if (strcasecmp(val, "20") == 0) {
3398 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3399 dut->chwidth = 0;
3400 } else if (strcasecmp(val, "40") == 0) {
3401 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
3402 dut->chwidth = 1;
3403 } else if (strcasecmp(val, "80") == 0) {
3404 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
3405 dut->chwidth = 2;
3406 } else if (strcasecmp(val, "160") == 0) {
3407 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 3", intf);
3408 dut->chwidth = 3;
3409 } else {
3410 send_resp(dut, conn, SIGMA_ERROR,
3411 "ErrorCode,WIDTH not supported");
3412 return -1;
3413 }
3414
3415 if (system(buf) != 0) {
3416 sigma_dut_print(dut, DUT_MSG_ERROR,
3417 "iwpriv chwidth failed");
3418 }
3419
3420 return 0;
3421}
3422
3423
3424static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3425 const char *val)
3426{
3427 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07003428 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003429
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003430 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003431 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003432 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003433 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003434 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003435 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003436 } else {
3437 sigma_dut_print(dut, DUT_MSG_ERROR,
3438 "SP_STREAM value not supported");
3439 return -1;
3440 }
3441
3442 if (system(buf) != 0) {
3443 sigma_dut_print(dut, DUT_MSG_ERROR,
3444 "Failed to set SP_STREAM");
3445 return -1;
3446 }
3447
Arif Hussainac6c5112018-05-25 17:34:00 -07003448 dut->sta_nss = sta_nss;
3449
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003450 return 0;
3451}
3452
3453
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303454static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3455 const char *val)
3456{
3457 char buf[60];
3458
3459 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3460 if (system(buf) != 0)
3461 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
3462
3463 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3464 if (system(buf) != 0)
3465 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
3466}
3467
3468
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303469static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
3470 struct sigma_conn *conn,
3471 const char *intf, int capa)
3472{
3473 char buf[32];
3474
3475 if (capa > 0 && capa < 4) {
3476 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
3477 if (wpa_command(intf, buf) < 0) {
3478 send_resp(dut, conn, SIGMA_ERROR,
3479 "ErrorCode, Failed to set cellular data capability");
3480 return 0;
3481 }
3482 return 1;
3483 }
3484
3485 sigma_dut_print(dut, DUT_MSG_ERROR,
3486 "Invalid Cellular data capability: %d", capa);
3487 send_resp(dut, conn, SIGMA_INVALID,
3488 "ErrorCode,Invalid cellular data capability");
3489 return 0;
3490}
3491
3492
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303493static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
3494 const char *intf, const char *val)
3495{
3496 if (strcasecmp(val, "Disable") == 0) {
3497 if (wpa_command(intf, "SET roaming 0") < 0) {
3498 send_resp(dut, conn, SIGMA_ERROR,
3499 "ErrorCode,Failed to disable roaming");
3500 return 0;
3501 }
3502 return 1;
3503 }
3504
3505 if (strcasecmp(val, "Enable") == 0) {
3506 if (wpa_command(intf, "SET roaming 1") < 0) {
3507 send_resp(dut, conn, SIGMA_ERROR,
3508 "ErrorCode,Failed to enable roaming");
3509 return 0;
3510 }
3511 return 1;
3512 }
3513
3514 sigma_dut_print(dut, DUT_MSG_ERROR,
3515 "Invalid value provided for roaming: %s", val);
3516 send_resp(dut, conn, SIGMA_INVALID,
3517 "ErrorCode,Unknown value provided for Roaming");
3518 return 0;
3519}
3520
3521
Ashwini Patila75de5a2017-04-13 16:35:05 +05303522static int mbo_set_assoc_disallow(struct sigma_dut *dut,
3523 struct sigma_conn *conn,
3524 const char *intf, const char *val)
3525{
3526 if (strcasecmp(val, "Disable") == 0) {
3527 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
3528 send_resp(dut, conn, SIGMA_ERROR,
3529 "ErrorCode,Failed to disable Assoc_disallow");
3530 return 0;
3531 }
3532 return 1;
3533 }
3534
3535 if (strcasecmp(val, "Enable") == 0) {
3536 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
3537 send_resp(dut, conn, SIGMA_ERROR,
3538 "ErrorCode,Failed to enable Assoc_disallow");
3539 return 0;
3540 }
3541 return 1;
3542 }
3543
3544 sigma_dut_print(dut, DUT_MSG_ERROR,
3545 "Invalid value provided for Assoc_disallow: %s", val);
3546 send_resp(dut, conn, SIGMA_INVALID,
3547 "ErrorCode,Unknown value provided for Assoc_disallow");
3548 return 0;
3549}
3550
3551
Ashwini Patilc63161e2017-04-13 16:30:23 +05303552static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
3553 const char *intf, const char *val)
3554{
3555 if (strcasecmp(val, "Reject") == 0) {
3556 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
3557 send_resp(dut, conn, SIGMA_ERROR,
3558 "ErrorCode,Failed to Reject BTM Request");
3559 return 0;
3560 }
3561 return 1;
3562 }
3563
3564 if (strcasecmp(val, "Accept") == 0) {
3565 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
3566 send_resp(dut, conn, SIGMA_ERROR,
3567 "ErrorCode,Failed to Accept BTM Request");
3568 return 0;
3569 }
3570 return 1;
3571 }
3572
3573 sigma_dut_print(dut, DUT_MSG_ERROR,
3574 "Invalid value provided for BSS_Transition: %s", val);
3575 send_resp(dut, conn, SIGMA_INVALID,
3576 "ErrorCode,Unknown value provided for BSS_Transition");
3577 return 0;
3578}
3579
3580
Ashwini Patil00402582017-04-13 12:29:39 +05303581static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
3582 struct sigma_conn *conn,
3583 const char *intf,
3584 struct sigma_cmd *cmd)
3585{
3586 const char *ch, *pref, *op_class, *reason;
3587 char buf[120];
3588 int len, ret;
3589
3590 pref = get_param(cmd, "Ch_Pref");
3591 if (!pref)
3592 return 1;
3593
3594 if (strcasecmp(pref, "clear") == 0) {
3595 free(dut->non_pref_ch_list);
3596 dut->non_pref_ch_list = NULL;
3597 } else {
3598 op_class = get_param(cmd, "Ch_Op_Class");
3599 if (!op_class) {
3600 send_resp(dut, conn, SIGMA_INVALID,
3601 "ErrorCode,Ch_Op_Class not provided");
3602 return 0;
3603 }
3604
3605 ch = get_param(cmd, "Ch_Pref_Num");
3606 if (!ch) {
3607 send_resp(dut, conn, SIGMA_INVALID,
3608 "ErrorCode,Ch_Pref_Num not provided");
3609 return 0;
3610 }
3611
3612 reason = get_param(cmd, "Ch_Reason_Code");
3613 if (!reason) {
3614 send_resp(dut, conn, SIGMA_INVALID,
3615 "ErrorCode,Ch_Reason_Code not provided");
3616 return 0;
3617 }
3618
3619 if (!dut->non_pref_ch_list) {
3620 dut->non_pref_ch_list =
3621 calloc(1, NON_PREF_CH_LIST_SIZE);
3622 if (!dut->non_pref_ch_list) {
3623 send_resp(dut, conn, SIGMA_ERROR,
3624 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
3625 return 0;
3626 }
3627 }
3628 len = strlen(dut->non_pref_ch_list);
3629 ret = snprintf(dut->non_pref_ch_list + len,
3630 NON_PREF_CH_LIST_SIZE - len,
3631 " %s:%s:%s:%s", op_class, ch, pref, reason);
3632 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
3633 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
3634 dut->non_pref_ch_list);
3635 } else {
3636 sigma_dut_print(dut, DUT_MSG_ERROR,
3637 "snprintf failed for non_pref_list, ret = %d",
3638 ret);
3639 send_resp(dut, conn, SIGMA_ERROR,
3640 "ErrorCode,snprintf failed");
3641 free(dut->non_pref_ch_list);
3642 dut->non_pref_ch_list = NULL;
3643 return 0;
3644 }
3645 }
3646
3647 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
3648 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
3649 if (ret < 0 || ret >= (int) sizeof(buf)) {
3650 sigma_dut_print(dut, DUT_MSG_DEBUG,
3651 "snprintf failed for set non_pref_chan, ret: %d",
3652 ret);
3653 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
3654 return 0;
3655 }
3656
3657 if (wpa_command(intf, buf) < 0) {
3658 send_resp(dut, conn, SIGMA_ERROR,
3659 "ErrorCode,Failed to set non-preferred channel list");
3660 return 0;
3661 }
3662
3663 return 1;
3664}
3665
3666
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003667#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003668
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08003669static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
3670 uint8_t cfg)
3671{
3672 struct nl_msg *msg;
3673 int ret = 0;
3674 struct nlattr *params;
3675 int ifindex;
3676
3677 ifindex = if_nametoindex(intf);
3678 if (ifindex == 0) {
3679 sigma_dut_print(dut, DUT_MSG_ERROR,
3680 "%s: Index for interface %s failed",
3681 __func__, intf);
3682 return -1;
3683 }
3684
3685 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3686 NL80211_CMD_VENDOR)) ||
3687 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3688 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3689 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3690 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3691 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3692 nla_put_u8(msg,
3693 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
3694 cfg)) {
3695 sigma_dut_print(dut, DUT_MSG_ERROR,
3696 "%s: err in adding vendor_cmd and vendor_data",
3697 __func__);
3698 nlmsg_free(msg);
3699 return -1;
3700 }
3701 nla_nest_end(msg, params);
3702
3703 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3704 if (ret) {
3705 sigma_dut_print(dut, DUT_MSG_ERROR,
3706 "%s: err in send_and_recv_msgs, ret=%d",
3707 __func__, ret);
3708 }
3709 return ret;
3710}
3711
3712
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003713static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
3714 enum he_fragmentation_val frag)
3715{
3716 struct nl_msg *msg;
3717 int ret = 0;
3718 struct nlattr *params;
3719 int ifindex;
3720
3721 ifindex = if_nametoindex(intf);
3722 if (ifindex == 0) {
3723 sigma_dut_print(dut, DUT_MSG_ERROR,
3724 "%s: Index for interface %s failed",
3725 __func__, intf);
3726 return -1;
3727 }
3728
3729 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3730 NL80211_CMD_VENDOR)) ||
3731 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3732 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3733 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3734 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3735 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3736 nla_put_u8(msg,
3737 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
3738 frag)) {
3739 sigma_dut_print(dut, DUT_MSG_ERROR,
3740 "%s: err in adding vendor_cmd and vendor_data",
3741 __func__);
3742 nlmsg_free(msg);
3743 return -1;
3744 }
3745 nla_nest_end(msg, params);
3746
3747 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3748 if (ret) {
3749 sigma_dut_print(dut, DUT_MSG_ERROR,
3750 "%s: err in send_and_recv_msgs, ret=%d",
3751 __func__, ret);
3752 }
3753 return ret;
3754}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003755
3756
Subhani Shaik8e7a3052018-04-24 14:03:00 -07003757static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
3758 enum qca_wlan_he_ltf_cfg ltf)
3759{
3760 struct nl_msg *msg;
3761 int ret = 0;
3762 struct nlattr *params;
3763 int ifindex;
3764
3765 ifindex = if_nametoindex(intf);
3766 if (ifindex == 0) {
3767 sigma_dut_print(dut, DUT_MSG_ERROR,
3768 "%s: Index for interface %s failed",
3769 __func__, intf);
3770 return -1;
3771 }
3772
3773 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3774 NL80211_CMD_VENDOR)) ||
3775 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3776 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3777 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3778 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3779 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3780 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
3781 ltf)) {
3782 sigma_dut_print(dut, DUT_MSG_ERROR,
3783 "%s: err in adding vendor_cmd and vendor_data",
3784 __func__);
3785 nlmsg_free(msg);
3786 return -1;
3787 }
3788 nla_nest_end(msg, params);
3789
3790 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3791 if (ret) {
3792 sigma_dut_print(dut, DUT_MSG_ERROR,
3793 "%s: err in send_and_recv_msgs, ret=%d",
3794 __func__, ret);
3795 }
3796 return ret;
3797}
3798
3799
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003800static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
3801 int noack, enum qca_wlan_ac_type ac)
3802{
3803 struct nl_msg *msg;
3804 int ret = 0;
3805 struct nlattr *params;
3806 int ifindex;
3807
3808 ifindex = if_nametoindex(intf);
3809 if (ifindex == 0) {
3810 sigma_dut_print(dut, DUT_MSG_ERROR,
3811 "%s: Index for interface %s failed",
3812 __func__, intf);
3813 return -1;
3814 }
3815
3816 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3817 NL80211_CMD_VENDOR)) ||
3818 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3819 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3820 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3821 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3822 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3823 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
3824 noack) ||
3825 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
3826 ac)) {
3827 sigma_dut_print(dut, DUT_MSG_ERROR,
3828 "%s: err in adding vendor_cmd and vendor_data",
3829 __func__);
3830 nlmsg_free(msg);
3831 return -1;
3832 }
3833 nla_nest_end(msg, params);
3834
3835 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3836 if (ret) {
3837 sigma_dut_print(dut, DUT_MSG_ERROR,
3838 "%s: err in send_and_recv_msgs, ret=%d",
3839 __func__, ret);
3840 }
3841 return ret;
3842}
3843
3844
3845static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
3846 const char *val)
3847{
3848 int noack, ret;
3849 char token[100];
3850 char *result;
3851 char *saveptr;
3852 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
3853
3854 strlcpy(token, val, sizeof(token));
3855 token[sizeof(token) - 1] = '\0';
3856 result = strtok_r(token, ":", &saveptr);
3857 while (result) {
3858 noack = strcasecmp(result, "Disable") != 0;
3859 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
3860 if (ret) {
3861 sigma_dut_print(dut, DUT_MSG_ERROR,
3862 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
3863 ac, ret);
3864 }
3865 result = strtok_r(NULL, ":", &saveptr);
3866 ac++;
3867 }
3868}
3869
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003870#endif /* NL80211_SUPPORT */
3871
3872
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003873static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
3874 struct sigma_conn *conn,
3875 struct sigma_cmd *cmd)
3876{
3877 const char *intf = get_param(cmd, "Interface");
3878 const char *val;
3879
3880 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03003881 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
3882 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003883 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
3884 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003885
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07003886 if (val && strcasecmp(val, "LOC") == 0)
3887 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02003888 if (val && strcasecmp(val, "60GHZ") == 0) {
3889 val = get_param(cmd, "WPS");
3890 if (val && strcasecmp(val, "disable") == 0) {
3891 dut->wps_disable = 1;
3892 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
3893 } else {
3894 /* wps_disable can have other value from the previous
3895 * test, so make sure it has the correct value.
3896 */
3897 dut->wps_disable = 0;
3898 }
3899
3900 val = get_param(cmd, "P2P");
3901 if (val && strcasecmp(val, "disable") == 0)
3902 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
3903 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07003904
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003905 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
3906 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
3907
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003908#ifdef ANDROID_NAN
3909 if (val && strcasecmp(val, "NAN") == 0)
3910 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
3911#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07003912#ifdef MIRACAST
3913 if (val && (strcasecmp(val, "WFD") == 0 ||
3914 strcasecmp(val, "DisplayR2") == 0))
3915 return miracast_preset_testparameters(dut, conn, cmd);
3916#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003917
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303918 if (val && strcasecmp(val, "MBO") == 0) {
3919 val = get_param(cmd, "Cellular_Data_Cap");
3920 if (val &&
3921 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
3922 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05303923
3924 val = get_param(cmd, "Ch_Pref");
3925 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
3926 return 0;
3927
Ashwini Patilc63161e2017-04-13 16:30:23 +05303928 val = get_param(cmd, "BSS_Transition");
3929 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
3930 return 0;
3931
Ashwini Patila75de5a2017-04-13 16:35:05 +05303932 val = get_param(cmd, "Assoc_Disallow");
3933 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
3934 return 0;
3935
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303936 val = get_param(cmd, "Roaming");
3937 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
3938 return 0;
3939
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303940 return 1;
3941 }
3942
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303943 if (val && strcasecmp(val, "OCE") == 0)
3944 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
3945
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003946#if 0
3947 val = get_param(cmd, "Supplicant");
3948 if (val && strcasecmp(val, "Default") != 0) {
3949 send_resp(dut, conn, SIGMA_ERROR,
3950 "ErrorCode,Only default(Vendor) supplicant "
3951 "supported");
3952 return 0;
3953 }
3954#endif
3955
3956 val = get_param(cmd, "RTS");
3957 if (val) {
3958 switch (get_driver_type()) {
3959 case DRIVER_ATHEROS:
3960 ath_sta_set_rts(dut, intf, val);
3961 break;
3962 default:
3963#if 0
3964 send_resp(dut, conn, SIGMA_ERROR,
3965 "ErrorCode,Setting RTS not supported");
3966 return 0;
3967#else
3968 sigma_dut_print(dut, DUT_MSG_DEBUG,
3969 "Setting RTS not supported");
3970 break;
3971#endif
3972 }
3973 }
3974
3975#if 0
3976 val = get_param(cmd, "FRGMNT");
3977 if (val) {
3978 /* TODO */
3979 send_resp(dut, conn, SIGMA_ERROR,
3980 "ErrorCode,Setting FRGMNT not supported");
3981 return 0;
3982 }
3983#endif
3984
3985#if 0
3986 val = get_param(cmd, "Preamble");
3987 if (val) {
3988 /* TODO: Long/Short */
3989 send_resp(dut, conn, SIGMA_ERROR,
3990 "ErrorCode,Setting Preamble not supported");
3991 return 0;
3992 }
3993#endif
3994
3995 val = get_param(cmd, "Mode");
3996 if (val) {
3997 if (strcmp(val, "11b") == 0 ||
3998 strcmp(val, "11g") == 0 ||
3999 strcmp(val, "11a") == 0 ||
4000 strcmp(val, "11n") == 0 ||
4001 strcmp(val, "11ng") == 0 ||
4002 strcmp(val, "11nl") == 0 ||
4003 strcmp(val, "11nl(nabg)") == 0 ||
4004 strcmp(val, "AC") == 0 ||
4005 strcmp(val, "11AC") == 0 ||
4006 strcmp(val, "11ac") == 0 ||
4007 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004008 strcmp(val, "11an") == 0 ||
4009 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004010 /* STA supports all modes by default */
4011 } else {
4012 send_resp(dut, conn, SIGMA_ERROR,
4013 "ErrorCode,Setting Mode not supported");
4014 return 0;
4015 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004016
4017 /* Change the mode only in case of testbed for HE program
4018 * and for 11a and 11g modes only. */
4019 if (dut->program == PROGRAM_HE &&
4020 dut->device_type == STA_testbed) {
4021 int phymode;
4022 char buf[60];
4023
4024 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004025 phymode = 1; /* IEEE80211_MODE_11A */
4026 } else if (strcmp(val, "11g") == 0) {
4027 phymode = 3; /* IEEE80211_MODE_11G */
4028 } else if (strcmp(val, "11b") == 0) {
4029 phymode = 2; /* IEEE80211_MODE_11B */
4030 } else if (strcmp(val, "11n") == 0 ||
4031 strcmp(val, "11nl") == 0 ||
4032 strcmp(val, "11nl(nabg)") == 0) {
4033 phymode = 22; /* IEEE80211_MODE_11AGN */
4034 } else if (strcmp(val, "11ng") == 0) {
4035 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4036 } else if (strcmp(val, "AC") == 0 ||
4037 strcasecmp(val, "11AC") == 0) {
4038 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4039 } else if (strcmp(val, "11na") == 0 ||
4040 strcasecmp(val, "11an") == 0) {
4041 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4042 } else if (strcmp(val, "11ax") == 0) {
4043 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004044 } else {
4045 sigma_dut_print(dut, DUT_MSG_DEBUG,
4046 "Ignoring mode change for mode: %s",
4047 val);
4048 phymode = -1;
4049 }
4050 if (phymode != -1) {
4051 snprintf(buf, sizeof(buf),
4052 "iwpriv %s setphymode %d",
4053 intf, phymode);
4054 if (system(buf) != 0) {
4055 sigma_dut_print(dut, DUT_MSG_ERROR,
4056 "iwpriv setting of phymode failed");
4057 }
4058 }
4059 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004060 }
4061
4062 val = get_param(cmd, "wmm");
4063 if (val) {
4064 switch (get_driver_type()) {
4065 case DRIVER_ATHEROS:
4066 ath_sta_set_wmm(dut, intf, val);
4067 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004068 case DRIVER_WCN:
4069 wcn_sta_set_wmm(dut, intf, val);
4070 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004071 default:
4072 sigma_dut_print(dut, DUT_MSG_DEBUG,
4073 "Setting wmm not supported");
4074 break;
4075 }
4076 }
4077
4078 val = get_param(cmd, "Powersave");
4079 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004080 char buf[60];
4081
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004082 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004083 if (get_driver_type() == DRIVER_WCN) {
4084 snprintf(buf, sizeof(buf),
4085 "iwpriv %s setPower 2", intf);
4086 if (system(buf) != 0) {
4087 sigma_dut_print(dut, DUT_MSG_ERROR,
4088 "iwpriv setPower 2 failed");
4089 return 0;
4090 }
4091 }
4092
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004093 if (wpa_command(get_station_ifname(),
4094 "P2P_SET ps 0") < 0)
4095 return -2;
4096 /* Make sure test modes are disabled */
4097 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4098 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4099 } else if (strcmp(val, "1") == 0 ||
4100 strcasecmp(val, "PSPoll") == 0 ||
4101 strcasecmp(val, "on") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004102 if (get_driver_type() == DRIVER_WCN) {
4103 snprintf(buf, sizeof(buf),
4104 "iwpriv %s setPower 1", intf);
4105 if (system(buf) != 0) {
4106 sigma_dut_print(dut, DUT_MSG_ERROR,
4107 "iwpriv setPower 1 failed");
4108 return 0;
4109 }
4110 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004111 /* Disable default power save mode */
4112 wpa_command(get_station_ifname(), "P2P_SET ps 0");
4113 /* Enable PS-Poll test mode */
4114 if (wpa_command(get_station_ifname(),
4115 "P2P_SET ps 97") < 0 ||
4116 wpa_command(get_station_ifname(),
4117 "P2P_SET ps 99") < 0)
4118 return -2;
4119 } else if (strcmp(val, "2") == 0 ||
4120 strcasecmp(val, "Fast") == 0) {
4121 /* TODO */
4122 send_resp(dut, conn, SIGMA_ERROR,
4123 "ErrorCode,Powersave=Fast not supported");
4124 return 0;
4125 } else if (strcmp(val, "3") == 0 ||
4126 strcasecmp(val, "PSNonPoll") == 0) {
4127 /* Make sure test modes are disabled */
4128 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4129 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4130
4131 /* Enable default power save mode */
4132 if (wpa_command(get_station_ifname(),
4133 "P2P_SET ps 1") < 0)
4134 return -2;
4135 } else
4136 return -1;
4137 }
4138
4139 val = get_param(cmd, "NoAck");
4140 if (val) {
4141 switch (get_driver_type()) {
4142 case DRIVER_ATHEROS:
4143 ath_sta_set_noack(dut, intf, val);
4144 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004145#ifdef NL80211_SUPPORT
4146 case DRIVER_WCN:
4147 wcn_sta_set_noack(dut, intf, val);
4148 break;
4149#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004150 default:
4151 send_resp(dut, conn, SIGMA_ERROR,
4152 "ErrorCode,Setting NoAck not supported");
4153 return 0;
4154 }
4155 }
4156
4157 val = get_param(cmd, "IgnoreChswitchProhibit");
4158 if (val) {
4159 /* TODO: Enabled/disabled */
4160 if (strcasecmp(val, "Enabled") == 0) {
4161 send_resp(dut, conn, SIGMA_ERROR,
4162 "ErrorCode,Enabling IgnoreChswitchProhibit "
4163 "not supported");
4164 return 0;
4165 }
4166 }
4167
4168 val = get_param(cmd, "TDLS");
4169 if (val) {
4170 if (strcasecmp(val, "Disabled") == 0) {
4171 if (wpa_command(intf, "SET tdls_disabled 1")) {
4172 send_resp(dut, conn, SIGMA_ERROR,
4173 "ErrorCode,Failed to disable TDLS");
4174 return 0;
4175 }
4176 } else if (strcasecmp(val, "Enabled") == 0) {
4177 if (wpa_command(intf, "SET tdls_disabled 0")) {
4178 send_resp(dut, conn, SIGMA_ERROR,
4179 "ErrorCode,Failed to enable TDLS");
4180 return 0;
4181 }
4182 } else {
4183 send_resp(dut, conn, SIGMA_ERROR,
4184 "ErrorCode,Unsupported TDLS value");
4185 return 0;
4186 }
4187 }
4188
4189 val = get_param(cmd, "TDLSmode");
4190 if (val) {
4191 if (strcasecmp(val, "Default") == 0) {
4192 wpa_command(intf, "SET tdls_testing 0");
4193 } else if (strcasecmp(val, "APProhibit") == 0) {
4194 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4195 send_resp(dut, conn, SIGMA_ERROR,
4196 "ErrorCode,Failed to enable ignore "
4197 "APProhibit TDLS mode");
4198 return 0;
4199 }
4200 } else if (strcasecmp(val, "HiLoMac") == 0) {
4201 /* STA should respond with TDLS setup req for a TDLS
4202 * setup req */
4203 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4204 send_resp(dut, conn, SIGMA_ERROR,
4205 "ErrorCode,Failed to enable HiLoMac "
4206 "TDLS mode");
4207 return 0;
4208 }
4209 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4210 /*
4211 * Since all security modes are enabled by default when
4212 * Sigma control is used, there is no need to do
4213 * anything here.
4214 */
4215 } else if (strcasecmp(val, "ExistLink") == 0) {
4216 /*
4217 * Since we allow new TDLS Setup Request even if there
4218 * is an existing link, nothing needs to be done for
4219 * this.
4220 */
4221 } else {
4222 /* TODO:
4223 * ExistLink: STA should send TDLS setup req even if
4224 * direct link already exists
4225 */
4226 send_resp(dut, conn, SIGMA_ERROR,
4227 "ErrorCode,Unsupported TDLSmode value");
4228 return 0;
4229 }
4230 }
4231
4232 val = get_param(cmd, "FakePubKey");
4233 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4234 send_resp(dut, conn, SIGMA_ERROR,
4235 "ErrorCode,Failed to enable FakePubKey");
4236 return 0;
4237 }
4238
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004239#ifdef NL80211_SUPPORT
4240 val = get_param(cmd, "FrgmntSupport");
4241 if (val) {
4242 if (strcasecmp(val, "Enable") == 0) {
4243 if (sta_set_he_fragmentation(dut, intf,
4244 HE_FRAG_LEVEL1)) {
4245 send_resp(dut, conn, SIGMA_ERROR,
4246 "ErrorCode,Failed to enable HE Fragmentation");
4247 return 0;
4248 }
4249 } else if (strcasecmp(val, "Disable") == 0) {
4250 if (sta_set_he_fragmentation(dut, intf,
4251 HE_FRAG_DISABLE)) {
4252 send_resp(dut, conn, SIGMA_ERROR,
4253 "ErrorCode,Failed to disable HE Fragmentation");
4254 return 0;
4255 }
4256 }
4257 }
4258#endif /* NL80211_SUPPORT */
4259
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004260 return 1;
4261}
4262
4263
4264static const char * ath_get_radio_name(const char *radio_name)
4265{
4266 if (radio_name == NULL)
4267 return "wifi0";
4268 if (strcmp(radio_name, "wifi1") == 0)
4269 return "wifi1";
4270 if (strcmp(radio_name, "wifi2") == 0)
4271 return "wifi2";
4272 return "wifi0";
4273}
4274
4275
4276static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
4277 const char *val)
4278{
4279 char buf[60];
4280 unsigned int vht_mcsmap = 0;
4281 int txchainmask = 0;
4282 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4283
4284 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4285 if (dut->testbed_flag_txsp == 1) {
4286 vht_mcsmap = 0xfffc;
4287 dut->testbed_flag_txsp = 0;
4288 } else {
4289 vht_mcsmap = 0xfffe;
4290 }
4291 txchainmask = 1;
4292 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4293 if (dut->testbed_flag_txsp == 1) {
4294 vht_mcsmap = 0xfff0;
4295 dut->testbed_flag_txsp = 0;
4296 } else {
4297 vht_mcsmap = 0xfffa;
4298 }
4299 txchainmask = 3;
4300 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4301 if (dut->testbed_flag_txsp == 1) {
4302 vht_mcsmap = 0xffc0;
4303 dut->testbed_flag_txsp = 0;
4304 } else {
4305 vht_mcsmap = 0xffea;
4306 }
4307 txchainmask = 7;
4308 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4309 if (dut->testbed_flag_txsp == 1) {
4310 vht_mcsmap = 0xff00;
4311 dut->testbed_flag_txsp = 0;
4312 } else {
4313 vht_mcsmap = 0xffaa;
4314 }
4315 txchainmask = 15;
4316 } else {
4317 if (dut->testbed_flag_txsp == 1) {
4318 vht_mcsmap = 0xffc0;
4319 dut->testbed_flag_txsp = 0;
4320 } else {
4321 vht_mcsmap = 0xffea;
4322 }
4323 }
4324
4325 if (txchainmask) {
4326 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
4327 basedev, txchainmask);
4328 if (system(buf) != 0) {
4329 sigma_dut_print(dut, DUT_MSG_ERROR,
4330 "iwpriv txchainmask failed");
4331 }
4332 }
4333
4334 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4335 intf, vht_mcsmap);
4336 if (system(buf) != 0) {
4337 sigma_dut_print(dut, DUT_MSG_ERROR,
4338 "iwpriv %s vht_mcsmap 0x%04x failed",
4339 intf, vht_mcsmap);
4340 }
4341}
4342
4343
4344static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
4345 const char *val)
4346{
4347 char buf[60];
4348 unsigned int vht_mcsmap = 0;
4349 int rxchainmask = 0;
4350 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4351
4352 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4353 if (dut->testbed_flag_rxsp == 1) {
4354 vht_mcsmap = 0xfffc;
4355 dut->testbed_flag_rxsp = 0;
4356 } else {
4357 vht_mcsmap = 0xfffe;
4358 }
4359 rxchainmask = 1;
4360 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4361 if (dut->testbed_flag_rxsp == 1) {
4362 vht_mcsmap = 0xfff0;
4363 dut->testbed_flag_rxsp = 0;
4364 } else {
4365 vht_mcsmap = 0xfffa;
4366 }
4367 rxchainmask = 3;
4368 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4369 if (dut->testbed_flag_rxsp == 1) {
4370 vht_mcsmap = 0xffc0;
4371 dut->testbed_flag_rxsp = 0;
4372 } else {
4373 vht_mcsmap = 0xffea;
4374 }
4375 rxchainmask = 7;
4376 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4377 if (dut->testbed_flag_rxsp == 1) {
4378 vht_mcsmap = 0xff00;
4379 dut->testbed_flag_rxsp = 0;
4380 } else {
4381 vht_mcsmap = 0xffaa;
4382 }
4383 rxchainmask = 15;
4384 } else {
4385 if (dut->testbed_flag_rxsp == 1) {
4386 vht_mcsmap = 0xffc0;
4387 dut->testbed_flag_rxsp = 0;
4388 } else {
4389 vht_mcsmap = 0xffea;
4390 }
4391 }
4392
4393 if (rxchainmask) {
4394 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
4395 basedev, rxchainmask);
4396 if (system(buf) != 0) {
4397 sigma_dut_print(dut, DUT_MSG_ERROR,
4398 "iwpriv rxchainmask failed");
4399 }
4400 }
4401
4402 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4403 intf, vht_mcsmap);
4404 if (system(buf) != 0) {
4405 sigma_dut_print(dut, DUT_MSG_ERROR,
4406 "iwpriv %s vht_mcsmap 0x%04x",
4407 intf, vht_mcsmap);
4408 }
4409}
4410
4411
4412void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
4413{
4414 if (strcasecmp(val, "enable") == 0) {
4415 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
4416 != 0) {
4417 sigma_dut_print(dut, DUT_MSG_ERROR,
4418 "Disable BB_VHTSIGB_CRC_CALC failed");
4419 }
4420
4421 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
4422 != 0) {
4423 sigma_dut_print(dut, DUT_MSG_ERROR,
4424 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4425 }
4426 } else {
4427 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4428 != 0) {
4429 sigma_dut_print(dut, DUT_MSG_ERROR,
4430 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4431 }
4432
4433 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4434 != 0) {
4435 sigma_dut_print(dut, DUT_MSG_ERROR,
4436 "Enable BB_VHTSIGB_CRC_CALC failed");
4437 }
4438 }
4439}
4440
4441
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004442static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
4443 const char *val)
4444{
4445 char buf[60];
4446
4447 if (strcmp(val, "20") == 0) {
4448 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
4449 dut->chwidth = 0;
4450 } else if (strcmp(val, "40") == 0) {
4451 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
4452 dut->chwidth = 1;
4453 } else if (strcmp(val, "80") == 0) {
4454 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
4455 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05304456 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004457 buf[0] = '\0';
4458 } else {
4459 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
4460 val);
4461 return -1;
4462 }
4463
4464 if (buf[0] != '\0' && system(buf) != 0) {
4465 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
4466 return -1;
4467 }
4468
4469 return 0;
4470}
4471
4472
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004473static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
4474 const char *intf, int addbareject)
4475{
4476#ifdef NL80211_SUPPORT
4477 struct nl_msg *msg;
4478 int ret = 0;
4479 struct nlattr *params;
4480 int ifindex;
4481
4482 ifindex = if_nametoindex(intf);
4483 if (ifindex == 0) {
4484 sigma_dut_print(dut, DUT_MSG_ERROR,
4485 "%s: Index for interface %s failed",
4486 __func__, intf);
4487 return -1;
4488 }
4489
4490 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4491 NL80211_CMD_VENDOR)) ||
4492 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4493 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4494 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4495 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4496 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4497 nla_put_u8(msg,
4498 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
4499 !addbareject)) {
4500 sigma_dut_print(dut, DUT_MSG_ERROR,
4501 "%s: err in adding vendor_cmd and vendor_data",
4502 __func__);
4503 nlmsg_free(msg);
4504 return -1;
4505 }
4506 nla_nest_end(msg, params);
4507
4508 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4509 if (ret) {
4510 sigma_dut_print(dut, DUT_MSG_ERROR,
4511 "%s: err in send_and_recv_msgs, ret=%d",
4512 __func__, ret);
4513 }
4514 return ret;
4515#else /* NL80211_SUPPORT */
4516 sigma_dut_print(dut, DUT_MSG_ERROR,
4517 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
4518 return -1;
4519#endif /* NL80211_SUPPORT */
4520}
4521
4522
4523static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
4524 int addbareject)
4525{
4526 int ret;
4527
4528 switch (get_driver_type()) {
4529 case DRIVER_WCN:
4530 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
4531 if (ret) {
4532 sigma_dut_print(dut, DUT_MSG_ERROR,
4533 "nlvendor_sta_set_addba_reject failed, ret:%d",
4534 ret);
4535 return ret;
4536 }
4537 break;
4538 default:
4539 sigma_dut_print(dut, DUT_MSG_ERROR,
4540 "errorCode,Unsupported ADDBA_REJECT with the current driver");
4541 ret = -1;
4542 break;
4543 }
4544
4545 return ret;
4546}
4547
4548
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004549static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
4550 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004551{
4552#ifdef NL80211_SUPPORT
4553 struct nl_msg *msg;
4554 int ret = 0;
4555 struct nlattr *params;
4556 int ifindex;
4557
4558 ifindex = if_nametoindex(intf);
4559 if (ifindex == 0) {
4560 sigma_dut_print(dut, DUT_MSG_ERROR,
4561 "%s: Index for interface %s failed",
4562 __func__, intf);
4563 return -1;
4564 }
4565
4566 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4567 NL80211_CMD_VENDOR)) ||
4568 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4569 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4570 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4571 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4572 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4573 nla_put_u8(msg,
4574 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004575 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004576 sigma_dut_print(dut, DUT_MSG_ERROR,
4577 "%s: err in adding vendor_cmd and vendor_data",
4578 __func__);
4579 nlmsg_free(msg);
4580 return -1;
4581 }
4582 nla_nest_end(msg, params);
4583
4584 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4585 if (ret) {
4586 sigma_dut_print(dut, DUT_MSG_ERROR,
4587 "%s: err in send_and_recv_msgs, ret=%d",
4588 __func__, ret);
4589 }
4590 return ret;
4591#else /* NL80211_SUPPORT */
4592 sigma_dut_print(dut, DUT_MSG_ERROR,
4593 "Disable addba not possible without NL80211_SUPPORT defined");
4594 return -1;
4595#endif /* NL80211_SUPPORT */
4596}
4597
4598
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004599static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
4600 struct sigma_conn *conn,
4601 struct sigma_cmd *cmd)
4602{
4603 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004604 int ampdu = -1, addbareject = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004605 char buf[30];
4606
4607 val = get_param(cmd, "40_INTOLERANT");
4608 if (val) {
4609 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4610 /* TODO: iwpriv ht40intol through wpa_supplicant */
4611 send_resp(dut, conn, SIGMA_ERROR,
4612 "ErrorCode,40_INTOLERANT not supported");
4613 return 0;
4614 }
4615 }
4616
4617 val = get_param(cmd, "ADDBA_REJECT");
4618 if (val) {
4619 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4620 /* reject any ADDBA with status "decline" */
4621 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004622 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004623 } else {
4624 /* accept ADDBA */
4625 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004626 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004627 }
4628 }
4629
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004630 if (addbareject >= 0 &&
4631 sta_set_addba_reject(dut, intf, addbareject) < 0) {
4632 send_resp(dut, conn, SIGMA_ERROR,
4633 "ErrorCode,set addba_reject failed");
4634 return 0;
4635 }
4636
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004637 val = get_param(cmd, "AMPDU");
4638 if (val) {
4639 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4640 /* enable AMPDU Aggregation */
4641 if (ampdu == 0) {
4642 send_resp(dut, conn, SIGMA_ERROR,
4643 "ErrorCode,Mismatch in "
4644 "addba_reject/ampdu - "
4645 "not supported");
4646 return 0;
4647 }
4648 ampdu = 1;
4649 } else {
4650 /* disable AMPDU Aggregation */
4651 if (ampdu == 1) {
4652 send_resp(dut, conn, SIGMA_ERROR,
4653 "ErrorCode,Mismatch in "
4654 "addba_reject/ampdu - "
4655 "not supported");
4656 return 0;
4657 }
4658 ampdu = 0;
4659 }
4660 }
4661
4662 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004663 int ret;
4664
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004665 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
4666 ampdu ? "Enabling" : "Disabling");
4667 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004668 if (wpa_command(intf, buf) < 0 &&
4669 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004670 send_resp(dut, conn, SIGMA_ERROR,
4671 "ErrorCode,set aggr failed");
4672 return 0;
4673 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004674
4675 if (ampdu == 0) {
4676 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004677 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004678 if (ret) {
4679 sigma_dut_print(dut, DUT_MSG_ERROR,
4680 "Failed to disable addba, ret:%d",
4681 ret);
4682 }
4683 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004684 }
4685
4686 val = get_param(cmd, "AMSDU");
4687 if (val) {
4688 switch (get_driver_type()) {
4689 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004690 case DRIVER_WCN:
4691 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004692 break;
4693 default:
4694 if (strcmp(val, "1") == 0 ||
4695 strcasecmp(val, "Enable") == 0) {
4696 /* Enable AMSDU Aggregation */
4697 send_resp(dut, conn, SIGMA_ERROR,
4698 "ErrorCode,AMSDU aggregation not supported");
4699 return 0;
4700 }
4701 break;
4702 }
4703 }
4704
4705 val = get_param(cmd, "STBC_RX");
4706 if (val) {
4707 switch (get_driver_type()) {
4708 case DRIVER_ATHEROS:
4709 ath_sta_set_stbc(dut, intf, val);
4710 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304711 case DRIVER_WCN:
4712 wcn_sta_set_stbc(dut, intf, val);
4713 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004714 default:
4715 send_resp(dut, conn, SIGMA_ERROR,
4716 "ErrorCode,STBC_RX not supported");
4717 return 0;
4718 }
4719 }
4720
4721 val = get_param(cmd, "WIDTH");
4722 if (val) {
4723 switch (get_driver_type()) {
4724 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004725 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004726 send_resp(dut, conn, SIGMA_ERROR,
4727 "ErrorCode,Failed to set WIDTH");
4728 return 0;
4729 }
4730 break;
4731 case DRIVER_ATHEROS:
4732 if (ath_set_width(dut, conn, intf, val) < 0)
4733 return 0;
4734 break;
4735 default:
4736 sigma_dut_print(dut, DUT_MSG_ERROR,
4737 "Setting WIDTH not supported");
4738 break;
4739 }
4740 }
4741
4742 val = get_param(cmd, "SMPS");
4743 if (val) {
4744 /* TODO: Dynamic/0, Static/1, No Limit/2 */
4745 send_resp(dut, conn, SIGMA_ERROR,
4746 "ErrorCode,SMPS not supported");
4747 return 0;
4748 }
4749
4750 val = get_param(cmd, "TXSP_STREAM");
4751 if (val) {
4752 switch (get_driver_type()) {
4753 case DRIVER_WCN:
4754 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4755 send_resp(dut, conn, SIGMA_ERROR,
4756 "ErrorCode,Failed to set TXSP_STREAM");
4757 return 0;
4758 }
4759 break;
4760 case DRIVER_ATHEROS:
4761 ath_sta_set_txsp_stream(dut, intf, val);
4762 break;
4763 default:
4764 sigma_dut_print(dut, DUT_MSG_ERROR,
4765 "Setting TXSP_STREAM not supported");
4766 break;
4767 }
4768 }
4769
4770 val = get_param(cmd, "RXSP_STREAM");
4771 if (val) {
4772 switch (get_driver_type()) {
4773 case DRIVER_WCN:
4774 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4775 send_resp(dut, conn, SIGMA_ERROR,
4776 "ErrorCode,Failed to set RXSP_STREAM");
4777 return 0;
4778 }
4779 break;
4780 case DRIVER_ATHEROS:
4781 ath_sta_set_rxsp_stream(dut, intf, val);
4782 break;
4783 default:
4784 sigma_dut_print(dut, DUT_MSG_ERROR,
4785 "Setting RXSP_STREAM not supported");
4786 break;
4787 }
4788 }
4789
4790 val = get_param(cmd, "DYN_BW_SGNL");
4791 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004792 switch (get_driver_type()) {
4793 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08004794 if (strcasecmp(val, "enable") == 0) {
4795 snprintf(buf, sizeof(buf),
4796 "iwpriv %s cwmenable 1", intf);
4797 if (system(buf) != 0) {
4798 sigma_dut_print(dut, DUT_MSG_ERROR,
4799 "iwpriv cwmenable 1 failed");
4800 return 0;
4801 }
4802 } else if (strcasecmp(val, "disable") == 0) {
4803 snprintf(buf, sizeof(buf),
4804 "iwpriv %s cwmenable 0", intf);
4805 if (system(buf) != 0) {
4806 sigma_dut_print(dut, DUT_MSG_ERROR,
4807 "iwpriv cwmenable 0 failed");
4808 return 0;
4809 }
4810 } else {
4811 sigma_dut_print(dut, DUT_MSG_ERROR,
4812 "Unsupported DYN_BW_SGL");
4813 }
4814
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004815 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4816 if (system(buf) != 0) {
4817 sigma_dut_print(dut, DUT_MSG_ERROR,
4818 "Failed to set cts_cbw in DYN_BW_SGNL");
4819 return 0;
4820 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004821 break;
4822 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004823 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004824 ath_config_dyn_bw_sig(dut, intf, val);
4825 break;
4826 default:
4827 sigma_dut_print(dut, DUT_MSG_ERROR,
4828 "Failed to set DYN_BW_SGNL");
4829 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004830 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004831 }
4832
4833 val = get_param(cmd, "RTS_FORCE");
4834 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004835 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004836 if (strcasecmp(val, "Enable") == 0) {
4837 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004838 if (system(buf) != 0) {
4839 sigma_dut_print(dut, DUT_MSG_ERROR,
4840 "Failed to set RTS_FORCE 64");
4841 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08004842 snprintf(buf, sizeof(buf),
4843 "wifitool %s beeliner_fw_test 100 1", intf);
4844 if (system(buf) != 0) {
4845 sigma_dut_print(dut, DUT_MSG_ERROR,
4846 "wifitool beeliner_fw_test 100 1 failed");
4847 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004848 } else if (strcasecmp(val, "Disable") == 0) {
4849 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
4850 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004851 if (system(buf) != 0) {
4852 sigma_dut_print(dut, DUT_MSG_ERROR,
4853 "Failed to set RTS_FORCE 2347");
4854 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004855 } else {
4856 send_resp(dut, conn, SIGMA_ERROR,
4857 "ErrorCode,RTS_FORCE value not supported");
4858 return 0;
4859 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004860 }
4861
4862 val = get_param(cmd, "CTS_WIDTH");
4863 if (val) {
4864 switch (get_driver_type()) {
4865 case DRIVER_WCN:
4866 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
4867 send_resp(dut, conn, SIGMA_ERROR,
4868 "ErrorCode,Failed to set CTS_WIDTH");
4869 return 0;
4870 }
4871 break;
4872 case DRIVER_ATHEROS:
4873 ath_set_cts_width(dut, intf, val);
4874 break;
4875 default:
4876 sigma_dut_print(dut, DUT_MSG_ERROR,
4877 "Setting CTS_WIDTH not supported");
4878 break;
4879 }
4880 }
4881
4882 val = get_param(cmd, "BW_SGNL");
4883 if (val) {
4884 if (strcasecmp(val, "Enable") == 0) {
4885 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1",
4886 intf);
4887 } else if (strcasecmp(val, "Disable") == 0) {
4888 /* TODO: Disable */
4889 buf[0] = '\0';
4890 } else {
4891 send_resp(dut, conn, SIGMA_ERROR,
4892 "ErrorCode,BW_SGNL value not supported");
4893 return 0;
4894 }
4895
4896 if (buf[0] != '\0' && system(buf) != 0) {
4897 sigma_dut_print(dut, DUT_MSG_ERROR,
4898 "Failed to set BW_SGNL");
4899 }
4900 }
4901
4902 val = get_param(cmd, "Band");
4903 if (val) {
4904 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
4905 /* STA supports all bands by default */
4906 } else {
4907 send_resp(dut, conn, SIGMA_ERROR,
4908 "ErrorCode,Unsupported Band");
4909 return 0;
4910 }
4911 }
4912
4913 val = get_param(cmd, "zero_crc");
4914 if (val) {
4915 switch (get_driver_type()) {
4916 case DRIVER_ATHEROS:
4917 ath_set_zero_crc(dut, val);
4918 break;
4919 default:
4920 break;
4921 }
4922 }
4923
4924 return 1;
4925}
4926
4927
4928static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
4929 struct sigma_cmd *cmd)
4930{
4931 const char *val;
4932 char buf[100];
4933
4934 val = get_param(cmd, "MSDUSize");
4935 if (val) {
4936 int mtu;
4937
4938 dut->amsdu_size = atoi(val);
4939 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
4940 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
4941 sigma_dut_print(dut, DUT_MSG_ERROR,
4942 "MSDUSize %d is above max %d or below min %d",
4943 dut->amsdu_size,
4944 IEEE80211_MAX_DATA_LEN_DMG,
4945 IEEE80211_SNAP_LEN_DMG);
4946 dut->amsdu_size = 0;
4947 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4948 }
4949
4950 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
4951 sigma_dut_print(dut, DUT_MSG_DEBUG,
4952 "Setting amsdu_size to %d", mtu);
4953 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
4954 get_station_ifname(), mtu);
4955
4956 if (system(buf) != 0) {
4957 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
4958 buf);
4959 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4960 }
4961 }
4962
4963 val = get_param(cmd, "BAckRcvBuf");
4964 if (val) {
4965 dut->back_rcv_buf = atoi(val);
4966 if (dut->back_rcv_buf == 0) {
4967 sigma_dut_print(dut, DUT_MSG_ERROR,
4968 "Failed to convert %s or value is 0",
4969 val);
4970 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4971 }
4972
4973 sigma_dut_print(dut, DUT_MSG_DEBUG,
4974 "Setting BAckRcvBuf to %s", val);
4975 }
4976
4977 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
4978}
4979
4980
4981static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
4982 struct sigma_cmd *cmd)
4983{
4984 int net_id;
4985 char *ifname;
4986 const char *val;
4987 char buf[100];
4988
4989 dut->mode = SIGMA_MODE_STATION;
4990 ifname = get_main_ifname();
4991 if (wpa_command(ifname, "PING") != 0) {
4992 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
4993 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4994 }
4995
4996 wpa_command(ifname, "FLUSH");
4997 net_id = add_network_common(dut, conn, ifname, cmd);
4998 if (net_id < 0) {
4999 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5000 return net_id;
5001 }
5002
5003 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5004 if (set_network(ifname, net_id, "mode", "2") < 0) {
5005 sigma_dut_print(dut, DUT_MSG_ERROR,
5006 "Failed to set supplicant network mode");
5007 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5008 }
5009
5010 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005011 "Supplicant set network with mode 2. network_id %d",
5012 net_id);
5013
5014 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5015 sigma_dut_print(dut, DUT_MSG_INFO,
5016 "Failed to set supplicant to WPS ENABLE");
5017 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5018 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005019
5020 val = get_param(cmd, "Security");
5021 if (val && strcasecmp(val, "OPEN") == 0) {
5022 dut->ap_key_mgmt = AP_OPEN;
5023 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5024 sigma_dut_print(dut, DUT_MSG_ERROR,
5025 "Failed to set supplicant to %s security",
5026 val);
5027 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5028 }
5029 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5030 dut->ap_key_mgmt = AP_WPA2_PSK;
5031 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5032 sigma_dut_print(dut, DUT_MSG_ERROR,
5033 "Failed to set supplicant to %s security",
5034 val);
5035 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5036 }
5037
5038 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5039 sigma_dut_print(dut, DUT_MSG_ERROR,
5040 "Failed to set supplicant to proto RSN");
5041 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5042 }
5043 } else if (val) {
5044 sigma_dut_print(dut, DUT_MSG_ERROR,
5045 "Requested Security %s is not supported on 60GHz",
5046 val);
5047 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
5048 }
5049
5050 val = get_param(cmd, "Encrypt");
5051 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5052 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5053 sigma_dut_print(dut, DUT_MSG_ERROR,
5054 "Failed to set supplicant to pairwise GCMP");
5055 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5056 }
5057 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5058 sigma_dut_print(dut, DUT_MSG_ERROR,
5059 "Failed to set supplicant to group GCMP");
5060 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5061 }
5062 } else if (val) {
5063 sigma_dut_print(dut, DUT_MSG_ERROR,
5064 "Requested Encrypt %s is not supported on 60 GHz",
5065 val);
5066 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
5067 }
5068
5069 val = get_param(cmd, "PSK");
5070 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5071 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5072 val);
5073 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5074 }
5075
5076 /* Convert 60G channel to freq */
5077 switch (dut->ap_channel) {
5078 case 1:
5079 val = "58320";
5080 break;
5081 case 2:
5082 val = "60480";
5083 break;
5084 case 3:
5085 val = "62640";
5086 break;
5087 default:
5088 sigma_dut_print(dut, DUT_MSG_ERROR,
5089 "Failed to configure channel %d. Not supported",
5090 dut->ap_channel);
5091 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5092 }
5093
5094 if (set_network(ifname, net_id, "frequency", val) < 0) {
5095 sigma_dut_print(dut, DUT_MSG_ERROR,
5096 "Failed to set supplicant network frequency");
5097 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5098 }
5099
5100 sigma_dut_print(dut, DUT_MSG_DEBUG,
5101 "Supplicant set network with frequency");
5102
5103 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5104 if (wpa_command(ifname, buf) < 0) {
5105 sigma_dut_print(dut, DUT_MSG_INFO,
5106 "Failed to select network id %d on %s",
5107 net_id, ifname);
5108 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5109 }
5110
5111 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5112
5113 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
5114}
5115
5116
Lior David67543f52017-01-03 19:04:22 +02005117static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
5118{
5119 char buf[128], fname[128];
5120 FILE *f;
5121
5122 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
5123 sigma_dut_print(dut, DUT_MSG_ERROR,
5124 "failed to get wil6210 debugfs dir");
5125 return -1;
5126 }
5127
5128 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5129 f = fopen(fname, "w");
5130 if (!f) {
5131 sigma_dut_print(dut, DUT_MSG_ERROR,
5132 "failed to open: %s", fname);
5133 return -1;
5134 }
5135
5136 fprintf(f, "%d\n", abft_len);
5137 fclose(f);
5138
5139 return 0;
5140}
5141
5142
5143static int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5144 int abft_len)
5145{
5146 switch (get_driver_type()) {
5147 case DRIVER_WIL6210:
5148 return wil6210_set_abft_len(dut, abft_len);
5149 default:
5150 sigma_dut_print(dut, DUT_MSG_ERROR,
5151 "set abft_len not supported");
5152 return -1;
5153 }
5154}
5155
5156
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005157static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5158 struct sigma_cmd *cmd)
5159{
5160 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005161 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005162
5163 if (dut->dev_role != DEVROLE_PCP) {
5164 send_resp(dut, conn, SIGMA_INVALID,
5165 "ErrorCode,Invalid DevRole");
5166 return 0;
5167 }
5168
5169 val = get_param(cmd, "SSID");
5170 if (val) {
5171 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5172 send_resp(dut, conn, SIGMA_INVALID,
5173 "ErrorCode,Invalid SSID");
5174 return -1;
5175 }
5176
Peng Xub8fc5cc2017-05-10 17:27:28 -07005177 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005178 }
5179
5180 val = get_param(cmd, "CHANNEL");
5181 if (val) {
5182 const char *pos;
5183
5184 dut->ap_channel = atoi(val);
5185 pos = strchr(val, ';');
5186 if (pos) {
5187 pos++;
5188 dut->ap_channel_1 = atoi(pos);
5189 }
5190 }
5191
5192 switch (dut->ap_channel) {
5193 case 1:
5194 case 2:
5195 case 3:
5196 break;
5197 default:
5198 sigma_dut_print(dut, DUT_MSG_ERROR,
5199 "Channel %d is not supported", dut->ap_channel);
5200 send_resp(dut, conn, SIGMA_ERROR,
5201 "Requested channel is not supported");
5202 return -1;
5203 }
5204
5205 val = get_param(cmd, "BCNINT");
5206 if (val)
5207 dut->ap_bcnint = atoi(val);
5208
5209
5210 val = get_param(cmd, "ExtSchIE");
5211 if (val) {
5212 send_resp(dut, conn, SIGMA_ERROR,
5213 "ErrorCode,ExtSchIE is not supported yet");
5214 return -1;
5215 }
5216
5217 val = get_param(cmd, "AllocType");
5218 if (val) {
5219 send_resp(dut, conn, SIGMA_ERROR,
5220 "ErrorCode,AllocType is not supported yet");
5221 return -1;
5222 }
5223
5224 val = get_param(cmd, "PercentBI");
5225 if (val) {
5226 send_resp(dut, conn, SIGMA_ERROR,
5227 "ErrorCode,PercentBI is not supported yet");
5228 return -1;
5229 }
5230
5231 val = get_param(cmd, "CBAPOnly");
5232 if (val) {
5233 send_resp(dut, conn, SIGMA_ERROR,
5234 "ErrorCode,CBAPOnly is not supported yet");
5235 return -1;
5236 }
5237
5238 val = get_param(cmd, "AMPDU");
5239 if (val) {
5240 if (strcasecmp(val, "Enable") == 0)
5241 dut->ap_ampdu = 1;
5242 else if (strcasecmp(val, "Disable") == 0)
5243 dut->ap_ampdu = 2;
5244 else {
5245 send_resp(dut, conn, SIGMA_ERROR,
5246 "ErrorCode,AMPDU value is not Enable nor Disabled");
5247 return -1;
5248 }
5249 }
5250
5251 val = get_param(cmd, "AMSDU");
5252 if (val) {
5253 if (strcasecmp(val, "Enable") == 0)
5254 dut->ap_amsdu = 1;
5255 else if (strcasecmp(val, "Disable") == 0)
5256 dut->ap_amsdu = 2;
5257 }
5258
5259 val = get_param(cmd, "NumMSDU");
5260 if (val) {
5261 send_resp(dut, conn, SIGMA_ERROR,
5262 "ErrorCode, NumMSDU is not supported yet");
5263 return -1;
5264 }
5265
5266 val = get_param(cmd, "ABFTLRang");
5267 if (val) {
5268 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02005269 "ABFTLRang parameter %s", val);
5270 if (strcmp(val, "Gt1") == 0)
5271 abft_len = 2; /* 2 slots in this case */
5272 }
5273
5274 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
5275 send_resp(dut, conn, SIGMA_ERROR,
5276 "ErrorCode, Can't set ABFT length");
5277 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005278 }
5279
5280 if (sta_pcp_start(dut, conn, cmd) < 0) {
5281 send_resp(dut, conn, SIGMA_ERROR,
5282 "ErrorCode, Can't start PCP role");
5283 return -1;
5284 }
5285
5286 return sta_set_60g_common(dut, conn, cmd);
5287}
5288
5289
5290static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
5291 struct sigma_cmd *cmd)
5292{
5293 const char *val = get_param(cmd, "DiscoveryMode");
5294
5295 if (dut->dev_role != DEVROLE_STA) {
5296 send_resp(dut, conn, SIGMA_INVALID,
5297 "ErrorCode,Invalid DevRole");
5298 return 0;
5299 }
5300
5301 if (val) {
5302 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
5303 /* Ignore Discovery mode till Driver expose API. */
5304#if 0
5305 if (strcasecmp(val, "1") == 0) {
5306 send_resp(dut, conn, SIGMA_INVALID,
5307 "ErrorCode,DiscoveryMode 1 not supported");
5308 return 0;
5309 }
5310
5311 if (strcasecmp(val, "0") == 0) {
5312 /* OK */
5313 } else {
5314 send_resp(dut, conn, SIGMA_INVALID,
5315 "ErrorCode,DiscoveryMode not supported");
5316 return 0;
5317 }
5318#endif
5319 }
5320
5321 if (start_sta_mode(dut) != 0)
5322 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5323 return sta_set_60g_common(dut, conn, cmd);
5324}
5325
5326
5327static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
5328 struct sigma_cmd *cmd)
5329{
5330 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02005331 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05305332
Jouni Malinened77e672018-01-10 16:45:13 +02005333 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08005334 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02005335 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05305336 wpa_command(intf, "DISCONNECT");
5337 return 1;
5338 }
5339
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005340 disconnect_station(dut);
5341 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
5342 * due to cached results. */
5343 wpa_command(intf, "SET ignore_old_scan_res 1");
5344 wpa_command(intf, "BSS_FLUSH");
5345 return 1;
5346}
5347
5348
5349static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
5350 struct sigma_cmd *cmd)
5351{
5352 const char *intf = get_param(cmd, "Interface");
5353 const char *bssid = get_param(cmd, "bssid");
5354 const char *val = get_param(cmd, "CHANNEL");
5355 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305356 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05305357 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005358 int res;
5359 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05305360 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05305361 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005362
5363 if (bssid == NULL) {
5364 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
5365 "argument");
5366 return 0;
5367 }
5368
5369 if (val)
5370 chan = atoi(val);
5371
5372 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
5373 /* The current network may be from sta_associate or
5374 * sta_hs2_associate
5375 */
5376 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
5377 0 ||
5378 set_network(intf, 0, "bssid", bssid) < 0)
5379 return -2;
5380 }
5381
5382 ctrl = open_wpa_mon(intf);
5383 if (ctrl == NULL) {
5384 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
5385 "wpa_supplicant monitor connection");
5386 return -1;
5387 }
5388
Sunil Duttd30ce092018-01-11 23:56:29 +05305389 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
5390 sizeof(result)) < 0 ||
5391 strncmp(result, "COMPLETED", 9) != 0) {
5392 sigma_dut_print(dut, DUT_MSG_DEBUG,
5393 "sta_reassoc: Not connected");
5394 fastreassoc = 0;
5395 }
5396
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305397 if (dut->rsne_override) {
5398#ifdef NL80211_SUPPORT
5399 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
5400 sta_config_rsnie(dut, 1);
5401 dut->config_rsnie = 1;
5402 }
5403#endif /* NL80211_SUPPORT */
5404 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
5405 dut->rsne_override);
5406 if (wpa_command(intf, buf) < 0) {
5407 send_resp(dut, conn, SIGMA_ERROR,
5408 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
5409 return 0;
5410 }
5411 }
5412
Sunil Duttd30ce092018-01-11 23:56:29 +05305413 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005414#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305415 if (chan) {
5416 unsigned int freq;
5417
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02005418 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305419 if (!freq) {
5420 sigma_dut_print(dut, DUT_MSG_ERROR,
5421 "Invalid channel number provided: %d",
5422 chan);
5423 send_resp(dut, conn, SIGMA_INVALID,
5424 "ErrorCode,Invalid channel number");
5425 goto close_mon_conn;
5426 }
5427 res = snprintf(buf, sizeof(buf),
5428 "SCAN TYPE=ONLY freq=%d", freq);
5429 } else {
5430 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
5431 }
5432 if (res < 0 || res >= (int) sizeof(buf)) {
5433 send_resp(dut, conn, SIGMA_ERROR,
5434 "ErrorCode,snprintf failed");
5435 goto close_mon_conn;
5436 }
5437 if (wpa_command(intf, buf) < 0) {
5438 sigma_dut_print(dut, DUT_MSG_INFO,
5439 "Failed to start scan");
5440 send_resp(dut, conn, SIGMA_ERROR,
5441 "ErrorCode,scan failed");
5442 goto close_mon_conn;
5443 }
5444
5445 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
5446 buf, sizeof(buf));
5447 if (res < 0) {
5448 sigma_dut_print(dut, DUT_MSG_INFO,
5449 "Scan did not complete");
5450 send_resp(dut, conn, SIGMA_ERROR,
5451 "ErrorCode,scan did not complete");
5452 goto close_mon_conn;
5453 }
5454
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005455 if (set_network(intf, dut->infra_network_id, "bssid", "any")
5456 < 0) {
5457 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
5458 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305459 status = -2;
5460 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005461 }
5462 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
5463 bssid, chan);
5464 if (res > 0 && res < (int) sizeof(buf))
5465 res = wpa_command(intf, buf);
5466
5467 if (res < 0 || res >= (int) sizeof(buf)) {
5468 send_resp(dut, conn, SIGMA_ERROR,
5469 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305470 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005471 }
5472#else /* ANDROID */
5473 sigma_dut_print(dut, DUT_MSG_DEBUG,
5474 "Reassoc using iwpriv - skip chan=%d info",
5475 chan);
5476 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
5477 if (system(buf) != 0) {
5478 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05305479 status = -2;
5480 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005481 }
5482#endif /* ANDROID */
5483 sigma_dut_print(dut, DUT_MSG_INFO,
5484 "sta_reassoc: Run %s successful", buf);
5485 } else if (wpa_command(intf, "REASSOCIATE")) {
5486 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
5487 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05305488 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005489 }
5490
5491 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
5492 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05305493 if (res < 0) {
5494 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
5495 status = -1;
5496 goto close_mon_conn;
5497 }
5498 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005499
Ashwini Patil467efef2017-05-25 12:18:27 +05305500close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005501 wpa_ctrl_detach(ctrl);
5502 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05305503 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005504}
5505
5506
5507static void hs2_clear_credentials(const char *intf)
5508{
5509 wpa_command(intf, "REMOVE_CRED all");
5510}
5511
5512
Lior Davidcc88b562017-01-03 18:52:09 +02005513#ifdef __linux__
5514static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
5515 unsigned int *aid)
5516{
Lior David0fe101e2017-03-09 16:09:50 +02005517 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02005518
Lior David0fe101e2017-03-09 16:09:50 +02005519 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02005520}
5521#endif /* __linux__ */
5522
5523
5524static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
5525 unsigned int *aid)
5526{
5527 switch (get_driver_type()) {
5528#ifdef __linux__
5529 case DRIVER_WIL6210:
5530 return wil6210_get_aid(dut, bssid, aid);
5531#endif /* __linux__ */
5532 default:
5533 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
5534 return -1;
5535 }
5536}
5537
5538
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005539static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
5540 struct sigma_cmd *cmd)
5541{
5542 char buf[MAX_CMD_LEN];
5543 char bss_list[MAX_CMD_LEN];
5544 const char *parameter = get_param(cmd, "Parameter");
5545
5546 if (parameter == NULL)
5547 return -1;
5548
Lior Davidcc88b562017-01-03 18:52:09 +02005549 if (strcasecmp(parameter, "AID") == 0) {
5550 unsigned int aid = 0;
5551 char bssid[20];
5552
5553 if (get_wpa_status(get_station_ifname(), "bssid",
5554 bssid, sizeof(bssid)) < 0) {
5555 sigma_dut_print(dut, DUT_MSG_ERROR,
5556 "could not get bssid");
5557 return -2;
5558 }
5559
5560 if (sta_get_aid_60g(dut, bssid, &aid))
5561 return -2;
5562
5563 snprintf(buf, sizeof(buf), "aid,%d", aid);
5564 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
5565 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5566 return 0;
5567 }
5568
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005569 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
5570 char *bss_line;
5571 char *bss_id = NULL;
5572 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305573 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005574
5575 if (ifname == NULL) {
5576 sigma_dut_print(dut, DUT_MSG_INFO,
5577 "For get DiscoveredDevList need Interface name.");
5578 return -1;
5579 }
5580
5581 /*
5582 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
5583 * of BSSIDs in "bssid=<BSSID>\n"
5584 */
5585 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
5586 bss_list,
5587 sizeof(bss_list)) < 0) {
5588 sigma_dut_print(dut, DUT_MSG_ERROR,
5589 "Failed to get bss list");
5590 return -1;
5591 }
5592
5593 sigma_dut_print(dut, DUT_MSG_DEBUG,
5594 "bss list for ifname:%s is:%s",
5595 ifname, bss_list);
5596
5597 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305598 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005599 while (bss_line) {
5600 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
5601 bss_id) {
5602 int len;
5603
5604 len = snprintf(buf + strlen(buf),
5605 sizeof(buf) - strlen(buf),
5606 ",%s", bss_id);
5607 free(bss_id);
5608 bss_id = NULL;
5609 if (len < 0) {
5610 sigma_dut_print(dut,
5611 DUT_MSG_ERROR,
5612 "Failed to read BSSID");
5613 send_resp(dut, conn, SIGMA_ERROR,
5614 "ErrorCode,Failed to read BSS ID");
5615 return 0;
5616 }
5617
5618 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
5619 sigma_dut_print(dut,
5620 DUT_MSG_ERROR,
5621 "Response buf too small for list");
5622 send_resp(dut, conn,
5623 SIGMA_ERROR,
5624 "ErrorCode,Response buf too small for list");
5625 return 0;
5626 }
5627 }
5628
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305629 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005630 }
5631
5632 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
5633 buf);
5634 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5635 return 0;
5636 }
5637
5638 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5639 return 0;
5640}
5641
5642
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07005643static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
5644 struct sigma_cmd *cmd)
5645{
5646 char buf[MAX_CMD_LEN];
5647 const char *parameter = get_param(cmd, "Parameter");
5648
5649 if (!parameter)
5650 return -1;
5651
5652 if (strcasecmp(parameter, "RSSI") == 0) {
5653 char rssi[10];
5654
5655 if (get_wpa_signal_poll(dut, get_station_ifname(), "RSSI",
5656 rssi, sizeof(rssi)) < 0) {
5657 sigma_dut_print(dut, DUT_MSG_ERROR,
5658 "Could not get RSSI");
5659 return -2;
5660 }
5661
5662 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
5663 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
5664 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5665 return 0;
5666 }
5667
5668 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5669 return 0;
5670}
5671
5672
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005673static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
5674 struct sigma_cmd *cmd)
5675{
5676 const char *program = get_param(cmd, "Program");
5677
5678 if (program == NULL)
5679 return -1;
5680
5681 if (strcasecmp(program, "P2PNFC") == 0)
5682 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
5683
5684 if (strcasecmp(program, "60ghz") == 0)
5685 return sta_get_parameter_60g(dut, conn, cmd);
5686
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07005687 if (strcasecmp(program, "he") == 0)
5688 return sta_get_parameter_he(dut, conn, cmd);
5689
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005690#ifdef ANDROID_NAN
5691 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07005692 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005693#endif /* ANDROID_NAN */
5694
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005695#ifdef MIRACAST
5696 if (strcasecmp(program, "WFD") == 0 ||
5697 strcasecmp(program, "DisplayR2") == 0)
5698 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
5699#endif /* MIRACAST */
5700
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005701 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5702 return 0;
5703}
5704
5705
5706static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
5707 const char *type)
5708{
5709 char buf[100];
5710
5711 if (dut->program == PROGRAM_VHT) {
5712 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5713 if (system(buf) != 0) {
5714 sigma_dut_print(dut, DUT_MSG_ERROR,
5715 "iwpriv %s chwidth failed", intf);
5716 }
5717
5718 snprintf(buf, sizeof(buf), "iwpriv %s mode 11ACVHT80", intf);
5719 if (system(buf) != 0) {
5720 sigma_dut_print(dut, DUT_MSG_ERROR,
5721 "iwpriv %s mode 11ACVHT80 failed",
5722 intf);
5723 }
5724
5725 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs -1", intf);
5726 if (system(buf) != 0) {
5727 sigma_dut_print(dut, DUT_MSG_ERROR,
5728 "iwpriv %s vhtmcs -1 failed", intf);
5729 }
5730 }
5731
5732 if (dut->program == PROGRAM_HT) {
5733 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5734 if (system(buf) != 0) {
5735 sigma_dut_print(dut, DUT_MSG_ERROR,
5736 "iwpriv %s chwidth failed", intf);
5737 }
5738
5739 snprintf(buf, sizeof(buf), "iwpriv %s mode 11naht40", intf);
5740 if (system(buf) != 0) {
5741 sigma_dut_print(dut, DUT_MSG_ERROR,
5742 "iwpriv %s mode 11naht40 failed",
5743 intf);
5744 }
5745
5746 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0", intf);
5747 if (system(buf) != 0) {
5748 sigma_dut_print(dut, DUT_MSG_ERROR,
5749 "iwpriv set11NRates failed");
5750 }
5751 }
5752
5753 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
5754 snprintf(buf, sizeof(buf), "iwpriv %s powersave 0", intf);
5755 if (system(buf) != 0) {
5756 sigma_dut_print(dut, DUT_MSG_ERROR,
5757 "disabling powersave failed");
5758 }
5759
5760 /* Reset CTS width */
5761 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
5762 intf);
5763 if (system(buf) != 0) {
5764 sigma_dut_print(dut, DUT_MSG_ERROR,
5765 "wifitool %s beeliner_fw_test 54 0 failed",
5766 intf);
5767 }
5768
5769 /* Enable Dynamic Bandwidth signalling by default */
5770 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", intf);
5771 if (system(buf) != 0) {
5772 sigma_dut_print(dut, DUT_MSG_ERROR,
5773 "iwpriv %s cwmenable 1 failed", intf);
5774 }
5775
5776 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
5777 if (system(buf) != 0) {
5778 sigma_dut_print(dut, DUT_MSG_ERROR,
5779 "iwpriv rts failed");
5780 }
5781 }
5782
5783 if (type && strcasecmp(type, "Testbed") == 0) {
5784 dut->testbed_flag_txsp = 1;
5785 dut->testbed_flag_rxsp = 1;
5786 /* STA has to set spatial stream to 2 per Appendix H */
5787 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0xfff0", intf);
5788 if (system(buf) != 0) {
5789 sigma_dut_print(dut, DUT_MSG_ERROR,
5790 "iwpriv vht_mcsmap failed");
5791 }
5792
5793 /* Disable LDPC per Appendix H */
5794 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", intf);
5795 if (system(buf) != 0) {
5796 sigma_dut_print(dut, DUT_MSG_ERROR,
5797 "iwpriv %s ldpc 0 failed", intf);
5798 }
5799
5800 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5801 if (system(buf) != 0) {
5802 sigma_dut_print(dut, DUT_MSG_ERROR,
5803 "iwpriv amsdu failed");
5804 }
5805
5806 /* TODO: Disable STBC 2x1 transmit and receive */
5807 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", intf);
5808 if (system(buf) != 0) {
5809 sigma_dut_print(dut, DUT_MSG_ERROR,
5810 "Disable tx_stbc 0 failed");
5811 }
5812
5813 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc 0", intf);
5814 if (system(buf) != 0) {
5815 sigma_dut_print(dut, DUT_MSG_ERROR,
5816 "Disable rx_stbc 0 failed");
5817 }
5818
5819 /* STA has to disable Short GI per Appendix H */
5820 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 0", intf);
5821 if (system(buf) != 0) {
5822 sigma_dut_print(dut, DUT_MSG_ERROR,
5823 "iwpriv %s shortgi 0 failed", intf);
5824 }
5825 }
5826
5827 if (type && strcasecmp(type, "DUT") == 0) {
5828 snprintf(buf, sizeof(buf), "iwpriv %s nss 3", intf);
5829 if (system(buf) != 0) {
5830 sigma_dut_print(dut, DUT_MSG_ERROR,
5831 "iwpriv %s nss 3 failed", intf);
5832 }
Arif Hussainac6c5112018-05-25 17:34:00 -07005833 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005834
5835 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 1", intf);
5836 if (system(buf) != 0) {
5837 sigma_dut_print(dut, DUT_MSG_ERROR,
5838 "iwpriv %s shortgi 1 failed", intf);
5839 }
5840 }
5841}
5842
5843
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08005844#ifdef NL80211_SUPPORT
5845static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
5846 enum he_mcs_config mcs)
5847{
5848 struct nl_msg *msg;
5849 int ret = 0;
5850 struct nlattr *params;
5851 int ifindex;
5852
5853 ifindex = if_nametoindex(intf);
5854 if (ifindex == 0) {
5855 sigma_dut_print(dut, DUT_MSG_ERROR,
5856 "%s: Index for interface %s failed",
5857 __func__, intf);
5858 return -1;
5859 }
5860
5861 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5862 NL80211_CMD_VENDOR)) ||
5863 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5864 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5865 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5866 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5867 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5868 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
5869 mcs)) {
5870 sigma_dut_print(dut, DUT_MSG_ERROR,
5871 "%s: err in adding vendor_cmd and vendor_data",
5872 __func__);
5873 nlmsg_free(msg);
5874 return -1;
5875 }
5876 nla_nest_end(msg, params);
5877
5878 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5879 if (ret) {
5880 sigma_dut_print(dut, DUT_MSG_ERROR,
5881 "%s: err in send_and_recv_msgs, ret=%d",
5882 __func__, ret);
5883 }
5884 return ret;
5885}
5886#endif /* NL80211_SUPPORT */
5887
5888
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07005889static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
5890 const char *intf, int enable)
5891{
5892#ifdef NL80211_SUPPORT
5893 struct nl_msg *msg;
5894 int ret = 0;
5895 struct nlattr *params;
5896 int ifindex;
5897
5898 ifindex = if_nametoindex(intf);
5899 if (ifindex == 0) {
5900 sigma_dut_print(dut, DUT_MSG_ERROR,
5901 "%s: Index for interface %s failed",
5902 __func__, intf);
5903 return -1;
5904 }
5905
5906 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5907 NL80211_CMD_VENDOR)) ||
5908 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5909 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5910 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5911 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5912 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5913 nla_put_u8(msg,
5914 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
5915 enable)) {
5916 sigma_dut_print(dut, DUT_MSG_ERROR,
5917 "%s: err in adding vendor_cmd and vendor_data",
5918 __func__);
5919 nlmsg_free(msg);
5920 return -1;
5921 }
5922 nla_nest_end(msg, params);
5923
5924 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5925 if (ret) {
5926 sigma_dut_print(dut, DUT_MSG_ERROR,
5927 "%s: err in send_and_recv_msgs, ret=%d",
5928 __func__, ret);
5929 }
5930 return ret;
5931#else /* NL80211_SUPPORT */
5932 sigma_dut_print(dut, DUT_MSG_ERROR,
5933 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
5934 return -1;
5935#endif /* NL80211_SUPPORT */
5936}
5937
5938
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08005939static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
5940 const char *intf, int enable)
5941{
5942#ifdef NL80211_SUPPORT
5943 struct nl_msg *msg;
5944 int ret = 0;
5945 struct nlattr *params;
5946 int ifindex;
5947
5948 ifindex = if_nametoindex(intf);
5949 if (ifindex == 0) {
5950 sigma_dut_print(dut, DUT_MSG_ERROR,
5951 "%s: Index for interface %s failed",
5952 __func__, intf);
5953 return -1;
5954 }
5955
5956 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5957 NL80211_CMD_VENDOR)) ||
5958 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5959 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5960 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5961 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5962 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5963 nla_put_u8(msg,
5964 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
5965 enable)) {
5966 sigma_dut_print(dut, DUT_MSG_ERROR,
5967 "%s: err in adding vendor_cmd and vendor_data",
5968 __func__);
5969 nlmsg_free(msg);
5970 return -1;
5971 }
5972 nla_nest_end(msg, params);
5973
5974 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5975 if (ret) {
5976 sigma_dut_print(dut, DUT_MSG_ERROR,
5977 "%s: err in send_and_recv_msgs, ret=%d",
5978 __func__, ret);
5979 }
5980 return ret;
5981#else /* NL80211_SUPPORT */
5982 sigma_dut_print(dut, DUT_MSG_ERROR,
5983 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
5984 return -1;
5985#endif /* NL80211_SUPPORT */
5986}
5987
5988
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08005989static int sta_set_addba_buf_size(struct sigma_dut *dut,
5990 const char *intf, int bufsize)
5991{
5992#ifdef NL80211_SUPPORT
5993 struct nl_msg *msg;
5994 int ret = 0;
5995 struct nlattr *params;
5996 int ifindex;
5997
5998 ifindex = if_nametoindex(intf);
5999 if (ifindex == 0) {
6000 sigma_dut_print(dut, DUT_MSG_ERROR,
6001 "%s: Index for interface %s failed",
6002 __func__, intf);
6003 return -1;
6004 }
6005
6006 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6007 NL80211_CMD_VENDOR)) ||
6008 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6009 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6010 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6011 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6012 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006013 nla_put_u16(msg,
6014 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6015 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006016 sigma_dut_print(dut, DUT_MSG_ERROR,
6017 "%s: err in adding vendor_cmd and vendor_data",
6018 __func__);
6019 nlmsg_free(msg);
6020 return -1;
6021 }
6022 nla_nest_end(msg, params);
6023
6024 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6025 if (ret) {
6026 sigma_dut_print(dut, DUT_MSG_ERROR,
6027 "%s: err in send_and_recv_msgs, ret=%d",
6028 __func__, ret);
6029 }
6030 return ret;
6031#else /* NL80211_SUPPORT */
6032 sigma_dut_print(dut, DUT_MSG_ERROR,
6033 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
6034 return -1;
6035#endif /* NL80211_SUPPORT */
6036}
6037
6038
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006039static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
6040 int enable)
6041{
6042#ifdef NL80211_SUPPORT
6043 struct nl_msg *msg;
6044 int ret = 0;
6045 struct nlattr *params;
6046 int ifindex;
6047
6048 ifindex = if_nametoindex(intf);
6049 if (ifindex == 0) {
6050 sigma_dut_print(dut, DUT_MSG_ERROR,
6051 "%s: Index for interface %s failed",
6052 __func__, intf);
6053 return -1;
6054 }
6055
6056 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6057 NL80211_CMD_VENDOR)) ||
6058 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6059 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6060 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6061 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6062 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6063 nla_put_u8(msg,
6064 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
6065 enable)) {
6066 sigma_dut_print(dut, DUT_MSG_ERROR,
6067 "%s: err in adding vendor_cmd and vendor_data",
6068 __func__);
6069 nlmsg_free(msg);
6070 return -1;
6071 }
6072 nla_nest_end(msg, params);
6073
6074 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6075 if (ret) {
6076 sigma_dut_print(dut, DUT_MSG_ERROR,
6077 "%s: err in send_and_recv_msgs, ret=%d",
6078 __func__, ret);
6079 }
6080 return ret;
6081#else /* NL80211_SUPPORT */
6082 sigma_dut_print(dut, DUT_MSG_ERROR,
6083 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
6084 return -1;
6085#endif /* NL80211_SUPPORT */
6086}
6087
6088
Arif Hussain9765f7d2018-07-03 08:28:26 -07006089static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
6090 int val)
6091{
6092#ifdef NL80211_SUPPORT
6093 struct nl_msg *msg;
6094 int ret = 0;
6095 struct nlattr *params;
6096 int ifindex;
6097
6098 ifindex = if_nametoindex(intf);
6099 if (ifindex == 0) {
6100 sigma_dut_print(dut, DUT_MSG_ERROR,
6101 "%s: Index for interface %s failed, val:%d",
6102 __func__, intf, val);
6103 return -1;
6104 }
6105
6106 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6107 NL80211_CMD_VENDOR)) ||
6108 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6109 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6110 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6111 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6112 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6113 nla_put_u8(msg,
6114 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
6115 val)) {
6116 sigma_dut_print(dut, DUT_MSG_ERROR,
6117 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6118 __func__, val);
6119 nlmsg_free(msg);
6120 return -1;
6121 }
6122 nla_nest_end(msg, params);
6123
6124 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6125 if (ret) {
6126 sigma_dut_print(dut, DUT_MSG_ERROR,
6127 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6128 __func__, ret, val);
6129 }
6130 return ret;
6131#else /* NL80211_SUPPORT */
6132 sigma_dut_print(dut, DUT_MSG_ERROR,
6133 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
6134 return -1;
6135#endif /* NL80211_SUPPORT */
6136}
6137
6138
Arif Hussain68d23f52018-07-11 13:39:08 -07006139#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006140static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
6141 enum qca_wlan_he_mac_padding_dur val)
6142{
Arif Hussain68d23f52018-07-11 13:39:08 -07006143 struct nl_msg *msg;
6144 int ret = 0;
6145 struct nlattr *params;
6146 int ifindex;
6147
6148 ifindex = if_nametoindex(intf);
6149 if (ifindex == 0) {
6150 sigma_dut_print(dut, DUT_MSG_ERROR,
6151 "%s: Index for interface %s failed, val:%d",
6152 __func__, intf, val);
6153 return -1;
6154 }
6155
6156 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6157 NL80211_CMD_VENDOR)) ||
6158 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6159 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6160 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6161 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6162 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6163 nla_put_u8(msg,
6164 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
6165 val)) {
6166 sigma_dut_print(dut, DUT_MSG_ERROR,
6167 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6168 __func__, val);
6169 nlmsg_free(msg);
6170 return -1;
6171 }
6172 nla_nest_end(msg, params);
6173
6174 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6175 if (ret) {
6176 sigma_dut_print(dut, DUT_MSG_ERROR,
6177 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6178 __func__, ret, val);
6179 }
6180 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07006181}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006182#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07006183
6184
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006185static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
6186 int val)
6187{
6188#ifdef NL80211_SUPPORT
6189 struct nl_msg *msg;
6190 int ret = 0;
6191 struct nlattr *params;
6192 int ifindex;
6193
6194 ifindex = if_nametoindex(intf);
6195 if (ifindex == 0) {
6196 sigma_dut_print(dut, DUT_MSG_ERROR,
6197 "%s: Index for interface %s failed, val:%d",
6198 __func__, intf, val);
6199 return -1;
6200 }
6201
6202 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6203 NL80211_CMD_VENDOR)) ||
6204 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6205 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6206 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6207 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6208 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6209 nla_put_u8(msg,
6210 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
6211 val)) {
6212 sigma_dut_print(dut, DUT_MSG_ERROR,
6213 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6214 __func__, val);
6215 nlmsg_free(msg);
6216 return -1;
6217 }
6218 nla_nest_end(msg, params);
6219
6220 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6221 if (ret) {
6222 sigma_dut_print(dut, DUT_MSG_ERROR,
6223 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6224 __func__, ret, val);
6225 }
6226 return ret;
6227#else /* NL80211_SUPPORT */
6228 sigma_dut_print(dut, DUT_MSG_ERROR,
6229 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
6230 return -1;
6231#endif /* NL80211_SUPPORT */
6232}
6233
6234
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006235static int sta_set_he_om_ctrl_nss(struct sigma_dut *dut, const char *intf,
6236 int val)
6237{
6238#ifdef NL80211_SUPPORT
6239 struct nl_msg *msg;
6240 int ret = 0;
6241 struct nlattr *params;
6242 int ifindex;
6243
6244 ifindex = if_nametoindex(intf);
6245 if (ifindex == 0) {
6246 sigma_dut_print(dut, DUT_MSG_ERROR,
6247 "%s: Index for interface %s failed, val:%d",
6248 __func__, intf, val);
6249 return -1;
6250 }
6251
6252 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6253 NL80211_CMD_VENDOR)) ||
6254 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6255 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6256 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6257 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6258 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6259 nla_put_u8(msg,
6260 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS,
6261 val)) {
6262 sigma_dut_print(dut, DUT_MSG_ERROR,
6263 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6264 __func__, val);
6265 nlmsg_free(msg);
6266 return -1;
6267 }
6268 nla_nest_end(msg, params);
6269
6270 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6271 if (ret) {
6272 sigma_dut_print(dut, DUT_MSG_ERROR,
6273 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6274 __func__, ret, val);
6275 }
6276 return ret;
6277#else /* NL80211_SUPPORT */
6278 sigma_dut_print(dut, DUT_MSG_ERROR,
6279 "OM CTRL NSS cannot be set without NL80211_SUPPORT defined");
6280 return -1;
6281#endif /* NL80211_SUPPORT */
6282}
6283
6284
6285static int sta_set_he_om_ctrl_bw(struct sigma_dut *dut, const char *intf,
6286 enum qca_wlan_he_om_ctrl_ch_bw val)
6287{
6288#ifdef NL80211_SUPPORT
6289 struct nl_msg *msg;
6290 int ret = 0;
6291 struct nlattr *params;
6292 int ifindex;
6293
6294 ifindex = if_nametoindex(intf);
6295 if (ifindex == 0) {
6296 sigma_dut_print(dut, DUT_MSG_ERROR,
6297 "%s: Index for interface %s failed, val:%d",
6298 __func__, intf, val);
6299 return -1;
6300 }
6301
6302 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6303 NL80211_CMD_VENDOR)) ||
6304 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6305 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6306 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6307 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6308 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6309 nla_put_u8(msg,
6310 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW,
6311 val)) {
6312 sigma_dut_print(dut, DUT_MSG_ERROR,
6313 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6314 __func__, val);
6315 nlmsg_free(msg);
6316 return -1;
6317 }
6318 nla_nest_end(msg, params);
6319
6320 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6321 if (ret) {
6322 sigma_dut_print(dut, DUT_MSG_ERROR,
6323 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6324 __func__, ret, val);
6325 }
6326 return ret;
6327#else /* NL80211_SUPPORT */
6328 sigma_dut_print(dut, DUT_MSG_ERROR,
6329 "OM CTRL BW cannot be set without NL80211_SUPPORT defined");
6330 return -1;
6331#endif /* NL80211_SUPPORT */
6332}
6333
6334
6335#ifdef NL80211_SUPPORT
6336static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
6337{
6338 struct nl_msg *msg;
6339 int ret = 0;
6340 struct nlattr *params;
6341 int ifindex;
6342
6343 ifindex = if_nametoindex(intf);
6344 if (ifindex == 0) {
6345 sigma_dut_print(dut, DUT_MSG_ERROR,
6346 "%s: Index for interface %s failed",
6347 __func__, intf);
6348 return -1;
6349 }
6350
6351 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6352 NL80211_CMD_VENDOR)) ||
6353 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6354 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6355 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6356 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6357 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6358 nla_put_flag(msg,
6359 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
6360 sigma_dut_print(dut, DUT_MSG_ERROR,
6361 "%s: err in adding vendor_cmd and vendor_data",
6362 __func__);
6363 nlmsg_free(msg);
6364 return -1;
6365 }
6366 nla_nest_end(msg, params);
6367
6368 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6369 if (ret) {
6370 sigma_dut_print(dut, DUT_MSG_ERROR,
6371 "%s: err in send_and_recv_msgs, ret=%d",
6372 __func__, ret);
6373 }
6374 return ret;
6375}
6376#endif /* NL80211_SUPPORT */
6377
6378
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006379static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
6380 int val)
6381{
6382#ifdef NL80211_SUPPORT
6383 struct nl_msg *msg;
6384 int ret = 0;
6385 struct nlattr *params;
6386 int ifindex;
6387
6388 ifindex = if_nametoindex(intf);
6389 if (ifindex == 0) {
6390 sigma_dut_print(dut, DUT_MSG_ERROR,
6391 "%s: Index for interface %s failed, val:%d",
6392 __func__, intf, val);
6393 return -1;
6394 }
6395
6396 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6397 NL80211_CMD_VENDOR)) ||
6398 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6399 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6400 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6401 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6402 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6403 nla_put_u8(msg,
6404 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
6405 val)) {
6406 sigma_dut_print(dut, DUT_MSG_ERROR,
6407 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6408 __func__, val);
6409 nlmsg_free(msg);
6410 return -1;
6411 }
6412 nla_nest_end(msg, params);
6413
6414 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6415 if (ret) {
6416 sigma_dut_print(dut, DUT_MSG_ERROR,
6417 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6418 __func__, ret, val);
6419 }
6420 return ret;
6421#else /* NL80211_SUPPORT */
6422 sigma_dut_print(dut, DUT_MSG_ERROR,
6423 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
6424 return -1;
6425#endif /* NL80211_SUPPORT */
6426}
6427
6428
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006429static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
6430 int val)
6431{
6432#ifdef NL80211_SUPPORT
6433 struct nl_msg *msg;
6434 int ret = 0;
6435 struct nlattr *params;
6436 int ifindex;
6437
6438 ifindex = if_nametoindex(intf);
6439 if (ifindex == 0) {
6440 sigma_dut_print(dut, DUT_MSG_ERROR,
6441 "%s: Index for interface %s failed, val:%d",
6442 __func__, intf, val);
6443 return -1;
6444 }
6445
6446 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6447 NL80211_CMD_VENDOR)) ||
6448 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6449 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6450 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6451 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6452 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6453 nla_put_u8(msg,
6454 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
6455 val)) {
6456 sigma_dut_print(dut, DUT_MSG_ERROR,
6457 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6458 __func__, val);
6459 nlmsg_free(msg);
6460 return -1;
6461 }
6462 nla_nest_end(msg, params);
6463
6464 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6465 if (ret) {
6466 sigma_dut_print(dut, DUT_MSG_ERROR,
6467 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6468 __func__, ret, val);
6469 }
6470 return ret;
6471#else /* NL80211_SUPPORT */
6472 sigma_dut_print(dut, DUT_MSG_ERROR,
6473 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
6474 return -1;
6475#endif /* NL80211_SUPPORT */
6476}
6477
6478
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006479static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
6480 const char *type)
6481{
6482 char buf[60];
6483
6484 if (dut->program == PROGRAM_HE) {
6485 /* resetting phymode to auto in case of HE program */
6486 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
6487 if (system(buf) != 0) {
6488 sigma_dut_print(dut, DUT_MSG_ERROR,
6489 "iwpriv %s setphymode failed", intf);
6490 }
6491
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07006492 /* reset the rate to Auto rate */
6493 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
6494 intf);
6495 if (system(buf) != 0) {
6496 sigma_dut_print(dut, DUT_MSG_ERROR,
6497 "iwpriv %s set_11ax_rate 0xff failed",
6498 intf);
6499 }
6500
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07006501 /* reset the LDPC setting */
6502 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
6503 if (system(buf) != 0) {
6504 sigma_dut_print(dut, DUT_MSG_ERROR,
6505 "iwpriv %s ldpc 1 failed", intf);
6506 }
6507
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006508 /* reset the power save setting */
6509 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
6510 if (system(buf) != 0) {
6511 sigma_dut_print(dut, DUT_MSG_ERROR,
6512 "iwpriv %s setPower 2 failed", intf);
6513 }
6514
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006515 /* remove all network profiles */
6516 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006517
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006518 /* Configure ADDBA Req/Rsp buffer size to be 64 */
6519 sta_set_addba_buf_size(dut, intf, 64);
6520
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08006521#ifdef NL80211_SUPPORT
6522 /* Disable noackpolicy for all AC */
6523 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
6524 sigma_dut_print(dut, DUT_MSG_ERROR,
6525 "Disable of noackpolicy for all AC failed");
6526 }
6527#endif /* NL80211_SUPPORT */
6528
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08006529 /* Enable WMM by default */
6530 if (wcn_sta_set_wmm(dut, intf, "on")) {
6531 sigma_dut_print(dut, DUT_MSG_ERROR,
6532 "Enable of WMM in sta_reset_default_wcn failed");
6533 }
6534
6535 /* Disable ADDBA_REJECT by default */
6536 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
6537 sigma_dut_print(dut, DUT_MSG_ERROR,
6538 "Disable of addba_reject in sta_reset_default_wcn failed");
6539 }
6540
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006541 /* Enable sending of ADDBA by default */
6542 if (nlvendor_config_send_addba(dut, intf, 1)) {
6543 sigma_dut_print(dut, DUT_MSG_ERROR,
6544 "Enable sending of ADDBA in sta_reset_default_wcn failed");
6545 }
6546
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08006547 /* Enable AMPDU by default */
6548 iwpriv_sta_set_ampdu(dut, intf, 1);
6549
Subhani Shaik8e7a3052018-04-24 14:03:00 -07006550#ifdef NL80211_SUPPORT
6551 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
6552 sigma_dut_print(dut, DUT_MSG_ERROR,
6553 "Set LTF config to default in sta_reset_default_wcn failed");
6554 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07006555
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08006556 /* set the beamformee NSTS(maximum number of
6557 * space-time streams) to default DUT config
6558 */
6559 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07006560 sigma_dut_print(dut, DUT_MSG_ERROR,
6561 "Failed to set BeamformeeSTS");
6562 }
Arif Hussain68d23f52018-07-11 13:39:08 -07006563
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006564 if (sta_set_mac_padding_duration(
6565 dut, intf,
6566 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07006567 sigma_dut_print(dut, DUT_MSG_ERROR,
6568 "Failed to set MAC padding duration");
6569 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006570
6571 if (sta_set_mu_edca_override(dut, intf, 0)) {
6572 sigma_dut_print(dut, DUT_MSG_ERROR,
6573 "ErrorCode,Failed to set MU EDCA override disable");
6574 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006575
6576 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
6577 sigma_dut_print(dut, DUT_MSG_ERROR,
6578 "Failed to set OM ctrl supp");
6579 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006580
6581 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
6582 sigma_dut_print(dut, DUT_MSG_ERROR,
6583 "Failed to set Tx SU PPDU enable");
6584 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006585
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006586 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
6587 sigma_dut_print(dut, DUT_MSG_ERROR,
6588 "failed to send TB PPDU Tx cfg");
6589 }
6590
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006591 if (sta_set_he_om_ctrl_reset(dut, intf)) {
6592 sigma_dut_print(dut, DUT_MSG_ERROR,
6593 "Failed to set OM ctrl reset");
6594 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08006595
6596 /* +HTC-HE support default on */
6597 if (sta_set_he_htc_supp(dut, intf, 1)) {
6598 sigma_dut_print(dut, DUT_MSG_ERROR,
6599 "Setting of +HTC-HE support failed");
6600 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07006601#endif /* NL80211_SUPPORT */
6602
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006603 if (sta_set_tx_beamformee(dut, intf, 1)) {
6604 sigma_dut_print(dut, DUT_MSG_ERROR,
6605 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
6606 }
6607
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006608 /* Set nss to 1 and MCS 0-7 in case of testbed */
6609 if (type && strcasecmp(type, "Testbed") == 0) {
6610#ifdef NL80211_SUPPORT
6611 int ret;
6612#endif /* NL80211_SUPPORT */
6613
6614 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
6615 if (system(buf) != 0) {
6616 sigma_dut_print(dut, DUT_MSG_ERROR,
6617 "iwpriv %s nss failed", intf);
6618 }
6619
6620#ifdef NL80211_SUPPORT
6621 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
6622 if (ret) {
6623 sigma_dut_print(dut, DUT_MSG_ERROR,
6624 "Setting of MCS failed, ret:%d",
6625 ret);
6626 }
6627#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08006628
6629 /* Disable STBC as default */
6630 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006631
6632 /* Disable AMSDU as default */
6633 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08006634
6635#ifdef NL80211_SUPPORT
6636 /* HE fragmentation default off */
6637 if (sta_set_he_fragmentation(dut, intf,
6638 HE_FRAG_DISABLE)) {
6639 sigma_dut_print(dut, DUT_MSG_ERROR,
6640 "Setting of HE fragmentation failed");
6641 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08006642
6643 /* set the beamformee NSTS(maximum number of
6644 * space-time streams) to default testbed config
6645 */
6646 if (sta_set_beamformee_sts(dut, intf, 3)) {
6647 sigma_dut_print(dut, DUT_MSG_ERROR,
6648 "Failed to set BeamformeeSTS");
6649 }
6650
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08006651 /* +HTC-HE support default off */
6652 if (sta_set_he_htc_supp(dut, intf, 0)) {
6653 sigma_dut_print(dut, DUT_MSG_ERROR,
6654 "Setting of +HTC-HE support failed");
6655 }
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08006656#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006657
6658 /* Enable WEP/TKIP with HE capability in testbed */
6659 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
6660 sigma_dut_print(dut, DUT_MSG_ERROR,
6661 "Enabling HE config with WEP/TKIP failed");
6662 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006663 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006664
6665 /* Defaults in case of DUT */
6666 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07006667 /* Enable STBC by default */
6668 wcn_sta_set_stbc(dut, intf, "1");
6669
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006670 /* set nss to 2 */
6671 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
6672 if (system(buf) != 0) {
6673 sigma_dut_print(dut, DUT_MSG_ERROR,
6674 "iwpriv %s nss 2 failed", intf);
6675 }
Arif Hussainac6c5112018-05-25 17:34:00 -07006676 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006677
6678#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07006679 /* Set HE_MCS to 0-11 */
6680 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006681 sigma_dut_print(dut, DUT_MSG_ERROR,
6682 "Setting of MCS failed");
6683 }
6684#endif /* NL80211_SUPPORT */
6685
6686 /* Disable WEP/TKIP with HE capability in DUT */
6687 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
6688 sigma_dut_print(dut, DUT_MSG_ERROR,
6689 "Enabling HE config with WEP/TKIP failed");
6690 }
6691 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006692 }
6693}
6694
6695
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006696static int cmd_sta_reset_default(struct sigma_dut *dut,
6697 struct sigma_conn *conn,
6698 struct sigma_cmd *cmd)
6699{
6700 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
6701 struct sigma_cmd *cmd);
6702 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006703 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006704 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006705 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05306706 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006707
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006708 if (!program)
6709 program = get_param(cmd, "prog");
6710 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006711 dut->device_type = STA_unknown;
6712 type = get_param(cmd, "type");
6713 if (type && strcasecmp(type, "Testbed") == 0)
6714 dut->device_type = STA_testbed;
6715 if (type && strcasecmp(type, "DUT") == 0)
6716 dut->device_type = STA_dut;
6717
6718 if (dut->program == PROGRAM_TDLS) {
6719 /* Clear TDLS testing mode */
6720 wpa_command(intf, "SET tdls_disabled 0");
6721 wpa_command(intf, "SET tdls_testing 0");
6722 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05306723 if (get_driver_type() == DRIVER_WCN) {
6724 /* Enable the WCN driver in TDLS Explicit trigger mode
6725 */
6726 wpa_command(intf, "SET tdls_external_control 0");
6727 wpa_command(intf, "SET tdls_trigger_control 0");
6728 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006729 }
6730
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006731#ifdef MIRACAST
6732 if (dut->program == PROGRAM_WFD ||
6733 dut->program == PROGRAM_DISPLAYR2)
6734 miracast_sta_reset_default(dut, conn, cmd);
6735#endif /* MIRACAST */
6736
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006737 switch (get_driver_type()) {
6738 case DRIVER_ATHEROS:
6739 sta_reset_default_ath(dut, intf, type);
6740 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006741 case DRIVER_WCN:
6742 sta_reset_default_wcn(dut, intf, type);
6743 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006744 default:
6745 break;
6746 }
6747
6748#ifdef ANDROID_NAN
6749 if (dut->program == PROGRAM_NAN)
6750 nan_cmd_sta_reset_default(dut, conn, cmd);
6751#endif /* ANDROID_NAN */
6752
Jouni Malinenba630452018-06-22 11:49:59 +03006753 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006754 unlink("SP/wi-fi.org/pps.xml");
6755 if (system("rm -r SP/*") != 0) {
6756 }
6757 unlink("next-client-cert.pem");
6758 unlink("next-client-key.pem");
6759 }
6760
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006761 /* For WPS program of the 60 GHz band the band type needs to be saved */
6762 if (dut->program == PROGRAM_WPS) {
6763 if (band && strcasecmp(band, "60GHz") == 0) {
6764 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02006765 /* For 60 GHz enable WPS for WPS TCs */
6766 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006767 } else {
6768 dut->band = WPS_BAND_NON_60G;
6769 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02006770 } else if (dut->program == PROGRAM_60GHZ) {
6771 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
6772 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006773 }
6774
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02006775 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006776 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02006777 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006778
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02006779 sigma_dut_print(dut, DUT_MSG_INFO,
6780 "WPS 60 GHz program, wps_disable = %d",
6781 dut->wps_disable);
6782
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006783 if (!dev_role) {
6784 send_resp(dut, conn, SIGMA_ERROR,
6785 "errorCode,Missing DevRole argument");
6786 return 0;
6787 }
6788
6789 if (strcasecmp(dev_role, "STA") == 0)
6790 dut->dev_role = DEVROLE_STA;
6791 else if (strcasecmp(dev_role, "PCP") == 0)
6792 dut->dev_role = DEVROLE_PCP;
6793 else {
6794 send_resp(dut, conn, SIGMA_ERROR,
6795 "errorCode,Unknown DevRole");
6796 return 0;
6797 }
6798
6799 if (dut->device_type == STA_unknown) {
6800 sigma_dut_print(dut, DUT_MSG_ERROR,
6801 "Device type is not STA testbed or DUT");
6802 send_resp(dut, conn, SIGMA_ERROR,
6803 "errorCode,Unknown device type");
6804 return 0;
6805 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02006806
6807 sigma_dut_print(dut, DUT_MSG_DEBUG,
6808 "Setting msdu_size to MAX: 7912");
6809 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
6810 get_station_ifname());
6811
6812 if (system(buf) != 0) {
6813 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
6814 buf);
6815 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
6816 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006817 }
6818
6819 wpa_command(intf, "WPS_ER_STOP");
6820 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05306821 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006822 wpa_command(intf, "SET radio_disabled 0");
6823
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006824 if (dut->wsc_fragment) {
6825 dut->wsc_fragment = 0;
6826 wpa_command(intf, "SET device_name Test client");
6827 wpa_command(intf, "SET manufacturer ");
6828 wpa_command(intf, "SET model_name ");
6829 wpa_command(intf, "SET model_number ");
6830 wpa_command(intf, "SET serial_number ");
6831 }
6832
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006833 if (dut->tmp_mac_addr && dut->set_macaddr) {
6834 dut->tmp_mac_addr = 0;
6835 if (system(dut->set_macaddr) != 0) {
6836 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
6837 "temporary MAC address");
6838 }
6839 }
6840
6841 set_ps(intf, dut, 0);
6842
Jouni Malinenba630452018-06-22 11:49:59 +03006843 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
6844 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006845 wpa_command(intf, "SET interworking 1");
6846 wpa_command(intf, "SET hs20 1");
6847 }
6848
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08006849 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03006850 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08006851 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006852 wpa_command(intf, "SET pmf 1");
6853 } else {
6854 wpa_command(intf, "SET pmf 0");
6855 }
6856
6857 hs2_clear_credentials(intf);
6858 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
6859 wpa_command(intf, "SET access_network_type 15");
6860
6861 static_ip_file(0, NULL, NULL, NULL);
6862 kill_dhcp_client(dut, intf);
6863 clear_ip_addr(dut, intf);
6864
6865 dut->er_oper_performed = 0;
6866 dut->er_oper_bssid[0] = '\0';
6867
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07006868 if (dut->program == PROGRAM_LOC) {
6869 /* Disable Interworking by default */
6870 wpa_command(get_station_ifname(), "SET interworking 0");
6871 }
6872
Ashwini Patil00402582017-04-13 12:29:39 +05306873 if (dut->program == PROGRAM_MBO) {
6874 free(dut->non_pref_ch_list);
6875 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05306876 free(dut->btm_query_cand_list);
6877 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05306878 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05306879 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05306880 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306881 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05306882 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05306883 }
6884
Jouni Malinen3c367e82017-06-23 17:01:47 +03006885 free(dut->rsne_override);
6886 dut->rsne_override = NULL;
6887
Jouni Malinen68143132017-09-02 02:34:08 +03006888 free(dut->sae_commit_override);
6889 dut->sae_commit_override = NULL;
6890
Jouni Malinend86e5822017-08-29 03:55:32 +03006891 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02006892 free(dut->dpp_peer_uri);
6893 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02006894 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02006895 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03006896
Jouni Malinenfac9cad2017-10-10 18:35:55 +03006897 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
6898
vamsi krishnaa2799492017-12-05 14:28:01 +05306899 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306900 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05306901 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05306902 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
6903 dut->fils_hlp = 0;
6904#ifdef ANDROID
6905 hlp_thread_cleanup(dut);
6906#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05306907 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306908
Sunil Dutt076081f2018-02-05 19:45:50 +05306909#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05306910 if (get_driver_type() == DRIVER_WCN &&
6911 dut->config_rsnie == 1) {
6912 dut->config_rsnie = 0;
6913 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05306914 }
6915#endif /* NL80211_SUPPORT */
6916
Sunil Duttfebf8a82018-02-09 18:50:13 +05306917 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
6918 dut->dev_role = DEVROLE_STA_CFON;
6919 return sta_cfon_reset_default(dut, conn, cmd);
6920 }
6921
Jouni Malinen439352d2018-09-13 03:42:23 +03006922 wpa_command(intf, "SET setband AUTO");
6923
Sunil Duttfebf8a82018-02-09 18:50:13 +05306924 if (dut->program != PROGRAM_VHT)
6925 return cmd_sta_p2p_reset(dut, conn, cmd);
6926
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08006927 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006928}
6929
6930
6931static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
6932 struct sigma_cmd *cmd)
6933{
6934 const char *program = get_param(cmd, "Program");
6935
6936 if (program == NULL)
6937 return -1;
6938#ifdef ANDROID_NAN
6939 if (strcasecmp(program, "NAN") == 0)
6940 return nan_cmd_sta_get_events(dut, conn, cmd);
6941#endif /* ANDROID_NAN */
6942 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6943 return 0;
6944}
6945
6946
Jouni Malinen82905202018-04-29 17:20:10 +03006947static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
6948 struct sigma_cmd *cmd)
6949{
6950 const char *url = get_param(cmd, "url");
6951 const char *method = get_param(cmd, "method");
6952 pid_t pid;
6953 int status;
6954
6955 if (!url || !method)
6956 return -1;
6957
6958 /* TODO: Add support for method,post */
6959 if (strcasecmp(method, "get") != 0) {
6960 send_resp(dut, conn, SIGMA_ERROR,
6961 "ErrorCode,Unsupported method");
6962 return 0;
6963 }
6964
6965 pid = fork();
6966 if (pid < 0) {
6967 perror("fork");
6968 return -1;
6969 }
6970
6971 if (pid == 0) {
6972 char * argv[5] = { "wget", "-O", "/dev/null",
6973 (char *) url, NULL };
6974
6975 execv("/usr/bin/wget", argv);
6976 perror("execv");
6977 exit(0);
6978 return -1;
6979 }
6980
6981 if (waitpid(pid, &status, 0) < 0) {
6982 perror("waitpid");
6983 return -1;
6984 }
6985
6986 if (WIFEXITED(status)) {
6987 const char *errmsg;
6988
6989 if (WEXITSTATUS(status) == 0)
6990 return 1;
6991 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
6992 WEXITSTATUS(status));
6993 switch (WEXITSTATUS(status)) {
6994 case 4:
6995 errmsg = "errmsg,Network failure";
6996 break;
6997 case 8:
6998 errmsg = "errmsg,Server issued an error response";
6999 break;
7000 default:
7001 errmsg = "errmsg,Unknown failure from wget";
7002 break;
7003 }
7004 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7005 return 0;
7006 }
7007
7008 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7009 return 0;
7010}
7011
7012
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007013static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
7014 struct sigma_cmd *cmd)
7015{
7016 const char *program = get_param(cmd, "Prog");
7017
Jouni Malinen82905202018-04-29 17:20:10 +03007018 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007019 return -1;
7020#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007021 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007022 return nan_cmd_sta_exec_action(dut, conn, cmd);
7023#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007024
7025 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007026 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007027
7028 if (get_param(cmd, "url"))
7029 return sta_exec_action_url(dut, conn, cmd);
7030
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007031 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7032 return 0;
7033}
7034
7035
7036static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
7037 struct sigma_cmd *cmd)
7038{
7039 const char *intf = get_param(cmd, "Interface");
7040 const char *val, *mcs32, *rate;
7041
7042 val = get_param(cmd, "GREENFIELD");
7043 if (val) {
7044 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
7045 /* Enable GD */
7046 send_resp(dut, conn, SIGMA_ERROR,
7047 "ErrorCode,GF not supported");
7048 return 0;
7049 }
7050 }
7051
7052 val = get_param(cmd, "SGI20");
7053 if (val) {
7054 switch (get_driver_type()) {
7055 case DRIVER_ATHEROS:
7056 ath_sta_set_sgi(dut, intf, val);
7057 break;
7058 default:
7059 send_resp(dut, conn, SIGMA_ERROR,
7060 "ErrorCode,SGI20 not supported");
7061 return 0;
7062 }
7063 }
7064
7065 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
7066 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
7067 if (mcs32 && rate) {
7068 /* TODO */
7069 send_resp(dut, conn, SIGMA_ERROR,
7070 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
7071 return 0;
7072 } else if (mcs32 && !rate) {
7073 /* TODO */
7074 send_resp(dut, conn, SIGMA_ERROR,
7075 "ErrorCode,MCS32 not supported");
7076 return 0;
7077 } else if (!mcs32 && rate) {
7078 switch (get_driver_type()) {
7079 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007080 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007081 ath_sta_set_11nrates(dut, intf, rate);
7082 break;
7083 default:
7084 send_resp(dut, conn, SIGMA_ERROR,
7085 "ErrorCode,MCS32_FIXEDRATE not supported");
7086 return 0;
7087 }
7088 }
7089
7090 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7091}
7092
7093
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007094static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
7095 int mcs_config)
7096{
7097#ifdef NL80211_SUPPORT
7098 int ret;
7099
7100 switch (mcs_config) {
7101 case HE_80_MCS0_7:
7102 case HE_80_MCS0_9:
7103 case HE_80_MCS0_11:
7104 ret = sta_set_he_mcs(dut, intf, mcs_config);
7105 if (ret) {
7106 sigma_dut_print(dut, DUT_MSG_ERROR,
7107 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
7108 mcs_config, ret);
7109 }
7110 break;
7111 default:
7112 sigma_dut_print(dut, DUT_MSG_ERROR,
7113 "cmd_set_max_he_mcs: Invalid mcs %d",
7114 mcs_config);
7115 break;
7116 }
7117#else /* NL80211_SUPPORT */
7118 sigma_dut_print(dut, DUT_MSG_ERROR,
7119 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
7120#endif /* NL80211_SUPPORT */
7121}
7122
7123
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007124static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
7125 struct sigma_conn *conn,
7126 struct sigma_cmd *cmd)
7127{
7128 const char *intf = get_param(cmd, "Interface");
7129 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07007130 const char *program;
Arif Hussaind13d6952018-07-02 16:23:47 -07007131 char buf[60];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007132 int tkip = -1;
7133 int wep = -1;
7134
Arif Hussaina37e9552018-06-20 17:05:59 -07007135 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007136 val = get_param(cmd, "SGI80");
7137 if (val) {
7138 int sgi80;
7139
7140 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7141 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi80);
7142 if (system(buf) != 0) {
7143 sigma_dut_print(dut, DUT_MSG_ERROR,
7144 "iwpriv shortgi failed");
7145 }
7146 }
7147
7148 val = get_param(cmd, "TxBF");
7149 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007150 switch (get_driver_type()) {
7151 case DRIVER_WCN:
7152 if (sta_set_tx_beamformee(dut, intf, 1)) {
7153 send_resp(dut, conn, SIGMA_ERROR,
7154 "ErrorCode,Failed to set TX beamformee enable");
7155 return 0;
7156 }
7157 break;
7158 case DRIVER_ATHEROS:
7159 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 1",
7160 intf);
7161 if (system(buf) != 0) {
7162 send_resp(dut, conn, SIGMA_ERROR,
7163 "ErrorCode,Setting vhtsubfee failed");
7164 return 0;
7165 }
7166
7167 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 1",
7168 intf);
7169 if (system(buf) != 0) {
7170 send_resp(dut, conn, SIGMA_ERROR,
7171 "ErrorCode,Setting vhtsubfer failed");
7172 return 0;
7173 }
7174 break;
7175 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007176 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007177 "Unsupported driver type");
7178 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007179 }
7180 }
7181
7182 val = get_param(cmd, "MU_TxBF");
7183 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
7184 switch (get_driver_type()) {
7185 case DRIVER_ATHEROS:
7186 ath_sta_set_txsp_stream(dut, intf, "1SS");
7187 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Sunil Duttae9e5d12018-06-29 11:50:47 +05307188 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 1",
7189 intf);
7190 if (system(buf) != 0) {
7191 sigma_dut_print(dut, DUT_MSG_ERROR,
7192 "iwpriv vhtmubfee failed");
7193 }
7194 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 1",
7195 intf);
7196 if (system(buf) != 0) {
7197 sigma_dut_print(dut, DUT_MSG_ERROR,
7198 "iwpriv vhtmubfer failed");
7199 }
7200 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007201 case DRIVER_WCN:
7202 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
7203 send_resp(dut, conn, SIGMA_ERROR,
7204 "ErrorCode,Failed to set RX/TXSP_STREAM");
7205 return 0;
7206 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05307207 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007208 default:
7209 sigma_dut_print(dut, DUT_MSG_ERROR,
7210 "Setting SP_STREAM not supported");
7211 break;
7212 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007213 }
7214
7215 val = get_param(cmd, "LDPC");
7216 if (val) {
7217 int ldpc;
7218
7219 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7220 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, ldpc);
7221 if (system(buf) != 0) {
7222 sigma_dut_print(dut, DUT_MSG_ERROR,
7223 "iwpriv ldpc failed");
7224 }
7225 }
7226
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08007227 val = get_param(cmd, "BCC");
7228 if (val) {
7229 int bcc;
7230
7231 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7232 /* use LDPC iwpriv itself to set bcc coding, bcc coding
7233 * is mutually exclusive to bcc */
7234 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, !bcc);
7235 if (system(buf) != 0) {
7236 sigma_dut_print(dut, DUT_MSG_ERROR,
7237 "Enabling/Disabling of BCC failed");
7238 }
7239 }
7240
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007241 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
7242 if (val && dut->sta_nss == 1)
7243 cmd_set_max_he_mcs(dut, intf, atoi(val));
7244
7245 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
7246 if (val && dut->sta_nss == 2)
7247 cmd_set_max_he_mcs(dut, intf, atoi(val));
7248
Arif Hussainac6c5112018-05-25 17:34:00 -07007249 val = get_param(cmd, "MCS_FixedRate");
7250 if (val) {
7251#ifdef NL80211_SUPPORT
7252 int mcs, ratecode = 0;
7253 enum he_mcs_config mcs_config;
7254 int ret;
7255
7256 ratecode = (0x07 & dut->sta_nss) << 5;
7257 mcs = atoi(val);
7258 /* Add the MCS to the ratecode */
7259 if (mcs >= 0 && mcs <= 11) {
7260 ratecode += mcs;
7261 if (dut->device_type == STA_testbed &&
7262 mcs > 7 && mcs <= 11) {
7263 if (mcs <= 9)
7264 mcs_config = HE_80_MCS0_9;
7265 else
7266 mcs_config = HE_80_MCS0_11;
7267 ret = sta_set_he_mcs(dut, intf, mcs_config);
7268 if (ret) {
7269 sigma_dut_print(dut, DUT_MSG_ERROR,
7270 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
7271 mcs, mcs_config, ret);
7272 }
7273 }
7274 snprintf(buf, sizeof(buf),
7275 "iwpriv %s set_11ax_rate 0x%03x",
7276 intf, ratecode);
7277 if (system(buf) != 0) {
7278 sigma_dut_print(dut, DUT_MSG_ERROR,
7279 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
7280 ratecode);
7281 }
7282 } else {
7283 sigma_dut_print(dut, DUT_MSG_ERROR,
7284 "MCS_FixedRate: HE MCS %d not supported",
7285 mcs);
7286 }
7287#else /* NL80211_SUPPORT */
7288 sigma_dut_print(dut, DUT_MSG_ERROR,
7289 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
7290#endif /* NL80211_SUPPORT */
7291 }
7292
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007293 val = get_param(cmd, "opt_md_notif_ie");
7294 if (val) {
7295 char *result = NULL;
7296 char delim[] = ";";
7297 char token[30];
7298 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307299 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007300
Peng Xub8fc5cc2017-05-10 17:27:28 -07007301 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307302 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007303
7304 /* Extract the NSS information */
7305 if (result) {
7306 value = atoi(result);
7307 switch (value) {
7308 case 1:
7309 config_val = 1;
7310 break;
7311 case 2:
7312 config_val = 3;
7313 break;
7314 case 3:
7315 config_val = 7;
7316 break;
7317 case 4:
7318 config_val = 15;
7319 break;
7320 default:
7321 config_val = 3;
7322 break;
7323 }
7324
7325 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
7326 intf, config_val);
7327 if (system(buf) != 0) {
7328 sigma_dut_print(dut, DUT_MSG_ERROR,
7329 "iwpriv rxchainmask failed");
7330 }
7331
7332 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
7333 intf, config_val);
7334 if (system(buf) != 0) {
7335 sigma_dut_print(dut, DUT_MSG_ERROR,
7336 "iwpriv txchainmask failed");
7337 }
7338 }
7339
7340 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307341 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007342 if (result) {
7343 value = atoi(result);
7344 switch (value) {
7345 case 20:
7346 config_val = 0;
7347 break;
7348 case 40:
7349 config_val = 1;
7350 break;
7351 case 80:
7352 config_val = 2;
7353 break;
7354 case 160:
7355 config_val = 3;
7356 break;
7357 default:
7358 config_val = 2;
7359 break;
7360 }
7361
7362 dut->chwidth = config_val;
7363
7364 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
7365 intf, config_val);
7366 if (system(buf) != 0) {
7367 sigma_dut_print(dut, DUT_MSG_ERROR,
7368 "iwpriv chwidth failed");
7369 }
7370 }
7371
7372 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", intf);
7373 if (system(buf) != 0) {
7374 sigma_dut_print(dut, DUT_MSG_ERROR,
7375 "iwpriv opmode_notify failed");
7376 }
7377 }
7378
7379 val = get_param(cmd, "nss_mcs_cap");
7380 if (val) {
7381 int nss, mcs;
7382 char token[20];
7383 char *result = NULL;
7384 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307385 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007386
Peng Xub8fc5cc2017-05-10 17:27:28 -07007387 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307388 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307389 if (!result) {
7390 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007391 "NSS not specified");
7392 send_resp(dut, conn, SIGMA_ERROR,
7393 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307394 return 0;
7395 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007396 nss = atoi(result);
7397
7398 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
7399 if (system(buf) != 0) {
7400 sigma_dut_print(dut, DUT_MSG_ERROR,
7401 "iwpriv nss failed");
7402 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007403 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007404
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307405 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007406 if (result == NULL) {
7407 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007408 "MCS not specified");
7409 send_resp(dut, conn, SIGMA_ERROR,
7410 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007411 return 0;
7412 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307413 result = strtok_r(result, "-", &saveptr);
7414 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307415 if (!result) {
7416 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007417 "MCS not specified");
7418 send_resp(dut, conn, SIGMA_ERROR,
7419 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307420 return 0;
7421 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007422 mcs = atoi(result);
7423
Arif Hussaina37e9552018-06-20 17:05:59 -07007424 if (program && strcasecmp(program, "HE") == 0) {
7425#ifdef NL80211_SUPPORT
7426 enum he_mcs_config mcs_config;
7427 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007428
Arif Hussaina37e9552018-06-20 17:05:59 -07007429 if (mcs >= 0 && mcs <= 7) {
7430 mcs_config = HE_80_MCS0_7;
7431 } else if (mcs > 7 && mcs <= 9) {
7432 mcs_config = HE_80_MCS0_9;
7433 } else if (mcs > 9 && mcs <= 11) {
7434 mcs_config = HE_80_MCS0_11;
7435 } else {
7436 sigma_dut_print(dut, DUT_MSG_ERROR,
7437 "nss_mcs_cap: HE: Invalid mcs: %d",
7438 mcs);
7439 send_resp(dut, conn, SIGMA_ERROR,
7440 "errorCode,Invalid MCS");
7441 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007442 }
Arif Hussaina37e9552018-06-20 17:05:59 -07007443
7444 ret = sta_set_he_mcs(dut, intf, mcs_config);
7445 if (ret) {
7446 sigma_dut_print(dut, DUT_MSG_ERROR,
7447 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
7448 mcs_config, ret);
7449 send_resp(dut, conn, SIGMA_ERROR,
7450 "errorCode,Failed to set MCS");
7451 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007452 }
Arif Hussaina37e9552018-06-20 17:05:59 -07007453#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007454 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007455 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
7456#endif /* NL80211_SUPPORT */
7457 } else {
7458 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
7459 intf, mcs);
7460 if (system(buf) != 0) {
7461 sigma_dut_print(dut, DUT_MSG_ERROR,
7462 "iwpriv mcs failed");
7463 }
7464
7465 switch (nss) {
7466 case 1:
7467 switch (mcs) {
7468 case 7:
7469 vht_mcsmap = 0xfffc;
7470 break;
7471 case 8:
7472 vht_mcsmap = 0xfffd;
7473 break;
7474 case 9:
7475 vht_mcsmap = 0xfffe;
7476 break;
7477 default:
7478 vht_mcsmap = 0xfffe;
7479 break;
7480 }
7481 break;
7482 case 2:
7483 switch (mcs) {
7484 case 7:
7485 vht_mcsmap = 0xfff0;
7486 break;
7487 case 8:
7488 vht_mcsmap = 0xfff5;
7489 break;
7490 case 9:
7491 vht_mcsmap = 0xfffa;
7492 break;
7493 default:
7494 vht_mcsmap = 0xfffa;
7495 break;
7496 }
7497 break;
7498 case 3:
7499 switch (mcs) {
7500 case 7:
7501 vht_mcsmap = 0xffc0;
7502 break;
7503 case 8:
7504 vht_mcsmap = 0xffd5;
7505 break;
7506 case 9:
7507 vht_mcsmap = 0xffea;
7508 break;
7509 default:
7510 vht_mcsmap = 0xffea;
7511 break;
7512 }
7513 break;
7514 default:
7515 vht_mcsmap = 0xffea;
7516 break;
7517 }
7518 snprintf(buf, sizeof(buf),
7519 "iwpriv %s vht_mcsmap 0x%04x",
7520 intf, vht_mcsmap);
7521 if (system(buf) != 0) {
7522 sigma_dut_print(dut, DUT_MSG_ERROR,
7523 "iwpriv vht_mcsmap failed");
7524 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007525 }
7526 }
7527
7528 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
7529
7530 val = get_param(cmd, "Vht_tkip");
7531 if (val)
7532 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7533
7534 val = get_param(cmd, "Vht_wep");
7535 if (val)
7536 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7537
7538 if (tkip != -1 || wep != -1) {
7539 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
7540 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1",
7541 intf);
7542 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
7543 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 0",
7544 intf);
7545 } else {
7546 sigma_dut_print(dut, DUT_MSG_ERROR,
7547 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
7548 return 0;
7549 }
7550
7551 if (system(buf) != 0) {
7552 sigma_dut_print(dut, DUT_MSG_ERROR,
7553 "iwpriv htweptkip failed");
7554 }
7555 }
7556
Arif Hussain55f00da2018-07-03 08:28:26 -07007557 val = get_param(cmd, "txBandwidth");
7558 if (val) {
7559 switch (get_driver_type()) {
7560 case DRIVER_WCN:
7561 if (wcn_sta_set_width(dut, intf, val) < 0) {
7562 send_resp(dut, conn, SIGMA_ERROR,
7563 "ErrorCode,Failed to set txBandwidth");
7564 return 0;
7565 }
7566 break;
7567 case DRIVER_ATHEROS:
7568 if (ath_set_width(dut, conn, intf, val) < 0) {
7569 send_resp(dut, conn, SIGMA_ERROR,
7570 "ErrorCode,Failed to set txBandwidth");
7571 return 0;
7572 }
7573 break;
7574 default:
7575 sigma_dut_print(dut, DUT_MSG_ERROR,
7576 "Setting txBandwidth not supported");
7577 break;
7578 }
7579 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007580
Arif Hussain9765f7d2018-07-03 08:28:26 -07007581 val = get_param(cmd, "BeamformeeSTS");
7582 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07007583 if (sta_set_tx_beamformee(dut, intf, 1)) {
7584 send_resp(dut, conn, SIGMA_ERROR,
7585 "ErrorCode,Failed to set TX beamformee enable");
7586 return 0;
7587 }
7588
Arif Hussain9765f7d2018-07-03 08:28:26 -07007589 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
7590 send_resp(dut, conn, SIGMA_ERROR,
7591 "ErrorCode,Failed to set BeamformeeSTS");
7592 return 0;
7593 }
7594 }
7595
Arif Hussain68d23f52018-07-11 13:39:08 -07007596 val = get_param(cmd, "Trig_MAC_Padding_Dur");
7597 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007598#ifdef NL80211_SUPPORT
7599 enum qca_wlan_he_mac_padding_dur set_val;
7600
7601 switch (atoi(val)) {
7602 case 16:
7603 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
7604 break;
7605 case 8:
7606 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
7607 break;
7608 default:
7609 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
7610 break;
7611 }
7612 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007613 send_resp(dut, conn, SIGMA_ERROR,
7614 "ErrorCode,Failed to set MAC padding duration");
7615 return 0;
7616 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007617#else /* NL80211_SUPPORT */
7618 sigma_dut_print(dut, DUT_MSG_ERROR,
7619 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
7620#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007621 }
7622
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007623 val = get_param(cmd, "MU_EDCA");
7624 if (val && (strcasecmp(val, "Override") == 0)) {
7625 if (sta_set_mu_edca_override(dut, intf, 1)) {
7626 send_resp(dut, conn, SIGMA_ERROR,
7627 "ErrorCode,Failed to set MU EDCA override");
7628 return 0;
7629 }
7630 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07007631
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007632 val = get_param(cmd, "OMControl");
7633 if (val) {
7634 int set_val = 1;
7635
7636 if (strcasecmp(val, "Enable") == 0)
7637 set_val = 1;
7638 else if (strcasecmp(val, "Disable") == 0)
7639 set_val = 0;
7640
7641 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
7642 send_resp(dut, conn, SIGMA_ERROR,
7643 "ErrorCode,Failed to set OM ctrl supp");
7644 return 0;
7645 }
7646 }
7647
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07007648 val = get_param(cmd, "ADDBAResp_BufSize");
7649 if (val) {
7650 int buf_size;
7651
7652 if (strcasecmp(val, "gt64") == 0)
7653 buf_size = 256;
7654 else
7655 buf_size = 64;
7656 if (get_driver_type() == DRIVER_WCN &&
7657 sta_set_addba_buf_size(dut, intf, buf_size)) {
7658 send_resp(dut, conn, SIGMA_ERROR,
7659 "ErrorCode,set addbaresp_buff_size failed");
7660 return 0;
7661 }
7662 }
7663
7664 val = get_param(cmd, "ADDBAReq_BufSize");
7665 if (val) {
7666 int buf_size;
7667
7668 if (strcasecmp(val, "gt64") == 0)
7669 buf_size = 256;
7670 else
7671 buf_size = 64;
7672 if (get_driver_type() == DRIVER_WCN &&
7673 sta_set_addba_buf_size(dut, intf, buf_size)) {
7674 send_resp(dut, conn, SIGMA_ERROR,
7675 "ErrorCode,set addbareq_buff_size failed");
7676 return 0;
7677 }
7678 }
7679
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007680 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7681}
7682
7683
7684static int sta_set_wireless_60g(struct sigma_dut *dut,
7685 struct sigma_conn *conn,
7686 struct sigma_cmd *cmd)
7687{
7688 const char *dev_role = get_param(cmd, "DevRole");
7689
7690 if (!dev_role) {
7691 send_resp(dut, conn, SIGMA_INVALID,
7692 "ErrorCode,DevRole not specified");
7693 return 0;
7694 }
7695
7696 if (strcasecmp(dev_role, "PCP") == 0)
7697 return sta_set_60g_pcp(dut, conn, cmd);
7698 if (strcasecmp(dev_role, "STA") == 0)
7699 return sta_set_60g_sta(dut, conn, cmd);
7700 send_resp(dut, conn, SIGMA_INVALID,
7701 "ErrorCode,DevRole not supported");
7702 return 0;
7703}
7704
7705
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307706static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
7707 struct sigma_cmd *cmd)
7708{
7709 int status;
7710 const char *intf = get_param(cmd, "Interface");
7711 const char *val = get_param(cmd, "DevRole");
7712
7713 if (val && strcasecmp(val, "STA-CFON") == 0) {
7714 status = sta_cfon_set_wireless(dut, conn, cmd);
7715 if (status)
7716 return status;
7717 }
7718 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7719}
7720
7721
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007722static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
7723 struct sigma_cmd *cmd)
7724{
7725 const char *val;
7726
7727 val = get_param(cmd, "Program");
7728 if (val) {
7729 if (strcasecmp(val, "11n") == 0)
7730 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08007731 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007732 return cmd_sta_set_wireless_vht(dut, conn, cmd);
7733 if (strcasecmp(val, "60ghz") == 0)
7734 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307735 if (strcasecmp(val, "OCE") == 0)
7736 return sta_set_wireless_oce(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007737 send_resp(dut, conn, SIGMA_ERROR,
7738 "ErrorCode,Program value not supported");
7739 } else {
7740 send_resp(dut, conn, SIGMA_ERROR,
7741 "ErrorCode,Program argument not available");
7742 }
7743
7744 return 0;
7745}
7746
7747
7748static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
7749 int tid)
7750{
7751 char buf[100];
7752 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
7753
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05307754 if (tid < 0 ||
7755 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
7756 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
7757 return;
7758 }
7759
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007760 /*
7761 * Two ways to ensure that addba request with a
7762 * non zero TID could be sent out. EV 117296
7763 */
7764 snprintf(buf, sizeof(buf),
7765 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
7766 tid);
7767 if (system(buf) != 0) {
7768 sigma_dut_print(dut, DUT_MSG_ERROR,
7769 "Ping did not send out");
7770 }
7771
7772 snprintf(buf, sizeof(buf),
7773 "iwconfig %s | grep Access | awk '{print $6}' > %s",
7774 intf, VI_QOS_TMP_FILE);
7775 if (system(buf) != 0)
7776 return;
7777
7778 snprintf(buf, sizeof(buf),
7779 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
7780 intf, VI_QOS_TMP_FILE);
7781 if (system(buf) != 0)
7782 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
7783
7784 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
7785 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
7786 if (system(buf) != 0) {
7787 sigma_dut_print(dut, DUT_MSG_ERROR,
7788 "VI_QOS_TEMP_FILE generation error failed");
7789 }
7790 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
7791 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
7792 if (system(buf) != 0) {
7793 sigma_dut_print(dut, DUT_MSG_ERROR,
7794 "VI_QOS_FILE generation failed");
7795 }
7796
7797 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
7798 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
7799 if (system(buf) != 0) {
7800 sigma_dut_print(dut, DUT_MSG_ERROR,
7801 "VI_QOS_FILE generation failed");
7802 }
7803
7804 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
7805 if (system(buf) != 0) {
7806 }
7807}
7808
7809
7810static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
7811 struct sigma_cmd *cmd)
7812{
7813 const char *intf = get_param(cmd, "Interface");
7814 const char *val;
7815 int tid = 0;
7816 char buf[100];
7817
7818 val = get_param(cmd, "TID");
7819 if (val) {
7820 tid = atoi(val);
7821 if (tid)
7822 ath_sta_inject_frame(dut, intf, tid);
7823 }
7824
7825 /* Command sequence for ADDBA request on Peregrine based devices */
7826 snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", intf);
7827 if (system(buf) != 0) {
7828 sigma_dut_print(dut, DUT_MSG_ERROR,
7829 "iwpriv setaddbaoper failed");
7830 }
7831
7832 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
7833 if (system(buf) != 0) {
7834 sigma_dut_print(dut, DUT_MSG_ERROR,
7835 "wifitool senddelba failed");
7836 }
7837
7838 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
7839 if (system(buf) != 0) {
7840 sigma_dut_print(dut, DUT_MSG_ERROR,
7841 "wifitool sendaddba failed");
7842 }
7843
7844 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
7845
7846 return 1;
7847}
7848
7849
Lior David9981b512017-01-20 13:16:40 +02007850#ifdef __linux__
7851
7852static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
7853 int agg_size)
7854{
7855 char dir[128], buf[128];
7856 FILE *f;
7857 regex_t re;
7858 regmatch_t m[2];
7859 int rc, ret = -1, vring_id, found;
7860
7861 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
7862 sigma_dut_print(dut, DUT_MSG_ERROR,
7863 "failed to get wil6210 debugfs dir");
7864 return -1;
7865 }
7866
7867 snprintf(buf, sizeof(buf), "%s/vrings", dir);
7868 f = fopen(buf, "r");
7869 if (!f) {
7870 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02007871 /* newer wil6210 driver renamed file to "rings" */
7872 snprintf(buf, sizeof(buf), "%s/rings", dir);
7873 f = fopen(buf, "r");
7874 if (!f) {
7875 sigma_dut_print(dut, DUT_MSG_ERROR,
7876 "failed to open: %s", buf);
7877 return -1;
7878 }
Lior David9981b512017-01-20 13:16:40 +02007879 }
7880
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02007881 /* can be either VRING tx... or RING... */
7882 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02007883 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
7884 goto out;
7885 }
7886
7887 /* find TX VRING for the mac address */
7888 found = 0;
7889 while (fgets(buf, sizeof(buf), f)) {
7890 if (strcasestr(buf, dest_mac)) {
7891 found = 1;
7892 break;
7893 }
7894 }
7895
7896 if (!found) {
7897 sigma_dut_print(dut, DUT_MSG_ERROR,
7898 "no TX VRING for %s", dest_mac);
7899 goto out;
7900 }
7901
7902 /* extract VRING ID, "VRING tx_<id> = {" */
7903 if (!fgets(buf, sizeof(buf), f)) {
7904 sigma_dut_print(dut, DUT_MSG_ERROR,
7905 "no VRING start line for %s", dest_mac);
7906 goto out;
7907 }
7908
7909 rc = regexec(&re, buf, 2, m, 0);
7910 regfree(&re);
7911 if (rc || m[1].rm_so < 0) {
7912 sigma_dut_print(dut, DUT_MSG_ERROR,
7913 "no VRING TX ID for %s", dest_mac);
7914 goto out;
7915 }
7916 buf[m[1].rm_eo] = 0;
7917 vring_id = atoi(&buf[m[1].rm_so]);
7918
7919 /* send the addba command */
7920 fclose(f);
7921 snprintf(buf, sizeof(buf), "%s/back", dir);
7922 f = fopen(buf, "w");
7923 if (!f) {
7924 sigma_dut_print(dut, DUT_MSG_ERROR,
7925 "failed to open: %s", buf);
7926 return -1;
7927 }
7928
7929 fprintf(f, "add %d %d\n", vring_id, agg_size);
7930
7931 ret = 0;
7932
7933out:
7934 fclose(f);
7935
7936 return ret;
7937}
7938
7939
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02007940int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7941 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007942{
7943 const char *val;
7944 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007945
7946 val = get_param(cmd, "TID");
7947 if (val) {
7948 tid = atoi(val);
7949 if (tid != 0) {
7950 sigma_dut_print(dut, DUT_MSG_ERROR,
7951 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
7952 tid);
7953 }
7954 }
7955
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02007956 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007957 if (!val) {
7958 sigma_dut_print(dut, DUT_MSG_ERROR,
7959 "Currently not supporting addba for 60G without Dest_mac");
7960 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
7961 }
7962
Lior David9981b512017-01-20 13:16:40 +02007963 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007964 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007965
7966 return 1;
7967}
7968
Lior David9981b512017-01-20 13:16:40 +02007969#endif /* __linux__ */
7970
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007971
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08007972static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
7973 struct sigma_cmd *cmd)
7974{
7975#ifdef NL80211_SUPPORT
7976 const char *intf = get_param(cmd, "Interface");
7977 const char *val;
7978 int tid = -1;
7979 int bufsize = 64;
7980 struct nl_msg *msg;
7981 int ret = 0;
7982 struct nlattr *params;
7983 int ifindex;
7984
7985 val = get_param(cmd, "TID");
7986 if (val)
7987 tid = atoi(val);
7988
7989 if (tid == -1) {
7990 send_resp(dut, conn, SIGMA_ERROR,
7991 "ErrorCode,sta_send_addba tid invalid");
7992 return 0;
7993 }
7994
7995 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
7996
7997 ifindex = if_nametoindex(intf);
7998 if (ifindex == 0) {
7999 sigma_dut_print(dut, DUT_MSG_ERROR,
8000 "%s: Index for interface %s failed",
8001 __func__, intf);
8002 send_resp(dut, conn, SIGMA_ERROR,
8003 "ErrorCode,sta_send_addba interface invalid");
8004 return 0;
8005 }
8006
8007 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8008 NL80211_CMD_VENDOR)) ||
8009 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8010 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8011 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8012 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8013 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8014 nla_put_u8(msg,
8015 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
8016 QCA_WLAN_ADD_BA) ||
8017 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
8018 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07008019 nla_put_u16(msg,
8020 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
8021 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008022 sigma_dut_print(dut, DUT_MSG_ERROR,
8023 "%s: err in adding vendor_cmd and vendor_data",
8024 __func__);
8025 nlmsg_free(msg);
8026 send_resp(dut, conn, SIGMA_ERROR,
8027 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
8028 return 0;
8029 }
8030 nla_nest_end(msg, params);
8031
8032 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8033 if (ret) {
8034 sigma_dut_print(dut, DUT_MSG_ERROR,
8035 "%s: err in send_and_recv_msgs, ret=%d",
8036 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05308037 if (ret == -EOPNOTSUPP)
8038 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008039 send_resp(dut, conn, SIGMA_ERROR,
8040 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
8041 return 0;
8042 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008043#else /* NL80211_SUPPORT */
8044 sigma_dut_print(dut, DUT_MSG_ERROR,
8045 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008046#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05308047
8048 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008049}
8050
8051
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008052static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8053 struct sigma_cmd *cmd)
8054{
8055 switch (get_driver_type()) {
8056 case DRIVER_ATHEROS:
8057 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008058 case DRIVER_WCN:
8059 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02008060#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008061 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008062 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02008063#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008064 default:
8065 /*
8066 * There is no driver specific implementation for other drivers.
8067 * Ignore the command and report COMPLETE since the following
8068 * throughput test operation will end up sending ADDBA anyway.
8069 */
8070 return 1;
8071 }
8072}
8073
8074
8075int inject_eth_frame(int s, const void *data, size_t len,
8076 unsigned short ethtype, char *dst, char *src)
8077{
8078 struct iovec iov[4] = {
8079 {
8080 .iov_base = dst,
8081 .iov_len = ETH_ALEN,
8082 },
8083 {
8084 .iov_base = src,
8085 .iov_len = ETH_ALEN,
8086 },
8087 {
8088 .iov_base = &ethtype,
8089 .iov_len = sizeof(unsigned short),
8090 },
8091 {
8092 .iov_base = (void *) data,
8093 .iov_len = len,
8094 }
8095 };
8096 struct msghdr msg = {
8097 .msg_name = NULL,
8098 .msg_namelen = 0,
8099 .msg_iov = iov,
8100 .msg_iovlen = 4,
8101 .msg_control = NULL,
8102 .msg_controllen = 0,
8103 .msg_flags = 0,
8104 };
8105
8106 return sendmsg(s, &msg, 0);
8107}
8108
8109#if defined(__linux__) || defined(__QNXNTO__)
8110
8111int inject_frame(int s, const void *data, size_t len, int encrypt)
8112{
8113#define IEEE80211_RADIOTAP_F_WEP 0x04
8114#define IEEE80211_RADIOTAP_F_FRAG 0x08
8115 unsigned char rtap_hdr[] = {
8116 0x00, 0x00, /* radiotap version */
8117 0x0e, 0x00, /* radiotap length */
8118 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
8119 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
8120 0x00, /* padding */
8121 0x00, 0x00, /* RX and TX flags to indicate that */
8122 0x00, 0x00, /* this is the injected frame directly */
8123 };
8124 struct iovec iov[2] = {
8125 {
8126 .iov_base = &rtap_hdr,
8127 .iov_len = sizeof(rtap_hdr),
8128 },
8129 {
8130 .iov_base = (void *) data,
8131 .iov_len = len,
8132 }
8133 };
8134 struct msghdr msg = {
8135 .msg_name = NULL,
8136 .msg_namelen = 0,
8137 .msg_iov = iov,
8138 .msg_iovlen = 2,
8139 .msg_control = NULL,
8140 .msg_controllen = 0,
8141 .msg_flags = 0,
8142 };
8143
8144 if (encrypt)
8145 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
8146
8147 return sendmsg(s, &msg, 0);
8148}
8149
8150
8151int open_monitor(const char *ifname)
8152{
8153#ifdef __QNXNTO__
8154 struct sockaddr_dl ll;
8155 int s;
8156
8157 memset(&ll, 0, sizeof(ll));
8158 ll.sdl_family = AF_LINK;
8159 ll.sdl_index = if_nametoindex(ifname);
8160 if (ll.sdl_index == 0) {
8161 perror("if_nametoindex");
8162 return -1;
8163 }
8164 s = socket(PF_INET, SOCK_RAW, 0);
8165#else /* __QNXNTO__ */
8166 struct sockaddr_ll ll;
8167 int s;
8168
8169 memset(&ll, 0, sizeof(ll));
8170 ll.sll_family = AF_PACKET;
8171 ll.sll_ifindex = if_nametoindex(ifname);
8172 if (ll.sll_ifindex == 0) {
8173 perror("if_nametoindex");
8174 return -1;
8175 }
8176 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
8177#endif /* __QNXNTO__ */
8178 if (s < 0) {
8179 perror("socket[PF_PACKET,SOCK_RAW]");
8180 return -1;
8181 }
8182
8183 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
8184 perror("monitor socket bind");
8185 close(s);
8186 return -1;
8187 }
8188
8189 return s;
8190}
8191
8192
8193static int hex2num(char c)
8194{
8195 if (c >= '0' && c <= '9')
8196 return c - '0';
8197 if (c >= 'a' && c <= 'f')
8198 return c - 'a' + 10;
8199 if (c >= 'A' && c <= 'F')
8200 return c - 'A' + 10;
8201 return -1;
8202}
8203
8204
8205int hwaddr_aton(const char *txt, unsigned char *addr)
8206{
8207 int i;
8208
8209 for (i = 0; i < 6; i++) {
8210 int a, b;
8211
8212 a = hex2num(*txt++);
8213 if (a < 0)
8214 return -1;
8215 b = hex2num(*txt++);
8216 if (b < 0)
8217 return -1;
8218 *addr++ = (a << 4) | b;
8219 if (i < 5 && *txt++ != ':')
8220 return -1;
8221 }
8222
8223 return 0;
8224}
8225
8226#endif /* defined(__linux__) || defined(__QNXNTO__) */
8227
8228enum send_frame_type {
8229 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
8230};
8231enum send_frame_protection {
8232 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
8233};
8234
8235
8236static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
8237 enum send_frame_type frame,
8238 enum send_frame_protection protected,
8239 const char *dest)
8240{
8241#ifdef __linux__
8242 unsigned char buf[1000], *pos;
8243 int s, res;
8244 char bssid[20], addr[20];
8245 char result[32], ssid[100];
8246 size_t ssid_len;
8247
8248 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
8249 sizeof(result)) < 0 ||
8250 strncmp(result, "COMPLETED", 9) != 0) {
8251 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
8252 return 0;
8253 }
8254
8255 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
8256 < 0) {
8257 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8258 "current BSSID");
8259 return 0;
8260 }
8261
8262 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
8263 < 0) {
8264 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8265 "own MAC address");
8266 return 0;
8267 }
8268
8269 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
8270 < 0) {
8271 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8272 "current SSID");
8273 return 0;
8274 }
8275 ssid_len = strlen(ssid);
8276
8277 pos = buf;
8278
8279 /* Frame Control */
8280 switch (frame) {
8281 case DISASSOC:
8282 *pos++ = 0xa0;
8283 break;
8284 case DEAUTH:
8285 *pos++ = 0xc0;
8286 break;
8287 case SAQUERY:
8288 *pos++ = 0xd0;
8289 break;
8290 case AUTH:
8291 *pos++ = 0xb0;
8292 break;
8293 case ASSOCREQ:
8294 *pos++ = 0x00;
8295 break;
8296 case REASSOCREQ:
8297 *pos++ = 0x20;
8298 break;
8299 case DLS_REQ:
8300 *pos++ = 0xd0;
8301 break;
8302 }
8303
8304 if (protected == INCORRECT_KEY)
8305 *pos++ = 0x40; /* Set Protected field to 1 */
8306 else
8307 *pos++ = 0x00;
8308
8309 /* Duration */
8310 *pos++ = 0x00;
8311 *pos++ = 0x00;
8312
8313 /* addr1 = DA (current AP) */
8314 hwaddr_aton(bssid, pos);
8315 pos += 6;
8316 /* addr2 = SA (own address) */
8317 hwaddr_aton(addr, pos);
8318 pos += 6;
8319 /* addr3 = BSSID (current AP) */
8320 hwaddr_aton(bssid, pos);
8321 pos += 6;
8322
8323 /* Seq# (to be filled by driver/mac80211) */
8324 *pos++ = 0x00;
8325 *pos++ = 0x00;
8326
8327 if (protected == INCORRECT_KEY) {
8328 /* CCMP parameters */
8329 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
8330 pos += 8;
8331 }
8332
8333 if (protected == INCORRECT_KEY) {
8334 switch (frame) {
8335 case DEAUTH:
8336 /* Reason code (encrypted) */
8337 memcpy(pos, "\xa7\x39", 2);
8338 pos += 2;
8339 break;
8340 case DISASSOC:
8341 /* Reason code (encrypted) */
8342 memcpy(pos, "\xa7\x39", 2);
8343 pos += 2;
8344 break;
8345 case SAQUERY:
8346 /* Category|Action|TransID (encrypted) */
8347 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
8348 pos += 4;
8349 break;
8350 default:
8351 return -1;
8352 }
8353
8354 /* CCMP MIC */
8355 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
8356 pos += 8;
8357 } else {
8358 switch (frame) {
8359 case DEAUTH:
8360 /* reason code = 8 */
8361 *pos++ = 0x08;
8362 *pos++ = 0x00;
8363 break;
8364 case DISASSOC:
8365 /* reason code = 8 */
8366 *pos++ = 0x08;
8367 *pos++ = 0x00;
8368 break;
8369 case SAQUERY:
8370 /* Category - SA Query */
8371 *pos++ = 0x08;
8372 /* SA query Action - Request */
8373 *pos++ = 0x00;
8374 /* Transaction ID */
8375 *pos++ = 0x12;
8376 *pos++ = 0x34;
8377 break;
8378 case AUTH:
8379 /* Auth Alg (Open) */
8380 *pos++ = 0x00;
8381 *pos++ = 0x00;
8382 /* Seq# */
8383 *pos++ = 0x01;
8384 *pos++ = 0x00;
8385 /* Status code */
8386 *pos++ = 0x00;
8387 *pos++ = 0x00;
8388 break;
8389 case ASSOCREQ:
8390 /* Capability Information */
8391 *pos++ = 0x31;
8392 *pos++ = 0x04;
8393 /* Listen Interval */
8394 *pos++ = 0x0a;
8395 *pos++ = 0x00;
8396 /* SSID */
8397 *pos++ = 0x00;
8398 *pos++ = ssid_len;
8399 memcpy(pos, ssid, ssid_len);
8400 pos += ssid_len;
8401 /* Supported Rates */
8402 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
8403 10);
8404 pos += 10;
8405 /* Extended Supported Rates */
8406 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
8407 pos += 6;
8408 /* RSN */
8409 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
8410 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
8411 "\x00\x00\x00\x00\x0f\xac\x06", 28);
8412 pos += 28;
8413 break;
8414 case REASSOCREQ:
8415 /* Capability Information */
8416 *pos++ = 0x31;
8417 *pos++ = 0x04;
8418 /* Listen Interval */
8419 *pos++ = 0x0a;
8420 *pos++ = 0x00;
8421 /* Current AP */
8422 hwaddr_aton(bssid, pos);
8423 pos += 6;
8424 /* SSID */
8425 *pos++ = 0x00;
8426 *pos++ = ssid_len;
8427 memcpy(pos, ssid, ssid_len);
8428 pos += ssid_len;
8429 /* Supported Rates */
8430 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
8431 10);
8432 pos += 10;
8433 /* Extended Supported Rates */
8434 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
8435 pos += 6;
8436 /* RSN */
8437 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
8438 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
8439 "\x00\x00\x00\x00\x0f\xac\x06", 28);
8440 pos += 28;
8441 break;
8442 case DLS_REQ:
8443 /* Category - DLS */
8444 *pos++ = 0x02;
8445 /* DLS Action - Request */
8446 *pos++ = 0x00;
8447 /* Destination MACAddress */
8448 if (dest)
8449 hwaddr_aton(dest, pos);
8450 else
8451 memset(pos, 0, 6);
8452 pos += 6;
8453 /* Source MACAddress */
8454 hwaddr_aton(addr, pos);
8455 pos += 6;
8456 /* Capability Information */
8457 *pos++ = 0x10; /* Privacy */
8458 *pos++ = 0x06; /* QoS */
8459 /* DLS Timeout Value */
8460 *pos++ = 0x00;
8461 *pos++ = 0x01;
8462 /* Supported rates */
8463 *pos++ = 0x01;
8464 *pos++ = 0x08;
8465 *pos++ = 0x0c; /* 6 Mbps */
8466 *pos++ = 0x12; /* 9 Mbps */
8467 *pos++ = 0x18; /* 12 Mbps */
8468 *pos++ = 0x24; /* 18 Mbps */
8469 *pos++ = 0x30; /* 24 Mbps */
8470 *pos++ = 0x48; /* 36 Mbps */
8471 *pos++ = 0x60; /* 48 Mbps */
8472 *pos++ = 0x6c; /* 54 Mbps */
8473 /* TODO: Extended Supported Rates */
8474 /* TODO: HT Capabilities */
8475 break;
8476 }
8477 }
8478
8479 s = open_monitor("sigmadut");
8480 if (s < 0) {
8481 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
8482 "monitor socket");
8483 return 0;
8484 }
8485
8486 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
8487 if (res < 0) {
8488 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
8489 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308490 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008491 return 0;
8492 }
8493 if (res < pos - buf) {
8494 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
8495 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308496 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008497 return 0;
8498 }
8499
8500 close(s);
8501
8502 return 1;
8503#else /* __linux__ */
8504 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
8505 "yet supported");
8506 return 0;
8507#endif /* __linux__ */
8508}
8509
8510
8511static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
8512 struct sigma_conn *conn,
8513 struct sigma_cmd *cmd)
8514{
8515 const char *intf = get_param(cmd, "Interface");
8516 const char *sta, *val;
8517 unsigned char addr[ETH_ALEN];
8518 char buf[100];
8519
8520 sta = get_param(cmd, "peer");
8521 if (sta == NULL)
8522 sta = get_param(cmd, "station");
8523 if (sta == NULL) {
8524 send_resp(dut, conn, SIGMA_ERROR,
8525 "ErrorCode,Missing peer address");
8526 return 0;
8527 }
8528 if (hwaddr_aton(sta, addr) < 0) {
8529 send_resp(dut, conn, SIGMA_ERROR,
8530 "ErrorCode,Invalid peer address");
8531 return 0;
8532 }
8533
8534 val = get_param(cmd, "type");
8535 if (val == NULL)
8536 return -1;
8537
8538 if (strcasecmp(val, "DISCOVERY") == 0) {
8539 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
8540 if (wpa_command(intf, buf) < 0) {
8541 send_resp(dut, conn, SIGMA_ERROR,
8542 "ErrorCode,Failed to send TDLS discovery");
8543 return 0;
8544 }
8545 return 1;
8546 }
8547
8548 if (strcasecmp(val, "SETUP") == 0) {
8549 int status = 0, timeout = 0;
8550
8551 val = get_param(cmd, "Status");
8552 if (val)
8553 status = atoi(val);
8554
8555 val = get_param(cmd, "Timeout");
8556 if (val)
8557 timeout = atoi(val);
8558
8559 if (status != 0 && status != 37) {
8560 send_resp(dut, conn, SIGMA_ERROR,
8561 "ErrorCode,Unsupported status value");
8562 return 0;
8563 }
8564
8565 if (timeout != 0 && timeout != 301) {
8566 send_resp(dut, conn, SIGMA_ERROR,
8567 "ErrorCode,Unsupported timeout value");
8568 return 0;
8569 }
8570
8571 if (status && timeout) {
8572 send_resp(dut, conn, SIGMA_ERROR,
8573 "ErrorCode,Unsupported timeout+status "
8574 "combination");
8575 return 0;
8576 }
8577
8578 if (status == 37 &&
8579 wpa_command(intf, "SET tdls_testing 0x200")) {
8580 send_resp(dut, conn, SIGMA_ERROR,
8581 "ErrorCode,Failed to enable "
8582 "decline setup response test mode");
8583 return 0;
8584 }
8585
8586 if (timeout == 301) {
8587 int res;
8588 if (dut->no_tpk_expiration)
8589 res = wpa_command(intf,
8590 "SET tdls_testing 0x108");
8591 else
8592 res = wpa_command(intf,
8593 "SET tdls_testing 0x8");
8594 if (res) {
8595 send_resp(dut, conn, SIGMA_ERROR,
8596 "ErrorCode,Failed to set short TPK "
8597 "lifetime");
8598 return 0;
8599 }
8600 }
8601
8602 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
8603 if (wpa_command(intf, buf) < 0) {
8604 send_resp(dut, conn, SIGMA_ERROR,
8605 "ErrorCode,Failed to send TDLS setup");
8606 return 0;
8607 }
8608 return 1;
8609 }
8610
8611 if (strcasecmp(val, "TEARDOWN") == 0) {
8612 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
8613 if (wpa_command(intf, buf) < 0) {
8614 send_resp(dut, conn, SIGMA_ERROR,
8615 "ErrorCode,Failed to send TDLS teardown");
8616 return 0;
8617 }
8618 return 1;
8619 }
8620
8621 send_resp(dut, conn, SIGMA_ERROR,
8622 "ErrorCode,Unsupported TDLS frame");
8623 return 0;
8624}
8625
8626
8627static int sta_ap_known(const char *ifname, const char *bssid)
8628{
8629 char buf[4096];
8630
Jouni Malinendd32f192018-09-15 02:55:19 +03008631 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008632 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
8633 return 0;
8634 if (strncmp(buf, "id=", 3) != 0)
8635 return 0;
8636 return 1;
8637}
8638
8639
8640static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
8641 const char *bssid)
8642{
8643 int res;
8644 struct wpa_ctrl *ctrl;
8645 char buf[256];
8646
8647 if (sta_ap_known(ifname, bssid))
8648 return 0;
8649 sigma_dut_print(dut, DUT_MSG_DEBUG,
8650 "AP not in BSS table - start scan");
8651
8652 ctrl = open_wpa_mon(ifname);
8653 if (ctrl == NULL) {
8654 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
8655 "wpa_supplicant monitor connection");
8656 return -1;
8657 }
8658
8659 if (wpa_command(ifname, "SCAN") < 0) {
8660 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
8661 wpa_ctrl_detach(ctrl);
8662 wpa_ctrl_close(ctrl);
8663 return -1;
8664 }
8665
8666 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
8667 buf, sizeof(buf));
8668
8669 wpa_ctrl_detach(ctrl);
8670 wpa_ctrl_close(ctrl);
8671
8672 if (res < 0) {
8673 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
8674 return -1;
8675 }
8676
8677 if (sta_ap_known(ifname, bssid))
8678 return 0;
8679 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
8680 return -1;
8681}
8682
8683
8684static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
8685 struct sigma_conn *conn,
8686 struct sigma_cmd *cmd,
8687 const char *intf)
8688{
8689 char buf[200];
8690
8691 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
8692 if (system(buf) != 0) {
8693 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
8694 "ndsend");
8695 return 0;
8696 }
8697
8698 return 1;
8699}
8700
8701
8702static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
8703 struct sigma_conn *conn,
8704 struct sigma_cmd *cmd,
8705 const char *intf)
8706{
8707 char buf[200];
8708 const char *ip = get_param(cmd, "SenderIP");
8709
Peng Xu26b356d2017-10-04 17:58:16 -07008710 if (!ip)
8711 return 0;
8712
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008713 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
8714 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8715 if (system(buf) == 0) {
8716 sigma_dut_print(dut, DUT_MSG_INFO,
8717 "Neighbor Solicitation got a response "
8718 "for %s@%s", ip, intf);
8719 }
8720
8721 return 1;
8722}
8723
8724
8725static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
8726 struct sigma_conn *conn,
8727 struct sigma_cmd *cmd,
8728 const char *ifname)
8729{
8730 char buf[200];
8731 const char *ip = get_param(cmd, "SenderIP");
8732
8733 if (ip == NULL) {
8734 send_resp(dut, conn, SIGMA_ERROR,
8735 "ErrorCode,Missing SenderIP parameter");
8736 return 0;
8737 }
8738 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
8739 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8740 if (system(buf) != 0) {
8741 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
8742 "for %s@%s", ip, ifname);
8743 }
8744
8745 return 1;
8746}
8747
8748
8749static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
8750 struct sigma_conn *conn,
8751 struct sigma_cmd *cmd,
8752 const char *ifname)
8753{
8754 char buf[200];
8755 char ip[16];
8756 int s;
Peng Xub3756882017-10-04 14:39:09 -07008757 struct ifreq ifr;
8758 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008759
8760 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07008761 if (s < 0) {
8762 perror("socket");
8763 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008764 }
8765
Peng Xub3756882017-10-04 14:39:09 -07008766 memset(&ifr, 0, sizeof(ifr));
8767 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
8768 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
8769 sigma_dut_print(dut, DUT_MSG_INFO,
8770 "Failed to get %s IP address: %s",
8771 ifname, strerror(errno));
8772 close(s);
8773 return -1;
8774 }
8775 close(s);
8776
8777 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
8778 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
8779
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008780 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
8781 ip);
8782 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8783 if (system(buf) != 0) {
8784 }
8785
8786 return 1;
8787}
8788
8789
8790static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
8791 struct sigma_conn *conn,
8792 struct sigma_cmd *cmd,
8793 const char *ifname)
8794{
8795 char buf[200], addr[20];
8796 char dst[ETH_ALEN], src[ETH_ALEN];
8797 short ethtype = htons(ETH_P_ARP);
8798 char *pos;
8799 int s, res;
8800 const char *val;
8801 struct sockaddr_in taddr;
8802
8803 val = get_param(cmd, "dest");
8804 if (val)
8805 hwaddr_aton(val, (unsigned char *) dst);
8806
8807 val = get_param(cmd, "DestIP");
8808 if (val)
8809 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07008810 else
8811 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008812
8813 if (get_wpa_status(get_station_ifname(), "address", addr,
8814 sizeof(addr)) < 0)
8815 return -2;
8816 hwaddr_aton(addr, (unsigned char *) src);
8817
8818 pos = buf;
8819 *pos++ = 0x00;
8820 *pos++ = 0x01;
8821 *pos++ = 0x08;
8822 *pos++ = 0x00;
8823 *pos++ = 0x06;
8824 *pos++ = 0x04;
8825 *pos++ = 0x00;
8826 *pos++ = 0x02;
8827 memcpy(pos, src, ETH_ALEN);
8828 pos += ETH_ALEN;
8829 memcpy(pos, &taddr.sin_addr, 4);
8830 pos += 4;
8831 memcpy(pos, dst, ETH_ALEN);
8832 pos += ETH_ALEN;
8833 memcpy(pos, &taddr.sin_addr, 4);
8834 pos += 4;
8835
8836 s = open_monitor(get_station_ifname());
8837 if (s < 0) {
8838 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
8839 "monitor socket");
8840 return 0;
8841 }
8842
8843 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
8844 if (res < 0) {
8845 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
8846 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308847 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008848 return 0;
8849 }
8850
8851 close(s);
8852
8853 return 1;
8854}
8855
8856
8857static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
8858 struct sigma_conn *conn,
8859 struct sigma_cmd *cmd,
8860 const char *intf, const char *dest)
8861{
8862 char buf[100];
8863
8864 if (if_nametoindex("sigmadut") == 0) {
8865 snprintf(buf, sizeof(buf),
8866 "iw dev %s interface add sigmadut type monitor",
8867 get_station_ifname());
8868 if (system(buf) != 0 ||
8869 if_nametoindex("sigmadut") == 0) {
8870 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
8871 "monitor interface with '%s'", buf);
8872 return -2;
8873 }
8874 }
8875
8876 if (system("ifconfig sigmadut up") != 0) {
8877 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
8878 "monitor interface up");
8879 return -2;
8880 }
8881
8882 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
8883}
8884
8885
8886static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
8887 struct sigma_conn *conn,
8888 struct sigma_cmd *cmd)
8889{
8890 const char *intf = get_param(cmd, "Interface");
8891 const char *dest = get_param(cmd, "Dest");
8892 const char *type = get_param(cmd, "FrameName");
8893 const char *val;
8894 char buf[200], *pos, *end;
8895 int count, count2;
8896
8897 if (type == NULL)
8898 type = get_param(cmd, "Type");
8899
8900 if (intf == NULL || dest == NULL || type == NULL)
8901 return -1;
8902
8903 if (strcasecmp(type, "NeighAdv") == 0)
8904 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
8905
8906 if (strcasecmp(type, "NeighSolicitReq") == 0)
8907 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
8908
8909 if (strcasecmp(type, "ARPProbe") == 0)
8910 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
8911
8912 if (strcasecmp(type, "ARPAnnounce") == 0)
8913 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
8914
8915 if (strcasecmp(type, "ARPReply") == 0)
8916 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
8917
8918 if (strcasecmp(type, "DLS-request") == 0 ||
8919 strcasecmp(type, "DLSrequest") == 0)
8920 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
8921 dest);
8922
8923 if (strcasecmp(type, "ANQPQuery") != 0 &&
8924 strcasecmp(type, "Query") != 0) {
8925 send_resp(dut, conn, SIGMA_ERROR,
8926 "ErrorCode,Unsupported HS 2.0 send frame type");
8927 return 0;
8928 }
8929
8930 if (sta_scan_ap(dut, intf, dest) < 0) {
8931 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
8932 "the requested AP");
8933 return 0;
8934 }
8935
8936 pos = buf;
8937 end = buf + sizeof(buf);
8938 count = 0;
8939 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
8940
8941 val = get_param(cmd, "ANQP_CAP_LIST");
8942 if (val && atoi(val)) {
8943 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
8944 count++;
8945 }
8946
8947 val = get_param(cmd, "VENUE_NAME");
8948 if (val && atoi(val)) {
8949 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
8950 count++;
8951 }
8952
8953 val = get_param(cmd, "NETWORK_AUTH_TYPE");
8954 if (val && atoi(val)) {
8955 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
8956 count++;
8957 }
8958
8959 val = get_param(cmd, "ROAMING_CONS");
8960 if (val && atoi(val)) {
8961 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
8962 count++;
8963 }
8964
8965 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
8966 if (val && atoi(val)) {
8967 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
8968 count++;
8969 }
8970
8971 val = get_param(cmd, "NAI_REALM_LIST");
8972 if (val && atoi(val)) {
8973 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
8974 count++;
8975 }
8976
8977 val = get_param(cmd, "3GPP_INFO");
8978 if (val && atoi(val)) {
8979 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
8980 count++;
8981 }
8982
8983 val = get_param(cmd, "DOMAIN_LIST");
8984 if (val && atoi(val)) {
8985 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
8986 count++;
8987 }
8988
Jouni Malinen34cf9532018-04-29 19:26:33 +03008989 val = get_param(cmd, "Venue_URL");
8990 if (val && atoi(val)) {
8991 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
8992 count++;
8993 }
8994
Jouni Malinend3bca5d2018-04-29 17:25:23 +03008995 val = get_param(cmd, "Advice_Of_Charge");
8996 if (val && atoi(val)) {
8997 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
8998 count++;
8999 }
9000
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009001 if (count && wpa_command(intf, buf)) {
9002 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
9003 return 0;
9004 }
9005
9006 pos = buf;
9007 end = buf + sizeof(buf);
9008 count2 = 0;
9009 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
9010
9011 val = get_param(cmd, "HS_CAP_LIST");
9012 if (val && atoi(val)) {
9013 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
9014 count2++;
9015 }
9016
9017 val = get_param(cmd, "OPER_NAME");
9018 if (val && atoi(val)) {
9019 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
9020 count2++;
9021 }
9022
9023 val = get_param(cmd, "WAN_METRICS");
9024 if (!val)
9025 val = get_param(cmd, "WAN_MAT");
9026 if (!val)
9027 val = get_param(cmd, "WAN_MET");
9028 if (val && atoi(val)) {
9029 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
9030 count2++;
9031 }
9032
9033 val = get_param(cmd, "CONNECTION_CAPABILITY");
9034 if (val && atoi(val)) {
9035 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
9036 count2++;
9037 }
9038
9039 val = get_param(cmd, "OP_CLASS");
9040 if (val && atoi(val)) {
9041 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
9042 count2++;
9043 }
9044
9045 val = get_param(cmd, "OSU_PROVIDER_LIST");
9046 if (val && atoi(val)) {
9047 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
9048 count2++;
9049 }
9050
Jouni Malinenf67afec2018-04-29 19:24:58 +03009051 val = get_param(cmd, "OPER_ICON_METADATA");
9052 if (!val)
9053 val = get_param(cmd, "OPERATOR_ICON_METADATA");
9054 if (val && atoi(val)) {
9055 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
9056 count2++;
9057 }
9058
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009059 if (count && count2) {
9060 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
9061 "second query");
9062 sleep(1);
9063 }
9064
9065 if (count2 && wpa_command(intf, buf)) {
9066 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
9067 "failed");
9068 return 0;
9069 }
9070
9071 val = get_param(cmd, "NAI_HOME_REALM_LIST");
9072 if (val) {
9073 if (count || count2) {
9074 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9075 "sending out second query");
9076 sleep(1);
9077 }
9078
9079 if (strcmp(val, "1") == 0)
9080 val = "mail.example.com";
9081 snprintf(buf, end - pos,
9082 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
9083 dest, val);
9084 if (wpa_command(intf, buf)) {
9085 send_resp(dut, conn, SIGMA_ERROR,
9086 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
9087 "failed");
9088 return 0;
9089 }
9090 }
9091
9092 val = get_param(cmd, "ICON_REQUEST");
9093 if (val) {
9094 if (count || count2) {
9095 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9096 "sending out second query");
9097 sleep(1);
9098 }
9099
9100 snprintf(buf, end - pos,
9101 "HS20_ICON_REQUEST %s %s", dest, val);
9102 if (wpa_command(intf, buf)) {
9103 send_resp(dut, conn, SIGMA_ERROR,
9104 "ErrorCode,HS20_ICON_REQUEST failed");
9105 return 0;
9106 }
9107 }
9108
9109 return 1;
9110}
9111
9112
9113static int ath_sta_send_frame_vht(struct sigma_dut *dut,
9114 struct sigma_conn *conn,
9115 struct sigma_cmd *cmd)
9116{
9117 const char *val;
9118 char *ifname;
9119 char buf[100];
9120 int chwidth, nss;
9121
9122 val = get_param(cmd, "framename");
9123 if (!val)
9124 return -1;
9125 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9126
9127 /* Command sequence to generate Op mode notification */
9128 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
9129 ifname = get_station_ifname();
9130
9131 /* Disable STBC */
9132 snprintf(buf, sizeof(buf),
9133 "iwpriv %s tx_stbc 0", ifname);
9134 if (system(buf) != 0) {
9135 sigma_dut_print(dut, DUT_MSG_ERROR,
9136 "iwpriv tx_stbc 0 failed!");
9137 }
9138
9139 /* Extract Channel width */
9140 val = get_param(cmd, "Channel_width");
9141 if (val) {
9142 switch (atoi(val)) {
9143 case 20:
9144 chwidth = 0;
9145 break;
9146 case 40:
9147 chwidth = 1;
9148 break;
9149 case 80:
9150 chwidth = 2;
9151 break;
9152 case 160:
9153 chwidth = 3;
9154 break;
9155 default:
9156 chwidth = 2;
9157 break;
9158 }
9159
9160 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
9161 ifname, chwidth);
9162 if (system(buf) != 0) {
9163 sigma_dut_print(dut, DUT_MSG_ERROR,
9164 "iwpriv chwidth failed!");
9165 }
9166 }
9167
9168 /* Extract NSS */
9169 val = get_param(cmd, "NSS");
9170 if (val) {
9171 switch (atoi(val)) {
9172 case 1:
9173 nss = 1;
9174 break;
9175 case 2:
9176 nss = 3;
9177 break;
9178 case 3:
9179 nss = 7;
9180 break;
9181 default:
9182 /* We do not support NSS > 3 */
9183 nss = 3;
9184 break;
9185 }
9186 snprintf(buf, sizeof(buf),
9187 "iwpriv %s rxchainmask %d", ifname, nss);
9188 if (system(buf) != 0) {
9189 sigma_dut_print(dut, DUT_MSG_ERROR,
9190 "iwpriv rxchainmask failed!");
9191 }
9192 }
9193
9194 /* Opmode notify */
9195 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
9196 if (system(buf) != 0) {
9197 sigma_dut_print(dut, DUT_MSG_ERROR,
9198 "iwpriv opmode_notify failed!");
9199 } else {
9200 sigma_dut_print(dut, DUT_MSG_INFO,
9201 "Sent out the notify frame!");
9202 }
9203 }
9204
9205 return 1;
9206}
9207
9208
9209static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
9210 struct sigma_conn *conn,
9211 struct sigma_cmd *cmd)
9212{
9213 switch (get_driver_type()) {
9214 case DRIVER_ATHEROS:
9215 return ath_sta_send_frame_vht(dut, conn, cmd);
9216 default:
9217 send_resp(dut, conn, SIGMA_ERROR,
9218 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
9219 return 0;
9220 }
9221}
9222
9223
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009224static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
9225 struct sigma_cmd *cmd)
9226{
9227 const char *val;
9228 const char *intf = get_param(cmd, "Interface");
9229
9230 val = get_param(cmd, "framename");
9231 if (!val)
9232 return -1;
9233 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9234
9235 /* Command sequence to generate Op mode notification */
9236 if (val && strcasecmp(val, "action") == 0) {
9237 val = get_param(cmd, "PPDUTxType");
9238 if (val && strcasecmp(val, "TB") == 0) {
9239 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
9240 sigma_dut_print(dut, DUT_MSG_ERROR,
9241 "failed to send TB PPDU Tx cfg");
9242 send_resp(dut, conn, SIGMA_ERROR,
9243 "ErrorCode,set TB PPDU Tx cfg failed");
9244 return 0;
9245 }
9246 return 1;
9247 }
9248
9249 sigma_dut_print(dut, DUT_MSG_ERROR,
9250 "Action Tx type is not defined");
9251 }
9252
9253 return 1;
9254}
9255
9256
9257static int cmd_sta_send_frame_he(struct sigma_dut *dut,
9258 struct sigma_conn *conn,
9259 struct sigma_cmd *cmd)
9260{
9261 switch (get_driver_type()) {
9262 case DRIVER_WCN:
9263 return wcn_sta_send_frame_he(dut, conn, cmd);
9264 default:
9265 send_resp(dut, conn, SIGMA_ERROR,
9266 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
9267 return 0;
9268 }
9269}
9270
9271
Lior David0fe101e2017-03-09 16:09:50 +02009272#ifdef __linux__
9273int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9274 struct sigma_cmd *cmd)
9275{
9276 const char *frame_name = get_param(cmd, "framename");
9277 const char *mac = get_param(cmd, "dest_mac");
9278
9279 if (!frame_name || !mac) {
9280 sigma_dut_print(dut, DUT_MSG_ERROR,
9281 "framename and dest_mac must be provided");
9282 return -1;
9283 }
9284
9285 if (strcasecmp(frame_name, "brp") == 0) {
9286 const char *l_rx = get_param(cmd, "L-RX");
9287 int l_rx_i;
9288
9289 if (!l_rx) {
9290 sigma_dut_print(dut, DUT_MSG_ERROR,
9291 "L-RX must be provided");
9292 return -1;
9293 }
9294 l_rx_i = atoi(l_rx);
9295
9296 sigma_dut_print(dut, DUT_MSG_INFO,
9297 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
9298 mac, l_rx);
9299 if (l_rx_i != 16) {
9300 sigma_dut_print(dut, DUT_MSG_ERROR,
9301 "unsupported L-RX: %s", l_rx);
9302 return -1;
9303 }
9304
9305 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
9306 return -1;
9307 } else if (strcasecmp(frame_name, "ssw") == 0) {
9308 sigma_dut_print(dut, DUT_MSG_INFO,
9309 "dev_send_frame: SLS, dest_mac %s", mac);
9310 if (wil6210_send_sls(dut, mac))
9311 return -1;
9312 } else {
9313 sigma_dut_print(dut, DUT_MSG_ERROR,
9314 "unsupported frame type: %s", frame_name);
9315 return -1;
9316 }
9317
9318 return 1;
9319}
9320#endif /* __linux__ */
9321
9322
9323static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
9324 struct sigma_conn *conn,
9325 struct sigma_cmd *cmd)
9326{
9327 switch (get_driver_type()) {
9328#ifdef __linux__
9329 case DRIVER_WIL6210:
9330 return wil6210_send_frame_60g(dut, conn, cmd);
9331#endif /* __linux__ */
9332 default:
9333 send_resp(dut, conn, SIGMA_ERROR,
9334 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
9335 return 0;
9336 }
9337}
9338
9339
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309340static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
9341 const char *intf, struct sigma_cmd *cmd)
9342{
9343 const char *val, *addr;
9344 char buf[100];
9345
9346 addr = get_param(cmd, "DestMac");
9347 if (!addr) {
9348 send_resp(dut, conn, SIGMA_INVALID,
9349 "ErrorCode,AP MAC address is missing");
9350 return 0;
9351 }
9352
9353 val = get_param(cmd, "ANQPQuery_ID");
9354 if (!val) {
9355 send_resp(dut, conn, SIGMA_INVALID,
9356 "ErrorCode,Missing ANQPQuery_ID");
9357 return 0;
9358 }
9359
9360 if (strcasecmp(val, "NeighborReportReq") == 0) {
9361 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
9362 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
9363 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
9364 } else {
9365 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
9366 val);
9367 send_resp(dut, conn, SIGMA_INVALID,
9368 "ErrorCode,Invalid ANQPQuery_ID");
9369 return 0;
9370 }
9371
Ashwini Patild174f2c2017-04-13 16:49:46 +05309372 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
9373 * (Address3 = Wildcard BSSID when sent to not-associated AP;
9374 * if associated, AP BSSID).
9375 */
9376 if (wpa_command(intf, "SET gas_address3 1") < 0) {
9377 send_resp(dut, conn, SIGMA_ERROR,
9378 "ErrorCode,Failed to set gas_address3");
9379 return 0;
9380 }
9381
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309382 if (wpa_command(intf, buf) < 0) {
9383 send_resp(dut, conn, SIGMA_ERROR,
9384 "ErrorCode,Failed to send ANQP query");
9385 return 0;
9386 }
9387
9388 return 1;
9389}
9390
9391
9392static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
9393 struct sigma_conn *conn,
9394 const char *intf,
9395 struct sigma_cmd *cmd)
9396{
9397 const char *val = get_param(cmd, "FrameName");
9398
9399 if (val && strcasecmp(val, "ANQPQuery") == 0)
9400 return mbo_send_anqp_query(dut, conn, intf, cmd);
9401
9402 return 2;
9403}
9404
9405
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009406int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9407 struct sigma_cmd *cmd)
9408{
9409 const char *intf = get_param(cmd, "Interface");
9410 const char *val;
9411 enum send_frame_type frame;
9412 enum send_frame_protection protected;
9413 char buf[100];
9414 unsigned char addr[ETH_ALEN];
9415 int res;
9416
9417 val = get_param(cmd, "program");
9418 if (val == NULL)
9419 val = get_param(cmd, "frame");
9420 if (val && strcasecmp(val, "TDLS") == 0)
9421 return cmd_sta_send_frame_tdls(dut, conn, cmd);
9422 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +03009423 strcasecmp(val, "HS2-R2") == 0 ||
9424 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009425 return cmd_sta_send_frame_hs2(dut, conn, cmd);
9426 if (val && strcasecmp(val, "VHT") == 0)
9427 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009428 if (val && strcasecmp(val, "HE") == 0)
9429 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009430 if (val && strcasecmp(val, "LOC") == 0)
9431 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +02009432 if (val && strcasecmp(val, "60GHz") == 0)
9433 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309434 if (val && strcasecmp(val, "MBO") == 0) {
9435 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
9436 if (res != 2)
9437 return res;
9438 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009439
9440 val = get_param(cmd, "TD_DISC");
9441 if (val) {
9442 if (hwaddr_aton(val, addr) < 0)
9443 return -1;
9444 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
9445 if (wpa_command(intf, buf) < 0) {
9446 send_resp(dut, conn, SIGMA_ERROR,
9447 "ErrorCode,Failed to send TDLS discovery");
9448 return 0;
9449 }
9450 return 1;
9451 }
9452
9453 val = get_param(cmd, "TD_Setup");
9454 if (val) {
9455 if (hwaddr_aton(val, addr) < 0)
9456 return -1;
9457 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
9458 if (wpa_command(intf, buf) < 0) {
9459 send_resp(dut, conn, SIGMA_ERROR,
9460 "ErrorCode,Failed to start TDLS setup");
9461 return 0;
9462 }
9463 return 1;
9464 }
9465
9466 val = get_param(cmd, "TD_TearDown");
9467 if (val) {
9468 if (hwaddr_aton(val, addr) < 0)
9469 return -1;
9470 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
9471 if (wpa_command(intf, buf) < 0) {
9472 send_resp(dut, conn, SIGMA_ERROR,
9473 "ErrorCode,Failed to tear down TDLS link");
9474 return 0;
9475 }
9476 return 1;
9477 }
9478
9479 val = get_param(cmd, "TD_ChannelSwitch");
9480 if (val) {
9481 /* TODO */
9482 send_resp(dut, conn, SIGMA_ERROR,
9483 "ErrorCode,TD_ChannelSwitch not yet supported");
9484 return 0;
9485 }
9486
9487 val = get_param(cmd, "TD_NF");
9488 if (val) {
9489 /* TODO */
9490 send_resp(dut, conn, SIGMA_ERROR,
9491 "ErrorCode,TD_NF not yet supported");
9492 return 0;
9493 }
9494
9495 val = get_param(cmd, "PMFFrameType");
9496 if (val == NULL)
9497 val = get_param(cmd, "FrameName");
9498 if (val == NULL)
9499 val = get_param(cmd, "Type");
9500 if (val == NULL)
9501 return -1;
9502 if (strcasecmp(val, "disassoc") == 0)
9503 frame = DISASSOC;
9504 else if (strcasecmp(val, "deauth") == 0)
9505 frame = DEAUTH;
9506 else if (strcasecmp(val, "saquery") == 0)
9507 frame = SAQUERY;
9508 else if (strcasecmp(val, "auth") == 0)
9509 frame = AUTH;
9510 else if (strcasecmp(val, "assocreq") == 0)
9511 frame = ASSOCREQ;
9512 else if (strcasecmp(val, "reassocreq") == 0)
9513 frame = REASSOCREQ;
9514 else if (strcasecmp(val, "neigreq") == 0) {
9515 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
9516
9517 val = get_param(cmd, "ssid");
9518 if (val == NULL)
9519 return -1;
9520
9521 res = send_neighbor_request(dut, intf, val);
9522 if (res) {
9523 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9524 "Failed to send neighbor report request");
9525 return 0;
9526 }
9527
9528 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309529 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
9530 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009531 sigma_dut_print(dut, DUT_MSG_DEBUG,
9532 "Got Transition Management Query");
9533
Ashwini Patil5acd7382017-04-13 15:55:04 +05309534 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009535 if (res) {
9536 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9537 "Failed to send Transition Management Query");
9538 return 0;
9539 }
9540
9541 return 1;
9542 } else {
9543 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9544 "PMFFrameType");
9545 return 0;
9546 }
9547
9548 val = get_param(cmd, "PMFProtected");
9549 if (val == NULL)
9550 val = get_param(cmd, "Protected");
9551 if (val == NULL)
9552 return -1;
9553 if (strcasecmp(val, "Correct-key") == 0 ||
9554 strcasecmp(val, "CorrectKey") == 0)
9555 protected = CORRECT_KEY;
9556 else if (strcasecmp(val, "IncorrectKey") == 0)
9557 protected = INCORRECT_KEY;
9558 else if (strcasecmp(val, "Unprotected") == 0)
9559 protected = UNPROTECTED;
9560 else {
9561 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9562 "PMFProtected");
9563 return 0;
9564 }
9565
9566 if (protected != UNPROTECTED &&
9567 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
9568 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
9569 "PMFProtected for auth/assocreq/reassocreq");
9570 return 0;
9571 }
9572
9573 if (if_nametoindex("sigmadut") == 0) {
9574 snprintf(buf, sizeof(buf),
9575 "iw dev %s interface add sigmadut type monitor",
9576 get_station_ifname());
9577 if (system(buf) != 0 ||
9578 if_nametoindex("sigmadut") == 0) {
9579 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9580 "monitor interface with '%s'", buf);
9581 return -2;
9582 }
9583 }
9584
9585 if (system("ifconfig sigmadut up") != 0) {
9586 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9587 "monitor interface up");
9588 return -2;
9589 }
9590
9591 return sta_inject_frame(dut, conn, frame, protected, NULL);
9592}
9593
9594
9595static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
9596 struct sigma_conn *conn,
9597 struct sigma_cmd *cmd,
9598 const char *ifname)
9599{
9600 char buf[200];
9601 const char *val;
9602
9603 val = get_param(cmd, "ClearARP");
9604 if (val && atoi(val) == 1) {
9605 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
9606 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9607 if (system(buf) != 0) {
9608 send_resp(dut, conn, SIGMA_ERROR,
9609 "errorCode,Failed to clear ARP cache");
9610 return 0;
9611 }
9612 }
9613
9614 return 1;
9615}
9616
9617
9618int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
9619 struct sigma_cmd *cmd)
9620{
9621 const char *intf = get_param(cmd, "Interface");
9622 const char *val;
9623
9624 if (intf == NULL)
9625 return -1;
9626
9627 val = get_param(cmd, "program");
9628 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +03009629 strcasecmp(val, "HS2-R2") == 0 ||
9630 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009631 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
9632
9633 return -1;
9634}
9635
9636
9637static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
9638 struct sigma_cmd *cmd)
9639{
9640 const char *intf = get_param(cmd, "Interface");
9641 const char *mac = get_param(cmd, "MAC");
9642
9643 if (intf == NULL || mac == NULL)
9644 return -1;
9645
9646 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
9647 "interface %s to %s", intf, mac);
9648
9649 if (dut->set_macaddr) {
9650 char buf[128];
9651 int res;
9652 if (strcasecmp(mac, "default") == 0) {
9653 res = snprintf(buf, sizeof(buf), "%s",
9654 dut->set_macaddr);
9655 dut->tmp_mac_addr = 0;
9656 } else {
9657 res = snprintf(buf, sizeof(buf), "%s %s",
9658 dut->set_macaddr, mac);
9659 dut->tmp_mac_addr = 1;
9660 }
9661 if (res < 0 || res >= (int) sizeof(buf))
9662 return -1;
9663 if (system(buf) != 0) {
9664 send_resp(dut, conn, SIGMA_ERROR,
9665 "errorCode,Failed to set MAC "
9666 "address");
9667 return 0;
9668 }
9669 return 1;
9670 }
9671
9672 if (strcasecmp(mac, "default") == 0)
9673 return 1;
9674
9675 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9676 "command");
9677 return 0;
9678}
9679
9680
9681static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
9682 struct sigma_conn *conn, const char *intf,
9683 int val)
9684{
9685 char buf[200];
9686 int res;
9687
9688 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
9689 intf, val);
9690 if (res < 0 || res >= (int) sizeof(buf))
9691 return -1;
9692 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9693 if (system(buf) != 0) {
9694 send_resp(dut, conn, SIGMA_ERROR,
9695 "errorCode,Failed to configure offchannel mode");
9696 return 0;
9697 }
9698
9699 return 1;
9700}
9701
9702
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009703static int off_chan_val(enum sec_ch_offset off)
9704{
9705 switch (off) {
9706 case SEC_CH_NO:
9707 return 0;
9708 case SEC_CH_40ABOVE:
9709 return 40;
9710 case SEC_CH_40BELOW:
9711 return -40;
9712 }
9713
9714 return 0;
9715}
9716
9717
9718static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
9719 const char *intf, int off_ch_num,
9720 enum sec_ch_offset sec)
9721{
9722 char buf[200];
9723 int res;
9724
9725 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
9726 intf, off_ch_num);
9727 if (res < 0 || res >= (int) sizeof(buf))
9728 return -1;
9729 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9730 if (system(buf) != 0) {
9731 send_resp(dut, conn, SIGMA_ERROR,
9732 "errorCode,Failed to set offchan");
9733 return 0;
9734 }
9735
9736 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
9737 intf, off_chan_val(sec));
9738 if (res < 0 || res >= (int) sizeof(buf))
9739 return -1;
9740 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9741 if (system(buf) != 0) {
9742 send_resp(dut, conn, SIGMA_ERROR,
9743 "errorCode,Failed to set sec chan offset");
9744 return 0;
9745 }
9746
9747 return 1;
9748}
9749
9750
9751static int tdls_set_offchannel_offset(struct sigma_dut *dut,
9752 struct sigma_conn *conn,
9753 const char *intf, int off_ch_num,
9754 enum sec_ch_offset sec)
9755{
9756 char buf[200];
9757 int res;
9758
9759 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
9760 off_ch_num);
9761 if (res < 0 || res >= (int) sizeof(buf))
9762 return -1;
9763 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9764
9765 if (wpa_command(intf, buf) < 0) {
9766 send_resp(dut, conn, SIGMA_ERROR,
9767 "ErrorCode,Failed to set offchan");
9768 return 0;
9769 }
9770 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
9771 off_chan_val(sec));
9772 if (res < 0 || res >= (int) sizeof(buf))
9773 return -1;
9774
9775 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9776
9777 if (wpa_command(intf, buf) < 0) {
9778 send_resp(dut, conn, SIGMA_ERROR,
9779 "ErrorCode,Failed to set sec chan offset");
9780 return 0;
9781 }
9782
9783 return 1;
9784}
9785
9786
9787static int tdls_set_offchannel_mode(struct sigma_dut *dut,
9788 struct sigma_conn *conn,
9789 const char *intf, int val)
9790{
9791 char buf[200];
9792 int res;
9793
9794 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
9795 val);
9796 if (res < 0 || res >= (int) sizeof(buf))
9797 return -1;
9798 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9799
9800 if (wpa_command(intf, buf) < 0) {
9801 send_resp(dut, conn, SIGMA_ERROR,
9802 "ErrorCode,Failed to configure offchannel mode");
9803 return 0;
9804 }
9805
9806 return 1;
9807}
9808
9809
9810static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
9811 struct sigma_conn *conn,
9812 struct sigma_cmd *cmd)
9813{
9814 const char *val;
9815 enum {
9816 CHSM_NOT_SET,
9817 CHSM_ENABLE,
9818 CHSM_DISABLE,
9819 CHSM_REJREQ,
9820 CHSM_UNSOLRESP
9821 } chsm = CHSM_NOT_SET;
9822 int off_ch_num = -1;
9823 enum sec_ch_offset sec_ch = SEC_CH_NO;
9824 int res;
9825
9826 val = get_param(cmd, "Uapsd");
9827 if (val) {
9828 char buf[100];
9829 if (strcasecmp(val, "Enable") == 0)
9830 snprintf(buf, sizeof(buf), "SET ps 99");
9831 else if (strcasecmp(val, "Disable") == 0)
9832 snprintf(buf, sizeof(buf), "SET ps 98");
9833 else {
9834 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9835 "Unsupported uapsd parameter value");
9836 return 0;
9837 }
9838 if (wpa_command(intf, buf)) {
9839 send_resp(dut, conn, SIGMA_ERROR,
9840 "ErrorCode,Failed to change U-APSD "
9841 "powersave mode");
9842 return 0;
9843 }
9844 }
9845
9846 val = get_param(cmd, "TPKTIMER");
9847 if (val && strcasecmp(val, "DISABLE") == 0) {
9848 if (wpa_command(intf, "SET tdls_testing 0x100")) {
9849 send_resp(dut, conn, SIGMA_ERROR,
9850 "ErrorCode,Failed to enable no TPK "
9851 "expiration test mode");
9852 return 0;
9853 }
9854 dut->no_tpk_expiration = 1;
9855 }
9856
9857 val = get_param(cmd, "ChSwitchMode");
9858 if (val) {
9859 if (strcasecmp(val, "Enable") == 0 ||
9860 strcasecmp(val, "Initiate") == 0)
9861 chsm = CHSM_ENABLE;
9862 else if (strcasecmp(val, "Disable") == 0 ||
9863 strcasecmp(val, "passive") == 0)
9864 chsm = CHSM_DISABLE;
9865 else if (strcasecmp(val, "RejReq") == 0)
9866 chsm = CHSM_REJREQ;
9867 else if (strcasecmp(val, "UnSolResp") == 0)
9868 chsm = CHSM_UNSOLRESP;
9869 else {
9870 send_resp(dut, conn, SIGMA_ERROR,
9871 "ErrorCode,Unknown ChSwitchMode value");
9872 return 0;
9873 }
9874 }
9875
9876 val = get_param(cmd, "OffChNum");
9877 if (val) {
9878 off_ch_num = atoi(val);
9879 if (off_ch_num == 0) {
9880 send_resp(dut, conn, SIGMA_ERROR,
9881 "ErrorCode,Invalid OffChNum");
9882 return 0;
9883 }
9884 }
9885
9886 val = get_param(cmd, "SecChOffset");
9887 if (val) {
9888 if (strcmp(val, "20") == 0)
9889 sec_ch = SEC_CH_NO;
9890 else if (strcasecmp(val, "40above") == 0)
9891 sec_ch = SEC_CH_40ABOVE;
9892 else if (strcasecmp(val, "40below") == 0)
9893 sec_ch = SEC_CH_40BELOW;
9894 else {
9895 send_resp(dut, conn, SIGMA_ERROR,
9896 "ErrorCode,Unknown SecChOffset value");
9897 return 0;
9898 }
9899 }
9900
9901 if (chsm == CHSM_NOT_SET) {
9902 /* no offchannel changes requested */
9903 return 1;
9904 }
9905
9906 if (strcmp(intf, get_main_ifname()) != 0 &&
9907 strcmp(intf, get_station_ifname()) != 0) {
9908 send_resp(dut, conn, SIGMA_ERROR,
9909 "ErrorCode,Unknown interface");
9910 return 0;
9911 }
9912
9913 switch (chsm) {
9914 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +03009915 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009916 break;
9917 case CHSM_ENABLE:
9918 if (off_ch_num < 0) {
9919 send_resp(dut, conn, SIGMA_ERROR,
9920 "ErrorCode,Missing OffChNum argument");
9921 return 0;
9922 }
9923 if (wifi_chip_type == DRIVER_WCN) {
9924 res = tdls_set_offchannel_offset(dut, conn, intf,
9925 off_ch_num, sec_ch);
9926 } else {
9927 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
9928 sec_ch);
9929 }
9930 if (res != 1)
9931 return res;
9932 if (wifi_chip_type == DRIVER_WCN)
9933 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
9934 else
9935 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
9936 break;
9937 case CHSM_DISABLE:
9938 if (wifi_chip_type == DRIVER_WCN)
9939 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
9940 else
9941 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
9942 break;
9943 case CHSM_REJREQ:
9944 if (wifi_chip_type == DRIVER_WCN)
9945 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
9946 else
9947 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
9948 break;
9949 case CHSM_UNSOLRESP:
9950 if (off_ch_num < 0) {
9951 send_resp(dut, conn, SIGMA_ERROR,
9952 "ErrorCode,Missing OffChNum argument");
9953 return 0;
9954 }
9955 if (wifi_chip_type == DRIVER_WCN) {
9956 res = tdls_set_offchannel_offset(dut, conn, intf,
9957 off_ch_num, sec_ch);
9958 } else {
9959 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
9960 sec_ch);
9961 }
9962 if (res != 1)
9963 return res;
9964 if (wifi_chip_type == DRIVER_WCN)
9965 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
9966 else
9967 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
9968 break;
9969 }
9970
9971 return res;
9972}
9973
9974
9975static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
9976 struct sigma_conn *conn,
9977 struct sigma_cmd *cmd)
9978{
9979 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +05309980 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009981
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08009982 novap_reset(dut, intf);
9983
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009984 val = get_param(cmd, "nss_mcs_opt");
9985 if (val) {
9986 /* String (nss_operating_mode; mcs_operating_mode) */
9987 int nss, mcs;
9988 char buf[50];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309989 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009990
9991 token = strdup(val);
9992 if (!token)
9993 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05309994 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +05309995 if (!result) {
9996 sigma_dut_print(dut, DUT_MSG_ERROR,
9997 "VHT NSS not specified");
9998 goto failed;
9999 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010000 if (strcasecmp(result, "def") != 0) {
10001 nss = atoi(result);
10002 if (nss == 4)
10003 ath_disable_txbf(dut, intf);
10004 snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
10005 intf, nss);
10006 if (system(buf) != 0) {
10007 sigma_dut_print(dut, DUT_MSG_ERROR,
10008 "iwpriv nss failed");
10009 goto failed;
10010 }
10011 }
10012
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010013 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053010014 if (!result) {
10015 sigma_dut_print(dut, DUT_MSG_ERROR,
10016 "VHT MCS not specified");
10017 goto failed;
10018 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010019 if (strcasecmp(result, "def") == 0) {
10020 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0",
10021 intf);
10022 if (system(buf) != 0) {
10023 sigma_dut_print(dut, DUT_MSG_ERROR,
10024 "iwpriv set11NRates failed");
10025 goto failed;
10026 }
10027
10028 } else {
10029 mcs = atoi(result);
10030 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
10031 intf, mcs);
10032 if (system(buf) != 0) {
10033 sigma_dut_print(dut, DUT_MSG_ERROR,
10034 "iwpriv vhtmcs failed");
10035 goto failed;
10036 }
10037 }
10038 /* Channel width gets messed up, fix this */
10039 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
10040 intf, dut->chwidth);
10041 if (system(buf) != 0) {
10042 sigma_dut_print(dut, DUT_MSG_ERROR,
10043 "iwpriv chwidth failed");
10044 }
10045 }
10046
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053010047 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010048 return 1;
10049failed:
10050 free(token);
10051 return 0;
10052}
10053
10054
10055static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10056 struct sigma_conn *conn,
10057 struct sigma_cmd *cmd)
10058{
10059 switch (get_driver_type()) {
10060 case DRIVER_ATHEROS:
10061 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
10062 default:
10063 send_resp(dut, conn, SIGMA_ERROR,
10064 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
10065 return 0;
10066 }
10067}
10068
10069
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010070static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
10071 struct sigma_conn *conn,
10072 struct sigma_cmd *cmd)
10073{
10074 const char *val;
10075 char *token = NULL, *result;
10076 char buf[60];
10077
10078 val = get_param(cmd, "nss_mcs_opt");
10079 if (val) {
10080 /* String (nss_operating_mode; mcs_operating_mode) */
10081 int nss, mcs, ratecode;
10082 char *saveptr;
10083
10084 token = strdup(val);
10085 if (!token)
10086 return -2;
10087
10088 result = strtok_r(token, ";", &saveptr);
10089 if (!result) {
10090 sigma_dut_print(dut, DUT_MSG_ERROR,
10091 "HE NSS not specified");
10092 goto failed;
10093 }
10094 nss = 1;
10095 if (strcasecmp(result, "def") != 0)
10096 nss = atoi(result);
10097
10098 result = strtok_r(NULL, ";", &saveptr);
10099 if (!result) {
10100 sigma_dut_print(dut, DUT_MSG_ERROR,
10101 "HE MCS not specified");
10102 goto failed;
10103 }
10104 mcs = 7;
10105 if (strcasecmp(result, "def") != 0)
10106 mcs = atoi(result);
10107
Arif Hussain557bf412018-05-25 17:29:36 -070010108 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010109 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070010110 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010111 } else if (nss > 2) {
10112 sigma_dut_print(dut, DUT_MSG_ERROR,
10113 "HE NSS %d not supported", nss);
10114 goto failed;
10115 }
10116
Arif Hussain557bf412018-05-25 17:29:36 -070010117 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
10118 if (system(buf) != 0) {
10119 sigma_dut_print(dut, DUT_MSG_ERROR,
10120 "nss_mcs_opt: iwpriv %s nss %d failed",
10121 intf, nss);
10122 goto failed;
10123 }
Arif Hussainac6c5112018-05-25 17:34:00 -070010124 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070010125
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010126 /* Add the MCS to the ratecode */
10127 if (mcs >= 0 && mcs <= 11) {
10128 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070010129#ifdef NL80211_SUPPORT
10130 if (dut->device_type == STA_testbed) {
10131 enum he_mcs_config mcs_config;
10132 int ret;
10133
10134 if (mcs <= 7)
10135 mcs_config = HE_80_MCS0_7;
10136 else if (mcs <= 9)
10137 mcs_config = HE_80_MCS0_9;
10138 else
10139 mcs_config = HE_80_MCS0_11;
10140 ret = sta_set_he_mcs(dut, intf, mcs_config);
10141 if (ret) {
10142 sigma_dut_print(dut, DUT_MSG_ERROR,
10143 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10144 mcs, mcs_config, ret);
10145 goto failed;
10146 }
10147 }
10148#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010149 } else {
10150 sigma_dut_print(dut, DUT_MSG_ERROR,
10151 "HE MCS %d not supported", mcs);
10152 goto failed;
10153 }
10154 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
10155 intf, ratecode);
10156 if (system(buf) != 0) {
10157 sigma_dut_print(dut, DUT_MSG_ERROR,
10158 "iwpriv setting of 11ax rates failed");
10159 goto failed;
10160 }
10161 free(token);
10162 }
10163
10164 val = get_param(cmd, "GI");
10165 if (val) {
10166 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010167 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010168 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010169 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
10170 intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010171 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010172 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
10173 intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010174 } else {
10175 send_resp(dut, conn, SIGMA_ERROR,
10176 "errorCode,GI value not supported");
10177 return 0;
10178 }
10179 if (system(buf) != 0) {
10180 send_resp(dut, conn, SIGMA_ERROR,
10181 "errorCode,Failed to set shortgi");
10182 return 0;
10183 }
10184 }
10185
Subhani Shaik8e7a3052018-04-24 14:03:00 -070010186 val = get_param(cmd, "LTF");
10187 if (val) {
10188#ifdef NL80211_SUPPORT
10189 if (strcmp(val, "3.2") == 0) {
10190 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
10191 } if (strcmp(val, "6.4") == 0) {
10192 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
10193 } else if (strcmp(val, "12.8") == 0) {
10194 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
10195 } else {
10196 send_resp(dut, conn, SIGMA_ERROR,
10197 "errorCode, LTF value not supported");
10198 return 0;
10199 }
10200#else /* NL80211_SUPPORT */
10201 sigma_dut_print(dut, DUT_MSG_ERROR,
10202 "LTF cannot be set without NL80211_SUPPORT defined");
10203 return -2;
10204#endif /* NL80211_SUPPORT */
10205 }
10206
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070010207 val = get_param(cmd, "TxSUPPDU");
10208 if (val) {
10209 int set_val = 1;
10210
10211 if (strcasecmp(val, "Enable") == 0)
10212 set_val = 1;
10213 else if (strcasecmp(val, "Disable") == 0)
10214 set_val = 0;
10215
10216 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
10217 send_resp(dut, conn, SIGMA_ERROR,
10218 "ErrorCode,Failed to set Tx SU PPDU config");
10219 return 0;
10220 }
10221 }
10222
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070010223 val = get_param(cmd, "OMCtrl_RxNSS");
10224 if (val) {
10225 /*
10226 * OMCtrl_RxNSS uses the IEEE 802.11 standard values for Nss,
10227 * i.e., 0 for 1Nss, 1 for Nss 2, etc. The driver checks for
10228 * the actual Nss value hence add 1 to the set value.
10229 */
10230 int set_val = atoi(val) + 1;
10231
10232 if (sta_set_he_om_ctrl_nss(dut, intf, set_val)) {
10233 send_resp(dut, conn, SIGMA_ERROR,
10234 "ErrorCode,Failed to set OM ctrl NSS config");
10235 return 0;
10236 }
10237 }
10238
10239 val = get_param(cmd, "OMCtrl_ChnlWidth");
10240 if (val) {
10241 int set_val = atoi(val);
10242
10243 if (sta_set_he_om_ctrl_bw(dut, intf,
10244 (enum qca_wlan_he_om_ctrl_ch_bw)
10245 set_val)) {
10246 send_resp(dut, conn, SIGMA_ERROR,
10247 "ErrorCode,Failed to set OM ctrl BW config");
10248 return 0;
10249 }
10250 }
10251
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080010252 val = get_param(cmd, "Powersave");
10253 if (val) {
10254 char buf[60];
10255
10256 if (strcasecmp(val, "off") == 0) {
10257 snprintf(buf, sizeof(buf),
10258 "iwpriv %s setPower 2", intf);
10259 if (system(buf) != 0) {
10260 sigma_dut_print(dut, DUT_MSG_ERROR,
10261 "iwpriv setPower 2 failed");
10262 return 0;
10263 }
10264 } else if (strcasecmp(val, "on") == 0) {
10265 snprintf(buf, sizeof(buf),
10266 "iwpriv %s setPower 1", intf);
10267 if (system(buf) != 0) {
10268 sigma_dut_print(dut, DUT_MSG_ERROR,
10269 "iwpriv setPower 1 failed");
10270 return 0;
10271 }
10272 } else {
10273 sigma_dut_print(dut, DUT_MSG_ERROR,
10274 "Unsupported Powersave value '%s'",
10275 val);
10276 return -1;
10277 }
10278 }
10279
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010280 return 1;
10281
10282failed:
10283 free(token);
10284 return -2;
10285}
10286
10287
10288static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
10289 struct sigma_conn *conn,
10290 struct sigma_cmd *cmd)
10291{
10292 switch (get_driver_type()) {
10293 case DRIVER_WCN:
10294 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
10295 default:
10296 send_resp(dut, conn, SIGMA_ERROR,
10297 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
10298 return 0;
10299 }
10300}
10301
10302
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080010303static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
10304 struct sigma_conn *conn,
10305 struct sigma_cmd *cmd)
10306{
10307 const char *val;
10308
10309 val = get_param(cmd, "powersave");
10310 if (val) {
10311 char buf[60];
10312
10313 if (strcasecmp(val, "off") == 0) {
10314 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
10315 intf);
10316 if (system(buf) != 0) {
10317 sigma_dut_print(dut, DUT_MSG_ERROR,
10318 "iwpriv setPower 2 failed");
10319 return 0;
10320 }
10321 } else if (strcasecmp(val, "on") == 0) {
10322 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
10323 intf);
10324 if (system(buf) != 0) {
10325 sigma_dut_print(dut, DUT_MSG_ERROR,
10326 "iwpriv setPower 1 failed");
10327 return 0;
10328 }
10329 } else {
10330 sigma_dut_print(dut, DUT_MSG_ERROR,
10331 "Unsupported power save config");
10332 return -1;
10333 }
10334 return 1;
10335 }
10336
10337 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
10338
10339 return 0;
10340}
10341
10342
Ashwini Patil5acd7382017-04-13 15:55:04 +053010343static int btm_query_candidate_list(struct sigma_dut *dut,
10344 struct sigma_conn *conn,
10345 struct sigma_cmd *cmd)
10346{
10347 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
10348 int len, ret;
10349 char buf[10];
10350
10351 /*
10352 * Neighbor Report elements format:
10353 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
10354 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
10355 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
10356 */
10357
10358 bssid = get_param(cmd, "Nebor_BSSID");
10359 if (!bssid) {
10360 send_resp(dut, conn, SIGMA_INVALID,
10361 "errorCode,Nebor_BSSID is missing");
10362 return 0;
10363 }
10364
10365 info = get_param(cmd, "Nebor_Bssid_Info");
10366 if (!info) {
10367 sigma_dut_print(dut, DUT_MSG_INFO,
10368 "Using default value for Nebor_Bssid_Info: %s",
10369 DEFAULT_NEIGHBOR_BSSID_INFO);
10370 info = DEFAULT_NEIGHBOR_BSSID_INFO;
10371 }
10372
10373 op_class = get_param(cmd, "Nebor_Op_Class");
10374 if (!op_class) {
10375 send_resp(dut, conn, SIGMA_INVALID,
10376 "errorCode,Nebor_Op_Class is missing");
10377 return 0;
10378 }
10379
10380 ch = get_param(cmd, "Nebor_Op_Ch");
10381 if (!ch) {
10382 send_resp(dut, conn, SIGMA_INVALID,
10383 "errorCode,Nebor_Op_Ch is missing");
10384 return 0;
10385 }
10386
10387 phy_type = get_param(cmd, "Nebor_Phy_Type");
10388 if (!phy_type) {
10389 sigma_dut_print(dut, DUT_MSG_INFO,
10390 "Using default value for Nebor_Phy_Type: %s",
10391 DEFAULT_NEIGHBOR_PHY_TYPE);
10392 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
10393 }
10394
10395 /* Parse optional subelements */
10396 buf[0] = '\0';
10397 pref = get_param(cmd, "Nebor_Pref");
10398 if (pref) {
10399 /* hexdump for preferrence subelement */
10400 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
10401 if (ret < 0 || ret >= (int) sizeof(buf)) {
10402 sigma_dut_print(dut, DUT_MSG_ERROR,
10403 "snprintf failed for optional subelement ret: %d",
10404 ret);
10405 send_resp(dut, conn, SIGMA_ERROR,
10406 "errorCode,snprintf failed for subelement");
10407 return 0;
10408 }
10409 }
10410
10411 if (!dut->btm_query_cand_list) {
10412 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
10413 if (!dut->btm_query_cand_list) {
10414 send_resp(dut, conn, SIGMA_ERROR,
10415 "errorCode,Failed to allocate memory for btm_query_cand_list");
10416 return 0;
10417 }
10418 }
10419
10420 len = strlen(dut->btm_query_cand_list);
10421 ret = snprintf(dut->btm_query_cand_list + len,
10422 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
10423 bssid, info, op_class, ch, phy_type, buf);
10424 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
10425 sigma_dut_print(dut, DUT_MSG_ERROR,
10426 "snprintf failed for neighbor report list ret: %d",
10427 ret);
10428 send_resp(dut, conn, SIGMA_ERROR,
10429 "errorCode,snprintf failed for neighbor report");
10430 free(dut->btm_query_cand_list);
10431 dut->btm_query_cand_list = NULL;
10432 return 0;
10433 }
10434
10435 return 1;
10436}
10437
10438
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080010439static int cmd_sta_set_power_save(struct sigma_dut *dut,
10440 struct sigma_conn *conn,
10441 struct sigma_cmd *cmd)
10442{
10443 const char *intf = get_param(cmd, "interface");
10444 const char *prog = get_param(cmd, "program");
10445
10446 if (!intf || !prog)
10447 return -1;
10448
10449 if ((get_driver_type() == DRIVER_WCN) && (strcasecmp(prog, "HE") == 0))
10450 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
10451
10452 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
10453 return 0;
10454}
10455
10456
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010457static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
10458 struct sigma_cmd *cmd)
10459{
10460 const char *intf = get_param(cmd, "Interface");
10461 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010462 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010463
10464 if (intf == NULL || prog == NULL)
10465 return -1;
10466
Ashwini Patil5acd7382017-04-13 15:55:04 +053010467 /* BSS Transition candidate list for BTM query */
10468 val = get_param(cmd, "Nebor_BSSID");
10469 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
10470 return 0;
10471
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010472 if (strcasecmp(prog, "TDLS") == 0)
10473 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
10474
10475 if (strcasecmp(prog, "VHT") == 0)
10476 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
10477
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010478 if (strcasecmp(prog, "HE") == 0)
10479 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
10480
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010481 if (strcasecmp(prog, "MBO") == 0) {
10482 val = get_param(cmd, "Cellular_Data_Cap");
10483 if (val &&
10484 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
10485 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053010486
10487 val = get_param(cmd, "Ch_Pref");
10488 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
10489 return 0;
10490
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010491 return 1;
10492 }
10493
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010494 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
10495 return 0;
10496}
10497
10498
10499static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
10500 struct sigma_cmd *cmd)
10501{
10502 const char *intf = get_param(cmd, "Interface");
10503 const char *mode = get_param(cmd, "Mode");
10504 int res;
10505
10506 if (intf == NULL || mode == NULL)
10507 return -1;
10508
10509 if (strcasecmp(mode, "On") == 0)
10510 res = wpa_command(intf, "SET radio_disabled 0");
10511 else if (strcasecmp(mode, "Off") == 0)
10512 res = wpa_command(intf, "SET radio_disabled 1");
10513 else
10514 return -1;
10515
10516 if (res) {
10517 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
10518 "radio mode");
10519 return 0;
10520 }
10521
10522 return 1;
10523}
10524
10525
10526static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
10527 struct sigma_cmd *cmd)
10528{
10529 const char *intf = get_param(cmd, "Interface");
10530 const char *mode = get_param(cmd, "Mode");
10531 int res;
10532
10533 if (intf == NULL || mode == NULL)
10534 return -1;
10535
10536 if (strcasecmp(mode, "On") == 0)
10537 res = set_ps(intf, dut, 1);
10538 else if (strcasecmp(mode, "Off") == 0)
10539 res = set_ps(intf, dut, 0);
10540 else
10541 return -1;
10542
10543 if (res) {
10544 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
10545 "power save mode");
10546 return 0;
10547 }
10548
10549 return 1;
10550}
10551
10552
10553static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
10554 struct sigma_cmd *cmd)
10555{
10556 const char *intf = get_param(cmd, "Interface");
10557 const char *val, *bssid;
10558 int res;
10559 char *buf;
10560 size_t buf_len;
10561
10562 val = get_param(cmd, "BSSID_FILTER");
10563 if (val == NULL)
10564 return -1;
10565
10566 bssid = get_param(cmd, "BSSID_List");
10567 if (atoi(val) == 0 || bssid == NULL) {
10568 /* Disable BSSID filter */
10569 if (wpa_command(intf, "SET bssid_filter ")) {
10570 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
10571 "to disable BSSID filter");
10572 return 0;
10573 }
10574
10575 return 1;
10576 }
10577
10578 buf_len = 100 + strlen(bssid);
10579 buf = malloc(buf_len);
10580 if (buf == NULL)
10581 return -1;
10582
10583 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
10584 res = wpa_command(intf, buf);
10585 free(buf);
10586 if (res) {
10587 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
10588 "BSSID filter");
10589 return 0;
10590 }
10591
10592 return 1;
10593}
10594
10595
10596static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
10597 struct sigma_cmd *cmd)
10598{
10599 const char *intf = get_param(cmd, "Interface");
10600 const char *val;
10601
10602 /* TODO: ARP */
10603
10604 val = get_param(cmd, "HS2_CACHE_PROFILE");
10605 if (val && strcasecmp(val, "All") == 0)
10606 hs2_clear_credentials(intf);
10607
10608 return 1;
10609}
10610
10611
10612static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
10613 struct sigma_cmd *cmd)
10614{
10615 const char *intf = get_param(cmd, "Interface");
10616 const char *key_type = get_param(cmd, "KeyType");
10617 char buf[100], resp[200];
10618
10619 if (key_type == NULL)
10620 return -1;
10621
10622 if (strcasecmp(key_type, "GTK") == 0) {
10623 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
10624 strncmp(buf, "FAIL", 4) == 0) {
10625 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10626 "not fetch current GTK");
10627 return 0;
10628 }
10629 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
10630 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10631 return 0;
10632 } else {
10633 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10634 "KeyType");
10635 return 0;
10636 }
10637
10638 return 1;
10639}
10640
10641
10642static int hs2_set_policy(struct sigma_dut *dut)
10643{
10644#ifdef ANDROID
10645 system("ip rule del prio 23000");
10646 if (system("ip rule add from all lookup main prio 23000") != 0) {
10647 sigma_dut_print(dut, DUT_MSG_ERROR,
10648 "Failed to run:ip rule add from all lookup main prio");
10649 return -1;
10650 }
10651 if (system("ip route flush cache") != 0) {
10652 sigma_dut_print(dut, DUT_MSG_ERROR,
10653 "Failed to run ip route flush cache");
10654 return -1;
10655 }
10656 return 1;
10657#else /* ANDROID */
10658 return 0;
10659#endif /* ANDROID */
10660}
10661
10662
10663static int cmd_sta_hs2_associate(struct sigma_dut *dut,
10664 struct sigma_conn *conn,
10665 struct sigma_cmd *cmd)
10666{
10667 const char *intf = get_param(cmd, "Interface");
10668 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030010669 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010670 struct wpa_ctrl *ctrl;
10671 int res;
10672 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
10673 int tries = 0;
10674 int ignore_blacklist = 0;
10675 const char *events[] = {
10676 "CTRL-EVENT-CONNECTED",
10677 "INTERWORKING-BLACKLISTED",
10678 "INTERWORKING-NO-MATCH",
10679 NULL
10680 };
10681
10682 start_sta_mode(dut);
10683
Jouni Malinen439352d2018-09-13 03:42:23 +030010684 if (band) {
10685 if (strcmp(band, "2.4") == 0) {
10686 wpa_command(intf, "SET setband 2G");
10687 } else if (strcmp(band, "5") == 0) {
10688 wpa_command(intf, "SET setband 5G");
10689 } else {
10690 send_resp(dut, conn, SIGMA_ERROR,
10691 "errorCode,Unsupported band");
10692 return 0;
10693 }
10694 }
10695
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010696 blacklisted[0] = '\0';
10697 if (val && atoi(val))
10698 ignore_blacklist = 1;
10699
10700try_again:
10701 ctrl = open_wpa_mon(intf);
10702 if (ctrl == NULL) {
10703 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
10704 "wpa_supplicant monitor connection");
10705 return -2;
10706 }
10707
10708 tries++;
10709 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
10710 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
10711 "Interworking connection");
10712 wpa_ctrl_detach(ctrl);
10713 wpa_ctrl_close(ctrl);
10714 return 0;
10715 }
10716
10717 buf[0] = '\0';
10718 while (1) {
10719 char *pos;
10720 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
10721 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
10722 if (!pos)
10723 break;
10724 pos += 25;
10725 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
10726 pos);
10727 if (!blacklisted[0])
10728 memcpy(blacklisted, pos, strlen(pos) + 1);
10729 }
10730
10731 if (ignore_blacklist && blacklisted[0]) {
10732 char *end;
10733 end = strchr(blacklisted, ' ');
10734 if (end)
10735 *end = '\0';
10736 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
10737 blacklisted);
10738 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
10739 blacklisted);
10740 if (wpa_command(intf, buf)) {
10741 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
10742 wpa_ctrl_detach(ctrl);
10743 wpa_ctrl_close(ctrl);
10744 return 0;
10745 }
10746 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
10747 buf, sizeof(buf));
10748 }
10749
10750 wpa_ctrl_detach(ctrl);
10751 wpa_ctrl_close(ctrl);
10752
10753 if (res < 0) {
10754 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
10755 "connect");
10756 return 0;
10757 }
10758
10759 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
10760 strstr(buf, "INTERWORKING-BLACKLISTED")) {
10761 if (tries < 2) {
10762 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
10763 goto try_again;
10764 }
10765 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
10766 "matching credentials found");
10767 return 0;
10768 }
10769
10770 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
10771 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
10772 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
10773 "get current BSSID/SSID");
10774 return 0;
10775 }
10776
10777 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
10778 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10779 hs2_set_policy(dut);
10780 return 0;
10781}
10782
10783
Jouni Malinenb639f1c2018-09-13 02:39:46 +030010784static int cmd_sta_hs2_venue_info(struct sigma_dut *dut,
10785 struct sigma_conn *conn,
10786 struct sigma_cmd *cmd)
10787{
10788 const char *intf = get_param(cmd, "Interface");
10789 const char *display = get_param(cmd, "Display");
10790 struct wpa_ctrl *ctrl;
10791 char buf[300], params[400], *pos;
10792 char bssid[20];
10793 int info_avail = 0;
10794 unsigned int old_timeout;
10795 int res;
10796
10797 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
10798 send_resp(dut, conn, SIGMA_ERROR,
10799 "ErrorCode,Could not get current BSSID");
10800 return 0;
10801 }
10802 ctrl = open_wpa_mon(intf);
10803 if (!ctrl) {
10804 sigma_dut_print(dut, DUT_MSG_ERROR,
10805 "Failed to open wpa_supplicant monitor connection");
10806 return -2;
10807 }
10808
10809 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
10810 wpa_command(intf, buf);
10811
10812 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
10813 if (res < 0) {
10814 send_resp(dut, conn, SIGMA_ERROR,
10815 "ErrorCode,Could not complete GAS query");
10816 goto fail;
10817 }
10818
10819 old_timeout = dut->default_timeout;
10820 dut->default_timeout = 2;
10821 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
10822 dut->default_timeout = old_timeout;
10823 if (res < 0)
10824 goto done;
10825 pos = strchr(buf, ' ');
10826 if (!pos)
10827 goto done;
10828 pos++;
10829 pos = strchr(pos, ' ');
10830 if (!pos)
10831 goto done;
10832 pos++;
10833 info_avail = 1;
10834 snprintf(params, sizeof(params), "browser %s", pos);
10835
10836 if (display && strcasecmp(display, "Yes") == 0) {
10837 pid_t pid;
10838
10839 pid = fork();
10840 if (pid < 0) {
10841 perror("fork");
10842 return -1;
10843 }
10844
10845 if (pid == 0) {
10846 run_hs20_osu(dut, params);
10847 exit(0);
10848 }
10849 }
10850
10851done:
10852 snprintf(buf, sizeof(buf), "Info_available,%s",
10853 info_avail ? "Yes" : "No");
10854 send_resp(dut, conn, SIGMA_COMPLETE, buf);
10855fail:
10856 wpa_ctrl_detach(ctrl);
10857 wpa_ctrl_close(ctrl);
10858 return 0;
10859}
10860
10861
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010862static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
10863 struct sigma_conn *conn,
10864 const char *ifname,
10865 struct sigma_cmd *cmd)
10866{
10867 const char *val;
10868 int id;
10869
10870 id = add_cred(ifname);
10871 if (id < 0)
10872 return -2;
10873 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
10874
10875 val = get_param(cmd, "prefer");
10876 if (val && atoi(val) > 0)
10877 set_cred(ifname, id, "priority", "1");
10878
10879 val = get_param(cmd, "REALM");
10880 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
10881 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10882 "realm");
10883 return 0;
10884 }
10885
10886 val = get_param(cmd, "HOME_FQDN");
10887 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
10888 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10889 "home_fqdn");
10890 return 0;
10891 }
10892
10893 val = get_param(cmd, "Username");
10894 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
10895 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10896 "username");
10897 return 0;
10898 }
10899
10900 val = get_param(cmd, "Password");
10901 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
10902 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10903 "password");
10904 return 0;
10905 }
10906
10907 val = get_param(cmd, "ROOT_CA");
10908 if (val) {
10909 char fname[200];
10910 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
10911#ifdef __linux__
10912 if (!file_exists(fname)) {
10913 char msg[300];
10914 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
10915 "file (%s) not found", fname);
10916 send_resp(dut, conn, SIGMA_ERROR, msg);
10917 return 0;
10918 }
10919#endif /* __linux__ */
10920 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
10921 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10922 "not set root CA");
10923 return 0;
10924 }
10925 }
10926
10927 return 1;
10928}
10929
10930
10931static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
10932{
10933 FILE *in, *out;
10934 char buf[500];
10935 int found = 0;
10936
10937 in = fopen("devdetail.xml", "r");
10938 if (in == NULL)
10939 return -1;
10940 out = fopen("devdetail.xml.tmp", "w");
10941 if (out == NULL) {
10942 fclose(in);
10943 return -1;
10944 }
10945
10946 while (fgets(buf, sizeof(buf), in)) {
10947 char *pos = strstr(buf, "<IMSI>");
10948 if (pos) {
10949 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
10950 imsi);
10951 pos += 6;
10952 *pos = '\0';
10953 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
10954 found++;
10955 } else {
10956 fprintf(out, "%s", buf);
10957 }
10958 }
10959
10960 fclose(out);
10961 fclose(in);
10962 if (found)
10963 rename("devdetail.xml.tmp", "devdetail.xml");
10964 else
10965 unlink("devdetail.xml.tmp");
10966
10967 return 0;
10968}
10969
10970
10971static int sta_add_credential_sim(struct sigma_dut *dut,
10972 struct sigma_conn *conn,
10973 const char *ifname, struct sigma_cmd *cmd)
10974{
10975 const char *val, *imsi = NULL;
10976 int id;
10977 char buf[200];
10978 int res;
10979 const char *pos;
10980 size_t mnc_len;
10981 char plmn_mcc[4];
10982 char plmn_mnc[4];
10983
10984 id = add_cred(ifname);
10985 if (id < 0)
10986 return -2;
10987 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
10988
10989 val = get_param(cmd, "prefer");
10990 if (val && atoi(val) > 0)
10991 set_cred(ifname, id, "priority", "1");
10992
10993 val = get_param(cmd, "PLMN_MCC");
10994 if (val == NULL) {
10995 send_resp(dut, conn, SIGMA_ERROR,
10996 "errorCode,Missing PLMN_MCC");
10997 return 0;
10998 }
10999 if (strlen(val) != 3) {
11000 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
11001 return 0;
11002 }
11003 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
11004
11005 val = get_param(cmd, "PLMN_MNC");
11006 if (val == NULL) {
11007 send_resp(dut, conn, SIGMA_ERROR,
11008 "errorCode,Missing PLMN_MNC");
11009 return 0;
11010 }
11011 if (strlen(val) != 2 && strlen(val) != 3) {
11012 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
11013 return 0;
11014 }
11015 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
11016
11017 val = get_param(cmd, "IMSI");
11018 if (val == NULL) {
11019 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
11020 "IMSI");
11021 return 0;
11022 }
11023
11024 imsi = pos = val;
11025
11026 if (strncmp(plmn_mcc, pos, 3) != 0) {
11027 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
11028 return 0;
11029 }
11030 pos += 3;
11031
11032 mnc_len = strlen(plmn_mnc);
11033 if (mnc_len < 2) {
11034 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
11035 return 0;
11036 }
11037
11038 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
11039 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
11040 return 0;
11041 }
11042 pos += mnc_len;
11043
11044 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
11045 if (res < 0 || res >= (int) sizeof(buf))
11046 return -1;
11047 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
11048 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11049 "not set IMSI");
11050 return 0;
11051 }
11052
11053 val = get_param(cmd, "Password");
11054 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
11055 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11056 "not set password");
11057 return 0;
11058 }
11059
Jouni Malinenba630452018-06-22 11:49:59 +030011060 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011061 /*
11062 * Set provisioning_sp for the test cases where SIM/USIM
11063 * provisioning is used.
11064 */
11065 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
11066 "wi-fi.org") < 0) {
11067 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11068 "not set provisioning_sp");
11069 return 0;
11070 }
11071
11072 update_devdetail_imsi(dut, imsi);
11073 }
11074
11075 return 1;
11076}
11077
11078
11079static int sta_add_credential_cert(struct sigma_dut *dut,
11080 struct sigma_conn *conn,
11081 const char *ifname,
11082 struct sigma_cmd *cmd)
11083{
11084 const char *val;
11085 int id;
11086
11087 id = add_cred(ifname);
11088 if (id < 0)
11089 return -2;
11090 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
11091
11092 val = get_param(cmd, "prefer");
11093 if (val && atoi(val) > 0)
11094 set_cred(ifname, id, "priority", "1");
11095
11096 val = get_param(cmd, "REALM");
11097 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
11098 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11099 "realm");
11100 return 0;
11101 }
11102
11103 val = get_param(cmd, "HOME_FQDN");
11104 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
11105 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11106 "home_fqdn");
11107 return 0;
11108 }
11109
11110 val = get_param(cmd, "Username");
11111 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
11112 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11113 "username");
11114 return 0;
11115 }
11116
11117 val = get_param(cmd, "clientCertificate");
11118 if (val) {
11119 char fname[200];
11120 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
11121#ifdef __linux__
11122 if (!file_exists(fname)) {
11123 char msg[300];
11124 snprintf(msg, sizeof(msg),
11125 "ErrorCode,clientCertificate "
11126 "file (%s) not found", fname);
11127 send_resp(dut, conn, SIGMA_ERROR, msg);
11128 return 0;
11129 }
11130#endif /* __linux__ */
11131 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
11132 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11133 "not set client_cert");
11134 return 0;
11135 }
11136 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
11137 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11138 "not set private_key");
11139 return 0;
11140 }
11141 }
11142
11143 val = get_param(cmd, "ROOT_CA");
11144 if (val) {
11145 char fname[200];
11146 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
11147#ifdef __linux__
11148 if (!file_exists(fname)) {
11149 char msg[300];
11150 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
11151 "file (%s) not found", fname);
11152 send_resp(dut, conn, SIGMA_ERROR, msg);
11153 return 0;
11154 }
11155#endif /* __linux__ */
11156 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
11157 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11158 "not set root CA");
11159 return 0;
11160 }
11161 }
11162
11163 return 1;
11164}
11165
11166
11167static int cmd_sta_add_credential(struct sigma_dut *dut,
11168 struct sigma_conn *conn,
11169 struct sigma_cmd *cmd)
11170{
11171 const char *intf = get_param(cmd, "Interface");
11172 const char *type;
11173
11174 start_sta_mode(dut);
11175
11176 type = get_param(cmd, "Type");
11177 if (!type)
11178 return -1;
11179
11180 if (strcasecmp(type, "uname_pwd") == 0)
11181 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
11182
11183 if (strcasecmp(type, "sim") == 0)
11184 return sta_add_credential_sim(dut, conn, intf, cmd);
11185
11186 if (strcasecmp(type, "cert") == 0)
11187 return sta_add_credential_cert(dut, conn, intf, cmd);
11188
11189 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
11190 "type");
11191 return 0;
11192}
11193
11194
11195static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
11196 struct sigma_cmd *cmd)
11197{
11198 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053011199 const char *val, *bssid, *ssid;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011200 char buf[100];
vamsi krishna89ad8c62017-09-19 12:51:18 +053011201 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011202 int res;
11203
11204 val = get_param(cmd, "HESSID");
11205 if (val) {
11206 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
11207 if (res < 0 || res >= (int) sizeof(buf))
11208 return -1;
11209 wpa_command(intf, buf);
11210 }
11211
11212 val = get_param(cmd, "ACCS_NET_TYPE");
11213 if (val) {
11214 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
11215 val);
11216 if (res < 0 || res >= (int) sizeof(buf))
11217 return -1;
11218 wpa_command(intf, buf);
11219 }
11220
vamsi krishna89ad8c62017-09-19 12:51:18 +053011221 bssid = get_param(cmd, "Bssid");
11222 ssid = get_param(cmd, "Ssid");
11223
11224 if (ssid) {
11225 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
11226 send_resp(dut, conn, SIGMA_ERROR,
11227 "ErrorCode,Too long SSID");
11228 return 0;
11229 }
11230 ascii2hexstr(ssid, ssid_hex);
11231 }
11232
11233 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
11234 bssid ? " bssid=": "",
11235 bssid ? bssid : "",
11236 ssid ? " ssid " : "",
11237 ssid ? ssid_hex : "");
11238 if (res < 0 || res >= (int) sizeof(buf))
11239 return -1;
11240
11241 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011242 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
11243 "scan");
11244 return 0;
11245 }
11246
11247 return 1;
11248}
11249
11250
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020011251static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
11252 struct sigma_cmd *cmd)
11253{
11254 const char *intf = get_param(cmd, "Interface");
11255 const char *bssid;
11256 char buf[4096], *pos;
11257 int freq, chan;
11258 char *ssid;
11259 char resp[100];
11260 int res;
11261 struct wpa_ctrl *ctrl;
11262
11263 bssid = get_param(cmd, "BSSID");
11264 if (!bssid) {
11265 send_resp(dut, conn, SIGMA_INVALID,
11266 "errorCode,BSSID argument is missing");
11267 return 0;
11268 }
11269
11270 ctrl = open_wpa_mon(intf);
11271 if (!ctrl) {
11272 sigma_dut_print(dut, DUT_MSG_ERROR,
11273 "Failed to open wpa_supplicant monitor connection");
11274 return -1;
11275 }
11276
11277 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
11278 send_resp(dut, conn, SIGMA_ERROR,
11279 "errorCode,Could not start scan");
11280 wpa_ctrl_detach(ctrl);
11281 wpa_ctrl_close(ctrl);
11282 return 0;
11283 }
11284
11285 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
11286 buf, sizeof(buf));
11287
11288 wpa_ctrl_detach(ctrl);
11289 wpa_ctrl_close(ctrl);
11290
11291 if (res < 0) {
11292 send_resp(dut, conn, SIGMA_ERROR,
11293 "errorCode,Scan did not complete");
11294 return 0;
11295 }
11296
11297 snprintf(buf, sizeof(buf), "BSS %s", bssid);
11298 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
11299 strncmp(buf, "id=", 3) != 0) {
11300 send_resp(dut, conn, SIGMA_ERROR,
11301 "errorCode,Specified BSSID not found");
11302 return 0;
11303 }
11304
11305 pos = strstr(buf, "\nfreq=");
11306 if (!pos) {
11307 send_resp(dut, conn, SIGMA_ERROR,
11308 "errorCode,Channel not found");
11309 return 0;
11310 }
11311 freq = atoi(pos + 6);
11312 chan = freq_to_channel(freq);
11313
11314 pos = strstr(buf, "\nssid=");
11315 if (!pos) {
11316 send_resp(dut, conn, SIGMA_ERROR,
11317 "errorCode,SSID not found");
11318 return 0;
11319 }
11320 ssid = pos + 6;
11321 pos = strchr(ssid, '\n');
11322 if (pos)
11323 *pos = '\0';
11324 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
11325 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11326 return 0;
11327}
11328
11329
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011330static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
11331 struct sigma_cmd *cmd)
11332{
11333#ifdef __linux__
11334 struct timeval tv;
11335 struct tm tm;
11336 time_t t;
11337 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053011338 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011339
11340 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
11341
11342 memset(&tm, 0, sizeof(tm));
11343 val = get_param(cmd, "seconds");
11344 if (val)
11345 tm.tm_sec = atoi(val);
11346 val = get_param(cmd, "minutes");
11347 if (val)
11348 tm.tm_min = atoi(val);
11349 val = get_param(cmd, "hours");
11350 if (val)
11351 tm.tm_hour = atoi(val);
11352 val = get_param(cmd, "date");
11353 if (val)
11354 tm.tm_mday = atoi(val);
11355 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053011356 if (val) {
11357 v = atoi(val);
11358 if (v < 1 || v > 12) {
11359 send_resp(dut, conn, SIGMA_INVALID,
11360 "errorCode,Invalid month");
11361 return 0;
11362 }
11363 tm.tm_mon = v - 1;
11364 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011365 val = get_param(cmd, "year");
11366 if (val) {
11367 int year = atoi(val);
11368#ifdef ANDROID
11369 if (year > 2035)
11370 year = 2035; /* years beyond 2035 not supported */
11371#endif /* ANDROID */
11372 tm.tm_year = year - 1900;
11373 }
11374 t = mktime(&tm);
11375 if (t == (time_t) -1) {
11376 send_resp(dut, conn, SIGMA_ERROR,
11377 "errorCode,Invalid date or time");
11378 return 0;
11379 }
11380
11381 memset(&tv, 0, sizeof(tv));
11382 tv.tv_sec = t;
11383
11384 if (settimeofday(&tv, NULL) < 0) {
11385 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
11386 strerror(errno));
11387 send_resp(dut, conn, SIGMA_ERROR,
11388 "errorCode,Failed to set time");
11389 return 0;
11390 }
11391
11392 return 1;
11393#endif /* __linux__ */
11394
11395 return -1;
11396}
11397
11398
11399static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
11400 struct sigma_cmd *cmd)
11401{
11402 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011403 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011404 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011405 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011406 int res;
11407 struct wpa_ctrl *ctrl;
11408
11409 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011410 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011411
11412 val = get_param(cmd, "ProdESSAssoc");
11413 if (val)
11414 prod_ess_assoc = atoi(val);
11415
11416 kill_dhcp_client(dut, intf);
11417 if (start_dhcp_client(dut, intf) < 0)
11418 return -2;
11419
11420 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
11421 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
11422 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011423 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011424 prod_ess_assoc ? "" : "-N",
11425 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011426 name ? "'" : "",
11427 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
11428 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011429
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053011430 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011431 if (run_hs20_osu(dut, buf) < 0) {
11432 FILE *f;
11433
11434 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
11435
11436 f = fopen("hs20-osu-client.res", "r");
11437 if (f) {
11438 char resp[400], res[300], *pos;
11439 if (!fgets(res, sizeof(res), f))
11440 res[0] = '\0';
11441 pos = strchr(res, '\n');
11442 if (pos)
11443 *pos = '\0';
11444 fclose(f);
11445 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
11446 res);
11447 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
11448 if (system(resp) != 0) {
11449 }
11450 snprintf(resp, sizeof(resp),
11451 "SSID,,BSSID,,failureReason,%s", res);
11452 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11453 return 0;
11454 }
11455
11456 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11457 return 0;
11458 }
11459
11460 if (!prod_ess_assoc)
11461 goto report;
11462
11463 ctrl = open_wpa_mon(intf);
11464 if (ctrl == NULL) {
11465 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11466 "wpa_supplicant monitor connection");
11467 return -1;
11468 }
11469
11470 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
11471 buf, sizeof(buf));
11472
11473 wpa_ctrl_detach(ctrl);
11474 wpa_ctrl_close(ctrl);
11475
11476 if (res < 0) {
11477 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
11478 "network after OSU");
11479 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11480 return 0;
11481 }
11482
11483report:
11484 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
11485 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
11486 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
11487 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11488 return 0;
11489 }
11490
11491 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
11492 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011493 return 0;
11494}
11495
11496
11497static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
11498 struct sigma_cmd *cmd)
11499{
11500 const char *val;
11501 int timeout = 120;
11502
11503 val = get_param(cmd, "PolicyUpdate");
11504 if (val == NULL || atoi(val) == 0)
11505 return 1; /* No operation requested */
11506
11507 val = get_param(cmd, "Timeout");
11508 if (val)
11509 timeout = atoi(val);
11510
11511 if (timeout) {
11512 /* TODO: time out the command and return
11513 * PolicyUpdateStatus,TIMEOUT if needed. */
11514 }
11515
11516 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
11517 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
11518 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
11519 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
11520 return 0;
11521 }
11522
11523 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
11524 return 0;
11525}
11526
11527
11528static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
11529 struct sigma_cmd *cmd)
11530{
11531 struct wpa_ctrl *ctrl;
11532 const char *intf = get_param(cmd, "Interface");
11533 const char *bssid = get_param(cmd, "Bssid");
11534 const char *ssid = get_param(cmd, "SSID");
11535 const char *security = get_param(cmd, "Security");
11536 const char *passphrase = get_param(cmd, "Passphrase");
11537 const char *pin = get_param(cmd, "PIN");
11538 char buf[1000];
11539 char ssid_hex[200], passphrase_hex[200];
11540 const char *keymgmt, *cipher;
11541
11542 if (intf == NULL)
11543 intf = get_main_ifname();
11544
11545 if (!bssid) {
11546 send_resp(dut, conn, SIGMA_ERROR,
11547 "ErrorCode,Missing Bssid argument");
11548 return 0;
11549 }
11550
11551 if (!ssid) {
11552 send_resp(dut, conn, SIGMA_ERROR,
11553 "ErrorCode,Missing SSID argument");
11554 return 0;
11555 }
11556
11557 if (!security) {
11558 send_resp(dut, conn, SIGMA_ERROR,
11559 "ErrorCode,Missing Security argument");
11560 return 0;
11561 }
11562
11563 if (!passphrase) {
11564 send_resp(dut, conn, SIGMA_ERROR,
11565 "ErrorCode,Missing Passphrase argument");
11566 return 0;
11567 }
11568
11569 if (!pin) {
11570 send_resp(dut, conn, SIGMA_ERROR,
11571 "ErrorCode,Missing PIN argument");
11572 return 0;
11573 }
11574
vamsi krishna8c9c1562017-05-12 15:51:46 +053011575 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
11576 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011577 send_resp(dut, conn, SIGMA_ERROR,
11578 "ErrorCode,Too long SSID/passphrase");
11579 return 0;
11580 }
11581
11582 ctrl = open_wpa_mon(intf);
11583 if (ctrl == NULL) {
11584 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11585 "wpa_supplicant monitor connection");
11586 return -2;
11587 }
11588
11589 if (strcasecmp(security, "wpa2-psk") == 0) {
11590 keymgmt = "WPA2PSK";
11591 cipher = "CCMP";
11592 } else {
11593 wpa_ctrl_detach(ctrl);
11594 wpa_ctrl_close(ctrl);
11595 send_resp(dut, conn, SIGMA_ERROR,
11596 "ErrorCode,Unsupported Security value");
11597 return 0;
11598 }
11599
11600 ascii2hexstr(ssid, ssid_hex);
11601 ascii2hexstr(passphrase, passphrase_hex);
11602 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
11603 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
11604
11605 if (wpa_command(intf, buf) < 0) {
11606 wpa_ctrl_detach(ctrl);
11607 wpa_ctrl_close(ctrl);
11608 send_resp(dut, conn, SIGMA_ERROR,
11609 "ErrorCode,Failed to start registrar");
11610 return 0;
11611 }
11612
11613 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
11614 dut->er_oper_performed = 1;
11615
11616 return wps_connection_event(dut, conn, ctrl, intf, 0);
11617}
11618
11619
11620static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
11621 struct sigma_conn *conn,
11622 struct sigma_cmd *cmd)
11623{
11624 struct wpa_ctrl *ctrl;
11625 const char *intf = get_param(cmd, "Interface");
11626 const char *bssid = get_param(cmd, "Bssid");
11627 char buf[100];
11628
11629 if (!bssid) {
11630 send_resp(dut, conn, SIGMA_ERROR,
11631 "ErrorCode,Missing Bssid argument");
11632 return 0;
11633 }
11634
11635 ctrl = open_wpa_mon(intf);
11636 if (ctrl == NULL) {
11637 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11638 "wpa_supplicant monitor connection");
11639 return -2;
11640 }
11641
11642 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
11643
11644 if (wpa_command(intf, buf) < 0) {
11645 wpa_ctrl_detach(ctrl);
11646 wpa_ctrl_close(ctrl);
11647 send_resp(dut, conn, SIGMA_ERROR,
11648 "ErrorCode,Failed to start registrar");
11649 return 0;
11650 }
11651
11652 return wps_connection_event(dut, conn, ctrl, intf, 0);
11653}
11654
11655
vamsi krishna9b144002017-09-20 13:28:13 +053011656static int cmd_start_wps_registration(struct sigma_dut *dut,
11657 struct sigma_conn *conn,
11658 struct sigma_cmd *cmd)
11659{
11660 struct wpa_ctrl *ctrl;
11661 const char *intf = get_param(cmd, "Interface");
11662 const char *role, *method;
11663 int res;
11664 char buf[256];
11665 const char *events[] = {
11666 "CTRL-EVENT-CONNECTED",
11667 "WPS-OVERLAP-DETECTED",
11668 "WPS-TIMEOUT",
11669 "WPS-FAIL",
11670 NULL
11671 };
11672
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020011673 /* 60G WPS tests do not pass Interface parameter */
11674 if (!intf)
11675 intf = get_main_ifname();
11676
vamsi krishna9b144002017-09-20 13:28:13 +053011677 ctrl = open_wpa_mon(intf);
11678 if (!ctrl) {
11679 sigma_dut_print(dut, DUT_MSG_ERROR,
11680 "Failed to open wpa_supplicant monitor connection");
11681 return -2;
11682 }
11683
11684 role = get_param(cmd, "WpsRole");
11685 if (!role) {
11686 send_resp(dut, conn, SIGMA_INVALID,
11687 "ErrorCode,WpsRole not provided");
11688 goto fail;
11689 }
11690
11691 if (strcasecmp(role, "Enrollee") == 0) {
11692 method = get_param(cmd, "WpsConfigMethod");
11693 if (!method) {
11694 send_resp(dut, conn, SIGMA_INVALID,
11695 "ErrorCode,WpsConfigMethod not provided");
11696 goto fail;
11697 }
11698 if (strcasecmp(method, "PBC") == 0) {
11699 if (wpa_command(intf, "WPS_PBC") < 0) {
11700 send_resp(dut, conn, SIGMA_ERROR,
11701 "ErrorCode,Failed to enable PBC");
11702 goto fail;
11703 }
11704 } else {
11705 /* TODO: PIN method */
11706 send_resp(dut, conn, SIGMA_ERROR,
11707 "ErrorCode,Unsupported WpsConfigMethod value");
11708 goto fail;
11709 }
11710 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
11711 if (res < 0) {
11712 send_resp(dut, conn, SIGMA_ERROR,
11713 "ErrorCode,WPS connection did not complete");
11714 goto fail;
11715 }
11716 if (strstr(buf, "WPS-TIMEOUT")) {
11717 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
11718 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
11719 send_resp(dut, conn, SIGMA_ERROR,
11720 "ErrorCode,OverlapSession");
11721 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
11722 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
11723 } else {
11724 send_resp(dut, conn, SIGMA_ERROR,
11725 "ErrorCode,WPS operation failed");
11726 }
11727 } else {
11728 /* TODO: Registrar role */
11729 send_resp(dut, conn, SIGMA_ERROR,
11730 "ErrorCode,Unsupported WpsRole value");
11731 }
11732
11733fail:
11734 wpa_ctrl_detach(ctrl);
11735 wpa_ctrl_close(ctrl);
11736 return 0;
11737}
11738
11739
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011740static int req_intf(struct sigma_cmd *cmd)
11741{
11742 return get_param(cmd, "interface") == NULL ? -1 : 0;
11743}
11744
11745
11746void sta_register_cmds(void)
11747{
11748 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
11749 cmd_sta_get_ip_config);
11750 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
11751 cmd_sta_set_ip_config);
11752 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
11753 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
11754 cmd_sta_get_mac_address);
11755 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
11756 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
11757 cmd_sta_verify_ip_connection);
11758 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
11759 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
11760 cmd_sta_set_encryption);
11761 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
11762 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
11763 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
11764 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
11765 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
11766 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
11767 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
11768 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
11769 cmd_sta_set_eapakaprime);
11770 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
11771 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
11772 /* TODO: sta_set_ibss */
11773 /* TODO: sta_set_mode */
11774 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
11775 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
11776 /* TODO: sta_up_load */
11777 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
11778 cmd_sta_preset_testparameters);
11779 /* TODO: sta_set_system */
11780 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
11781 /* TODO: sta_set_rifs_test */
11782 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
11783 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
11784 /* TODO: sta_send_coexist_mgmt */
11785 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
11786 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
11787 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
11788 sigma_dut_reg_cmd("sta_reset_default", req_intf,
11789 cmd_sta_reset_default);
11790 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
11791 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
11792 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
11793 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
11794 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
11795 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
11796 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
11797 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
11798 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
11799 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030011800 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
11801 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011802 sigma_dut_reg_cmd("sta_add_credential", req_intf,
11803 cmd_sta_add_credential);
11804 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020011805 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011806 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
11807 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
11808 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
11809 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
11810 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
11811 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030011812 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011813 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
11814 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020011815 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053011816 cmd_start_wps_registration);
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011817 sigma_dut_reg_cmd("sta_set_power_save", req_intf,
11818 cmd_sta_set_power_save);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011819}