blob: bf42f72590fb774f60c73c0572b1fc5d0602a714 [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
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020066#define WIL_WMI_UNIT_TEST_CMDID 0x900
Lior David0fe101e2017-03-09 16:09:50 +020067
68struct wil_wmi_header {
69 uint8_t mid;
70 uint8_t reserved;
71 uint16_t cmd;
72 uint32_t ts;
73} __attribute__((packed));
74
75enum wil_wmi_bf_trig_type {
76 WIL_WMI_SLS,
77 WIL_WMI_BRP_RX,
78 WIL_WMI_BRP_TX,
79};
80
81struct wil_wmi_bf_trig_cmd {
82 /* enum wil_wmi_bf_trig_type */
83 uint32_t bf_type;
84 /* cid when type == WMI_BRP_RX */
85 uint32_t sta_id;
86 uint32_t reserved;
87 /* mac address when type = WIL_WMI_SLS */
88 uint8_t dest_mac[6];
89} __attribute__((packed));
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020090
91#define WIL_WMI_UT_HW_SYSAPI 10
92#define WIL_WMI_UT_FORCE_RSN_IE 0x29
93struct wil_wmi_force_rsn_ie {
94 /* WIL_WMI_UT_HW_SYSAPI */
95 uint16_t module_id;
96 /* WIL_WMI_UT_FORCE_RSN_IE */
97 uint16_t subtype_id;
98 /* 0 = no change, 1 = remove if exists, 2 = add if does not exist */
99 uint32_t state;
100} __attribute__((packed));
Lior David0fe101e2017-03-09 16:09:50 +0200101#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200102
103#ifdef ANDROID
104
105static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
106
107#define ANDROID_KEYSTORE_GET 'g'
108#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
109
110static int android_keystore_get(char cmd, const char *key, unsigned char *val)
111{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200112 /* Android 4.3 changed keystore design, so need to use keystore_get() */
113#ifndef KEYSTORE_MESSAGE_SIZE
114#define KEYSTORE_MESSAGE_SIZE 65535
115#endif /* KEYSTORE_MESSAGE_SIZE */
116
117 ssize_t len;
118 uint8_t *value = NULL;
119
120 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
121 "keystore command '%c' key '%s' --> keystore_get",
122 cmd, key);
123
124 len = keystore_get(key, strlen(key), &value);
125 if (len < 0) {
126 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
127 "keystore_get() failed");
128 return -1;
129 }
130
131 if (len > KEYSTORE_MESSAGE_SIZE)
132 len = KEYSTORE_MESSAGE_SIZE;
133 memcpy(val, value, len);
134 free(value);
135 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200136}
137#endif /* ANDROID */
138
139
140int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
141{
142#ifdef __linux__
143 char buf[100];
144
145 if (wifi_chip_type == DRIVER_WCN) {
146 if (enabled) {
147 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 906");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530148 if (system(buf) != 0)
149 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200150 } else {
151 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 905");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530152 if (system(buf) != 0)
153 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200154 snprintf(buf, sizeof(buf), "iwpriv wlan0 dump 912");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530155 if (system(buf) != 0)
156 goto set_power_save;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200157 }
158
159 return 0;
160 }
161
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530162set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200163 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
164 intf, enabled ? "on" : "off");
165 if (system(buf) != 0) {
166 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
167 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530168 if (system(buf) != 0) {
169 sigma_dut_print(dut, DUT_MSG_ERROR,
170 "Failed to set power save %s",
171 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200172 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530173 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200174 }
175
176 return 0;
177#else /* __linux__ */
178 return -1;
179#endif /* __linux__ */
180}
181
182
Lior Davidcc88b562017-01-03 18:52:09 +0200183#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200184
Lior Davidcc88b562017-01-03 18:52:09 +0200185static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
186 size_t len)
187{
188 DIR *dir, *wil_dir;
189 struct dirent *entry;
190 int ret = -1;
191 const char *root_path = "/sys/kernel/debug/ieee80211";
192
193 dir = opendir(root_path);
194 if (!dir)
195 return -2;
196
197 while ((entry = readdir(dir))) {
198 if (strcmp(entry->d_name, ".") == 0 ||
199 strcmp(entry->d_name, "..") == 0)
200 continue;
201
202 if (snprintf(path, len, "%s/%s/wil6210",
203 root_path, entry->d_name) >= (int) len) {
204 ret = -3;
205 break;
206 }
207
208 wil_dir = opendir(path);
209 if (wil_dir) {
210 closedir(wil_dir);
211 ret = 0;
212 break;
213 }
214 }
215
216 closedir(dir);
217 return ret;
218}
Lior David0fe101e2017-03-09 16:09:50 +0200219
220
221static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
222 void *payload, uint16_t length)
223{
224 struct {
225 struct wil_wmi_header hdr;
226 char payload[WIL_WMI_MAX_PAYLOAD];
227 } __attribute__((packed)) cmd;
228 char buf[128], fname[128];
229 size_t towrite, written;
230 FILE *f;
231
232 if (length > WIL_WMI_MAX_PAYLOAD) {
233 sigma_dut_print(dut, DUT_MSG_ERROR,
234 "payload too large(%u, max %u)",
235 length, WIL_WMI_MAX_PAYLOAD);
236 return -1;
237 }
238
239 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
240 cmd.hdr.cmd = command;
241 memcpy(cmd.payload, payload, length);
242
243 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
244 sigma_dut_print(dut, DUT_MSG_ERROR,
245 "failed to get wil6210 debugfs dir");
246 return -1;
247 }
248
249 snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
250 f = fopen(fname, "wb");
251 if (!f) {
252 sigma_dut_print(dut, DUT_MSG_ERROR,
253 "failed to open: %s", fname);
254 return -1;
255 }
256
257 towrite = sizeof(cmd.hdr) + length;
258 written = fwrite(&cmd, 1, towrite, f);
259 fclose(f);
260 if (written != towrite) {
261 sigma_dut_print(dut, DUT_MSG_ERROR,
262 "failed to send wmi %u", command);
263 return -1;
264 }
265
266 return 0;
267}
268
269
270static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
271 const char *pattern, unsigned int *field)
272{
273 char buf[128], fname[128];
274 FILE *f;
275 regex_t re;
276 regmatch_t m[2];
277 int rc, ret = -1;
278
279 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
280 sigma_dut_print(dut, DUT_MSG_ERROR,
281 "failed to get wil6210 debugfs dir");
282 return -1;
283 }
284
285 snprintf(fname, sizeof(fname), "%s/stations", buf);
286 f = fopen(fname, "r");
287 if (!f) {
288 sigma_dut_print(dut, DUT_MSG_ERROR,
289 "failed to open: %s", fname);
290 return -1;
291 }
292
293 if (regcomp(&re, pattern, REG_EXTENDED)) {
294 sigma_dut_print(dut, DUT_MSG_ERROR,
295 "regcomp failed: %s", pattern);
296 goto out;
297 }
298
299 /*
300 * find the entry for the mac address
301 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
302 */
303 while (fgets(buf, sizeof(buf), f)) {
304 if (strcasestr(buf, bssid)) {
305 /* extract the field (CID/AID/state) */
306 rc = regexec(&re, buf, 2, m, 0);
307 if (!rc && (m[1].rm_so >= 0)) {
308 buf[m[1].rm_eo] = 0;
309 *field = atoi(&buf[m[1].rm_so]);
310 ret = 0;
311 break;
312 }
313 }
314 }
315
316 regfree(&re);
317 if (ret)
318 sigma_dut_print(dut, DUT_MSG_ERROR,
319 "could not extract field");
320
321out:
322 fclose(f);
323
324 return ret;
325}
326
327
328static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
329 unsigned int *cid)
330{
331 const char *pattern = "\\[([0-9]+)\\]";
332
333 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
334}
335
336
337static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
338 int l_rx)
339{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700340 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200341 unsigned int cid;
342
Rakesh Sunki556237d2017-03-30 14:49:31 -0700343 memset(&cmd, 0, sizeof(cmd));
344
Lior David0fe101e2017-03-09 16:09:50 +0200345 if (wil6210_get_cid(dut, mac, &cid))
346 return -1;
347
348 cmd.bf_type = WIL_WMI_BRP_RX;
349 cmd.sta_id = cid;
350 /* training length (l_rx) is ignored, FW always uses length 16 */
351 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
352 &cmd, sizeof(cmd));
353}
354
355
356static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
357{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700358 struct wil_wmi_bf_trig_cmd cmd;
359
360 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200361
362 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
363 return -1;
364
365 cmd.bf_type = WIL_WMI_SLS;
366 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
367 &cmd, sizeof(cmd));
368}
369
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200370
371static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
372{
373 struct wil_wmi_force_rsn_ie cmd = { };
374
375 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
376 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
377 cmd.state = (uint32_t) state;
378
379 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
380 &cmd, sizeof(cmd));
381}
382
Lior Davidcc88b562017-01-03 18:52:09 +0200383#endif /* __linux__ */
384
385
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200386static void static_ip_file(int proto, const char *addr, const char *mask,
387 const char *gw)
388{
389 if (proto) {
390 FILE *f = fopen("static-ip", "w");
391 if (f) {
392 fprintf(f, "%d %s %s %s\n", proto, addr,
393 mask ? mask : "N/A",
394 gw ? gw : "N/A");
395 fclose(f);
396 }
397 } else {
398 unlink("static-ip");
399 }
400}
401
402
403static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
404 const char *ssid)
405{
406#ifdef __linux__
407 char buf[100];
408
409 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
410 intf, ssid);
411 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
412
413 if (system(buf) != 0) {
414 sigma_dut_print(dut, DUT_MSG_ERROR,
415 "iwpriv neighbor request failed");
416 return -1;
417 }
418
419 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
420
421 return 0;
422#else /* __linux__ */
423 return -1;
424#endif /* __linux__ */
425}
426
427
428static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530429 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200430{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530431 const char *val;
432 int reason_code = 0;
433 char buf[1024];
434
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200435 /*
436 * In the earlier builds we used WNM_QUERY and in later
437 * builds used WNM_BSS_QUERY.
438 */
439
Ashwini Patil5acd7382017-04-13 15:55:04 +0530440 val = get_param(cmd, "BTMQuery_Reason_Code");
441 if (val)
442 reason_code = atoi(val);
443
444 val = get_param(cmd, "Cand_List");
445 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
446 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
447 dut->btm_query_cand_list);
448 free(dut->btm_query_cand_list);
449 dut->btm_query_cand_list = NULL;
450 } else {
451 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
452 }
453
454 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200455 sigma_dut_print(dut, DUT_MSG_ERROR,
456 "transition management query failed");
457 return -1;
458 }
459
460 sigma_dut_print(dut, DUT_MSG_DEBUG,
461 "transition management query sent");
462
463 return 0;
464}
465
466
467int is_ip_addr(const char *str)
468{
469 const char *pos = str;
470 struct in_addr addr;
471
472 while (*pos) {
473 if (*pos != '.' && (*pos < '0' || *pos > '9'))
474 return 0;
475 pos++;
476 }
477
478 return inet_aton(str, &addr);
479}
480
481
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200482int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
483 size_t buf_len)
484{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530485 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200486 char ip[16], mask[15], dns[16], sec_dns[16];
487 int is_dhcp = 0;
488 int s;
489#ifdef ANDROID
490 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530491#else /* ANDROID */
492 FILE *f;
493#ifdef __linux__
494 const char *str_ps;
495#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200496#endif /* ANDROID */
497
498 ip[0] = '\0';
499 mask[0] = '\0';
500 dns[0] = '\0';
501 sec_dns[0] = '\0';
502
503 s = socket(PF_INET, SOCK_DGRAM, 0);
504 if (s >= 0) {
505 struct ifreq ifr;
506 struct sockaddr_in saddr;
507
508 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700509 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200510 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
511 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
512 "%s IP address: %s",
513 ifname, strerror(errno));
514 } else {
515 memcpy(&saddr, &ifr.ifr_addr,
516 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700517 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200518 }
519
520 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
521 memcpy(&saddr, &ifr.ifr_addr,
522 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700523 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200524 }
525 close(s);
526 }
527
528#ifdef ANDROID
529 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
530 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
531 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
532 if (property_get(tmp, prop, NULL) != 0 &&
533 strcmp(prop, "ok") == 0) {
534 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
535 ifname);
536 if (property_get(tmp, prop, NULL) != 0 &&
537 strcmp(ip, prop) == 0)
538 is_dhcp = 1;
539 }
540 }
541
542 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700543 if (property_get(tmp, prop, NULL) != 0)
544 strlcpy(dns, prop, sizeof(dns));
545 else if (property_get("net.dns1", prop, NULL) != 0)
546 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200547
548 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700549 if (property_get(tmp, prop, NULL) != 0)
550 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200551#else /* ANDROID */
552#ifdef __linux__
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530553 if (get_driver_type() == DRIVER_OPENWRT)
554 str_ps = "ps -w";
555 else
556 str_ps = "ps ax";
557 snprintf(tmp, sizeof(tmp),
558 "%s | grep dhclient | grep -v grep | grep -q %s",
559 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200560 if (system(tmp) == 0)
561 is_dhcp = 1;
562 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530563 snprintf(tmp, sizeof(tmp),
564 "%s | grep udhcpc | grep -v grep | grep -q %s",
565 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200566 if (system(tmp) == 0)
567 is_dhcp = 1;
568 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530569 snprintf(tmp, sizeof(tmp),
570 "%s | grep dhcpcd | grep -v grep | grep -q %s",
571 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200572 if (system(tmp) == 0)
573 is_dhcp = 1;
574 }
575 }
576#endif /* __linux__ */
577
578 f = fopen("/etc/resolv.conf", "r");
579 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +0530580 char *pos, *pos2;
581
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200582 while (fgets(tmp, sizeof(tmp), f)) {
583 if (strncmp(tmp, "nameserver", 10) != 0)
584 continue;
585 pos = tmp + 10;
586 while (*pos == ' ' || *pos == '\t')
587 pos++;
588 pos2 = pos;
589 while (*pos2) {
590 if (*pos2 == '\n' || *pos2 == '\r') {
591 *pos2 = '\0';
592 break;
593 }
594 pos2++;
595 }
Peng Xub8fc5cc2017-05-10 17:27:28 -0700596 if (!dns[0])
597 strlcpy(dns, pos, sizeof(dns));
598 else if (!sec_dns[0])
599 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200600 }
601 fclose(f);
602 }
603#endif /* ANDROID */
604
605 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
606 is_dhcp, ip, mask, dns);
607 buf[buf_len - 1] = '\0';
608
609 return 0;
610}
611
612
613
614
615int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
616 size_t buf_len)
617{
618#ifdef __linux__
619#ifdef ANDROID
620 char cmd[200], result[1000], *pos, *end;
621 FILE *f;
622 size_t len;
623
624 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
625 f = popen(cmd, "r");
626 if (f == NULL)
627 return -1;
628 len = fread(result, 1, sizeof(result) - 1, f);
629 pclose(f);
630 if (len == 0)
631 return -1;
632 result[len] = '\0';
633 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
634
635 pos = strstr(result, "inet6 ");
636 if (pos == NULL)
637 return -1;
638 pos += 6;
639 end = strchr(pos, ' ');
640 if (end)
641 *end = '\0';
642 end = strchr(pos, '/');
643 if (end)
644 *end = '\0';
645 snprintf(buf, buf_len, "ip,%s", pos);
646 buf[buf_len - 1] = '\0';
647 return 0;
648#else /* ANDROID */
649 struct ifaddrs *ifaddr, *ifa;
650 int res, found = 0;
651 char host[NI_MAXHOST];
652
653 if (getifaddrs(&ifaddr) < 0) {
654 perror("getifaddrs");
655 return -1;
656 }
657
658 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
659 if (strcasecmp(ifname, ifa->ifa_name) != 0)
660 continue;
661 if (ifa->ifa_addr == NULL ||
662 ifa->ifa_addr->sa_family != AF_INET6)
663 continue;
664
665 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
666 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
667 if (res != 0) {
668 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
669 gai_strerror(res));
670 continue;
671 }
672 if (strncmp(host, "fe80::", 6) == 0)
673 continue; /* skip link-local */
674
675 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
676 found = 1;
677 break;
678 }
679
680 freeifaddrs(ifaddr);
681
682 if (found) {
683 char *pos;
684 pos = strchr(host, '%');
685 if (pos)
686 *pos = '\0';
687 snprintf(buf, buf_len, "ip,%s", host);
688 buf[buf_len - 1] = '\0';
689 return 0;
690 }
691
692#endif /* ANDROID */
693#endif /* __linux__ */
694 return -1;
695}
696
697
698static int cmd_sta_get_ip_config(struct sigma_dut *dut,
699 struct sigma_conn *conn,
700 struct sigma_cmd *cmd)
701{
702 const char *intf = get_param(cmd, "Interface");
703 const char *ifname;
704 char buf[200];
705 const char *val;
706 int type = 1;
707
708 if (intf == NULL)
709 return -1;
710
711 if (strcmp(intf, get_main_ifname()) == 0)
712 ifname = get_station_ifname();
713 else
714 ifname = intf;
715
716 /*
717 * UCC may assume the IP address to be available immediately after
718 * association without trying to run sta_get_ip_config multiple times.
719 * Sigma CAPI does not specify this command as a block command that
720 * would wait for the address to become available, but to pass tests
721 * more reliably, it looks like such a wait may be needed here.
722 */
723 if (wait_ip_addr(dut, ifname, 15) < 0) {
724 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
725 "for sta_get_ip_config");
726 /*
727 * Try to continue anyway since many UCC tests do not really
728 * care about the return value from here..
729 */
730 }
731
732 val = get_param(cmd, "Type");
733 if (val)
734 type = atoi(val);
735 if (type == 2 || dut->last_set_ip_config_ipv6) {
736 int i;
737
738 /*
739 * Since we do not have proper wait for IPv6 addresses, use a
740 * fixed two second delay here as a workaround for UCC script
741 * assuming IPv6 address is available when this command returns.
742 * Some scripts did not use Type,2 properly for IPv6, so include
743 * also the cases where the previous sta_set_ip_config indicated
744 * use of IPv6.
745 */
746 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
747 for (i = 0; i < 10; i++) {
748 sleep(1);
749 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
750 {
751 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
752 send_resp(dut, conn, SIGMA_COMPLETE, buf);
753#ifdef ANDROID
754 sigma_dut_print(dut, DUT_MSG_INFO,
755 "Adding IPv6 rule on Android");
756 add_ipv6_rule(dut, intf);
757#endif /* ANDROID */
758
759 return 0;
760 }
761 }
762 }
763 if (type == 1) {
764 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
765 return -2;
766 } else if (type == 2) {
767 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
768 return -2;
769 } else {
770 send_resp(dut, conn, SIGMA_ERROR,
771 "errorCode,Unsupported address type");
772 return 0;
773 }
774
775 send_resp(dut, conn, SIGMA_COMPLETE, buf);
776 return 0;
777}
778
779
780static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
781{
782#ifdef __linux__
783 char buf[200];
784 char path[128];
785 struct stat s;
786
787#ifdef ANDROID
788 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
789#else /* ANDROID */
790 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
791#endif /* ANDROID */
792 if (stat(path, &s) == 0) {
793 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
794 sigma_dut_print(dut, DUT_MSG_INFO,
795 "Kill previous DHCP client: %s", buf);
796 if (system(buf) != 0)
797 sigma_dut_print(dut, DUT_MSG_INFO,
798 "Failed to kill DHCP client");
799 unlink(path);
800 sleep(1);
801 } else {
802 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
803
804 if (stat(path, &s) == 0) {
805 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
806 sigma_dut_print(dut, DUT_MSG_INFO,
807 "Kill previous DHCP client: %s", buf);
808 if (system(buf) != 0)
809 sigma_dut_print(dut, DUT_MSG_INFO,
810 "Failed to kill DHCP client");
811 unlink(path);
812 sleep(1);
813 }
814 }
815#endif /* __linux__ */
816}
817
818
819static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
820{
821#ifdef __linux__
822 char buf[200];
823
824#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +0530825 if (access("/system/bin/dhcpcd", F_OK) != -1) {
826 snprintf(buf, sizeof(buf),
827 "/system/bin/dhcpcd -b %s", ifname);
828 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
829 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
830 } else {
831 sigma_dut_print(dut, DUT_MSG_ERROR,
832 "DHCP client program missing");
833 return 0;
834 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200835#else /* ANDROID */
836 snprintf(buf, sizeof(buf),
837 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
838 ifname, ifname);
839#endif /* ANDROID */
840 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
841 if (system(buf) != 0) {
842 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
843 if (system(buf) != 0) {
844 sigma_dut_print(dut, DUT_MSG_INFO,
845 "Failed to start DHCP client");
846#ifndef ANDROID
847 return -1;
848#endif /* ANDROID */
849 }
850 }
851#endif /* __linux__ */
852
853 return 0;
854}
855
856
857static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
858{
859#ifdef __linux__
860 char buf[200];
861
862 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
863 if (system(buf) != 0) {
864 sigma_dut_print(dut, DUT_MSG_INFO,
865 "Failed to clear IP addresses");
866 return -1;
867 }
868#endif /* __linux__ */
869
870 return 0;
871}
872
873
874#ifdef ANDROID
875static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
876{
877 char cmd[200], *result, *pos;
878 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530879 int tableid;
880 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200881
882 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
883 ifname);
884 fp = popen(cmd, "r");
885 if (fp == NULL)
886 return -1;
887
888 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530889 if (result == NULL) {
890 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200891 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +0530892 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200893
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530894 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200895 fclose(fp);
896
897 if (len == 0) {
898 free(result);
899 return -1;
900 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +0530901 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200902
903 pos = strstr(result, "table ");
904 if (pos == NULL) {
905 free(result);
906 return -1;
907 }
908
909 pos += strlen("table ");
910 tableid = atoi(pos);
911 if (tableid != 0) {
912 if (system("ip -6 rule del prio 22000") != 0) {
913 /* ignore any error */
914 }
915 snprintf(cmd, sizeof(cmd),
916 "ip -6 rule add from all lookup %d prio 22000",
917 tableid);
918 if (system(cmd) != 0) {
919 sigma_dut_print(dut, DUT_MSG_INFO,
920 "Failed to run %s", cmd);
921 free(result);
922 return -1;
923 }
924 } else {
925 sigma_dut_print(dut, DUT_MSG_INFO,
926 "No Valid Table Id found %s", pos);
927 free(result);
928 return -1;
929 }
930 free(result);
931
932 return 0;
933}
934#endif /* ANDROID */
935
936
Ankita Bajaj1bde7942018-01-09 19:15:01 +0530937int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
938 const char *ip, const char *mask)
939{
940 char buf[200];
941
942 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
943 ifname, ip, mask);
944 return system(buf) == 0;
945}
946
947
948int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
949{
950 char buf[200];
951
952 if (!is_ip_addr(gw)) {
953 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
954 return -1;
955 }
956
957 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
958 if (!dut->no_ip_addr_set && system(buf) != 0) {
959 snprintf(buf, sizeof(buf), "ip ro re default via %s",
960 gw);
961 if (system(buf) != 0)
962 return 0;
963 }
964
965 return 1;
966}
967
968
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200969static int cmd_sta_set_ip_config(struct sigma_dut *dut,
970 struct sigma_conn *conn,
971 struct sigma_cmd *cmd)
972{
973 const char *intf = get_param(cmd, "Interface");
974 const char *ifname;
975 char buf[200];
976 const char *val, *ip, *mask, *gw;
977 int type = 1;
978
979 if (intf == NULL)
980 return -1;
981
982 if (strcmp(intf, get_main_ifname()) == 0)
983 ifname = get_station_ifname();
984 else
985 ifname = intf;
986
987 if (if_nametoindex(ifname) == 0) {
988 send_resp(dut, conn, SIGMA_ERROR,
989 "ErrorCode,Unknown interface");
990 return 0;
991 }
992
993 val = get_param(cmd, "Type");
994 if (val) {
995 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +0530996 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200997 send_resp(dut, conn, SIGMA_ERROR,
998 "ErrorCode,Unsupported address type");
999 return 0;
1000 }
1001 }
1002
1003 dut->last_set_ip_config_ipv6 = 0;
1004
1005 val = get_param(cmd, "dhcp");
1006 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1007 static_ip_file(0, NULL, NULL, NULL);
1008#ifdef __linux__
1009 if (type == 2) {
1010 dut->last_set_ip_config_ipv6 = 1;
1011 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1012 "stateless address autoconfiguration");
1013#ifdef ANDROID
1014 /*
1015 * This sleep is required as the assignment in case of
1016 * Android is taking time and is done by the kernel.
1017 * The subsequent ping for IPv6 is impacting HS20 test
1018 * case.
1019 */
1020 sleep(2);
1021 add_ipv6_rule(dut, intf);
1022#endif /* ANDROID */
1023 /* Assume this happens by default */
1024 return 1;
1025 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301026 if (type != 3) {
1027 kill_dhcp_client(dut, ifname);
1028 if (start_dhcp_client(dut, ifname) < 0)
1029 return -2;
1030 } else {
1031 sigma_dut_print(dut, DUT_MSG_DEBUG,
1032 "Using FILS HLP DHCPv4 Rapid Commit");
1033 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001034
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001035 return 1;
1036#endif /* __linux__ */
1037 return -2;
1038 }
1039
1040 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301041 if (!ip) {
1042 send_resp(dut, conn, SIGMA_INVALID,
1043 "ErrorCode,Missing IP address");
1044 return 0;
1045 }
1046
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001047 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301048 if (!mask) {
1049 send_resp(dut, conn, SIGMA_INVALID,
1050 "ErrorCode,Missing subnet mask");
1051 return 0;
1052 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001053
1054 if (type == 2) {
1055 int net = atoi(mask);
1056
1057 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1058 return -1;
1059
1060 if (dut->no_ip_addr_set) {
1061 snprintf(buf, sizeof(buf),
1062 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1063 ifname);
1064 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1065 if (system(buf) != 0) {
1066 sigma_dut_print(dut, DUT_MSG_DEBUG,
1067 "Failed to disable IPv6 address before association");
1068 }
1069 } else {
1070 snprintf(buf, sizeof(buf),
1071 "ip -6 addr del %s/%s dev %s",
1072 ip, mask, ifname);
1073 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1074 if (system(buf) != 0) {
1075 /*
1076 * This command may fail if the address being
1077 * deleted does not exist. Inaction here is
1078 * intentional.
1079 */
1080 }
1081
1082 snprintf(buf, sizeof(buf),
1083 "ip -6 addr add %s/%s dev %s",
1084 ip, mask, ifname);
1085 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1086 if (system(buf) != 0) {
1087 send_resp(dut, conn, SIGMA_ERROR,
1088 "ErrorCode,Failed to set IPv6 address");
1089 return 0;
1090 }
1091 }
1092
1093 dut->last_set_ip_config_ipv6 = 1;
1094 static_ip_file(6, ip, mask, NULL);
1095 return 1;
1096 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301097 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001098 return -1;
1099 }
1100
1101 kill_dhcp_client(dut, ifname);
1102
1103 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301104 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001105 send_resp(dut, conn, SIGMA_ERROR,
1106 "ErrorCode,Failed to set IP address");
1107 return 0;
1108 }
1109 }
1110
1111 gw = get_param(cmd, "defaultGateway");
1112 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301113 if (set_ipv4_gw(dut, gw) < 1) {
1114 send_resp(dut, conn, SIGMA_ERROR,
1115 "ErrorCode,Failed to set default gateway");
1116 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001117 }
1118 }
1119
1120 val = get_param(cmd, "primary-dns");
1121 if (val) {
1122 /* TODO */
1123 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1124 "setting", val);
1125 }
1126
1127 val = get_param(cmd, "secondary-dns");
1128 if (val) {
1129 /* TODO */
1130 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1131 "setting", val);
1132 }
1133
1134 static_ip_file(4, ip, mask, gw);
1135
1136 return 1;
1137}
1138
1139
1140static int cmd_sta_get_info(struct sigma_dut *dut, struct sigma_conn *conn,
1141 struct sigma_cmd *cmd)
1142{
1143 /* const char *intf = get_param(cmd, "Interface"); */
1144 /* TODO: could report more details here */
1145 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1146 return 0;
1147}
1148
1149
1150static int cmd_sta_get_mac_address(struct sigma_dut *dut,
1151 struct sigma_conn *conn,
1152 struct sigma_cmd *cmd)
1153{
1154 /* const char *intf = get_param(cmd, "Interface"); */
1155 char addr[20], resp[50];
1156
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301157 if (dut->dev_role == DEVROLE_STA_CFON)
1158 return sta_cfon_get_mac_address(dut, conn, cmd);
1159
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001160 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
1161 < 0)
1162 return -2;
1163
1164 snprintf(resp, sizeof(resp), "mac,%s", addr);
1165 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1166 return 0;
1167}
1168
1169
1170static int cmd_sta_is_connected(struct sigma_dut *dut, struct sigma_conn *conn,
1171 struct sigma_cmd *cmd)
1172{
1173 /* const char *intf = get_param(cmd, "Interface"); */
1174 int connected = 0;
1175 char result[32];
1176 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
1177 sizeof(result)) < 0) {
1178 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get interface "
1179 "%s status", get_station_ifname());
1180 return -2;
1181 }
1182
1183 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1184 if (strncmp(result, "COMPLETED", 9) == 0)
1185 connected = 1;
1186
1187 if (connected)
1188 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1189 else
1190 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1191
1192 return 0;
1193}
1194
1195
1196static int cmd_sta_verify_ip_connection(struct sigma_dut *dut,
1197 struct sigma_conn *conn,
1198 struct sigma_cmd *cmd)
1199{
1200 /* const char *intf = get_param(cmd, "Interface"); */
1201 const char *dst, *timeout;
1202 int wait_time = 90;
1203 char buf[100];
1204 int res;
1205
1206 dst = get_param(cmd, "destination");
1207 if (dst == NULL || !is_ip_addr(dst))
1208 return -1;
1209
1210 timeout = get_param(cmd, "timeout");
1211 if (timeout) {
1212 wait_time = atoi(timeout);
1213 if (wait_time < 1)
1214 wait_time = 1;
1215 }
1216
1217 /* TODO: force renewal of IP lease if DHCP is enabled */
1218
1219 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1220 res = system(buf);
1221 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1222 if (res == 0)
1223 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1224 else if (res == 256)
1225 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1226 else
1227 return -2;
1228
1229 return 0;
1230}
1231
1232
1233static int cmd_sta_get_bssid(struct sigma_dut *dut, struct sigma_conn *conn,
1234 struct sigma_cmd *cmd)
1235{
1236 /* const char *intf = get_param(cmd, "Interface"); */
1237 char bssid[20], resp[50];
1238
1239 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
1240 < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001241 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001242
1243 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1244 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1245 return 0;
1246}
1247
1248
1249#ifdef __SAMSUNG__
1250static int add_use_network(const char *ifname)
1251{
1252 char buf[100];
1253
1254 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1255 wpa_command(ifname, buf);
1256 return 0;
1257}
1258#endif /* __SAMSUNG__ */
1259
1260
1261static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1262 const char *ifname, struct sigma_cmd *cmd)
1263{
1264 const char *ssid = get_param(cmd, "ssid");
1265 int id;
1266 const char *val;
1267
1268 if (ssid == NULL)
1269 return -1;
1270
1271 start_sta_mode(dut);
1272
1273#ifdef __SAMSUNG__
1274 add_use_network(ifname);
1275#endif /* __SAMSUNG__ */
1276
1277 id = add_network(ifname);
1278 if (id < 0)
1279 return -2;
1280 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1281
1282 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1283 return -2;
1284
1285 dut->infra_network_id = id;
1286 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1287
1288 val = get_param(cmd, "program");
1289 if (!val)
1290 val = get_param(cmd, "prog");
1291 if (val && strcasecmp(val, "hs2") == 0) {
1292 char buf[100];
1293 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1294 wpa_command(ifname, buf);
1295
1296 val = get_param(cmd, "prefer");
1297 if (val && atoi(val) > 0)
1298 set_network(ifname, id, "priority", "1");
1299 }
1300
1301 return id;
1302}
1303
1304
1305static int cmd_sta_set_encryption(struct sigma_dut *dut,
1306 struct sigma_conn *conn,
1307 struct sigma_cmd *cmd)
1308{
1309 const char *intf = get_param(cmd, "Interface");
1310 const char *ssid = get_param(cmd, "ssid");
1311 const char *type = get_param(cmd, "encpType");
1312 const char *ifname;
1313 char buf[200];
1314 int id;
1315
1316 if (intf == NULL || ssid == NULL)
1317 return -1;
1318
1319 if (strcmp(intf, get_main_ifname()) == 0)
1320 ifname = get_station_ifname();
1321 else
1322 ifname = intf;
1323
1324 id = add_network_common(dut, conn, ifname, cmd);
1325 if (id < 0)
1326 return id;
1327
1328 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1329 return -2;
1330
1331 if (type && strcasecmp(type, "wep") == 0) {
1332 const char *val;
1333 int i;
1334
1335 val = get_param(cmd, "activeKey");
1336 if (val) {
1337 int keyid;
1338 keyid = atoi(val);
1339 if (keyid < 1 || keyid > 4)
1340 return -1;
1341 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1342 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1343 return -2;
1344 }
1345
1346 for (i = 0; i < 4; i++) {
1347 snprintf(buf, sizeof(buf), "key%d", i + 1);
1348 val = get_param(cmd, buf);
1349 if (val == NULL)
1350 continue;
1351 snprintf(buf, sizeof(buf), "wep_key%d", i);
1352 if (set_network(ifname, id, buf, val) < 0)
1353 return -2;
1354 }
1355 }
1356
1357 return 1;
1358}
1359
1360
1361static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1362 const char *ifname, struct sigma_cmd *cmd)
1363{
1364 const char *val;
1365 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001366 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001367 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301368 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001369
1370 id = add_network_common(dut, conn, ifname, cmd);
1371 if (id < 0)
1372 return id;
1373
Jouni Malinen47dcc952017-10-09 16:43:24 +03001374 val = get_param(cmd, "Type");
1375 owe = val && strcasecmp(val, "OWE") == 0;
1376
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001377 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001378 if (!val && owe)
1379 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001380 if (val == NULL) {
1381 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Missing keyMgmtType");
1382 return 0;
1383 }
1384 if (strcasecmp(val, "wpa") == 0 ||
1385 strcasecmp(val, "wpa-psk") == 0) {
1386 if (set_network(ifname, id, "proto", "WPA") < 0)
1387 return -2;
1388 } else if (strcasecmp(val, "wpa2") == 0 ||
1389 strcasecmp(val, "wpa2-psk") == 0 ||
1390 strcasecmp(val, "wpa2-ft") == 0 ||
1391 strcasecmp(val, "wpa2-sha256") == 0) {
1392 if (set_network(ifname, id, "proto", "WPA2") < 0)
1393 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301394 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1395 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001396 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1397 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001398 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301399 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001400 if (set_network(ifname, id, "proto", "WPA2") < 0)
1401 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001402 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001403 } else {
1404 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1405 return 0;
1406 }
1407
1408 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001409 if (val) {
1410 cipher_set = 1;
1411 if (strcasecmp(val, "tkip") == 0) {
1412 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1413 return -2;
1414 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1415 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1416 return -2;
1417 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1418 if (set_network(ifname, id, "pairwise",
1419 "CCMP TKIP") < 0)
1420 return -2;
1421 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1422 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1423 return -2;
1424 if (set_network(ifname, id, "group", "GCMP") < 0)
1425 return -2;
1426 } else {
1427 send_resp(dut, conn, SIGMA_ERROR,
1428 "errorCode,Unrecognized encpType value");
1429 return 0;
1430 }
1431 }
1432
1433 val = get_param(cmd, "PairwiseCipher");
1434 if (val) {
1435 cipher_set = 1;
1436 /* TODO: Support space separated list */
1437 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1438 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1439 return -2;
1440 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1441 if (set_network(ifname, id, "pairwise",
1442 "CCMP-256") < 0)
1443 return -2;
1444 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1445 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1446 return -2;
1447 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1448 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1449 return -2;
1450 } else {
1451 send_resp(dut, conn, SIGMA_ERROR,
1452 "errorCode,Unrecognized PairwiseCipher value");
1453 return 0;
1454 }
1455 }
1456
Jouni Malinen47dcc952017-10-09 16:43:24 +03001457 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001458 send_resp(dut, conn, SIGMA_ERROR,
1459 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001460 return 0;
1461 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001462
1463 val = get_param(cmd, "GroupCipher");
1464 if (val) {
1465 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1466 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1467 return -2;
1468 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1469 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1470 return -2;
1471 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1472 if (set_network(ifname, id, "group", "GCMP") < 0)
1473 return -2;
1474 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1475 if (set_network(ifname, id, "group", "CCMP") < 0)
1476 return -2;
1477 } else {
1478 send_resp(dut, conn, SIGMA_ERROR,
1479 "errorCode,Unrecognized GroupCipher value");
1480 return 0;
1481 }
1482 }
1483
Jouni Malinen7b239522017-09-14 21:37:18 +03001484 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001485 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001486 const char *cipher;
1487
1488 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1489 cipher = "BIP-GMAC-256";
1490 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1491 cipher = "BIP-CMAC-256";
1492 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
1493 cipher = "BIP-GMAC-128";
1494 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
1495 cipher = "AES-128-CMAC";
1496 } else {
1497 send_resp(dut, conn, SIGMA_INVALID,
1498 "errorCode,Unsupported GroupMgntCipher");
1499 return 0;
1500 }
1501 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
1502 send_resp(dut, conn, SIGMA_INVALID,
1503 "errorCode,Failed to set GroupMgntCipher");
1504 return 0;
1505 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001506 }
1507
1508 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301509
1510 if (dut->program == PROGRAM_OCE) {
1511 dut->sta_pmf = STA_PMF_OPTIONAL;
1512 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1513 return -2;
1514 }
1515
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001516 val = get_param(cmd, "PMF");
1517 if (val) {
1518 if (strcasecmp(val, "Required") == 0 ||
1519 strcasecmp(val, "Forced_Required") == 0) {
1520 dut->sta_pmf = STA_PMF_REQUIRED;
1521 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1522 return -2;
1523 } else if (strcasecmp(val, "Optional") == 0) {
1524 dut->sta_pmf = STA_PMF_OPTIONAL;
1525 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1526 return -2;
1527 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08001528 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001529 strcasecmp(val, "Forced_Disabled") == 0) {
1530 dut->sta_pmf = STA_PMF_DISABLED;
1531 } else {
1532 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
1533 return 0;
1534 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05301535 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02001536 dut->sta_pmf = STA_PMF_REQUIRED;
1537 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1538 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001539 }
1540
1541 return id;
1542}
1543
1544
1545static int cmd_sta_set_psk(struct sigma_dut *dut, struct sigma_conn *conn,
1546 struct sigma_cmd *cmd)
1547{
1548 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03001549 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02001550 const char *pmf = get_param(cmd, "PMF");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001551 const char *ifname, *val, *alg;
1552 int id;
1553
1554 if (intf == NULL)
1555 return -1;
1556
1557 if (strcmp(intf, get_main_ifname()) == 0)
1558 ifname = get_station_ifname();
1559 else
1560 ifname = intf;
1561
1562 id = set_wpa_common(dut, conn, ifname, cmd);
1563 if (id < 0)
1564 return id;
1565
1566 val = get_param(cmd, "keyMgmtType");
1567 alg = get_param(cmd, "micAlg");
1568
Jouni Malinen992a81e2017-08-22 13:57:47 +03001569 if (type && strcasecmp(type, "SAE") == 0) {
1570 if (val && strcasecmp(val, "wpa2-ft") == 0) {
1571 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
1572 return -2;
1573 } else {
1574 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
1575 return -2;
1576 }
1577 if (wpa_command(ifname, "SET sae_groups ") != 0) {
1578 sigma_dut_print(dut, DUT_MSG_ERROR,
1579 "Failed to clear sae_groups to default");
1580 return -2;
1581 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02001582 if (!pmf) {
1583 dut->sta_pmf = STA_PMF_REQUIRED;
1584 if (set_network(ifname, id, "ieee80211w", "2") < 0)
1585 return -2;
1586 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03001587 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
1588 if (val && strcasecmp(val, "wpa2-ft") == 0) {
1589 if (set_network(ifname, id, "key_mgmt",
1590 "FT-SAE FT-PSK") < 0)
1591 return -2;
1592 } else {
1593 if (set_network(ifname, id, "key_mgmt",
1594 "SAE WPA-PSK") < 0)
1595 return -2;
1596 }
1597 if (wpa_command(ifname, "SET sae_groups ") != 0) {
1598 sigma_dut_print(dut, DUT_MSG_ERROR,
1599 "Failed to clear sae_groups to default");
1600 return -2;
1601 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02001602 if (!pmf) {
1603 dut->sta_pmf = STA_PMF_OPTIONAL;
1604 if (set_network(ifname, id, "ieee80211w", "1") < 0)
1605 return -2;
1606 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03001607 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001608 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
1609 return -2;
1610 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1611 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1612 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05301613 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1614 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
1615 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001616 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1617 dut->sta_pmf == STA_PMF_REQUIRED) {
1618 if (set_network(ifname, id, "key_mgmt",
1619 "WPA-PSK WPA-PSK-SHA256") < 0)
1620 return -2;
1621 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1622 if (set_network(ifname, id, "key_mgmt",
1623 "WPA-PSK WPA-PSK-SHA256") < 0)
1624 return -2;
1625 } else {
1626 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
1627 return -2;
1628 }
1629
1630 val = get_param(cmd, "passPhrase");
1631 if (val == NULL)
1632 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03001633 if (type && strcasecmp(type, "SAE") == 0) {
1634 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
1635 return -2;
1636 } else {
1637 if (set_network_quoted(ifname, id, "psk", val) < 0)
1638 return -2;
1639 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001640
Jouni Malinen992a81e2017-08-22 13:57:47 +03001641 val = get_param(cmd, "ECGroupID");
1642 if (val) {
1643 char buf[50];
1644
1645 snprintf(buf, sizeof(buf), "SET sae_groups %u", atoi(val));
1646 if (wpa_command(ifname, buf) != 0) {
1647 sigma_dut_print(dut, DUT_MSG_ERROR,
1648 "Failed to clear sae_groups");
1649 return -2;
1650 }
1651 }
1652
Jouni Malinen68143132017-09-02 02:34:08 +03001653 val = get_param(cmd, "InvalidSAEElement");
1654 if (val) {
1655 free(dut->sae_commit_override);
1656 dut->sae_commit_override = strdup(val);
1657 }
1658
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001659 return 1;
1660}
1661
1662
1663static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301664 const char *ifname, int username_identity,
1665 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001666{
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301667 const char *val, *alg, *akm;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001668 int id;
1669 char buf[200];
1670#ifdef ANDROID
1671 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1672 int length;
1673#endif /* ANDROID */
1674
1675 id = set_wpa_common(dut, conn, ifname, cmd);
1676 if (id < 0)
1677 return id;
1678
1679 val = get_param(cmd, "keyMgmtType");
1680 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301681 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001682
Jouni Malinenad395a22017-09-01 21:13:46 +03001683 if (val && strcasecmp(val, "SuiteB") == 0) {
1684 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
1685 0)
1686 return -2;
1687 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001688 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
1689 return -2;
1690 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
1691 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1692 return -2;
1693 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
1694 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
1695 return -2;
1696 } else if ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
1697 dut->sta_pmf == STA_PMF_REQUIRED) {
1698 if (set_network(ifname, id, "key_mgmt",
1699 "WPA-EAP WPA-EAP-SHA256") < 0)
1700 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05301701 } else if (akm && atoi(akm) == 14) {
1702 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
1703 dut->sta_pmf == STA_PMF_REQUIRED) {
1704 if (set_network(ifname, id, "key_mgmt",
1705 "WPA-EAP-SHA256 FILS-SHA256") < 0)
1706 return -2;
1707 } else {
1708 if (set_network(ifname, id, "key_mgmt",
1709 "WPA-EAP FILS-SHA256") < 0)
1710 return -2;
1711 }
1712
1713 if (set_network(ifname, id, "erp", "1") < 0)
1714 return -2;
1715 } else if (akm && atoi(akm) == 15) {
1716 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
1717 dut->sta_pmf == STA_PMF_REQUIRED) {
1718 if (set_network(ifname, id, "key_mgmt",
1719 "WPA-EAP-SHA256 FILS-SHA384") < 0)
1720 return -2;
1721 } else {
1722 if (set_network(ifname, id, "key_mgmt",
1723 "WPA-EAP FILS-SHA384") < 0)
1724 return -2;
1725 }
1726
1727 if (set_network(ifname, id, "erp", "1") < 0)
1728 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001729 } else if (dut->sta_pmf == STA_PMF_OPTIONAL) {
1730 if (set_network(ifname, id, "key_mgmt",
1731 "WPA-EAP WPA-EAP-SHA256") < 0)
1732 return -2;
1733 } else {
1734 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
1735 return -2;
1736 }
1737
1738 val = get_param(cmd, "trustedRootCA");
1739 if (val) {
1740#ifdef ANDROID
1741 snprintf(buf, sizeof(buf), "CACERT_%s", val);
1742 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf,
1743 kvalue);
1744 if (length > 0) {
1745 sigma_dut_print(dut, DUT_MSG_INFO,
1746 "Use Android keystore [%s]", buf);
1747 snprintf(buf, sizeof(buf), "keystore://CACERT_%s",
1748 val);
1749 goto ca_cert_selected;
1750 }
1751#endif /* ANDROID */
1752
1753 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1754#ifdef __linux__
1755 if (!file_exists(buf)) {
1756 char msg[300];
1757 snprintf(msg, sizeof(msg), "ErrorCode,trustedRootCA "
1758 "file (%s) not found", buf);
1759 send_resp(dut, conn, SIGMA_ERROR, msg);
1760 return -3;
1761 }
1762#endif /* __linux__ */
1763#ifdef ANDROID
1764ca_cert_selected:
1765#endif /* ANDROID */
1766 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
1767 return -2;
1768 }
1769
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301770 if (username_identity) {
1771 val = get_param(cmd, "username");
1772 if (val) {
1773 if (set_network_quoted(ifname, id, "identity", val) < 0)
1774 return -2;
1775 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001776
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301777 val = get_param(cmd, "password");
1778 if (val) {
1779 if (set_network_quoted(ifname, id, "password", val) < 0)
1780 return -2;
1781 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001782 }
1783
1784 return id;
1785}
1786
1787
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03001788static int set_tls_cipher(const char *ifname, int id, const char *cipher)
1789{
1790 const char *val;
1791
1792 if (!cipher)
1793 return 0;
1794
1795 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
1796 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
1797 else if (strcasecmp(cipher,
1798 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
1799 val = "ECDHE-RSA-AES256-GCM-SHA384";
1800 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
1801 val = "DHE-RSA-AES256-GCM-SHA384";
1802 else if (strcasecmp(cipher,
1803 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
1804 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
1805 else
1806 return -1;
1807
1808 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
1809 set_network_quoted(ifname, id, "phase1", "");
1810
1811 return set_network_quoted(ifname, id, "openssl_ciphers", val);
1812}
1813
1814
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001815static int cmd_sta_set_eaptls(struct sigma_dut *dut, struct sigma_conn *conn,
1816 struct sigma_cmd *cmd)
1817{
1818 const char *intf = get_param(cmd, "Interface");
1819 const char *ifname, *val;
1820 int id;
1821 char buf[200];
1822#ifdef ANDROID
1823 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
1824 int length;
1825 int jb_or_newer = 0;
1826 char prop[PROPERTY_VALUE_MAX];
1827#endif /* ANDROID */
1828
1829 if (intf == NULL)
1830 return -1;
1831
1832 if (strcmp(intf, get_main_ifname()) == 0)
1833 ifname = get_station_ifname();
1834 else
1835 ifname = intf;
1836
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301837 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001838 if (id < 0)
1839 return id;
1840
1841 if (set_network(ifname, id, "eap", "TLS") < 0)
1842 return -2;
1843
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05301844 if (!get_param(cmd, "username") &&
1845 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001846 "wifi-user@wifilabs.local") < 0)
1847 return -2;
1848
1849 val = get_param(cmd, "clientCertificate");
1850 if (val == NULL)
1851 return -1;
1852#ifdef ANDROID
1853 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1854 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
1855 if (length < 0) {
1856 /*
1857 * JB started reporting keystore type mismatches, so retry with
1858 * the GET_PUBKEY command if the generic GET fails.
1859 */
1860 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
1861 buf, kvalue);
1862 }
1863
1864 if (property_get("ro.build.version.release", prop, NULL) != 0) {
1865 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
1866 if (strncmp(prop, "4.0", 3) != 0)
1867 jb_or_newer = 1;
1868 } else
1869 jb_or_newer = 1; /* assume newer */
1870
1871 if (jb_or_newer && length > 0) {
1872 sigma_dut_print(dut, DUT_MSG_INFO,
1873 "Use Android keystore [%s]", buf);
1874 if (set_network(ifname, id, "engine", "1") < 0)
1875 return -2;
1876 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
1877 return -2;
1878 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
1879 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
1880 return -2;
1881 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
1882 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1883 return -2;
1884 return 1;
1885 } else if (length > 0) {
1886 sigma_dut_print(dut, DUT_MSG_INFO,
1887 "Use Android keystore [%s]", buf);
1888 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
1889 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
1890 return -2;
1891 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
1892 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1893 return -2;
1894 return 1;
1895 }
1896#endif /* ANDROID */
1897
1898 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
1899#ifdef __linux__
1900 if (!file_exists(buf)) {
1901 char msg[300];
1902 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
1903 "(%s) not found", buf);
1904 send_resp(dut, conn, SIGMA_ERROR, msg);
1905 return -3;
1906 }
1907#endif /* __linux__ */
1908 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
1909 return -2;
1910 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
1911 return -2;
1912
1913 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
1914 return -2;
1915
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03001916 val = get_param(cmd, "keyMgmtType");
1917 if (val && strcasecmp(val, "SuiteB") == 0) {
1918 val = get_param(cmd, "CertType");
1919 if (val && strcasecmp(val, "RSA") == 0) {
1920 if (set_network_quoted(ifname, id, "phase1",
1921 "tls_suiteb=1") < 0)
1922 return -2;
1923 } else {
1924 if (set_network_quoted(ifname, id, "openssl_ciphers",
1925 "SUITEB192") < 0)
1926 return -2;
1927 }
1928
1929 val = get_param(cmd, "TLSCipher");
1930 if (set_tls_cipher(ifname, id, val) < 0) {
1931 send_resp(dut, conn, SIGMA_ERROR,
1932 "ErrorCode,Unsupported TLSCipher value");
1933 return -3;
1934 }
1935 }
1936
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001937 return 1;
1938}
1939
1940
1941static int cmd_sta_set_eapttls(struct sigma_dut *dut, struct sigma_conn *conn,
1942 struct sigma_cmd *cmd)
1943{
1944 const char *intf = get_param(cmd, "Interface");
1945 const char *ifname;
1946 int id;
1947
1948 if (intf == NULL)
1949 return -1;
1950
1951 if (strcmp(intf, get_main_ifname()) == 0)
1952 ifname = get_station_ifname();
1953 else
1954 ifname = intf;
1955
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301956 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001957 if (id < 0)
1958 return id;
1959
1960 if (set_network(ifname, id, "eap", "TTLS") < 0) {
1961 send_resp(dut, conn, SIGMA_ERROR,
1962 "errorCode,Failed to set TTLS method");
1963 return 0;
1964 }
1965
1966 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
1967 send_resp(dut, conn, SIGMA_ERROR,
1968 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
1969 return 0;
1970 }
1971
1972 return 1;
1973}
1974
1975
1976static int cmd_sta_set_eapsim(struct sigma_dut *dut, struct sigma_conn *conn,
1977 struct sigma_cmd *cmd)
1978{
1979 const char *intf = get_param(cmd, "Interface");
1980 const char *ifname;
1981 int id;
1982
1983 if (intf == NULL)
1984 return -1;
1985
1986 if (strcmp(intf, get_main_ifname()) == 0)
1987 ifname = get_station_ifname();
1988 else
1989 ifname = intf;
1990
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05301991 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001992 if (id < 0)
1993 return id;
1994
1995 if (set_network(ifname, id, "eap", "SIM") < 0)
1996 return -2;
1997
1998 return 1;
1999}
2000
2001
2002static int cmd_sta_set_peap(struct sigma_dut *dut, struct sigma_conn *conn,
2003 struct sigma_cmd *cmd)
2004{
2005 const char *intf = get_param(cmd, "Interface");
2006 const char *ifname, *val;
2007 int id;
2008 char buf[100];
2009
2010 if (intf == NULL)
2011 return -1;
2012
2013 if (strcmp(intf, get_main_ifname()) == 0)
2014 ifname = get_station_ifname();
2015 else
2016 ifname = intf;
2017
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302018 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002019 if (id < 0)
2020 return id;
2021
2022 if (set_network(ifname, id, "eap", "PEAP") < 0)
2023 return -2;
2024
2025 val = get_param(cmd, "innerEAP");
2026 if (val) {
2027 if (strcasecmp(val, "MSCHAPv2") == 0) {
2028 if (set_network_quoted(ifname, id, "phase2",
2029 "auth=MSCHAPV2") < 0)
2030 return -2;
2031 } else if (strcasecmp(val, "GTC") == 0) {
2032 if (set_network_quoted(ifname, id, "phase2",
2033 "auth=GTC") < 0)
2034 return -2;
2035 } else
2036 return -1;
2037 }
2038
2039 val = get_param(cmd, "peapVersion");
2040 if (val) {
2041 int ver = atoi(val);
2042 if (ver < 0 || ver > 1)
2043 return -1;
2044 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2045 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2046 return -2;
2047 }
2048
2049 return 1;
2050}
2051
2052
2053static int cmd_sta_set_eapfast(struct sigma_dut *dut, struct sigma_conn *conn,
2054 struct sigma_cmd *cmd)
2055{
2056 const char *intf = get_param(cmd, "Interface");
2057 const char *ifname, *val;
2058 int id;
2059 char buf[100];
2060
2061 if (intf == NULL)
2062 return -1;
2063
2064 if (strcmp(intf, get_main_ifname()) == 0)
2065 ifname = get_station_ifname();
2066 else
2067 ifname = intf;
2068
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302069 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002070 if (id < 0)
2071 return id;
2072
2073 if (set_network(ifname, id, "eap", "FAST") < 0)
2074 return -2;
2075
2076 val = get_param(cmd, "innerEAP");
2077 if (val) {
2078 if (strcasecmp(val, "MSCHAPV2") == 0) {
2079 if (set_network_quoted(ifname, id, "phase2",
2080 "auth=MSCHAPV2") < 0)
2081 return -2;
2082 } else if (strcasecmp(val, "GTC") == 0) {
2083 if (set_network_quoted(ifname, id, "phase2",
2084 "auth=GTC") < 0)
2085 return -2;
2086 } else
2087 return -1;
2088 }
2089
2090 val = get_param(cmd, "validateServer");
2091 if (val) {
2092 /* TODO */
2093 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2094 "validateServer=%s", val);
2095 }
2096
2097 val = get_param(cmd, "pacFile");
2098 if (val) {
2099 snprintf(buf, sizeof(buf), "blob://%s", val);
2100 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2101 return -2;
2102 }
2103
2104 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2105 0)
2106 return -2;
2107
2108 return 1;
2109}
2110
2111
2112static int cmd_sta_set_eapaka(struct sigma_dut *dut, struct sigma_conn *conn,
2113 struct sigma_cmd *cmd)
2114{
2115 const char *intf = get_param(cmd, "Interface");
2116 const char *ifname;
2117 int id;
2118
2119 if (intf == NULL)
2120 return -1;
2121
2122 if (strcmp(intf, get_main_ifname()) == 0)
2123 ifname = get_station_ifname();
2124 else
2125 ifname = intf;
2126
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302127 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002128 if (id < 0)
2129 return id;
2130
2131 if (set_network(ifname, id, "eap", "AKA") < 0)
2132 return -2;
2133
2134 return 1;
2135}
2136
2137
2138static int cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2139 struct sigma_conn *conn,
2140 struct sigma_cmd *cmd)
2141{
2142 const char *intf = get_param(cmd, "Interface");
2143 const char *ifname;
2144 int id;
2145
2146 if (intf == NULL)
2147 return -1;
2148
2149 if (strcmp(intf, get_main_ifname()) == 0)
2150 ifname = get_station_ifname();
2151 else
2152 ifname = intf;
2153
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302154 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002155 if (id < 0)
2156 return id;
2157
2158 if (set_network(ifname, id, "eap", "AKA'") < 0)
2159 return -2;
2160
2161 return 1;
2162}
2163
2164
2165static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2166 struct sigma_cmd *cmd)
2167{
2168 const char *intf = get_param(cmd, "Interface");
2169 const char *ifname;
2170 int id;
2171
2172 if (strcmp(intf, get_main_ifname()) == 0)
2173 ifname = get_station_ifname();
2174 else
2175 ifname = intf;
2176
2177 id = add_network_common(dut, conn, ifname, cmd);
2178 if (id < 0)
2179 return id;
2180
2181 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2182 return -2;
2183
2184 return 1;
2185}
2186
2187
Jouni Malinen47dcc952017-10-09 16:43:24 +03002188static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2189 struct sigma_cmd *cmd)
2190{
2191 const char *intf = get_param(cmd, "Interface");
2192 const char *ifname, *val;
2193 int id;
2194
2195 if (intf == NULL)
2196 return -1;
2197
2198 if (strcmp(intf, get_main_ifname()) == 0)
2199 ifname = get_station_ifname();
2200 else
2201 ifname = intf;
2202
2203 id = set_wpa_common(dut, conn, ifname, cmd);
2204 if (id < 0)
2205 return id;
2206
2207 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2208 return -2;
2209
2210 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002211 if (val && strcmp(val, "0") == 0) {
2212 if (wpa_command(ifname,
2213 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2214 sigma_dut_print(dut, DUT_MSG_ERROR,
2215 "Failed to set OWE DH Param element override");
2216 return -2;
2217 }
2218 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002219 sigma_dut_print(dut, DUT_MSG_ERROR,
2220 "Failed to clear owe_group");
2221 return -2;
2222 }
2223
2224 return 1;
2225}
2226
2227
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002228static int cmd_sta_set_security(struct sigma_dut *dut, struct sigma_conn *conn,
2229 struct sigma_cmd *cmd)
2230{
2231 const char *type = get_param(cmd, "Type");
2232
2233 if (type == NULL) {
2234 send_resp(dut, conn, SIGMA_ERROR,
2235 "ErrorCode,Missing Type argument");
2236 return 0;
2237 }
2238
2239 if (strcasecmp(type, "OPEN") == 0)
2240 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002241 if (strcasecmp(type, "OWE") == 0)
2242 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002243 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002244 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002245 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002246 return cmd_sta_set_psk(dut, conn, cmd);
2247 if (strcasecmp(type, "EAPTLS") == 0)
2248 return cmd_sta_set_eaptls(dut, conn, cmd);
2249 if (strcasecmp(type, "EAPTTLS") == 0)
2250 return cmd_sta_set_eapttls(dut, conn, cmd);
2251 if (strcasecmp(type, "EAPPEAP") == 0)
2252 return cmd_sta_set_peap(dut, conn, cmd);
2253 if (strcasecmp(type, "EAPSIM") == 0)
2254 return cmd_sta_set_eapsim(dut, conn, cmd);
2255 if (strcasecmp(type, "EAPFAST") == 0)
2256 return cmd_sta_set_eapfast(dut, conn, cmd);
2257 if (strcasecmp(type, "EAPAKA") == 0)
2258 return cmd_sta_set_eapaka(dut, conn, cmd);
2259 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2260 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002261 if (strcasecmp(type, "wep") == 0)
2262 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002263
2264 send_resp(dut, conn, SIGMA_ERROR,
2265 "ErrorCode,Unsupported Type value");
2266 return 0;
2267}
2268
2269
2270int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
2271{
2272#ifdef __linux__
2273 /* special handling for ath6kl */
2274 char path[128], fname[128], *pos;
2275 ssize_t res;
2276 FILE *f;
2277
2278 snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", intf);
2279 res = readlink(path, path, sizeof(path));
2280 if (res < 0)
2281 return 0; /* not ath6kl */
2282
2283 if (res >= (int) sizeof(path))
2284 res = sizeof(path) - 1;
2285 path[res] = '\0';
2286 pos = strrchr(path, '/');
2287 if (pos == NULL)
2288 pos = path;
2289 else
2290 pos++;
2291 snprintf(fname, sizeof(fname),
2292 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2293 "create_qos", pos);
2294 if (!file_exists(fname))
2295 return 0; /* not ath6kl */
2296
2297 if (uapsd) {
2298 f = fopen(fname, "w");
2299 if (f == NULL)
2300 return -1;
2301
2302 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
2303 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
2304 "45000 200 56789000 56789000 5678900 0 0 9999999 "
2305 "20000 0\n");
2306 fclose(f);
2307 } else {
2308 snprintf(fname, sizeof(fname),
2309 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
2310 "delete_qos", pos);
2311
2312 f = fopen(fname, "w");
2313 if (f == NULL)
2314 return -1;
2315
2316 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
2317 fprintf(f, "2 4\n");
2318 fclose(f);
2319 }
2320#endif /* __linux__ */
2321
2322 return 0;
2323}
2324
2325
2326static int cmd_sta_set_uapsd(struct sigma_dut *dut, struct sigma_conn *conn,
2327 struct sigma_cmd *cmd)
2328{
2329 const char *intf = get_param(cmd, "Interface");
2330 /* const char *ssid = get_param(cmd, "ssid"); */
2331 const char *val;
2332 int max_sp_len = 4;
2333 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
2334 char buf[100];
2335 int ret1, ret2;
2336
2337 val = get_param(cmd, "maxSPLength");
2338 if (val) {
2339 max_sp_len = atoi(val);
2340 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
2341 max_sp_len != 4)
2342 return -1;
2343 }
2344
2345 val = get_param(cmd, "acBE");
2346 if (val)
2347 ac_be = atoi(val);
2348
2349 val = get_param(cmd, "acBK");
2350 if (val)
2351 ac_bk = atoi(val);
2352
2353 val = get_param(cmd, "acVI");
2354 if (val)
2355 ac_vi = atoi(val);
2356
2357 val = get_param(cmd, "acVO");
2358 if (val)
2359 ac_vo = atoi(val);
2360
2361 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
2362
2363 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
2364 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2365 ret1 = wpa_command(intf, buf);
2366
2367 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
2368 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
2369 ret2 = wpa_command(intf, buf);
2370
2371 if (ret1 && ret2) {
2372 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
2373 "UAPSD parameters.");
2374 return -2;
2375 }
2376
2377 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
2378 send_resp(dut, conn, SIGMA_ERROR,
2379 "ErrorCode,Failed to set ath6kl QoS parameters");
2380 return 0;
2381 }
2382
2383 return 1;
2384}
2385
2386
2387static int cmd_sta_set_wmm(struct sigma_dut *dut, struct sigma_conn *conn,
2388 struct sigma_cmd *cmd)
2389{
2390 char buf[1000];
2391 const char *intf = get_param(cmd, "Interface");
2392 const char *grp = get_param(cmd, "Group");
2393 const char *act = get_param(cmd, "Action");
2394 const char *tid = get_param(cmd, "Tid");
2395 const char *dir = get_param(cmd, "Direction");
2396 const char *psb = get_param(cmd, "Psb");
2397 const char *up = get_param(cmd, "Up");
2398 const char *fixed = get_param(cmd, "Fixed");
2399 const char *size = get_param(cmd, "Size");
2400 const char *msize = get_param(cmd, "Maxsize");
2401 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
2402 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
2403 const char *inact = get_param(cmd, "Inactivity");
2404 const char *sus = get_param(cmd, "Suspension");
2405 const char *mindr = get_param(cmd, "Mindatarate");
2406 const char *meandr = get_param(cmd, "Meandatarate");
2407 const char *peakdr = get_param(cmd, "Peakdatarate");
2408 const char *phyrate = get_param(cmd, "Phyrate");
2409 const char *burstsize = get_param(cmd, "Burstsize");
2410 const char *sba = get_param(cmd, "Sba");
2411 int direction;
2412 int handle;
Peng Xu93319622017-10-04 17:58:16 -07002413 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002414 int fixed_int;
2415 int psb_ts;
2416
2417 if (intf == NULL || grp == NULL || act == NULL )
2418 return -1;
2419
2420 if (strcasecmp(act, "addts") == 0) {
2421 if (tid == NULL || dir == NULL || psb == NULL ||
2422 up == NULL || fixed == NULL || size == NULL)
2423 return -1;
2424
2425 /*
2426 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
2427 * possible values, but WMM-AC and V-E test scripts use "UP,
2428 * "DOWN", and "BIDI".
2429 */
2430 if (strcasecmp(dir, "uplink") == 0 ||
2431 strcasecmp(dir, "up") == 0) {
2432 direction = 0;
2433 } else if (strcasecmp(dir, "downlink") == 0 ||
2434 strcasecmp(dir, "down") == 0) {
2435 direction = 1;
2436 } else if (strcasecmp(dir, "bidi") == 0) {
2437 direction = 2;
2438 } else {
2439 sigma_dut_print(dut, DUT_MSG_ERROR,
2440 "Direction %s not supported", dir);
2441 return -1;
2442 }
2443
2444 if (strcasecmp(psb, "legacy") == 0) {
2445 psb_ts = 0;
2446 } else if (strcasecmp(psb, "uapsd") == 0) {
2447 psb_ts = 1;
2448 } else {
2449 sigma_dut_print(dut, DUT_MSG_ERROR,
2450 "PSB %s not supported", psb);
2451 return -1;
2452 }
2453
2454 if (atoi(tid) < 0 || atoi(tid) > 7) {
2455 sigma_dut_print(dut, DUT_MSG_ERROR,
2456 "TID %s not supported", tid);
2457 return -1;
2458 }
2459
2460 if (strcasecmp(fixed, "true") == 0) {
2461 fixed_int = 1;
2462 } else {
2463 fixed_int = 0;
2464 }
2465
Peng Xu93319622017-10-04 17:58:16 -07002466 if (sba)
2467 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002468
2469 dut->dialog_token++;
2470 handle = 7000 + dut->dialog_token;
2471
2472 /*
2473 * size: convert to hex
2474 * maxsi: convert to hex
2475 * mindr: convert to hex
2476 * meandr: convert to hex
2477 * peakdr: convert to hex
2478 * burstsize: convert to hex
2479 * phyrate: convert to hex
2480 * sba: convert to hex with modification
2481 * minsi: convert to integer
2482 * sus: convert to integer
2483 * inact: convert to integer
2484 * maxsi: convert to integer
2485 */
2486
2487 /*
2488 * The Nominal MSDU Size field is 2 octets long and contains an
2489 * unsigned integer that specifies the nominal size, in octets,
2490 * of MSDUs belonging to the traffic under this traffic
2491 * specification and is defined in Figure 16. If the Fixed
2492 * subfield is set to 1, then the size of the MSDU is fixed and
2493 * is indicated by the Size Subfield. If the Fixed subfield is
2494 * set to 0, then the size of the MSDU might not be fixed and
2495 * the Size indicates the nominal MSDU size.
2496 *
2497 * The Surplus Bandwidth Allowance Factor field is 2 octets long
2498 * and specifies the excess allocation of time (and bandwidth)
2499 * over and above the stated rates required to transport an MSDU
2500 * belonging to the traffic in this TSPEC. This field is
2501 * represented as an unsigned binary number with an implicit
2502 * binary point after the leftmost 3 bits. For example, an SBA
2503 * of 1.75 is represented as 0x3800. This field is included to
2504 * account for retransmissions. As such, the value of this field
2505 * must be greater than unity.
2506 */
2507
2508 snprintf(buf, sizeof(buf),
2509 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
2510 " 0x%X 0x%X 0x%X"
2511 " 0x%X 0x%X 0x%X"
2512 " 0x%X %d %d %d %d"
2513 " %d %d",
2514 intf, handle, tid, direction, psb_ts, up,
2515 (unsigned int) ((fixed_int << 15) | atoi(size)),
2516 msize ? atoi(msize) : 0,
2517 mindr ? atoi(mindr) : 0,
2518 meandr ? atoi(meandr) : 0,
2519 peakdr ? atoi(peakdr) : 0,
2520 burstsize ? atoi(burstsize) : 0,
2521 phyrate ? atoi(phyrate) : 0,
2522 sba ? ((unsigned int) (((int) sba_fv << 13) |
2523 (int)((sba_fv - (int) sba_fv) *
2524 8192))) : 0,
2525 minsi ? atoi(minsi) : 0,
2526 sus ? atoi(sus) : 0,
2527 0, 0,
2528 inact ? atoi(inact) : 0,
2529 maxsi ? atoi(maxsi) : 0);
2530
2531 if (system(buf) != 0) {
2532 sigma_dut_print(dut, DUT_MSG_ERROR,
2533 "iwpriv addtspec request failed");
2534 send_resp(dut, conn, SIGMA_ERROR,
2535 "errorCode,Failed to execute addTspec command");
2536 return 0;
2537 }
2538
2539 sigma_dut_print(dut, DUT_MSG_INFO,
2540 "iwpriv addtspec request send");
2541
2542 /* Mapping handle to a TID */
2543 dut->tid_to_handle[atoi(tid)] = handle;
2544 } else if (strcasecmp(act, "delts") == 0) {
2545 if (tid == NULL)
2546 return -1;
2547
2548 if (atoi(tid) < 0 || atoi(tid) > 7) {
2549 sigma_dut_print(dut, DUT_MSG_ERROR,
2550 "TID %s not supported", tid);
2551 send_resp(dut, conn, SIGMA_ERROR,
2552 "errorCode,Unsupported TID");
2553 return 0;
2554 }
2555
2556 handle = dut->tid_to_handle[atoi(tid)];
2557
2558 if (handle < 7000 || handle > 7255) {
2559 /* Invalid handle ie no mapping for that TID */
2560 sigma_dut_print(dut, DUT_MSG_ERROR,
2561 "handle-> %d not found", handle);
2562 }
2563
2564 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
2565 intf, handle);
2566
2567 if (system(buf) != 0) {
2568 sigma_dut_print(dut, DUT_MSG_ERROR,
2569 "iwpriv deltspec request failed");
2570 send_resp(dut, conn, SIGMA_ERROR,
2571 "errorCode,Failed to execute delTspec command");
2572 return 0;
2573 }
2574
2575 sigma_dut_print(dut, DUT_MSG_INFO,
2576 "iwpriv deltspec request send");
2577
2578 dut->tid_to_handle[atoi(tid)] = 0;
2579 } else {
2580 sigma_dut_print(dut, DUT_MSG_ERROR,
2581 "Action type %s not supported", act);
2582 send_resp(dut, conn, SIGMA_ERROR,
2583 "errorCode,Unsupported Action");
2584 return 0;
2585 }
2586
2587 return 1;
2588}
2589
2590
vamsi krishna52e16f92017-08-29 12:37:34 +05302591static int find_network(struct sigma_dut *dut, const char *ssid)
2592{
2593 char list[4096];
2594 char *pos;
2595
2596 sigma_dut_print(dut, DUT_MSG_DEBUG,
2597 "Search for profile based on SSID: '%s'", ssid);
2598 if (wpa_command_resp(get_station_ifname(), "LIST_NETWORKS",
2599 list, sizeof(list)) < 0)
2600 return -1;
2601 pos = strstr(list, ssid);
2602 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
2603 return -1;
2604
2605 while (pos > list && pos[-1] != '\n')
2606 pos--;
2607 dut->infra_network_id = atoi(pos);
2608 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
2609 return 0;
2610}
2611
2612
Sunil Dutt44595082018-02-12 19:41:45 +05302613#ifdef NL80211_SUPPORT
2614static int sta_config_rsnie(struct sigma_dut *dut, int val)
2615{
2616 struct nl_msg *msg;
2617 int ret;
2618 struct nlattr *params;
2619 int ifindex;
2620
2621 ifindex = if_nametoindex("wlan0");
2622 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
2623 NL80211_CMD_VENDOR)) ||
2624 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
2625 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
2626 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
2627 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
2628 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
2629 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
2630 sigma_dut_print(dut, DUT_MSG_ERROR,
2631 "%s: err in adding vendor_cmd and vendor_data",
2632 __func__);
2633 nlmsg_free(msg);
2634 return -1;
2635 }
2636 nla_nest_end(msg, params);
2637
2638 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
2639 if (ret) {
2640 sigma_dut_print(dut, DUT_MSG_ERROR,
2641 "%s: err in send_and_recv_msgs, ret=%d",
2642 __func__, ret);
2643 return ret;
2644 }
2645
2646 return 0;
2647}
2648#endif /* NL80211_SUPPORT */
2649
2650
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002651static int cmd_sta_associate(struct sigma_dut *dut, struct sigma_conn *conn,
2652 struct sigma_cmd *cmd)
2653{
2654 /* const char *intf = get_param(cmd, "Interface"); */
2655 const char *ssid = get_param(cmd, "ssid");
2656 const char *wps_param = get_param(cmd, "WPS");
2657 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03002658 const char *chan = get_param(cmd, "channel");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002659 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03002660 char buf[1000], extra[50];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002661
2662 if (ssid == NULL)
2663 return -1;
2664
Jouni Malinen3c367e82017-06-23 17:01:47 +03002665 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05302666#ifdef NL80211_SUPPORT
2667 if (get_driver_type() == DRIVER_WCN) {
2668 sta_config_rsnie(dut, 1);
2669 dut->config_rsnie = 1;
2670 }
2671#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03002672 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
2673 dut->rsne_override);
2674 if (wpa_command(get_station_ifname(), buf) < 0) {
2675 send_resp(dut, conn, SIGMA_ERROR,
2676 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
2677 return 0;
2678 }
2679 }
2680
Jouni Malinen68143132017-09-02 02:34:08 +03002681 if (dut->sae_commit_override) {
2682 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
2683 dut->sae_commit_override);
2684 if (wpa_command(get_station_ifname(), buf) < 0) {
2685 send_resp(dut, conn, SIGMA_ERROR,
2686 "ErrorCode,Failed to set SAE commit override");
2687 return 0;
2688 }
2689 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05302690#ifdef ANDROID
2691 if (dut->fils_hlp)
2692 process_fils_hlp(dut);
2693#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03002694
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002695 if (wps_param &&
2696 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
2697 wps = 1;
2698
2699 if (wps) {
2700 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
2701 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
2702 "parameters not yet set");
2703 return 0;
2704 }
2705 if (dut->wps_method == WFA_CS_WPS_PBC) {
2706 if (wpa_command(get_station_ifname(), "WPS_PBC") < 0)
2707 return -2;
2708 } else {
2709 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
2710 dut->wps_pin);
2711 if (wpa_command(get_station_ifname(), buf) < 0)
2712 return -2;
2713 }
2714 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05302715 if (strcmp(ssid, dut->infra_ssid) == 0) {
2716 sigma_dut_print(dut, DUT_MSG_DEBUG,
2717 "sta_associate for the most recently added network");
2718 } else if (find_network(dut, ssid) < 0) {
2719 sigma_dut_print(dut, DUT_MSG_DEBUG,
2720 "sta_associate for a previously stored network profile");
2721 send_resp(dut, conn, SIGMA_ERROR,
2722 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002723 return 0;
2724 }
2725
2726 if (bssid &&
2727 set_network(get_station_ifname(), dut->infra_network_id,
2728 "bssid", bssid) < 0) {
2729 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2730 "Invalid bssid argument");
2731 return 0;
2732 }
2733
Jouni Malinen46a19b62017-06-23 14:31:27 +03002734 extra[0] = '\0';
2735 if (chan)
2736 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02002737 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03002738 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
2739 dut->infra_network_id, extra);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002740 if (wpa_command(get_station_ifname(), buf) < 0) {
2741 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
2742 "network id %d on %s",
2743 dut->infra_network_id,
2744 get_station_ifname());
2745 return -2;
2746 }
2747 }
2748
2749 return 1;
2750}
2751
2752
2753static int run_hs20_osu(struct sigma_dut *dut, const char *params)
2754{
2755 char buf[500], cmd[200];
2756 int res;
2757
2758 /* Use hs20-osu-client file at the current dir, if found; otherwise use
2759 * default path */
2760 res = snprintf(cmd, sizeof(cmd),
2761 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
2762 file_exists("./hs20-osu-client") ?
2763 "./hs20-osu-client" : "hs20-osu-client",
2764 sigma_wpas_ctrl,
2765 dut->summary_log ? "-s " : "",
2766 dut->summary_log ? dut->summary_log : "");
2767 if (res < 0 || res >= (int) sizeof(cmd))
2768 return -1;
2769
2770 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
2771 if (res < 0 || res >= (int) sizeof(buf))
2772 return -1;
2773 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
2774
2775 if (system(buf) != 0) {
2776 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
2777 return -1;
2778 }
2779 sigma_dut_print(dut, DUT_MSG_DEBUG,
2780 "Completed hs20-osu-client operation");
2781
2782 return 0;
2783}
2784
2785
2786static int download_ppsmo(struct sigma_dut *dut,
2787 struct sigma_conn *conn,
2788 const char *intf,
2789 struct sigma_cmd *cmd)
2790{
2791 const char *name, *path, *val;
2792 char url[500], buf[600], fbuf[100];
2793 char *fqdn = NULL;
2794
2795 name = get_param(cmd, "FileName");
2796 path = get_param(cmd, "FilePath");
2797 if (name == NULL || path == NULL)
2798 return -1;
2799
2800 if (strcasecmp(path, "VendorSpecific") == 0) {
2801 snprintf(url, sizeof(url), "PPS/%s", name);
2802 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
2803 "from the device (%s)", url);
2804 if (!file_exists(url)) {
2805 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2806 "PPS MO file does not exist");
2807 return 0;
2808 }
2809 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
2810 if (system(buf) != 0) {
2811 send_resp(dut, conn, SIGMA_ERROR,
2812 "errorCode,Failed to copy PPS MO");
2813 return 0;
2814 }
2815 } else if (strncasecmp(path, "http:", 5) != 0 &&
2816 strncasecmp(path, "https:", 6) != 0) {
2817 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
2818 "Unsupported FilePath value");
2819 return 0;
2820 } else {
2821 snprintf(url, sizeof(url), "%s/%s", path, name);
2822 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
2823 url);
2824 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
2825 remove("pps-tnds.xml");
2826 if (system(buf) != 0) {
2827 send_resp(dut, conn, SIGMA_ERROR,
2828 "errorCode,Failed to download PPS MO");
2829 return 0;
2830 }
2831 }
2832
2833 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
2834 send_resp(dut, conn, SIGMA_ERROR,
2835 "errorCode,Failed to parse downloaded PPSMO");
2836 return 0;
2837 }
2838 unlink("pps-tnds.xml");
2839
2840 val = get_param(cmd, "managementTreeURI");
2841 if (val) {
2842 const char *pos, *end;
2843 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
2844 val);
2845 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
2846 send_resp(dut, conn, SIGMA_ERROR,
2847 "errorCode,Invalid managementTreeURI prefix");
2848 return 0;
2849 }
2850 pos = val + 8;
2851 end = strchr(pos, '/');
2852 if (end == NULL ||
2853 strcmp(end, "/PerProviderSubscription") != 0) {
2854 send_resp(dut, conn, SIGMA_ERROR,
2855 "errorCode,Invalid managementTreeURI postfix");
2856 return 0;
2857 }
2858 if (end - pos >= (int) sizeof(fbuf)) {
2859 send_resp(dut, conn, SIGMA_ERROR,
2860 "errorCode,Too long FQDN in managementTreeURI");
2861 return 0;
2862 }
2863 memcpy(fbuf, pos, end - pos);
2864 fbuf[end - pos] = '\0';
2865 fqdn = fbuf;
2866 sigma_dut_print(dut, DUT_MSG_INFO,
2867 "FQDN from managementTreeURI: %s", fqdn);
2868 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
2869 FILE *f = fopen("pps-fqdn", "r");
2870 if (f) {
2871 if (fgets(fbuf, sizeof(fbuf), f)) {
2872 fbuf[sizeof(fbuf) - 1] = '\0';
2873 fqdn = fbuf;
2874 sigma_dut_print(dut, DUT_MSG_DEBUG,
2875 "Use FQDN %s", fqdn);
2876 }
2877 fclose(f);
2878 }
2879 }
2880
2881 if (fqdn == NULL) {
2882 send_resp(dut, conn, SIGMA_ERROR,
2883 "errorCode,No FQDN specified");
2884 return 0;
2885 }
2886
2887 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2888 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
2889 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
2890
2891 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
2892 if (rename("pps.xml", buf) < 0) {
2893 send_resp(dut, conn, SIGMA_ERROR,
2894 "errorCode,Could not move PPS MO");
2895 return 0;
2896 }
2897
2898 if (strcasecmp(path, "VendorSpecific") == 0) {
2899 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
2900 fqdn);
2901 if (system(buf)) {
2902 send_resp(dut, conn, SIGMA_ERROR,
2903 "errorCode,Failed to copy OSU CA cert");
2904 return 0;
2905 }
2906
2907 snprintf(buf, sizeof(buf),
2908 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
2909 fqdn);
2910 if (system(buf)) {
2911 send_resp(dut, conn, SIGMA_ERROR,
2912 "errorCode,Failed to copy AAA CA cert");
2913 return 0;
2914 }
2915 } else {
2916 snprintf(buf, sizeof(buf),
2917 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
2918 fqdn, fqdn);
2919 if (run_hs20_osu(dut, buf) < 0) {
2920 send_resp(dut, conn, SIGMA_ERROR,
2921 "errorCode,Failed to download OSU CA cert");
2922 return 0;
2923 }
2924
2925 snprintf(buf, sizeof(buf),
2926 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
2927 fqdn, fqdn);
2928 if (run_hs20_osu(dut, buf) < 0) {
2929 sigma_dut_print(dut, DUT_MSG_INFO,
2930 "Failed to download AAA CA cert");
2931 }
2932 }
2933
2934 if (file_exists("next-client-cert.pem")) {
2935 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
2936 if (rename("next-client-cert.pem", buf) < 0) {
2937 send_resp(dut, conn, SIGMA_ERROR,
2938 "errorCode,Could not move client certificate");
2939 return 0;
2940 }
2941 }
2942
2943 if (file_exists("next-client-key.pem")) {
2944 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
2945 if (rename("next-client-key.pem", buf) < 0) {
2946 send_resp(dut, conn, SIGMA_ERROR,
2947 "errorCode,Could not move client key");
2948 return 0;
2949 }
2950 }
2951
2952 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
2953 if (run_hs20_osu(dut, buf) < 0) {
2954 send_resp(dut, conn, SIGMA_ERROR,
2955 "errorCode,Failed to configure credential from "
2956 "PPSMO");
2957 return 0;
2958 }
2959
2960 return 1;
2961}
2962
2963
2964static int download_cert(struct sigma_dut *dut,
2965 struct sigma_conn *conn,
2966 const char *intf,
2967 struct sigma_cmd *cmd)
2968{
2969 const char *name, *path;
2970 char url[500], buf[600];
2971
2972 name = get_param(cmd, "FileName");
2973 path = get_param(cmd, "FilePath");
2974 if (name == NULL || path == NULL)
2975 return -1;
2976
2977 if (strcasecmp(path, "VendorSpecific") == 0) {
2978 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
2979 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2980 "certificate from the device (%s)", url);
2981 if (!file_exists(url)) {
2982 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2983 "certificate file does not exist");
2984 return 0;
2985 }
2986 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
2987 if (system(buf) != 0) {
2988 send_resp(dut, conn, SIGMA_ERROR,
2989 "errorCode,Failed to copy client "
2990 "certificate");
2991 return 0;
2992 }
2993
2994 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
2995 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
2996 "private key from the device (%s)", url);
2997 if (!file_exists(url)) {
2998 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
2999 "private key file does not exist");
3000 return 0;
3001 }
3002 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3003 if (system(buf) != 0) {
3004 send_resp(dut, conn, SIGMA_ERROR,
3005 "errorCode,Failed to copy client key");
3006 return 0;
3007 }
3008 } else if (strncasecmp(path, "http:", 5) != 0 &&
3009 strncasecmp(path, "https:", 6) != 0) {
3010 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3011 "Unsupported FilePath value");
3012 return 0;
3013 } else {
3014 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3015 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3016 "certificate/key from %s", url);
3017 snprintf(buf, sizeof(buf),
3018 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3019 if (system(buf) != 0) {
3020 send_resp(dut, conn, SIGMA_ERROR,
3021 "errorCode,Failed to download client "
3022 "certificate");
3023 return 0;
3024 }
3025
3026 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3027 {
3028 send_resp(dut, conn, SIGMA_ERROR,
3029 "errorCode,Failed to copy client key");
3030 return 0;
3031 }
3032 }
3033
3034 return 1;
3035}
3036
3037
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003038static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3039 struct sigma_conn *conn,
3040 struct sigma_cmd *cmd)
3041{
3042 const char *val;
3043 const char *intf = get_param(cmd, "interface");
3044
3045 if (!intf)
3046 return -1;
3047
3048 val = get_param(cmd, "WscIEFragment");
3049 if (val && strcasecmp(val, "enable") == 0) {
3050 sigma_dut_print(dut, DUT_MSG_DEBUG,
3051 "Enable WSC IE fragmentation");
3052
3053 dut->wsc_fragment = 1;
3054 /* set long attributes to force fragmentation */
3055 if (wpa_command(intf, "SET device_name "
3056 WPS_LONG_DEVICE_NAME) < 0)
3057 return -2;
3058 if (wpa_command(intf, "SET manufacturer "
3059 WPS_LONG_MANUFACTURER) < 0)
3060 return -2;
3061 if (wpa_command(intf, "SET model_name "
3062 WPS_LONG_MODEL_NAME) < 0)
3063 return -2;
3064 if (wpa_command(intf, "SET model_number "
3065 WPS_LONG_MODEL_NUMBER) < 0)
3066 return -2;
3067 if (wpa_command(intf, "SET serial_number "
3068 WPS_LONG_SERIAL_NUMBER) < 0)
3069 return -2;
3070 }
3071
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003072 val = get_param(cmd, "RSN_IE");
3073 if (val) {
3074 if (strcasecmp(val, "disable") == 0)
3075 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3076 else if (strcasecmp(val, "enable") == 0)
3077 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3078 }
3079
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003080 return 1;
3081}
3082
3083
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003084static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3085 struct sigma_conn *conn,
3086 const char *intf,
3087 struct sigma_cmd *cmd)
3088{
3089 const char *val;
3090
3091 val = get_param(cmd, "FileType");
3092 if (val && strcasecmp(val, "PPSMO") == 0)
3093 return download_ppsmo(dut, conn, intf, cmd);
3094 if (val && strcasecmp(val, "CERT") == 0)
3095 return download_cert(dut, conn, intf, cmd);
3096 if (val) {
3097 send_resp(dut, conn, SIGMA_ERROR,
3098 "ErrorCode,Unsupported FileType");
3099 return 0;
3100 }
3101
3102 return 1;
3103}
3104
3105
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303106static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3107 struct sigma_conn *conn,
3108 const char *intf,
3109 struct sigma_cmd *cmd)
3110{
3111 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303112 char buf[1000];
3113 char text[20];
3114 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303115
3116 val = get_param(cmd, "OCESupport");
3117 if (val && strcasecmp(val, "Disable") == 0) {
3118 if (wpa_command(intf, "SET oce 0") < 0) {
3119 send_resp(dut, conn, SIGMA_ERROR,
3120 "ErrorCode,Failed to disable OCE");
3121 return 0;
3122 }
3123 } else if (val && strcasecmp(val, "Enable") == 0) {
3124 if (wpa_command(intf, "SET oce 1") < 0) {
3125 send_resp(dut, conn, SIGMA_ERROR,
3126 "ErrorCode,Failed to enable OCE");
3127 return 0;
3128 }
3129 }
3130
vamsi krishnaa2799492017-12-05 14:28:01 +05303131 val = get_param(cmd, "FILScap");
3132 if (val && (atoi(val) == 1)) {
3133 if (wpa_command(intf, "SET disable_fils 0") < 0) {
3134 send_resp(dut, conn, SIGMA_ERROR,
3135 "ErrorCode,Failed to enable FILS");
3136 return 0;
3137 }
3138 } else if (val && (atoi(val) == 0)) {
3139 if (wpa_command(intf, "SET disable_fils 1") < 0) {
3140 send_resp(dut, conn, SIGMA_ERROR,
3141 "ErrorCode,Failed to disable FILS");
3142 return 0;
3143 }
3144 }
3145
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303146 val = get_param(cmd, "FILSHLP");
3147 if (val && strcasecmp(val, "Enable") == 0) {
3148 if (get_wpa_status(get_station_ifname(), "address", text,
3149 sizeof(text)) < 0)
3150 return -2;
3151 hwaddr_aton(text, addr);
3152 snprintf(buf, sizeof(buf),
3153 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
3154 "080045100140000040004011399e00000000ffffffff00440043"
3155 "012cb30001010600fd4f46410000000000000000000000000000"
3156 "000000000000"
3157 "%02x%02x%02x%02x%02x%02x"
3158 "0000000000000000000000000000000000000000000000000000"
3159 "0000000000000000000000000000000000000000000000000000"
3160 "0000000000000000000000000000000000000000000000000000"
3161 "0000000000000000000000000000000000000000000000000000"
3162 "0000000000000000000000000000000000000000000000000000"
3163 "0000000000000000000000000000000000000000000000000000"
3164 "0000000000000000000000000000000000000000000000000000"
3165 "0000000000000000000000000000000000000000638253633501"
3166 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
3167 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
3168 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
3169 if (wpa_command(intf, buf)) {
3170 send_resp(dut, conn, SIGMA_ERROR,
3171 "ErrorCode,Failed to add HLP");
3172 return 0;
3173 }
3174 dut->fils_hlp = 1;
3175 }
3176
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303177 return 1;
3178}
3179
3180
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003181static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
3182 const char *val)
3183{
3184 int counter = 0;
3185 char token[50];
3186 char *result;
3187 char buf[100];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303188 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003189
Peng Xub8fc5cc2017-05-10 17:27:28 -07003190 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003191 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303192 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003193 while (result) {
3194 if (strcmp(result, "disable") == 0) {
3195 snprintf(buf, sizeof(buf),
3196 "iwpriv %s noackpolicy %d 1 0",
3197 intf, counter);
3198 } else {
3199 snprintf(buf, sizeof(buf),
3200 "iwpriv %s noackpolicy %d 1 1",
3201 intf, counter);
3202 }
3203 if (system(buf) != 0) {
3204 sigma_dut_print(dut, DUT_MSG_ERROR,
3205 "iwpriv noackpolicy failed");
3206 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05303207 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003208 counter++;
3209 }
3210}
3211
3212
3213static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
3214 const char *val)
3215{
3216 char buf[100];
3217
3218 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
3219 if (system(buf) != 0) {
3220 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
3221 }
3222}
3223
3224
3225static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3226 const char *val)
3227{
3228 char buf[100];
3229
3230 if (strcasecmp(val, "off") == 0) {
3231 snprintf(buf, sizeof(buf), "iwpriv %s wmm 0", intf);
3232 if (system(buf) != 0) {
3233 sigma_dut_print(dut, DUT_MSG_ERROR,
3234 "Failed to turn off WMM");
3235 }
3236 }
3237}
3238
3239
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08003240static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
3241 const char *val)
3242{
3243#ifdef NL80211_SUPPORT
3244 struct nl_msg *msg;
3245 int ret = 0;
3246 struct nlattr *params;
3247 int ifindex;
3248 int wmmenable = 1;
3249
3250 if (val &&
3251 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
3252 wmmenable = 0;
3253
3254 ifindex = if_nametoindex(intf);
3255 if (ifindex == 0) {
3256 sigma_dut_print(dut, DUT_MSG_ERROR,
3257 "%s: Index for interface %s failed",
3258 __func__, intf);
3259 return -1;
3260 }
3261
3262 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3263 NL80211_CMD_VENDOR)) ||
3264 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3265 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3266 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3267 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3268 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3269 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
3270 wmmenable)) {
3271 sigma_dut_print(dut, DUT_MSG_ERROR,
3272 "%s: err in adding vendor_cmd and vendor_data",
3273 __func__);
3274 nlmsg_free(msg);
3275 return -1;
3276 }
3277 nla_nest_end(msg, params);
3278
3279 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3280 if (ret) {
3281 sigma_dut_print(dut, DUT_MSG_ERROR,
3282 "%s: err in send_and_recv_msgs, ret=%d",
3283 __func__, ret);
3284 }
3285 return ret;
3286#else /* NL80211_SUPPORT */
3287 sigma_dut_print(dut, DUT_MSG_ERROR,
3288 "WMM cannot be changed without NL80211_SUPPORT defined");
3289 return -1;
3290#endif /* NL80211_SUPPORT */
3291}
3292
3293
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003294static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
3295 const char *val)
3296{
3297 char buf[100];
3298 int sgi20;
3299
3300 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
3301
3302 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi20);
3303 if (system(buf) != 0)
3304 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv shortgi failed");
3305}
3306
3307
3308static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
3309 const char *val)
3310{
3311 char buf[100];
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303312 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003313
3314 /* Disable Tx Beam forming when using a fixed rate */
3315 ath_disable_txbf(dut, intf);
3316
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05303317 v = atoi(val);
3318 if (v < 0 || v > 32) {
3319 sigma_dut_print(dut, DUT_MSG_ERROR,
3320 "Invalid Fixed MCS rate: %d", v);
3321 return;
3322 }
3323 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003324
3325 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0x%x",
3326 intf, rate_code);
3327 if (system(buf) != 0) {
3328 sigma_dut_print(dut, DUT_MSG_ERROR,
3329 "iwpriv set11NRates failed");
3330 }
3331
3332 /* Channel width gets messed up, fix this */
3333 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d", intf, dut->chwidth);
3334 if (system(buf) != 0)
3335 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
3336}
3337
3338
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08003339static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
3340 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003341{
3342 char buf[60];
3343
3344 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
3345 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
3346 else
3347 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
3348
3349 if (system(buf) != 0)
3350 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
3351}
3352
3353
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003354static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
3355 int ampdu)
3356{
3357 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003358 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003359
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08003360 if (ampdu)
3361 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07003362 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
3363 if (system(buf) != 0) {
3364 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
3365 return -1;
3366 }
3367
3368 return 0;
3369}
3370
3371
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003372static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3373 const char *val)
3374{
3375 char buf[60];
3376
3377 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3378 if (system(buf) != 0) {
3379 sigma_dut_print(dut, DUT_MSG_ERROR,
3380 "iwpriv tx_stbc failed");
3381 }
3382
3383 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3384 if (system(buf) != 0) {
3385 sigma_dut_print(dut, DUT_MSG_ERROR,
3386 "iwpriv rx_stbc failed");
3387 }
3388}
3389
3390
3391static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
3392 const char *val)
3393{
3394 char buf[60];
3395
Peng Xucc317ed2017-05-18 16:44:37 -07003396 if (strcmp(val, "160") == 0) {
3397 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
3398 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003399 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
3400 } else if (strcmp(val, "40") == 0) {
3401 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
3402 } else if (strcmp(val, "20") == 0) {
3403 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
3404 } else if (strcasecmp(val, "Auto") == 0) {
3405 buf[0] = '\0';
3406 } else {
3407 sigma_dut_print(dut, DUT_MSG_ERROR,
3408 "WIDTH/CTS_WIDTH value not supported");
3409 return -1;
3410 }
3411
3412 if (buf[0] != '\0' && system(buf) != 0) {
3413 sigma_dut_print(dut, DUT_MSG_ERROR,
3414 "Failed to set WIDTH/CTS_WIDTH");
3415 return -1;
3416 }
3417
3418 return 0;
3419}
3420
3421
3422int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
3423 const char *intf, const char *val)
3424{
3425 char buf[60];
3426
3427 if (strcasecmp(val, "Auto") == 0) {
3428 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3429 dut->chwidth = 0;
3430 } else if (strcasecmp(val, "20") == 0) {
3431 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
3432 dut->chwidth = 0;
3433 } else if (strcasecmp(val, "40") == 0) {
3434 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
3435 dut->chwidth = 1;
3436 } else if (strcasecmp(val, "80") == 0) {
3437 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
3438 dut->chwidth = 2;
3439 } else if (strcasecmp(val, "160") == 0) {
3440 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 3", intf);
3441 dut->chwidth = 3;
3442 } else {
3443 send_resp(dut, conn, SIGMA_ERROR,
3444 "ErrorCode,WIDTH not supported");
3445 return -1;
3446 }
3447
3448 if (system(buf) != 0) {
3449 sigma_dut_print(dut, DUT_MSG_ERROR,
3450 "iwpriv chwidth failed");
3451 }
3452
3453 return 0;
3454}
3455
3456
3457static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
3458 const char *val)
3459{
3460 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07003461 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003462
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003463 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003464 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003465 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08003466 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003467 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07003468 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003469 } else {
3470 sigma_dut_print(dut, DUT_MSG_ERROR,
3471 "SP_STREAM value not supported");
3472 return -1;
3473 }
3474
3475 if (system(buf) != 0) {
3476 sigma_dut_print(dut, DUT_MSG_ERROR,
3477 "Failed to set SP_STREAM");
3478 return -1;
3479 }
3480
Arif Hussainac6c5112018-05-25 17:34:00 -07003481 dut->sta_nss = sta_nss;
3482
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003483 return 0;
3484}
3485
3486
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05303487static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
3488 const char *val)
3489{
3490 char buf[60];
3491
3492 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
3493 if (system(buf) != 0)
3494 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
3495
3496 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
3497 if (system(buf) != 0)
3498 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
3499}
3500
3501
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303502static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
3503 struct sigma_conn *conn,
3504 const char *intf, int capa)
3505{
3506 char buf[32];
3507
3508 if (capa > 0 && capa < 4) {
3509 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
3510 if (wpa_command(intf, buf) < 0) {
3511 send_resp(dut, conn, SIGMA_ERROR,
3512 "ErrorCode, Failed to set cellular data capability");
3513 return 0;
3514 }
3515 return 1;
3516 }
3517
3518 sigma_dut_print(dut, DUT_MSG_ERROR,
3519 "Invalid Cellular data capability: %d", capa);
3520 send_resp(dut, conn, SIGMA_INVALID,
3521 "ErrorCode,Invalid cellular data capability");
3522 return 0;
3523}
3524
3525
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303526static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
3527 const char *intf, const char *val)
3528{
3529 if (strcasecmp(val, "Disable") == 0) {
3530 if (wpa_command(intf, "SET roaming 0") < 0) {
3531 send_resp(dut, conn, SIGMA_ERROR,
3532 "ErrorCode,Failed to disable roaming");
3533 return 0;
3534 }
3535 return 1;
3536 }
3537
3538 if (strcasecmp(val, "Enable") == 0) {
3539 if (wpa_command(intf, "SET roaming 1") < 0) {
3540 send_resp(dut, conn, SIGMA_ERROR,
3541 "ErrorCode,Failed to enable roaming");
3542 return 0;
3543 }
3544 return 1;
3545 }
3546
3547 sigma_dut_print(dut, DUT_MSG_ERROR,
3548 "Invalid value provided for roaming: %s", val);
3549 send_resp(dut, conn, SIGMA_INVALID,
3550 "ErrorCode,Unknown value provided for Roaming");
3551 return 0;
3552}
3553
3554
Ashwini Patila75de5a2017-04-13 16:35:05 +05303555static int mbo_set_assoc_disallow(struct sigma_dut *dut,
3556 struct sigma_conn *conn,
3557 const char *intf, const char *val)
3558{
3559 if (strcasecmp(val, "Disable") == 0) {
3560 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
3561 send_resp(dut, conn, SIGMA_ERROR,
3562 "ErrorCode,Failed to disable Assoc_disallow");
3563 return 0;
3564 }
3565 return 1;
3566 }
3567
3568 if (strcasecmp(val, "Enable") == 0) {
3569 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
3570 send_resp(dut, conn, SIGMA_ERROR,
3571 "ErrorCode,Failed to enable Assoc_disallow");
3572 return 0;
3573 }
3574 return 1;
3575 }
3576
3577 sigma_dut_print(dut, DUT_MSG_ERROR,
3578 "Invalid value provided for Assoc_disallow: %s", val);
3579 send_resp(dut, conn, SIGMA_INVALID,
3580 "ErrorCode,Unknown value provided for Assoc_disallow");
3581 return 0;
3582}
3583
3584
Ashwini Patilc63161e2017-04-13 16:30:23 +05303585static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
3586 const char *intf, const char *val)
3587{
3588 if (strcasecmp(val, "Reject") == 0) {
3589 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
3590 send_resp(dut, conn, SIGMA_ERROR,
3591 "ErrorCode,Failed to Reject BTM Request");
3592 return 0;
3593 }
3594 return 1;
3595 }
3596
3597 if (strcasecmp(val, "Accept") == 0) {
3598 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
3599 send_resp(dut, conn, SIGMA_ERROR,
3600 "ErrorCode,Failed to Accept BTM Request");
3601 return 0;
3602 }
3603 return 1;
3604 }
3605
3606 sigma_dut_print(dut, DUT_MSG_ERROR,
3607 "Invalid value provided for BSS_Transition: %s", val);
3608 send_resp(dut, conn, SIGMA_INVALID,
3609 "ErrorCode,Unknown value provided for BSS_Transition");
3610 return 0;
3611}
3612
3613
Ashwini Patil00402582017-04-13 12:29:39 +05303614static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
3615 struct sigma_conn *conn,
3616 const char *intf,
3617 struct sigma_cmd *cmd)
3618{
3619 const char *ch, *pref, *op_class, *reason;
3620 char buf[120];
3621 int len, ret;
3622
3623 pref = get_param(cmd, "Ch_Pref");
3624 if (!pref)
3625 return 1;
3626
3627 if (strcasecmp(pref, "clear") == 0) {
3628 free(dut->non_pref_ch_list);
3629 dut->non_pref_ch_list = NULL;
3630 } else {
3631 op_class = get_param(cmd, "Ch_Op_Class");
3632 if (!op_class) {
3633 send_resp(dut, conn, SIGMA_INVALID,
3634 "ErrorCode,Ch_Op_Class not provided");
3635 return 0;
3636 }
3637
3638 ch = get_param(cmd, "Ch_Pref_Num");
3639 if (!ch) {
3640 send_resp(dut, conn, SIGMA_INVALID,
3641 "ErrorCode,Ch_Pref_Num not provided");
3642 return 0;
3643 }
3644
3645 reason = get_param(cmd, "Ch_Reason_Code");
3646 if (!reason) {
3647 send_resp(dut, conn, SIGMA_INVALID,
3648 "ErrorCode,Ch_Reason_Code not provided");
3649 return 0;
3650 }
3651
3652 if (!dut->non_pref_ch_list) {
3653 dut->non_pref_ch_list =
3654 calloc(1, NON_PREF_CH_LIST_SIZE);
3655 if (!dut->non_pref_ch_list) {
3656 send_resp(dut, conn, SIGMA_ERROR,
3657 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
3658 return 0;
3659 }
3660 }
3661 len = strlen(dut->non_pref_ch_list);
3662 ret = snprintf(dut->non_pref_ch_list + len,
3663 NON_PREF_CH_LIST_SIZE - len,
3664 " %s:%s:%s:%s", op_class, ch, pref, reason);
3665 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
3666 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
3667 dut->non_pref_ch_list);
3668 } else {
3669 sigma_dut_print(dut, DUT_MSG_ERROR,
3670 "snprintf failed for non_pref_list, ret = %d",
3671 ret);
3672 send_resp(dut, conn, SIGMA_ERROR,
3673 "ErrorCode,snprintf failed");
3674 free(dut->non_pref_ch_list);
3675 dut->non_pref_ch_list = NULL;
3676 return 0;
3677 }
3678 }
3679
3680 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
3681 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
3682 if (ret < 0 || ret >= (int) sizeof(buf)) {
3683 sigma_dut_print(dut, DUT_MSG_DEBUG,
3684 "snprintf failed for set non_pref_chan, ret: %d",
3685 ret);
3686 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
3687 return 0;
3688 }
3689
3690 if (wpa_command(intf, buf) < 0) {
3691 send_resp(dut, conn, SIGMA_ERROR,
3692 "ErrorCode,Failed to set non-preferred channel list");
3693 return 0;
3694 }
3695
3696 return 1;
3697}
3698
3699
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003700#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003701
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08003702static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
3703 uint8_t cfg)
3704{
3705 struct nl_msg *msg;
3706 int ret = 0;
3707 struct nlattr *params;
3708 int ifindex;
3709
3710 ifindex = if_nametoindex(intf);
3711 if (ifindex == 0) {
3712 sigma_dut_print(dut, DUT_MSG_ERROR,
3713 "%s: Index for interface %s failed",
3714 __func__, intf);
3715 return -1;
3716 }
3717
3718 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3719 NL80211_CMD_VENDOR)) ||
3720 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3721 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3722 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3723 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3724 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3725 nla_put_u8(msg,
3726 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
3727 cfg)) {
3728 sigma_dut_print(dut, DUT_MSG_ERROR,
3729 "%s: err in adding vendor_cmd and vendor_data",
3730 __func__);
3731 nlmsg_free(msg);
3732 return -1;
3733 }
3734 nla_nest_end(msg, params);
3735
3736 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3737 if (ret) {
3738 sigma_dut_print(dut, DUT_MSG_ERROR,
3739 "%s: err in send_and_recv_msgs, ret=%d",
3740 __func__, ret);
3741 }
3742 return ret;
3743}
3744
3745
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003746static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
3747 enum he_fragmentation_val frag)
3748{
3749 struct nl_msg *msg;
3750 int ret = 0;
3751 struct nlattr *params;
3752 int ifindex;
3753
3754 ifindex = if_nametoindex(intf);
3755 if (ifindex == 0) {
3756 sigma_dut_print(dut, DUT_MSG_ERROR,
3757 "%s: Index for interface %s failed",
3758 __func__, intf);
3759 return -1;
3760 }
3761
3762 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3763 NL80211_CMD_VENDOR)) ||
3764 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3765 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3766 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3767 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3768 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3769 nla_put_u8(msg,
3770 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
3771 frag)) {
3772 sigma_dut_print(dut, DUT_MSG_ERROR,
3773 "%s: err in adding vendor_cmd and vendor_data",
3774 __func__);
3775 nlmsg_free(msg);
3776 return -1;
3777 }
3778 nla_nest_end(msg, params);
3779
3780 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3781 if (ret) {
3782 sigma_dut_print(dut, DUT_MSG_ERROR,
3783 "%s: err in send_and_recv_msgs, ret=%d",
3784 __func__, ret);
3785 }
3786 return ret;
3787}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003788
3789
Subhani Shaik8e7a3052018-04-24 14:03:00 -07003790static int sta_set_he_ltf(struct sigma_dut *dut, const char *intf,
3791 enum qca_wlan_he_ltf_cfg ltf)
3792{
3793 struct nl_msg *msg;
3794 int ret = 0;
3795 struct nlattr *params;
3796 int ifindex;
3797
3798 ifindex = if_nametoindex(intf);
3799 if (ifindex == 0) {
3800 sigma_dut_print(dut, DUT_MSG_ERROR,
3801 "%s: Index for interface %s failed",
3802 __func__, intf);
3803 return -1;
3804 }
3805
3806 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3807 NL80211_CMD_VENDOR)) ||
3808 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3809 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3810 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3811 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3812 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3813 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
3814 ltf)) {
3815 sigma_dut_print(dut, DUT_MSG_ERROR,
3816 "%s: err in adding vendor_cmd and vendor_data",
3817 __func__);
3818 nlmsg_free(msg);
3819 return -1;
3820 }
3821 nla_nest_end(msg, params);
3822
3823 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3824 if (ret) {
3825 sigma_dut_print(dut, DUT_MSG_ERROR,
3826 "%s: err in send_and_recv_msgs, ret=%d",
3827 __func__, ret);
3828 }
3829 return ret;
3830}
3831
3832
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08003833static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
3834 int noack, enum qca_wlan_ac_type ac)
3835{
3836 struct nl_msg *msg;
3837 int ret = 0;
3838 struct nlattr *params;
3839 int ifindex;
3840
3841 ifindex = if_nametoindex(intf);
3842 if (ifindex == 0) {
3843 sigma_dut_print(dut, DUT_MSG_ERROR,
3844 "%s: Index for interface %s failed",
3845 __func__, intf);
3846 return -1;
3847 }
3848
3849 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3850 NL80211_CMD_VENDOR)) ||
3851 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3852 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3853 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3854 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
3855 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3856 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
3857 noack) ||
3858 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
3859 ac)) {
3860 sigma_dut_print(dut, DUT_MSG_ERROR,
3861 "%s: err in adding vendor_cmd and vendor_data",
3862 __func__);
3863 nlmsg_free(msg);
3864 return -1;
3865 }
3866 nla_nest_end(msg, params);
3867
3868 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3869 if (ret) {
3870 sigma_dut_print(dut, DUT_MSG_ERROR,
3871 "%s: err in send_and_recv_msgs, ret=%d",
3872 __func__, ret);
3873 }
3874 return ret;
3875}
3876
3877
3878static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
3879 const char *val)
3880{
3881 int noack, ret;
3882 char token[100];
3883 char *result;
3884 char *saveptr;
3885 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
3886
3887 strlcpy(token, val, sizeof(token));
3888 token[sizeof(token) - 1] = '\0';
3889 result = strtok_r(token, ":", &saveptr);
3890 while (result) {
3891 noack = strcasecmp(result, "Disable") != 0;
3892 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
3893 if (ret) {
3894 sigma_dut_print(dut, DUT_MSG_ERROR,
3895 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
3896 ac, ret);
3897 }
3898 result = strtok_r(NULL, ":", &saveptr);
3899 ac++;
3900 }
3901}
3902
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08003903#endif /* NL80211_SUPPORT */
3904
3905
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003906static int cmd_sta_preset_testparameters(struct sigma_dut *dut,
3907 struct sigma_conn *conn,
3908 struct sigma_cmd *cmd)
3909{
3910 const char *intf = get_param(cmd, "Interface");
3911 const char *val;
3912
3913 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03003914 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
3915 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003916 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
3917 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003918
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07003919 if (val && strcasecmp(val, "LOC") == 0)
3920 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02003921 if (val && strcasecmp(val, "60GHZ") == 0) {
3922 val = get_param(cmd, "WPS");
3923 if (val && strcasecmp(val, "disable") == 0) {
3924 dut->wps_disable = 1;
3925 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
3926 } else {
3927 /* wps_disable can have other value from the previous
3928 * test, so make sure it has the correct value.
3929 */
3930 dut->wps_disable = 0;
3931 }
3932
3933 val = get_param(cmd, "P2P");
3934 if (val && strcasecmp(val, "disable") == 0)
3935 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
3936 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07003937
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003938 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
3939 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
3940
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003941#ifdef ANDROID_NAN
3942 if (val && strcasecmp(val, "NAN") == 0)
3943 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
3944#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07003945#ifdef MIRACAST
3946 if (val && (strcasecmp(val, "WFD") == 0 ||
3947 strcasecmp(val, "DisplayR2") == 0))
3948 return miracast_preset_testparameters(dut, conn, cmd);
3949#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003950
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303951 if (val && strcasecmp(val, "MBO") == 0) {
3952 val = get_param(cmd, "Cellular_Data_Cap");
3953 if (val &&
3954 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
3955 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05303956
3957 val = get_param(cmd, "Ch_Pref");
3958 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
3959 return 0;
3960
Ashwini Patilc63161e2017-04-13 16:30:23 +05303961 val = get_param(cmd, "BSS_Transition");
3962 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
3963 return 0;
3964
Ashwini Patila75de5a2017-04-13 16:35:05 +05303965 val = get_param(cmd, "Assoc_Disallow");
3966 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
3967 return 0;
3968
Ashwini Patil9183fdb2017-04-13 16:58:25 +05303969 val = get_param(cmd, "Roaming");
3970 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
3971 return 0;
3972
Ashwini Patil68d02cd2017-01-10 15:39:16 +05303973 return 1;
3974 }
3975
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303976 if (val && strcasecmp(val, "OCE") == 0)
3977 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
3978
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003979#if 0
3980 val = get_param(cmd, "Supplicant");
3981 if (val && strcasecmp(val, "Default") != 0) {
3982 send_resp(dut, conn, SIGMA_ERROR,
3983 "ErrorCode,Only default(Vendor) supplicant "
3984 "supported");
3985 return 0;
3986 }
3987#endif
3988
3989 val = get_param(cmd, "RTS");
3990 if (val) {
3991 switch (get_driver_type()) {
3992 case DRIVER_ATHEROS:
3993 ath_sta_set_rts(dut, intf, val);
3994 break;
3995 default:
3996#if 0
3997 send_resp(dut, conn, SIGMA_ERROR,
3998 "ErrorCode,Setting RTS not supported");
3999 return 0;
4000#else
4001 sigma_dut_print(dut, DUT_MSG_DEBUG,
4002 "Setting RTS not supported");
4003 break;
4004#endif
4005 }
4006 }
4007
4008#if 0
4009 val = get_param(cmd, "FRGMNT");
4010 if (val) {
4011 /* TODO */
4012 send_resp(dut, conn, SIGMA_ERROR,
4013 "ErrorCode,Setting FRGMNT not supported");
4014 return 0;
4015 }
4016#endif
4017
4018#if 0
4019 val = get_param(cmd, "Preamble");
4020 if (val) {
4021 /* TODO: Long/Short */
4022 send_resp(dut, conn, SIGMA_ERROR,
4023 "ErrorCode,Setting Preamble not supported");
4024 return 0;
4025 }
4026#endif
4027
4028 val = get_param(cmd, "Mode");
4029 if (val) {
4030 if (strcmp(val, "11b") == 0 ||
4031 strcmp(val, "11g") == 0 ||
4032 strcmp(val, "11a") == 0 ||
4033 strcmp(val, "11n") == 0 ||
4034 strcmp(val, "11ng") == 0 ||
4035 strcmp(val, "11nl") == 0 ||
4036 strcmp(val, "11nl(nabg)") == 0 ||
4037 strcmp(val, "AC") == 0 ||
4038 strcmp(val, "11AC") == 0 ||
4039 strcmp(val, "11ac") == 0 ||
4040 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004041 strcmp(val, "11an") == 0 ||
4042 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004043 /* STA supports all modes by default */
4044 } else {
4045 send_resp(dut, conn, SIGMA_ERROR,
4046 "ErrorCode,Setting Mode not supported");
4047 return 0;
4048 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004049
4050 /* Change the mode only in case of testbed for HE program
4051 * and for 11a and 11g modes only. */
4052 if (dut->program == PROGRAM_HE &&
4053 dut->device_type == STA_testbed) {
4054 int phymode;
4055 char buf[60];
4056
4057 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004058 phymode = 1; /* IEEE80211_MODE_11A */
4059 } else if (strcmp(val, "11g") == 0) {
4060 phymode = 3; /* IEEE80211_MODE_11G */
4061 } else if (strcmp(val, "11b") == 0) {
4062 phymode = 2; /* IEEE80211_MODE_11B */
4063 } else if (strcmp(val, "11n") == 0 ||
4064 strcmp(val, "11nl") == 0 ||
4065 strcmp(val, "11nl(nabg)") == 0) {
4066 phymode = 22; /* IEEE80211_MODE_11AGN */
4067 } else if (strcmp(val, "11ng") == 0) {
4068 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4069 } else if (strcmp(val, "AC") == 0 ||
4070 strcasecmp(val, "11AC") == 0) {
4071 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4072 } else if (strcmp(val, "11na") == 0 ||
4073 strcasecmp(val, "11an") == 0) {
4074 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4075 } else if (strcmp(val, "11ax") == 0) {
4076 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004077 } else {
4078 sigma_dut_print(dut, DUT_MSG_DEBUG,
4079 "Ignoring mode change for mode: %s",
4080 val);
4081 phymode = -1;
4082 }
4083 if (phymode != -1) {
4084 snprintf(buf, sizeof(buf),
4085 "iwpriv %s setphymode %d",
4086 intf, phymode);
4087 if (system(buf) != 0) {
4088 sigma_dut_print(dut, DUT_MSG_ERROR,
4089 "iwpriv setting of phymode failed");
4090 }
4091 }
4092 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004093 }
4094
4095 val = get_param(cmd, "wmm");
4096 if (val) {
4097 switch (get_driver_type()) {
4098 case DRIVER_ATHEROS:
4099 ath_sta_set_wmm(dut, intf, val);
4100 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004101 case DRIVER_WCN:
4102 wcn_sta_set_wmm(dut, intf, val);
4103 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004104 default:
4105 sigma_dut_print(dut, DUT_MSG_DEBUG,
4106 "Setting wmm not supported");
4107 break;
4108 }
4109 }
4110
4111 val = get_param(cmd, "Powersave");
4112 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004113 char buf[60];
4114
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004115 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004116 if (get_driver_type() == DRIVER_WCN) {
4117 snprintf(buf, sizeof(buf),
4118 "iwpriv %s setPower 2", intf);
4119 if (system(buf) != 0) {
4120 sigma_dut_print(dut, DUT_MSG_ERROR,
4121 "iwpriv setPower 2 failed");
4122 return 0;
4123 }
4124 }
4125
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004126 if (wpa_command(get_station_ifname(),
4127 "P2P_SET ps 0") < 0)
4128 return -2;
4129 /* Make sure test modes are disabled */
4130 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4131 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4132 } else if (strcmp(val, "1") == 0 ||
4133 strcasecmp(val, "PSPoll") == 0 ||
4134 strcasecmp(val, "on") == 0) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004135 if (get_driver_type() == DRIVER_WCN) {
4136 snprintf(buf, sizeof(buf),
4137 "iwpriv %s setPower 1", intf);
4138 if (system(buf) != 0) {
4139 sigma_dut_print(dut, DUT_MSG_ERROR,
4140 "iwpriv setPower 1 failed");
4141 return 0;
4142 }
4143 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004144 /* Disable default power save mode */
4145 wpa_command(get_station_ifname(), "P2P_SET ps 0");
4146 /* Enable PS-Poll test mode */
4147 if (wpa_command(get_station_ifname(),
4148 "P2P_SET ps 97") < 0 ||
4149 wpa_command(get_station_ifname(),
4150 "P2P_SET ps 99") < 0)
4151 return -2;
4152 } else if (strcmp(val, "2") == 0 ||
4153 strcasecmp(val, "Fast") == 0) {
4154 /* TODO */
4155 send_resp(dut, conn, SIGMA_ERROR,
4156 "ErrorCode,Powersave=Fast not supported");
4157 return 0;
4158 } else if (strcmp(val, "3") == 0 ||
4159 strcasecmp(val, "PSNonPoll") == 0) {
4160 /* Make sure test modes are disabled */
4161 wpa_command(get_station_ifname(), "P2P_SET ps 98");
4162 wpa_command(get_station_ifname(), "P2P_SET ps 96");
4163
4164 /* Enable default power save mode */
4165 if (wpa_command(get_station_ifname(),
4166 "P2P_SET ps 1") < 0)
4167 return -2;
4168 } else
4169 return -1;
4170 }
4171
4172 val = get_param(cmd, "NoAck");
4173 if (val) {
4174 switch (get_driver_type()) {
4175 case DRIVER_ATHEROS:
4176 ath_sta_set_noack(dut, intf, val);
4177 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004178#ifdef NL80211_SUPPORT
4179 case DRIVER_WCN:
4180 wcn_sta_set_noack(dut, intf, val);
4181 break;
4182#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004183 default:
4184 send_resp(dut, conn, SIGMA_ERROR,
4185 "ErrorCode,Setting NoAck not supported");
4186 return 0;
4187 }
4188 }
4189
4190 val = get_param(cmd, "IgnoreChswitchProhibit");
4191 if (val) {
4192 /* TODO: Enabled/disabled */
4193 if (strcasecmp(val, "Enabled") == 0) {
4194 send_resp(dut, conn, SIGMA_ERROR,
4195 "ErrorCode,Enabling IgnoreChswitchProhibit "
4196 "not supported");
4197 return 0;
4198 }
4199 }
4200
4201 val = get_param(cmd, "TDLS");
4202 if (val) {
4203 if (strcasecmp(val, "Disabled") == 0) {
4204 if (wpa_command(intf, "SET tdls_disabled 1")) {
4205 send_resp(dut, conn, SIGMA_ERROR,
4206 "ErrorCode,Failed to disable TDLS");
4207 return 0;
4208 }
4209 } else if (strcasecmp(val, "Enabled") == 0) {
4210 if (wpa_command(intf, "SET tdls_disabled 0")) {
4211 send_resp(dut, conn, SIGMA_ERROR,
4212 "ErrorCode,Failed to enable TDLS");
4213 return 0;
4214 }
4215 } else {
4216 send_resp(dut, conn, SIGMA_ERROR,
4217 "ErrorCode,Unsupported TDLS value");
4218 return 0;
4219 }
4220 }
4221
4222 val = get_param(cmd, "TDLSmode");
4223 if (val) {
4224 if (strcasecmp(val, "Default") == 0) {
4225 wpa_command(intf, "SET tdls_testing 0");
4226 } else if (strcasecmp(val, "APProhibit") == 0) {
4227 if (wpa_command(intf, "SET tdls_testing 0x400")) {
4228 send_resp(dut, conn, SIGMA_ERROR,
4229 "ErrorCode,Failed to enable ignore "
4230 "APProhibit TDLS mode");
4231 return 0;
4232 }
4233 } else if (strcasecmp(val, "HiLoMac") == 0) {
4234 /* STA should respond with TDLS setup req for a TDLS
4235 * setup req */
4236 if (wpa_command(intf, "SET tdls_testing 0x80")) {
4237 send_resp(dut, conn, SIGMA_ERROR,
4238 "ErrorCode,Failed to enable HiLoMac "
4239 "TDLS mode");
4240 return 0;
4241 }
4242 } else if (strcasecmp(val, "WeakSecurity") == 0) {
4243 /*
4244 * Since all security modes are enabled by default when
4245 * Sigma control is used, there is no need to do
4246 * anything here.
4247 */
4248 } else if (strcasecmp(val, "ExistLink") == 0) {
4249 /*
4250 * Since we allow new TDLS Setup Request even if there
4251 * is an existing link, nothing needs to be done for
4252 * this.
4253 */
4254 } else {
4255 /* TODO:
4256 * ExistLink: STA should send TDLS setup req even if
4257 * direct link already exists
4258 */
4259 send_resp(dut, conn, SIGMA_ERROR,
4260 "ErrorCode,Unsupported TDLSmode value");
4261 return 0;
4262 }
4263 }
4264
4265 val = get_param(cmd, "FakePubKey");
4266 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
4267 send_resp(dut, conn, SIGMA_ERROR,
4268 "ErrorCode,Failed to enable FakePubKey");
4269 return 0;
4270 }
4271
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08004272#ifdef NL80211_SUPPORT
4273 val = get_param(cmd, "FrgmntSupport");
4274 if (val) {
4275 if (strcasecmp(val, "Enable") == 0) {
4276 if (sta_set_he_fragmentation(dut, intf,
4277 HE_FRAG_LEVEL1)) {
4278 send_resp(dut, conn, SIGMA_ERROR,
4279 "ErrorCode,Failed to enable HE Fragmentation");
4280 return 0;
4281 }
4282 } else if (strcasecmp(val, "Disable") == 0) {
4283 if (sta_set_he_fragmentation(dut, intf,
4284 HE_FRAG_DISABLE)) {
4285 send_resp(dut, conn, SIGMA_ERROR,
4286 "ErrorCode,Failed to disable HE Fragmentation");
4287 return 0;
4288 }
4289 }
4290 }
4291#endif /* NL80211_SUPPORT */
4292
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004293 return 1;
4294}
4295
4296
4297static const char * ath_get_radio_name(const char *radio_name)
4298{
4299 if (radio_name == NULL)
4300 return "wifi0";
4301 if (strcmp(radio_name, "wifi1") == 0)
4302 return "wifi1";
4303 if (strcmp(radio_name, "wifi2") == 0)
4304 return "wifi2";
4305 return "wifi0";
4306}
4307
4308
4309static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
4310 const char *val)
4311{
4312 char buf[60];
4313 unsigned int vht_mcsmap = 0;
4314 int txchainmask = 0;
4315 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4316
4317 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4318 if (dut->testbed_flag_txsp == 1) {
4319 vht_mcsmap = 0xfffc;
4320 dut->testbed_flag_txsp = 0;
4321 } else {
4322 vht_mcsmap = 0xfffe;
4323 }
4324 txchainmask = 1;
4325 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4326 if (dut->testbed_flag_txsp == 1) {
4327 vht_mcsmap = 0xfff0;
4328 dut->testbed_flag_txsp = 0;
4329 } else {
4330 vht_mcsmap = 0xfffa;
4331 }
4332 txchainmask = 3;
4333 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4334 if (dut->testbed_flag_txsp == 1) {
4335 vht_mcsmap = 0xffc0;
4336 dut->testbed_flag_txsp = 0;
4337 } else {
4338 vht_mcsmap = 0xffea;
4339 }
4340 txchainmask = 7;
4341 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4342 if (dut->testbed_flag_txsp == 1) {
4343 vht_mcsmap = 0xff00;
4344 dut->testbed_flag_txsp = 0;
4345 } else {
4346 vht_mcsmap = 0xffaa;
4347 }
4348 txchainmask = 15;
4349 } else {
4350 if (dut->testbed_flag_txsp == 1) {
4351 vht_mcsmap = 0xffc0;
4352 dut->testbed_flag_txsp = 0;
4353 } else {
4354 vht_mcsmap = 0xffea;
4355 }
4356 }
4357
4358 if (txchainmask) {
4359 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
4360 basedev, txchainmask);
4361 if (system(buf) != 0) {
4362 sigma_dut_print(dut, DUT_MSG_ERROR,
4363 "iwpriv txchainmask failed");
4364 }
4365 }
4366
4367 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4368 intf, vht_mcsmap);
4369 if (system(buf) != 0) {
4370 sigma_dut_print(dut, DUT_MSG_ERROR,
4371 "iwpriv %s vht_mcsmap 0x%04x failed",
4372 intf, vht_mcsmap);
4373 }
4374}
4375
4376
4377static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
4378 const char *val)
4379{
4380 char buf[60];
4381 unsigned int vht_mcsmap = 0;
4382 int rxchainmask = 0;
4383 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
4384
4385 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
4386 if (dut->testbed_flag_rxsp == 1) {
4387 vht_mcsmap = 0xfffc;
4388 dut->testbed_flag_rxsp = 0;
4389 } else {
4390 vht_mcsmap = 0xfffe;
4391 }
4392 rxchainmask = 1;
4393 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
4394 if (dut->testbed_flag_rxsp == 1) {
4395 vht_mcsmap = 0xfff0;
4396 dut->testbed_flag_rxsp = 0;
4397 } else {
4398 vht_mcsmap = 0xfffa;
4399 }
4400 rxchainmask = 3;
4401 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
4402 if (dut->testbed_flag_rxsp == 1) {
4403 vht_mcsmap = 0xffc0;
4404 dut->testbed_flag_rxsp = 0;
4405 } else {
4406 vht_mcsmap = 0xffea;
4407 }
4408 rxchainmask = 7;
4409 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
4410 if (dut->testbed_flag_rxsp == 1) {
4411 vht_mcsmap = 0xff00;
4412 dut->testbed_flag_rxsp = 0;
4413 } else {
4414 vht_mcsmap = 0xffaa;
4415 }
4416 rxchainmask = 15;
4417 } else {
4418 if (dut->testbed_flag_rxsp == 1) {
4419 vht_mcsmap = 0xffc0;
4420 dut->testbed_flag_rxsp = 0;
4421 } else {
4422 vht_mcsmap = 0xffea;
4423 }
4424 }
4425
4426 if (rxchainmask) {
4427 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
4428 basedev, rxchainmask);
4429 if (system(buf) != 0) {
4430 sigma_dut_print(dut, DUT_MSG_ERROR,
4431 "iwpriv rxchainmask failed");
4432 }
4433 }
4434
4435 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0x%04x",
4436 intf, vht_mcsmap);
4437 if (system(buf) != 0) {
4438 sigma_dut_print(dut, DUT_MSG_ERROR,
4439 "iwpriv %s vht_mcsmap 0x%04x",
4440 intf, vht_mcsmap);
4441 }
4442}
4443
4444
4445void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
4446{
4447 if (strcasecmp(val, "enable") == 0) {
4448 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
4449 != 0) {
4450 sigma_dut_print(dut, DUT_MSG_ERROR,
4451 "Disable BB_VHTSIGB_CRC_CALC failed");
4452 }
4453
4454 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
4455 != 0) {
4456 sigma_dut_print(dut, DUT_MSG_ERROR,
4457 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4458 }
4459 } else {
4460 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
4461 != 0) {
4462 sigma_dut_print(dut, DUT_MSG_ERROR,
4463 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
4464 }
4465
4466 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
4467 != 0) {
4468 sigma_dut_print(dut, DUT_MSG_ERROR,
4469 "Enable BB_VHTSIGB_CRC_CALC failed");
4470 }
4471 }
4472}
4473
4474
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004475static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
4476 const char *val)
4477{
4478 char buf[60];
4479
4480 if (strcmp(val, "20") == 0) {
4481 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
4482 dut->chwidth = 0;
4483 } else if (strcmp(val, "40") == 0) {
4484 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
4485 dut->chwidth = 1;
4486 } else if (strcmp(val, "80") == 0) {
4487 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
4488 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05304489 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004490 buf[0] = '\0';
4491 } else {
4492 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
4493 val);
4494 return -1;
4495 }
4496
4497 if (buf[0] != '\0' && system(buf) != 0) {
4498 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
4499 return -1;
4500 }
4501
4502 return 0;
4503}
4504
4505
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004506static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
4507 const char *intf, int addbareject)
4508{
4509#ifdef NL80211_SUPPORT
4510 struct nl_msg *msg;
4511 int ret = 0;
4512 struct nlattr *params;
4513 int ifindex;
4514
4515 ifindex = if_nametoindex(intf);
4516 if (ifindex == 0) {
4517 sigma_dut_print(dut, DUT_MSG_ERROR,
4518 "%s: Index for interface %s failed",
4519 __func__, intf);
4520 return -1;
4521 }
4522
4523 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4524 NL80211_CMD_VENDOR)) ||
4525 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4526 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4527 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4528 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4529 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4530 nla_put_u8(msg,
4531 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
4532 !addbareject)) {
4533 sigma_dut_print(dut, DUT_MSG_ERROR,
4534 "%s: err in adding vendor_cmd and vendor_data",
4535 __func__);
4536 nlmsg_free(msg);
4537 return -1;
4538 }
4539 nla_nest_end(msg, params);
4540
4541 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4542 if (ret) {
4543 sigma_dut_print(dut, DUT_MSG_ERROR,
4544 "%s: err in send_and_recv_msgs, ret=%d",
4545 __func__, ret);
4546 }
4547 return ret;
4548#else /* NL80211_SUPPORT */
4549 sigma_dut_print(dut, DUT_MSG_ERROR,
4550 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
4551 return -1;
4552#endif /* NL80211_SUPPORT */
4553}
4554
4555
4556static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
4557 int addbareject)
4558{
4559 int ret;
4560
4561 switch (get_driver_type()) {
4562 case DRIVER_WCN:
4563 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
4564 if (ret) {
4565 sigma_dut_print(dut, DUT_MSG_ERROR,
4566 "nlvendor_sta_set_addba_reject failed, ret:%d",
4567 ret);
4568 return ret;
4569 }
4570 break;
4571 default:
4572 sigma_dut_print(dut, DUT_MSG_ERROR,
4573 "errorCode,Unsupported ADDBA_REJECT with the current driver");
4574 ret = -1;
4575 break;
4576 }
4577
4578 return ret;
4579}
4580
4581
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004582static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
4583 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004584{
4585#ifdef NL80211_SUPPORT
4586 struct nl_msg *msg;
4587 int ret = 0;
4588 struct nlattr *params;
4589 int ifindex;
4590
4591 ifindex = if_nametoindex(intf);
4592 if (ifindex == 0) {
4593 sigma_dut_print(dut, DUT_MSG_ERROR,
4594 "%s: Index for interface %s failed",
4595 __func__, intf);
4596 return -1;
4597 }
4598
4599 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4600 NL80211_CMD_VENDOR)) ||
4601 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4602 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4603 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4604 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4605 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4606 nla_put_u8(msg,
4607 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004608 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004609 sigma_dut_print(dut, DUT_MSG_ERROR,
4610 "%s: err in adding vendor_cmd and vendor_data",
4611 __func__);
4612 nlmsg_free(msg);
4613 return -1;
4614 }
4615 nla_nest_end(msg, params);
4616
4617 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4618 if (ret) {
4619 sigma_dut_print(dut, DUT_MSG_ERROR,
4620 "%s: err in send_and_recv_msgs, ret=%d",
4621 __func__, ret);
4622 }
4623 return ret;
4624#else /* NL80211_SUPPORT */
4625 sigma_dut_print(dut, DUT_MSG_ERROR,
4626 "Disable addba not possible without NL80211_SUPPORT defined");
4627 return -1;
4628#endif /* NL80211_SUPPORT */
4629}
4630
4631
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004632static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
4633 struct sigma_conn *conn,
4634 struct sigma_cmd *cmd)
4635{
4636 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004637 int ampdu = -1, addbareject = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004638 char buf[30];
4639
4640 val = get_param(cmd, "40_INTOLERANT");
4641 if (val) {
4642 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4643 /* TODO: iwpriv ht40intol through wpa_supplicant */
4644 send_resp(dut, conn, SIGMA_ERROR,
4645 "ErrorCode,40_INTOLERANT not supported");
4646 return 0;
4647 }
4648 }
4649
4650 val = get_param(cmd, "ADDBA_REJECT");
4651 if (val) {
4652 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4653 /* reject any ADDBA with status "decline" */
4654 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004655 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004656 } else {
4657 /* accept ADDBA */
4658 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004659 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004660 }
4661 }
4662
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08004663 if (addbareject >= 0 &&
4664 sta_set_addba_reject(dut, intf, addbareject) < 0) {
4665 send_resp(dut, conn, SIGMA_ERROR,
4666 "ErrorCode,set addba_reject failed");
4667 return 0;
4668 }
4669
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004670 val = get_param(cmd, "AMPDU");
4671 if (val) {
4672 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
4673 /* enable AMPDU Aggregation */
4674 if (ampdu == 0) {
4675 send_resp(dut, conn, SIGMA_ERROR,
4676 "ErrorCode,Mismatch in "
4677 "addba_reject/ampdu - "
4678 "not supported");
4679 return 0;
4680 }
4681 ampdu = 1;
4682 } else {
4683 /* disable AMPDU Aggregation */
4684 if (ampdu == 1) {
4685 send_resp(dut, conn, SIGMA_ERROR,
4686 "ErrorCode,Mismatch in "
4687 "addba_reject/ampdu - "
4688 "not supported");
4689 return 0;
4690 }
4691 ampdu = 0;
4692 }
4693 }
4694
4695 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004696 int ret;
4697
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004698 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
4699 ampdu ? "Enabling" : "Disabling");
4700 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004701 if (wpa_command(intf, buf) < 0 &&
4702 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004703 send_resp(dut, conn, SIGMA_ERROR,
4704 "ErrorCode,set aggr failed");
4705 return 0;
4706 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004707
4708 if (ampdu == 0) {
4709 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08004710 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08004711 if (ret) {
4712 sigma_dut_print(dut, DUT_MSG_ERROR,
4713 "Failed to disable addba, ret:%d",
4714 ret);
4715 }
4716 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004717 }
4718
4719 val = get_param(cmd, "AMSDU");
4720 if (val) {
4721 switch (get_driver_type()) {
4722 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004723 case DRIVER_WCN:
4724 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004725 break;
4726 default:
4727 if (strcmp(val, "1") == 0 ||
4728 strcasecmp(val, "Enable") == 0) {
4729 /* Enable AMSDU Aggregation */
4730 send_resp(dut, conn, SIGMA_ERROR,
4731 "ErrorCode,AMSDU aggregation not supported");
4732 return 0;
4733 }
4734 break;
4735 }
4736 }
4737
4738 val = get_param(cmd, "STBC_RX");
4739 if (val) {
4740 switch (get_driver_type()) {
4741 case DRIVER_ATHEROS:
4742 ath_sta_set_stbc(dut, intf, val);
4743 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304744 case DRIVER_WCN:
4745 wcn_sta_set_stbc(dut, intf, val);
4746 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004747 default:
4748 send_resp(dut, conn, SIGMA_ERROR,
4749 "ErrorCode,STBC_RX not supported");
4750 return 0;
4751 }
4752 }
4753
4754 val = get_param(cmd, "WIDTH");
4755 if (val) {
4756 switch (get_driver_type()) {
4757 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08004758 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004759 send_resp(dut, conn, SIGMA_ERROR,
4760 "ErrorCode,Failed to set WIDTH");
4761 return 0;
4762 }
4763 break;
4764 case DRIVER_ATHEROS:
4765 if (ath_set_width(dut, conn, intf, val) < 0)
4766 return 0;
4767 break;
4768 default:
4769 sigma_dut_print(dut, DUT_MSG_ERROR,
4770 "Setting WIDTH not supported");
4771 break;
4772 }
4773 }
4774
4775 val = get_param(cmd, "SMPS");
4776 if (val) {
4777 /* TODO: Dynamic/0, Static/1, No Limit/2 */
4778 send_resp(dut, conn, SIGMA_ERROR,
4779 "ErrorCode,SMPS not supported");
4780 return 0;
4781 }
4782
4783 val = get_param(cmd, "TXSP_STREAM");
4784 if (val) {
4785 switch (get_driver_type()) {
4786 case DRIVER_WCN:
4787 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4788 send_resp(dut, conn, SIGMA_ERROR,
4789 "ErrorCode,Failed to set TXSP_STREAM");
4790 return 0;
4791 }
4792 break;
4793 case DRIVER_ATHEROS:
4794 ath_sta_set_txsp_stream(dut, intf, val);
4795 break;
4796 default:
4797 sigma_dut_print(dut, DUT_MSG_ERROR,
4798 "Setting TXSP_STREAM not supported");
4799 break;
4800 }
4801 }
4802
4803 val = get_param(cmd, "RXSP_STREAM");
4804 if (val) {
4805 switch (get_driver_type()) {
4806 case DRIVER_WCN:
4807 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
4808 send_resp(dut, conn, SIGMA_ERROR,
4809 "ErrorCode,Failed to set RXSP_STREAM");
4810 return 0;
4811 }
4812 break;
4813 case DRIVER_ATHEROS:
4814 ath_sta_set_rxsp_stream(dut, intf, val);
4815 break;
4816 default:
4817 sigma_dut_print(dut, DUT_MSG_ERROR,
4818 "Setting RXSP_STREAM not supported");
4819 break;
4820 }
4821 }
4822
4823 val = get_param(cmd, "DYN_BW_SGNL");
4824 if (val) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004825 switch (get_driver_type()) {
4826 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08004827 if (strcasecmp(val, "enable") == 0) {
4828 snprintf(buf, sizeof(buf),
4829 "iwpriv %s cwmenable 1", intf);
4830 if (system(buf) != 0) {
4831 sigma_dut_print(dut, DUT_MSG_ERROR,
4832 "iwpriv cwmenable 1 failed");
4833 return 0;
4834 }
4835 } else if (strcasecmp(val, "disable") == 0) {
4836 snprintf(buf, sizeof(buf),
4837 "iwpriv %s cwmenable 0", intf);
4838 if (system(buf) != 0) {
4839 sigma_dut_print(dut, DUT_MSG_ERROR,
4840 "iwpriv cwmenable 0 failed");
4841 return 0;
4842 }
4843 } else {
4844 sigma_dut_print(dut, DUT_MSG_ERROR,
4845 "Unsupported DYN_BW_SGL");
4846 }
4847
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004848 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4849 if (system(buf) != 0) {
4850 sigma_dut_print(dut, DUT_MSG_ERROR,
4851 "Failed to set cts_cbw in DYN_BW_SGNL");
4852 return 0;
4853 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004854 break;
4855 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004856 novap_reset(dut, intf);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08004857 ath_config_dyn_bw_sig(dut, intf, val);
4858 break;
4859 default:
4860 sigma_dut_print(dut, DUT_MSG_ERROR,
4861 "Failed to set DYN_BW_SGNL");
4862 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004863 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004864 }
4865
4866 val = get_param(cmd, "RTS_FORCE");
4867 if (val) {
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08004868 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004869 if (strcasecmp(val, "Enable") == 0) {
4870 snprintf(buf, sizeof(buf), "iwconfig %s rts 64", intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004871 if (system(buf) != 0) {
4872 sigma_dut_print(dut, DUT_MSG_ERROR,
4873 "Failed to set RTS_FORCE 64");
4874 }
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08004875 snprintf(buf, sizeof(buf),
4876 "wifitool %s beeliner_fw_test 100 1", intf);
4877 if (system(buf) != 0) {
4878 sigma_dut_print(dut, DUT_MSG_ERROR,
4879 "wifitool beeliner_fw_test 100 1 failed");
4880 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004881 } else if (strcasecmp(val, "Disable") == 0) {
4882 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347",
4883 intf);
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02004884 if (system(buf) != 0) {
4885 sigma_dut_print(dut, DUT_MSG_ERROR,
4886 "Failed to set RTS_FORCE 2347");
4887 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004888 } else {
4889 send_resp(dut, conn, SIGMA_ERROR,
4890 "ErrorCode,RTS_FORCE value not supported");
4891 return 0;
4892 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004893 }
4894
4895 val = get_param(cmd, "CTS_WIDTH");
4896 if (val) {
4897 switch (get_driver_type()) {
4898 case DRIVER_WCN:
4899 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
4900 send_resp(dut, conn, SIGMA_ERROR,
4901 "ErrorCode,Failed to set CTS_WIDTH");
4902 return 0;
4903 }
4904 break;
4905 case DRIVER_ATHEROS:
4906 ath_set_cts_width(dut, intf, val);
4907 break;
4908 default:
4909 sigma_dut_print(dut, DUT_MSG_ERROR,
4910 "Setting CTS_WIDTH not supported");
4911 break;
4912 }
4913 }
4914
4915 val = get_param(cmd, "BW_SGNL");
4916 if (val) {
4917 if (strcasecmp(val, "Enable") == 0) {
4918 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1",
4919 intf);
4920 } else if (strcasecmp(val, "Disable") == 0) {
4921 /* TODO: Disable */
4922 buf[0] = '\0';
4923 } else {
4924 send_resp(dut, conn, SIGMA_ERROR,
4925 "ErrorCode,BW_SGNL value not supported");
4926 return 0;
4927 }
4928
4929 if (buf[0] != '\0' && system(buf) != 0) {
4930 sigma_dut_print(dut, DUT_MSG_ERROR,
4931 "Failed to set BW_SGNL");
4932 }
4933 }
4934
4935 val = get_param(cmd, "Band");
4936 if (val) {
4937 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
4938 /* STA supports all bands by default */
4939 } else {
4940 send_resp(dut, conn, SIGMA_ERROR,
4941 "ErrorCode,Unsupported Band");
4942 return 0;
4943 }
4944 }
4945
4946 val = get_param(cmd, "zero_crc");
4947 if (val) {
4948 switch (get_driver_type()) {
4949 case DRIVER_ATHEROS:
4950 ath_set_zero_crc(dut, val);
4951 break;
4952 default:
4953 break;
4954 }
4955 }
4956
4957 return 1;
4958}
4959
4960
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02004961static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
4962{
4963 switch (get_driver_type()) {
4964#ifdef __linux__
4965 case DRIVER_WIL6210:
4966 return wil6210_force_rsn_ie(dut, state);
4967#endif /* __linux__ */
4968 default:
4969 sigma_dut_print(dut, DUT_MSG_ERROR,
4970 "Unsupported sta_60g_force_rsn_ie with the current driver");
4971 return -1;
4972 }
4973}
4974
4975
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004976static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
4977 struct sigma_cmd *cmd)
4978{
4979 const char *val;
4980 char buf[100];
4981
4982 val = get_param(cmd, "MSDUSize");
4983 if (val) {
4984 int mtu;
4985
4986 dut->amsdu_size = atoi(val);
4987 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
4988 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
4989 sigma_dut_print(dut, DUT_MSG_ERROR,
4990 "MSDUSize %d is above max %d or below min %d",
4991 dut->amsdu_size,
4992 IEEE80211_MAX_DATA_LEN_DMG,
4993 IEEE80211_SNAP_LEN_DMG);
4994 dut->amsdu_size = 0;
4995 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
4996 }
4997
4998 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
4999 sigma_dut_print(dut, DUT_MSG_DEBUG,
5000 "Setting amsdu_size to %d", mtu);
5001 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
5002 get_station_ifname(), mtu);
5003
5004 if (system(buf) != 0) {
5005 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5006 buf);
5007 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5008 }
5009 }
5010
5011 val = get_param(cmd, "BAckRcvBuf");
5012 if (val) {
5013 dut->back_rcv_buf = atoi(val);
5014 if (dut->back_rcv_buf == 0) {
5015 sigma_dut_print(dut, DUT_MSG_ERROR,
5016 "Failed to convert %s or value is 0",
5017 val);
5018 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5019 }
5020
5021 sigma_dut_print(dut, DUT_MSG_DEBUG,
5022 "Setting BAckRcvBuf to %s", val);
5023 }
5024
5025 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
5026}
5027
5028
5029static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5030 struct sigma_cmd *cmd)
5031{
5032 int net_id;
5033 char *ifname;
5034 const char *val;
5035 char buf[100];
5036
5037 dut->mode = SIGMA_MODE_STATION;
5038 ifname = get_main_ifname();
5039 if (wpa_command(ifname, "PING") != 0) {
5040 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
5041 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5042 }
5043
5044 wpa_command(ifname, "FLUSH");
5045 net_id = add_network_common(dut, conn, ifname, cmd);
5046 if (net_id < 0) {
5047 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5048 return net_id;
5049 }
5050
5051 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5052 if (set_network(ifname, net_id, "mode", "2") < 0) {
5053 sigma_dut_print(dut, DUT_MSG_ERROR,
5054 "Failed to set supplicant network mode");
5055 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5056 }
5057
5058 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005059 "Supplicant set network with mode 2. network_id %d",
5060 net_id);
5061
5062 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5063 sigma_dut_print(dut, DUT_MSG_INFO,
5064 "Failed to set supplicant to WPS ENABLE");
5065 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5066 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005067
5068 val = get_param(cmd, "Security");
5069 if (val && strcasecmp(val, "OPEN") == 0) {
5070 dut->ap_key_mgmt = AP_OPEN;
5071 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5072 sigma_dut_print(dut, DUT_MSG_ERROR,
5073 "Failed to set supplicant to %s security",
5074 val);
5075 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5076 }
5077 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5078 dut->ap_key_mgmt = AP_WPA2_PSK;
5079 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5080 sigma_dut_print(dut, DUT_MSG_ERROR,
5081 "Failed to set supplicant to %s security",
5082 val);
5083 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5084 }
5085
5086 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5087 sigma_dut_print(dut, DUT_MSG_ERROR,
5088 "Failed to set supplicant to proto RSN");
5089 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5090 }
5091 } else if (val) {
5092 sigma_dut_print(dut, DUT_MSG_ERROR,
5093 "Requested Security %s is not supported on 60GHz",
5094 val);
5095 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
5096 }
5097
5098 val = get_param(cmd, "Encrypt");
5099 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5100 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5101 sigma_dut_print(dut, DUT_MSG_ERROR,
5102 "Failed to set supplicant to pairwise GCMP");
5103 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5104 }
5105 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
5106 sigma_dut_print(dut, DUT_MSG_ERROR,
5107 "Failed to set supplicant to group GCMP");
5108 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5109 }
5110 } else if (val) {
5111 sigma_dut_print(dut, DUT_MSG_ERROR,
5112 "Requested Encrypt %s is not supported on 60 GHz",
5113 val);
5114 return SIGMA_DUT_INVALID_CALLER_SEND_STATUS;
5115 }
5116
5117 val = get_param(cmd, "PSK");
5118 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
5119 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
5120 val);
5121 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5122 }
5123
5124 /* Convert 60G channel to freq */
5125 switch (dut->ap_channel) {
5126 case 1:
5127 val = "58320";
5128 break;
5129 case 2:
5130 val = "60480";
5131 break;
5132 case 3:
5133 val = "62640";
5134 break;
5135 default:
5136 sigma_dut_print(dut, DUT_MSG_ERROR,
5137 "Failed to configure channel %d. Not supported",
5138 dut->ap_channel);
5139 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5140 }
5141
5142 if (set_network(ifname, net_id, "frequency", val) < 0) {
5143 sigma_dut_print(dut, DUT_MSG_ERROR,
5144 "Failed to set supplicant network frequency");
5145 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5146 }
5147
5148 sigma_dut_print(dut, DUT_MSG_DEBUG,
5149 "Supplicant set network with frequency");
5150
5151 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
5152 if (wpa_command(ifname, buf) < 0) {
5153 sigma_dut_print(dut, DUT_MSG_INFO,
5154 "Failed to select network id %d on %s",
5155 net_id, ifname);
5156 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5157 }
5158
5159 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
5160
5161 return SIGMA_DUT_SUCCESS_CALLER_SEND_STATUS;
5162}
5163
5164
Lior David67543f52017-01-03 19:04:22 +02005165static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
5166{
5167 char buf[128], fname[128];
5168 FILE *f;
5169
5170 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
5171 sigma_dut_print(dut, DUT_MSG_ERROR,
5172 "failed to get wil6210 debugfs dir");
5173 return -1;
5174 }
5175
5176 snprintf(fname, sizeof(fname), "%s/abft_len", buf);
5177 f = fopen(fname, "w");
5178 if (!f) {
5179 sigma_dut_print(dut, DUT_MSG_ERROR,
5180 "failed to open: %s", fname);
5181 return -1;
5182 }
5183
5184 fprintf(f, "%d\n", abft_len);
5185 fclose(f);
5186
5187 return 0;
5188}
5189
5190
5191static int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
5192 int abft_len)
5193{
5194 switch (get_driver_type()) {
5195 case DRIVER_WIL6210:
5196 return wil6210_set_abft_len(dut, abft_len);
5197 default:
5198 sigma_dut_print(dut, DUT_MSG_ERROR,
5199 "set abft_len not supported");
5200 return -1;
5201 }
5202}
5203
5204
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005205static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
5206 struct sigma_cmd *cmd)
5207{
5208 const char *val;
Lior David67543f52017-01-03 19:04:22 +02005209 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005210
5211 if (dut->dev_role != DEVROLE_PCP) {
5212 send_resp(dut, conn, SIGMA_INVALID,
5213 "ErrorCode,Invalid DevRole");
5214 return 0;
5215 }
5216
5217 val = get_param(cmd, "SSID");
5218 if (val) {
5219 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
5220 send_resp(dut, conn, SIGMA_INVALID,
5221 "ErrorCode,Invalid SSID");
5222 return -1;
5223 }
5224
Peng Xub8fc5cc2017-05-10 17:27:28 -07005225 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005226 }
5227
5228 val = get_param(cmd, "CHANNEL");
5229 if (val) {
5230 const char *pos;
5231
5232 dut->ap_channel = atoi(val);
5233 pos = strchr(val, ';');
5234 if (pos) {
5235 pos++;
5236 dut->ap_channel_1 = atoi(pos);
5237 }
5238 }
5239
5240 switch (dut->ap_channel) {
5241 case 1:
5242 case 2:
5243 case 3:
5244 break;
5245 default:
5246 sigma_dut_print(dut, DUT_MSG_ERROR,
5247 "Channel %d is not supported", dut->ap_channel);
5248 send_resp(dut, conn, SIGMA_ERROR,
5249 "Requested channel is not supported");
5250 return -1;
5251 }
5252
5253 val = get_param(cmd, "BCNINT");
5254 if (val)
5255 dut->ap_bcnint = atoi(val);
5256
5257
5258 val = get_param(cmd, "ExtSchIE");
5259 if (val) {
5260 send_resp(dut, conn, SIGMA_ERROR,
5261 "ErrorCode,ExtSchIE is not supported yet");
5262 return -1;
5263 }
5264
5265 val = get_param(cmd, "AllocType");
5266 if (val) {
5267 send_resp(dut, conn, SIGMA_ERROR,
5268 "ErrorCode,AllocType is not supported yet");
5269 return -1;
5270 }
5271
5272 val = get_param(cmd, "PercentBI");
5273 if (val) {
5274 send_resp(dut, conn, SIGMA_ERROR,
5275 "ErrorCode,PercentBI is not supported yet");
5276 return -1;
5277 }
5278
5279 val = get_param(cmd, "CBAPOnly");
5280 if (val) {
5281 send_resp(dut, conn, SIGMA_ERROR,
5282 "ErrorCode,CBAPOnly is not supported yet");
5283 return -1;
5284 }
5285
5286 val = get_param(cmd, "AMPDU");
5287 if (val) {
5288 if (strcasecmp(val, "Enable") == 0)
5289 dut->ap_ampdu = 1;
5290 else if (strcasecmp(val, "Disable") == 0)
5291 dut->ap_ampdu = 2;
5292 else {
5293 send_resp(dut, conn, SIGMA_ERROR,
5294 "ErrorCode,AMPDU value is not Enable nor Disabled");
5295 return -1;
5296 }
5297 }
5298
5299 val = get_param(cmd, "AMSDU");
5300 if (val) {
5301 if (strcasecmp(val, "Enable") == 0)
5302 dut->ap_amsdu = 1;
5303 else if (strcasecmp(val, "Disable") == 0)
5304 dut->ap_amsdu = 2;
5305 }
5306
5307 val = get_param(cmd, "NumMSDU");
5308 if (val) {
5309 send_resp(dut, conn, SIGMA_ERROR,
5310 "ErrorCode, NumMSDU is not supported yet");
5311 return -1;
5312 }
5313
5314 val = get_param(cmd, "ABFTLRang");
5315 if (val) {
5316 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02005317 "ABFTLRang parameter %s", val);
5318 if (strcmp(val, "Gt1") == 0)
5319 abft_len = 2; /* 2 slots in this case */
5320 }
5321
5322 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
5323 send_resp(dut, conn, SIGMA_ERROR,
5324 "ErrorCode, Can't set ABFT length");
5325 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005326 }
5327
5328 if (sta_pcp_start(dut, conn, cmd) < 0) {
5329 send_resp(dut, conn, SIGMA_ERROR,
5330 "ErrorCode, Can't start PCP role");
5331 return -1;
5332 }
5333
5334 return sta_set_60g_common(dut, conn, cmd);
5335}
5336
5337
5338static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
5339 struct sigma_cmd *cmd)
5340{
5341 const char *val = get_param(cmd, "DiscoveryMode");
5342
5343 if (dut->dev_role != DEVROLE_STA) {
5344 send_resp(dut, conn, SIGMA_INVALID,
5345 "ErrorCode,Invalid DevRole");
5346 return 0;
5347 }
5348
5349 if (val) {
5350 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
5351 /* Ignore Discovery mode till Driver expose API. */
5352#if 0
5353 if (strcasecmp(val, "1") == 0) {
5354 send_resp(dut, conn, SIGMA_INVALID,
5355 "ErrorCode,DiscoveryMode 1 not supported");
5356 return 0;
5357 }
5358
5359 if (strcasecmp(val, "0") == 0) {
5360 /* OK */
5361 } else {
5362 send_resp(dut, conn, SIGMA_INVALID,
5363 "ErrorCode,DiscoveryMode not supported");
5364 return 0;
5365 }
5366#endif
5367 }
5368
5369 if (start_sta_mode(dut) != 0)
5370 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
5371 return sta_set_60g_common(dut, conn, cmd);
5372}
5373
5374
5375static int cmd_sta_disconnect(struct sigma_dut *dut, struct sigma_conn *conn,
5376 struct sigma_cmd *cmd)
5377{
5378 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02005379 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05305380
Jouni Malinened77e672018-01-10 16:45:13 +02005381 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08005382 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02005383 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05305384 wpa_command(intf, "DISCONNECT");
5385 return 1;
5386 }
5387
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005388 disconnect_station(dut);
5389 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
5390 * due to cached results. */
5391 wpa_command(intf, "SET ignore_old_scan_res 1");
5392 wpa_command(intf, "BSS_FLUSH");
5393 return 1;
5394}
5395
5396
5397static int cmd_sta_reassoc(struct sigma_dut *dut, struct sigma_conn *conn,
5398 struct sigma_cmd *cmd)
5399{
5400 const char *intf = get_param(cmd, "Interface");
5401 const char *bssid = get_param(cmd, "bssid");
5402 const char *val = get_param(cmd, "CHANNEL");
5403 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305404 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05305405 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005406 int res;
5407 int chan = 0;
Ashwini Patil467efef2017-05-25 12:18:27 +05305408 int status = 0;
Sunil Duttd30ce092018-01-11 23:56:29 +05305409 int fastreassoc = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005410
5411 if (bssid == NULL) {
5412 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
5413 "argument");
5414 return 0;
5415 }
5416
5417 if (val)
5418 chan = atoi(val);
5419
5420 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
5421 /* The current network may be from sta_associate or
5422 * sta_hs2_associate
5423 */
5424 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
5425 0 ||
5426 set_network(intf, 0, "bssid", bssid) < 0)
5427 return -2;
5428 }
5429
5430 ctrl = open_wpa_mon(intf);
5431 if (ctrl == NULL) {
5432 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
5433 "wpa_supplicant monitor connection");
5434 return -1;
5435 }
5436
Sunil Duttd30ce092018-01-11 23:56:29 +05305437 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
5438 sizeof(result)) < 0 ||
5439 strncmp(result, "COMPLETED", 9) != 0) {
5440 sigma_dut_print(dut, DUT_MSG_DEBUG,
5441 "sta_reassoc: Not connected");
5442 fastreassoc = 0;
5443 }
5444
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05305445 if (dut->rsne_override) {
5446#ifdef NL80211_SUPPORT
5447 if (get_driver_type() == DRIVER_WCN && dut->config_rsnie == 0) {
5448 sta_config_rsnie(dut, 1);
5449 dut->config_rsnie = 1;
5450 }
5451#endif /* NL80211_SUPPORT */
5452 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
5453 dut->rsne_override);
5454 if (wpa_command(intf, buf) < 0) {
5455 send_resp(dut, conn, SIGMA_ERROR,
5456 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
5457 return 0;
5458 }
5459 }
5460
Sunil Duttd30ce092018-01-11 23:56:29 +05305461 if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005462#ifdef ANDROID
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305463 if (chan) {
5464 unsigned int freq;
5465
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02005466 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05305467 if (!freq) {
5468 sigma_dut_print(dut, DUT_MSG_ERROR,
5469 "Invalid channel number provided: %d",
5470 chan);
5471 send_resp(dut, conn, SIGMA_INVALID,
5472 "ErrorCode,Invalid channel number");
5473 goto close_mon_conn;
5474 }
5475 res = snprintf(buf, sizeof(buf),
5476 "SCAN TYPE=ONLY freq=%d", freq);
5477 } else {
5478 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
5479 }
5480 if (res < 0 || res >= (int) sizeof(buf)) {
5481 send_resp(dut, conn, SIGMA_ERROR,
5482 "ErrorCode,snprintf failed");
5483 goto close_mon_conn;
5484 }
5485 if (wpa_command(intf, buf) < 0) {
5486 sigma_dut_print(dut, DUT_MSG_INFO,
5487 "Failed to start scan");
5488 send_resp(dut, conn, SIGMA_ERROR,
5489 "ErrorCode,scan failed");
5490 goto close_mon_conn;
5491 }
5492
5493 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
5494 buf, sizeof(buf));
5495 if (res < 0) {
5496 sigma_dut_print(dut, DUT_MSG_INFO,
5497 "Scan did not complete");
5498 send_resp(dut, conn, SIGMA_ERROR,
5499 "ErrorCode,scan did not complete");
5500 goto close_mon_conn;
5501 }
5502
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005503 if (set_network(intf, dut->infra_network_id, "bssid", "any")
5504 < 0) {
5505 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
5506 "bssid to any during FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305507 status = -2;
5508 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005509 }
5510 res = snprintf(buf, sizeof(buf), "DRIVER FASTREASSOC %s %d",
5511 bssid, chan);
5512 if (res > 0 && res < (int) sizeof(buf))
5513 res = wpa_command(intf, buf);
5514
5515 if (res < 0 || res >= (int) sizeof(buf)) {
5516 send_resp(dut, conn, SIGMA_ERROR,
5517 "errorCode,Failed to run DRIVER FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05305518 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005519 }
5520#else /* ANDROID */
5521 sigma_dut_print(dut, DUT_MSG_DEBUG,
5522 "Reassoc using iwpriv - skip chan=%d info",
5523 chan);
5524 snprintf(buf, sizeof(buf), "iwpriv %s reassoc", intf);
5525 if (system(buf) != 0) {
5526 sigma_dut_print(dut, DUT_MSG_ERROR, "%s failed", buf);
Ashwini Patil467efef2017-05-25 12:18:27 +05305527 status = -2;
5528 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005529 }
5530#endif /* ANDROID */
5531 sigma_dut_print(dut, DUT_MSG_INFO,
5532 "sta_reassoc: Run %s successful", buf);
5533 } else if (wpa_command(intf, "REASSOCIATE")) {
5534 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
5535 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05305536 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005537 }
5538
5539 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
5540 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05305541 if (res < 0) {
5542 sigma_dut_print(dut, DUT_MSG_INFO, "Connection did not complete");
5543 status = -1;
5544 goto close_mon_conn;
5545 }
5546 status = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005547
Ashwini Patil467efef2017-05-25 12:18:27 +05305548close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005549 wpa_ctrl_detach(ctrl);
5550 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05305551 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005552}
5553
5554
5555static void hs2_clear_credentials(const char *intf)
5556{
5557 wpa_command(intf, "REMOVE_CRED all");
5558}
5559
5560
Lior Davidcc88b562017-01-03 18:52:09 +02005561#ifdef __linux__
5562static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
5563 unsigned int *aid)
5564{
Lior David0fe101e2017-03-09 16:09:50 +02005565 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02005566
Lior David0fe101e2017-03-09 16:09:50 +02005567 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02005568}
5569#endif /* __linux__ */
5570
5571
5572static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
5573 unsigned int *aid)
5574{
5575 switch (get_driver_type()) {
5576#ifdef __linux__
5577 case DRIVER_WIL6210:
5578 return wil6210_get_aid(dut, bssid, aid);
5579#endif /* __linux__ */
5580 default:
5581 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
5582 return -1;
5583 }
5584}
5585
5586
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005587static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
5588 struct sigma_cmd *cmd)
5589{
5590 char buf[MAX_CMD_LEN];
5591 char bss_list[MAX_CMD_LEN];
5592 const char *parameter = get_param(cmd, "Parameter");
5593
5594 if (parameter == NULL)
5595 return -1;
5596
Lior Davidcc88b562017-01-03 18:52:09 +02005597 if (strcasecmp(parameter, "AID") == 0) {
5598 unsigned int aid = 0;
5599 char bssid[20];
5600
5601 if (get_wpa_status(get_station_ifname(), "bssid",
5602 bssid, sizeof(bssid)) < 0) {
5603 sigma_dut_print(dut, DUT_MSG_ERROR,
5604 "could not get bssid");
5605 return -2;
5606 }
5607
5608 if (sta_get_aid_60g(dut, bssid, &aid))
5609 return -2;
5610
5611 snprintf(buf, sizeof(buf), "aid,%d", aid);
5612 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
5613 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5614 return 0;
5615 }
5616
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005617 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
5618 char *bss_line;
5619 char *bss_id = NULL;
5620 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305621 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005622
5623 if (ifname == NULL) {
5624 sigma_dut_print(dut, DUT_MSG_INFO,
5625 "For get DiscoveredDevList need Interface name.");
5626 return -1;
5627 }
5628
5629 /*
5630 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
5631 * of BSSIDs in "bssid=<BSSID>\n"
5632 */
5633 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
5634 bss_list,
5635 sizeof(bss_list)) < 0) {
5636 sigma_dut_print(dut, DUT_MSG_ERROR,
5637 "Failed to get bss list");
5638 return -1;
5639 }
5640
5641 sigma_dut_print(dut, DUT_MSG_DEBUG,
5642 "bss list for ifname:%s is:%s",
5643 ifname, bss_list);
5644
5645 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305646 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005647 while (bss_line) {
5648 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
5649 bss_id) {
5650 int len;
5651
5652 len = snprintf(buf + strlen(buf),
5653 sizeof(buf) - strlen(buf),
5654 ",%s", bss_id);
5655 free(bss_id);
5656 bss_id = NULL;
5657 if (len < 0) {
5658 sigma_dut_print(dut,
5659 DUT_MSG_ERROR,
5660 "Failed to read BSSID");
5661 send_resp(dut, conn, SIGMA_ERROR,
5662 "ErrorCode,Failed to read BSS ID");
5663 return 0;
5664 }
5665
5666 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
5667 sigma_dut_print(dut,
5668 DUT_MSG_ERROR,
5669 "Response buf too small for list");
5670 send_resp(dut, conn,
5671 SIGMA_ERROR,
5672 "ErrorCode,Response buf too small for list");
5673 return 0;
5674 }
5675 }
5676
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305677 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005678 }
5679
5680 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
5681 buf);
5682 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5683 return 0;
5684 }
5685
5686 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5687 return 0;
5688}
5689
5690
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07005691static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
5692 struct sigma_cmd *cmd)
5693{
5694 char buf[MAX_CMD_LEN];
5695 const char *parameter = get_param(cmd, "Parameter");
5696
5697 if (!parameter)
5698 return -1;
5699
5700 if (strcasecmp(parameter, "RSSI") == 0) {
5701 char rssi[10];
5702
5703 if (get_wpa_signal_poll(dut, get_station_ifname(), "RSSI",
5704 rssi, sizeof(rssi)) < 0) {
5705 sigma_dut_print(dut, DUT_MSG_ERROR,
5706 "Could not get RSSI");
5707 return -2;
5708 }
5709
5710 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
5711 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
5712 send_resp(dut, conn, SIGMA_COMPLETE, buf);
5713 return 0;
5714 }
5715
5716 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5717 return 0;
5718}
5719
5720
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005721static int cmd_sta_get_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
5722 struct sigma_cmd *cmd)
5723{
5724 const char *program = get_param(cmd, "Program");
5725
5726 if (program == NULL)
5727 return -1;
5728
5729 if (strcasecmp(program, "P2PNFC") == 0)
5730 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
5731
5732 if (strcasecmp(program, "60ghz") == 0)
5733 return sta_get_parameter_60g(dut, conn, cmd);
5734
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07005735 if (strcasecmp(program, "he") == 0)
5736 return sta_get_parameter_he(dut, conn, cmd);
5737
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005738#ifdef ANDROID_NAN
5739 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07005740 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005741#endif /* ANDROID_NAN */
5742
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07005743#ifdef MIRACAST
5744 if (strcasecmp(program, "WFD") == 0 ||
5745 strcasecmp(program, "DisplayR2") == 0)
5746 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
5747#endif /* MIRACAST */
5748
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005749 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
5750 return 0;
5751}
5752
5753
5754static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
5755 const char *type)
5756{
5757 char buf[100];
5758
5759 if (dut->program == PROGRAM_VHT) {
5760 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5761 if (system(buf) != 0) {
5762 sigma_dut_print(dut, DUT_MSG_ERROR,
5763 "iwpriv %s chwidth failed", intf);
5764 }
5765
5766 snprintf(buf, sizeof(buf), "iwpriv %s mode 11ACVHT80", intf);
5767 if (system(buf) != 0) {
5768 sigma_dut_print(dut, DUT_MSG_ERROR,
5769 "iwpriv %s mode 11ACVHT80 failed",
5770 intf);
5771 }
5772
5773 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs -1", intf);
5774 if (system(buf) != 0) {
5775 sigma_dut_print(dut, DUT_MSG_ERROR,
5776 "iwpriv %s vhtmcs -1 failed", intf);
5777 }
5778 }
5779
5780 if (dut->program == PROGRAM_HT) {
5781 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5782 if (system(buf) != 0) {
5783 sigma_dut_print(dut, DUT_MSG_ERROR,
5784 "iwpriv %s chwidth failed", intf);
5785 }
5786
5787 snprintf(buf, sizeof(buf), "iwpriv %s mode 11naht40", intf);
5788 if (system(buf) != 0) {
5789 sigma_dut_print(dut, DUT_MSG_ERROR,
5790 "iwpriv %s mode 11naht40 failed",
5791 intf);
5792 }
5793
5794 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0", intf);
5795 if (system(buf) != 0) {
5796 sigma_dut_print(dut, DUT_MSG_ERROR,
5797 "iwpriv set11NRates failed");
5798 }
5799 }
5800
5801 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
5802 snprintf(buf, sizeof(buf), "iwpriv %s powersave 0", intf);
5803 if (system(buf) != 0) {
5804 sigma_dut_print(dut, DUT_MSG_ERROR,
5805 "disabling powersave failed");
5806 }
5807
5808 /* Reset CTS width */
5809 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
5810 intf);
5811 if (system(buf) != 0) {
5812 sigma_dut_print(dut, DUT_MSG_ERROR,
5813 "wifitool %s beeliner_fw_test 54 0 failed",
5814 intf);
5815 }
5816
5817 /* Enable Dynamic Bandwidth signalling by default */
5818 snprintf(buf, sizeof(buf), "iwpriv %s cwmenable 1", intf);
5819 if (system(buf) != 0) {
5820 sigma_dut_print(dut, DUT_MSG_ERROR,
5821 "iwpriv %s cwmenable 1 failed", intf);
5822 }
5823
5824 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
5825 if (system(buf) != 0) {
5826 sigma_dut_print(dut, DUT_MSG_ERROR,
5827 "iwpriv rts failed");
5828 }
5829 }
5830
5831 if (type && strcasecmp(type, "Testbed") == 0) {
5832 dut->testbed_flag_txsp = 1;
5833 dut->testbed_flag_rxsp = 1;
5834 /* STA has to set spatial stream to 2 per Appendix H */
5835 snprintf(buf, sizeof(buf), "iwpriv %s vht_mcsmap 0xfff0", intf);
5836 if (system(buf) != 0) {
5837 sigma_dut_print(dut, DUT_MSG_ERROR,
5838 "iwpriv vht_mcsmap failed");
5839 }
5840
5841 /* Disable LDPC per Appendix H */
5842 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 0", intf);
5843 if (system(buf) != 0) {
5844 sigma_dut_print(dut, DUT_MSG_ERROR,
5845 "iwpriv %s ldpc 0 failed", intf);
5846 }
5847
5848 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5849 if (system(buf) != 0) {
5850 sigma_dut_print(dut, DUT_MSG_ERROR,
5851 "iwpriv amsdu failed");
5852 }
5853
5854 /* TODO: Disable STBC 2x1 transmit and receive */
5855 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc 0", intf);
5856 if (system(buf) != 0) {
5857 sigma_dut_print(dut, DUT_MSG_ERROR,
5858 "Disable tx_stbc 0 failed");
5859 }
5860
5861 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc 0", intf);
5862 if (system(buf) != 0) {
5863 sigma_dut_print(dut, DUT_MSG_ERROR,
5864 "Disable rx_stbc 0 failed");
5865 }
5866
5867 /* STA has to disable Short GI per Appendix H */
5868 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 0", intf);
5869 if (system(buf) != 0) {
5870 sigma_dut_print(dut, DUT_MSG_ERROR,
5871 "iwpriv %s shortgi 0 failed", intf);
5872 }
5873 }
5874
5875 if (type && strcasecmp(type, "DUT") == 0) {
5876 snprintf(buf, sizeof(buf), "iwpriv %s nss 3", intf);
5877 if (system(buf) != 0) {
5878 sigma_dut_print(dut, DUT_MSG_ERROR,
5879 "iwpriv %s nss 3 failed", intf);
5880 }
Arif Hussainac6c5112018-05-25 17:34:00 -07005881 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005882
5883 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 1", intf);
5884 if (system(buf) != 0) {
5885 sigma_dut_print(dut, DUT_MSG_ERROR,
5886 "iwpriv %s shortgi 1 failed", intf);
5887 }
5888 }
5889}
5890
5891
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08005892#ifdef NL80211_SUPPORT
5893static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
5894 enum he_mcs_config mcs)
5895{
5896 struct nl_msg *msg;
5897 int ret = 0;
5898 struct nlattr *params;
5899 int ifindex;
5900
5901 ifindex = if_nametoindex(intf);
5902 if (ifindex == 0) {
5903 sigma_dut_print(dut, DUT_MSG_ERROR,
5904 "%s: Index for interface %s failed",
5905 __func__, intf);
5906 return -1;
5907 }
5908
5909 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5910 NL80211_CMD_VENDOR)) ||
5911 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5912 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5913 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5914 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5915 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5916 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
5917 mcs)) {
5918 sigma_dut_print(dut, DUT_MSG_ERROR,
5919 "%s: err in adding vendor_cmd and vendor_data",
5920 __func__);
5921 nlmsg_free(msg);
5922 return -1;
5923 }
5924 nla_nest_end(msg, params);
5925
5926 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5927 if (ret) {
5928 sigma_dut_print(dut, DUT_MSG_ERROR,
5929 "%s: err in send_and_recv_msgs, ret=%d",
5930 __func__, ret);
5931 }
5932 return ret;
5933}
5934#endif /* NL80211_SUPPORT */
5935
5936
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07005937static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
5938 const char *intf, int enable)
5939{
5940#ifdef NL80211_SUPPORT
5941 struct nl_msg *msg;
5942 int ret = 0;
5943 struct nlattr *params;
5944 int ifindex;
5945
5946 ifindex = if_nametoindex(intf);
5947 if (ifindex == 0) {
5948 sigma_dut_print(dut, DUT_MSG_ERROR,
5949 "%s: Index for interface %s failed",
5950 __func__, intf);
5951 return -1;
5952 }
5953
5954 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5955 NL80211_CMD_VENDOR)) ||
5956 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5957 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5958 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5959 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5960 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5961 nla_put_u8(msg,
5962 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
5963 enable)) {
5964 sigma_dut_print(dut, DUT_MSG_ERROR,
5965 "%s: err in adding vendor_cmd and vendor_data",
5966 __func__);
5967 nlmsg_free(msg);
5968 return -1;
5969 }
5970 nla_nest_end(msg, params);
5971
5972 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5973 if (ret) {
5974 sigma_dut_print(dut, DUT_MSG_ERROR,
5975 "%s: err in send_and_recv_msgs, ret=%d",
5976 __func__, ret);
5977 }
5978 return ret;
5979#else /* NL80211_SUPPORT */
5980 sigma_dut_print(dut, DUT_MSG_ERROR,
5981 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
5982 return -1;
5983#endif /* NL80211_SUPPORT */
5984}
5985
5986
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08005987static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
5988 const char *intf, int enable)
5989{
5990#ifdef NL80211_SUPPORT
5991 struct nl_msg *msg;
5992 int ret = 0;
5993 struct nlattr *params;
5994 int ifindex;
5995
5996 ifindex = if_nametoindex(intf);
5997 if (ifindex == 0) {
5998 sigma_dut_print(dut, DUT_MSG_ERROR,
5999 "%s: Index for interface %s failed",
6000 __func__, intf);
6001 return -1;
6002 }
6003
6004 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6005 NL80211_CMD_VENDOR)) ||
6006 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6007 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6008 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6009 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6010 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6011 nla_put_u8(msg,
6012 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6013 enable)) {
6014 sigma_dut_print(dut, DUT_MSG_ERROR,
6015 "%s: err in adding vendor_cmd and vendor_data",
6016 __func__);
6017 nlmsg_free(msg);
6018 return -1;
6019 }
6020 nla_nest_end(msg, params);
6021
6022 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6023 if (ret) {
6024 sigma_dut_print(dut, DUT_MSG_ERROR,
6025 "%s: err in send_and_recv_msgs, ret=%d",
6026 __func__, ret);
6027 }
6028 return ret;
6029#else /* NL80211_SUPPORT */
6030 sigma_dut_print(dut, DUT_MSG_ERROR,
6031 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6032 return -1;
6033#endif /* NL80211_SUPPORT */
6034}
6035
6036
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006037static int sta_set_addba_buf_size(struct sigma_dut *dut,
6038 const char *intf, int bufsize)
6039{
6040#ifdef NL80211_SUPPORT
6041 struct nl_msg *msg;
6042 int ret = 0;
6043 struct nlattr *params;
6044 int ifindex;
6045
6046 ifindex = if_nametoindex(intf);
6047 if (ifindex == 0) {
6048 sigma_dut_print(dut, DUT_MSG_ERROR,
6049 "%s: Index for interface %s failed",
6050 __func__, intf);
6051 return -1;
6052 }
6053
6054 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6055 NL80211_CMD_VENDOR)) ||
6056 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6057 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6058 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6059 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6060 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07006061 nla_put_u16(msg,
6062 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
6063 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006064 sigma_dut_print(dut, DUT_MSG_ERROR,
6065 "%s: err in adding vendor_cmd and vendor_data",
6066 __func__);
6067 nlmsg_free(msg);
6068 return -1;
6069 }
6070 nla_nest_end(msg, params);
6071
6072 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6073 if (ret) {
6074 sigma_dut_print(dut, DUT_MSG_ERROR,
6075 "%s: err in send_and_recv_msgs, ret=%d",
6076 __func__, ret);
6077 }
6078 return ret;
6079#else /* NL80211_SUPPORT */
6080 sigma_dut_print(dut, DUT_MSG_ERROR,
6081 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
6082 return -1;
6083#endif /* NL80211_SUPPORT */
6084}
6085
6086
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006087static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
6088 int enable)
6089{
6090#ifdef NL80211_SUPPORT
6091 struct nl_msg *msg;
6092 int ret = 0;
6093 struct nlattr *params;
6094 int ifindex;
6095
6096 ifindex = if_nametoindex(intf);
6097 if (ifindex == 0) {
6098 sigma_dut_print(dut, DUT_MSG_ERROR,
6099 "%s: Index for interface %s failed",
6100 __func__, intf);
6101 return -1;
6102 }
6103
6104 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6105 NL80211_CMD_VENDOR)) ||
6106 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6107 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6108 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6109 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6110 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6111 nla_put_u8(msg,
6112 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
6113 enable)) {
6114 sigma_dut_print(dut, DUT_MSG_ERROR,
6115 "%s: err in adding vendor_cmd and vendor_data",
6116 __func__);
6117 nlmsg_free(msg);
6118 return -1;
6119 }
6120 nla_nest_end(msg, params);
6121
6122 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6123 if (ret) {
6124 sigma_dut_print(dut, DUT_MSG_ERROR,
6125 "%s: err in send_and_recv_msgs, ret=%d",
6126 __func__, ret);
6127 }
6128 return ret;
6129#else /* NL80211_SUPPORT */
6130 sigma_dut_print(dut, DUT_MSG_ERROR,
6131 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
6132 return -1;
6133#endif /* NL80211_SUPPORT */
6134}
6135
6136
Arif Hussain9765f7d2018-07-03 08:28:26 -07006137static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
6138 int val)
6139{
6140#ifdef NL80211_SUPPORT
6141 struct nl_msg *msg;
6142 int ret = 0;
6143 struct nlattr *params;
6144 int ifindex;
6145
6146 ifindex = if_nametoindex(intf);
6147 if (ifindex == 0) {
6148 sigma_dut_print(dut, DUT_MSG_ERROR,
6149 "%s: Index for interface %s failed, val:%d",
6150 __func__, intf, val);
6151 return -1;
6152 }
6153
6154 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6155 NL80211_CMD_VENDOR)) ||
6156 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6157 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6158 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6159 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6160 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6161 nla_put_u8(msg,
6162 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
6163 val)) {
6164 sigma_dut_print(dut, DUT_MSG_ERROR,
6165 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6166 __func__, val);
6167 nlmsg_free(msg);
6168 return -1;
6169 }
6170 nla_nest_end(msg, params);
6171
6172 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6173 if (ret) {
6174 sigma_dut_print(dut, DUT_MSG_ERROR,
6175 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6176 __func__, ret, val);
6177 }
6178 return ret;
6179#else /* NL80211_SUPPORT */
6180 sigma_dut_print(dut, DUT_MSG_ERROR,
6181 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
6182 return -1;
6183#endif /* NL80211_SUPPORT */
6184}
6185
6186
Arif Hussain68d23f52018-07-11 13:39:08 -07006187#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006188static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
6189 enum qca_wlan_he_mac_padding_dur val)
6190{
Arif Hussain68d23f52018-07-11 13:39:08 -07006191 struct nl_msg *msg;
6192 int ret = 0;
6193 struct nlattr *params;
6194 int ifindex;
6195
6196 ifindex = if_nametoindex(intf);
6197 if (ifindex == 0) {
6198 sigma_dut_print(dut, DUT_MSG_ERROR,
6199 "%s: Index for interface %s failed, val:%d",
6200 __func__, intf, val);
6201 return -1;
6202 }
6203
6204 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6205 NL80211_CMD_VENDOR)) ||
6206 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6207 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6208 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6209 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6210 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6211 nla_put_u8(msg,
6212 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
6213 val)) {
6214 sigma_dut_print(dut, DUT_MSG_ERROR,
6215 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6216 __func__, val);
6217 nlmsg_free(msg);
6218 return -1;
6219 }
6220 nla_nest_end(msg, params);
6221
6222 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6223 if (ret) {
6224 sigma_dut_print(dut, DUT_MSG_ERROR,
6225 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6226 __func__, ret, val);
6227 }
6228 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07006229}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006230#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07006231
6232
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006233static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
6234 int val)
6235{
6236#ifdef NL80211_SUPPORT
6237 struct nl_msg *msg;
6238 int ret = 0;
6239 struct nlattr *params;
6240 int ifindex;
6241
6242 ifindex = if_nametoindex(intf);
6243 if (ifindex == 0) {
6244 sigma_dut_print(dut, DUT_MSG_ERROR,
6245 "%s: Index for interface %s failed, val:%d",
6246 __func__, intf, val);
6247 return -1;
6248 }
6249
6250 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6251 NL80211_CMD_VENDOR)) ||
6252 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6253 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6254 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6255 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6256 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6257 nla_put_u8(msg,
6258 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
6259 val)) {
6260 sigma_dut_print(dut, DUT_MSG_ERROR,
6261 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6262 __func__, val);
6263 nlmsg_free(msg);
6264 return -1;
6265 }
6266 nla_nest_end(msg, params);
6267
6268 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6269 if (ret) {
6270 sigma_dut_print(dut, DUT_MSG_ERROR,
6271 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6272 __func__, ret, val);
6273 }
6274 return ret;
6275#else /* NL80211_SUPPORT */
6276 sigma_dut_print(dut, DUT_MSG_ERROR,
6277 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
6278 return -1;
6279#endif /* NL80211_SUPPORT */
6280}
6281
6282
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006283static int sta_set_he_om_ctrl_nss(struct sigma_dut *dut, const char *intf,
6284 int val)
6285{
6286#ifdef NL80211_SUPPORT
6287 struct nl_msg *msg;
6288 int ret = 0;
6289 struct nlattr *params;
6290 int ifindex;
6291
6292 ifindex = if_nametoindex(intf);
6293 if (ifindex == 0) {
6294 sigma_dut_print(dut, DUT_MSG_ERROR,
6295 "%s: Index for interface %s failed, val:%d",
6296 __func__, intf, val);
6297 return -1;
6298 }
6299
6300 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6301 NL80211_CMD_VENDOR)) ||
6302 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6303 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6304 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6305 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6306 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6307 nla_put_u8(msg,
6308 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS,
6309 val)) {
6310 sigma_dut_print(dut, DUT_MSG_ERROR,
6311 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6312 __func__, val);
6313 nlmsg_free(msg);
6314 return -1;
6315 }
6316 nla_nest_end(msg, params);
6317
6318 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6319 if (ret) {
6320 sigma_dut_print(dut, DUT_MSG_ERROR,
6321 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6322 __func__, ret, val);
6323 }
6324 return ret;
6325#else /* NL80211_SUPPORT */
6326 sigma_dut_print(dut, DUT_MSG_ERROR,
6327 "OM CTRL NSS cannot be set without NL80211_SUPPORT defined");
6328 return -1;
6329#endif /* NL80211_SUPPORT */
6330}
6331
6332
6333static int sta_set_he_om_ctrl_bw(struct sigma_dut *dut, const char *intf,
6334 enum qca_wlan_he_om_ctrl_ch_bw val)
6335{
6336#ifdef NL80211_SUPPORT
6337 struct nl_msg *msg;
6338 int ret = 0;
6339 struct nlattr *params;
6340 int ifindex;
6341
6342 ifindex = if_nametoindex(intf);
6343 if (ifindex == 0) {
6344 sigma_dut_print(dut, DUT_MSG_ERROR,
6345 "%s: Index for interface %s failed, val:%d",
6346 __func__, intf, val);
6347 return -1;
6348 }
6349
6350 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6351 NL80211_CMD_VENDOR)) ||
6352 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6353 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6354 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6355 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6356 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6357 nla_put_u8(msg,
6358 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW,
6359 val)) {
6360 sigma_dut_print(dut, DUT_MSG_ERROR,
6361 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6362 __func__, val);
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, val=%d",
6372 __func__, ret, val);
6373 }
6374 return ret;
6375#else /* NL80211_SUPPORT */
6376 sigma_dut_print(dut, DUT_MSG_ERROR,
6377 "OM CTRL BW cannot be set without NL80211_SUPPORT defined");
6378 return -1;
6379#endif /* NL80211_SUPPORT */
6380}
6381
6382
6383#ifdef NL80211_SUPPORT
6384static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
6385{
6386 struct nl_msg *msg;
6387 int ret = 0;
6388 struct nlattr *params;
6389 int ifindex;
6390
6391 ifindex = if_nametoindex(intf);
6392 if (ifindex == 0) {
6393 sigma_dut_print(dut, DUT_MSG_ERROR,
6394 "%s: Index for interface %s failed",
6395 __func__, intf);
6396 return -1;
6397 }
6398
6399 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6400 NL80211_CMD_VENDOR)) ||
6401 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6402 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6403 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6404 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6405 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6406 nla_put_flag(msg,
6407 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
6408 sigma_dut_print(dut, DUT_MSG_ERROR,
6409 "%s: err in adding vendor_cmd and vendor_data",
6410 __func__);
6411 nlmsg_free(msg);
6412 return -1;
6413 }
6414 nla_nest_end(msg, params);
6415
6416 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6417 if (ret) {
6418 sigma_dut_print(dut, DUT_MSG_ERROR,
6419 "%s: err in send_and_recv_msgs, ret=%d",
6420 __func__, ret);
6421 }
6422 return ret;
6423}
6424#endif /* NL80211_SUPPORT */
6425
6426
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006427static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
6428 int val)
6429{
6430#ifdef NL80211_SUPPORT
6431 struct nl_msg *msg;
6432 int ret = 0;
6433 struct nlattr *params;
6434 int ifindex;
6435
6436 ifindex = if_nametoindex(intf);
6437 if (ifindex == 0) {
6438 sigma_dut_print(dut, DUT_MSG_ERROR,
6439 "%s: Index for interface %s failed, val:%d",
6440 __func__, intf, val);
6441 return -1;
6442 }
6443
6444 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6445 NL80211_CMD_VENDOR)) ||
6446 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6447 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6448 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6449 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6450 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6451 nla_put_u8(msg,
6452 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
6453 val)) {
6454 sigma_dut_print(dut, DUT_MSG_ERROR,
6455 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6456 __func__, val);
6457 nlmsg_free(msg);
6458 return -1;
6459 }
6460 nla_nest_end(msg, params);
6461
6462 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6463 if (ret) {
6464 sigma_dut_print(dut, DUT_MSG_ERROR,
6465 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6466 __func__, ret, val);
6467 }
6468 return ret;
6469#else /* NL80211_SUPPORT */
6470 sigma_dut_print(dut, DUT_MSG_ERROR,
6471 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
6472 return -1;
6473#endif /* NL80211_SUPPORT */
6474}
6475
6476
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006477static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
6478 int val)
6479{
6480#ifdef NL80211_SUPPORT
6481 struct nl_msg *msg;
6482 int ret = 0;
6483 struct nlattr *params;
6484 int ifindex;
6485
6486 ifindex = if_nametoindex(intf);
6487 if (ifindex == 0) {
6488 sigma_dut_print(dut, DUT_MSG_ERROR,
6489 "%s: Index for interface %s failed, val:%d",
6490 __func__, intf, val);
6491 return -1;
6492 }
6493
6494 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6495 NL80211_CMD_VENDOR)) ||
6496 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6497 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6498 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6499 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6500 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6501 nla_put_u8(msg,
6502 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
6503 val)) {
6504 sigma_dut_print(dut, DUT_MSG_ERROR,
6505 "%s: err in adding vendor_cmd and vendor_data, val: %d",
6506 __func__, val);
6507 nlmsg_free(msg);
6508 return -1;
6509 }
6510 nla_nest_end(msg, params);
6511
6512 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6513 if (ret) {
6514 sigma_dut_print(dut, DUT_MSG_ERROR,
6515 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
6516 __func__, ret, val);
6517 }
6518 return ret;
6519#else /* NL80211_SUPPORT */
6520 sigma_dut_print(dut, DUT_MSG_ERROR,
6521 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
6522 return -1;
6523#endif /* NL80211_SUPPORT */
6524}
6525
6526
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006527static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
6528 const char *type)
6529{
6530 char buf[60];
6531
6532 if (dut->program == PROGRAM_HE) {
6533 /* resetting phymode to auto in case of HE program */
6534 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
6535 if (system(buf) != 0) {
6536 sigma_dut_print(dut, DUT_MSG_ERROR,
6537 "iwpriv %s setphymode failed", intf);
6538 }
6539
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07006540 /* reset the rate to Auto rate */
6541 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
6542 intf);
6543 if (system(buf) != 0) {
6544 sigma_dut_print(dut, DUT_MSG_ERROR,
6545 "iwpriv %s set_11ax_rate 0xff failed",
6546 intf);
6547 }
6548
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07006549 /* reset the LDPC setting */
6550 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
6551 if (system(buf) != 0) {
6552 sigma_dut_print(dut, DUT_MSG_ERROR,
6553 "iwpriv %s ldpc 1 failed", intf);
6554 }
6555
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006556 /* reset the power save setting */
6557 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
6558 if (system(buf) != 0) {
6559 sigma_dut_print(dut, DUT_MSG_ERROR,
6560 "iwpriv %s setPower 2 failed", intf);
6561 }
6562
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006563 /* remove all network profiles */
6564 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006565
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08006566 /* Configure ADDBA Req/Rsp buffer size to be 64 */
6567 sta_set_addba_buf_size(dut, intf, 64);
6568
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08006569#ifdef NL80211_SUPPORT
6570 /* Disable noackpolicy for all AC */
6571 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
6572 sigma_dut_print(dut, DUT_MSG_ERROR,
6573 "Disable of noackpolicy for all AC failed");
6574 }
6575#endif /* NL80211_SUPPORT */
6576
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08006577 /* Enable WMM by default */
6578 if (wcn_sta_set_wmm(dut, intf, "on")) {
6579 sigma_dut_print(dut, DUT_MSG_ERROR,
6580 "Enable of WMM in sta_reset_default_wcn failed");
6581 }
6582
6583 /* Disable ADDBA_REJECT by default */
6584 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
6585 sigma_dut_print(dut, DUT_MSG_ERROR,
6586 "Disable of addba_reject in sta_reset_default_wcn failed");
6587 }
6588
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006589 /* Enable sending of ADDBA by default */
6590 if (nlvendor_config_send_addba(dut, intf, 1)) {
6591 sigma_dut_print(dut, DUT_MSG_ERROR,
6592 "Enable sending of ADDBA in sta_reset_default_wcn failed");
6593 }
6594
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08006595 /* Enable AMPDU by default */
6596 iwpriv_sta_set_ampdu(dut, intf, 1);
6597
Subhani Shaik8e7a3052018-04-24 14:03:00 -07006598#ifdef NL80211_SUPPORT
6599 if (sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
6600 sigma_dut_print(dut, DUT_MSG_ERROR,
6601 "Set LTF config to default in sta_reset_default_wcn failed");
6602 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07006603
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08006604 /* set the beamformee NSTS(maximum number of
6605 * space-time streams) to default DUT config
6606 */
6607 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07006608 sigma_dut_print(dut, DUT_MSG_ERROR,
6609 "Failed to set BeamformeeSTS");
6610 }
Arif Hussain68d23f52018-07-11 13:39:08 -07006611
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07006612 if (sta_set_mac_padding_duration(
6613 dut, intf,
6614 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07006615 sigma_dut_print(dut, DUT_MSG_ERROR,
6616 "Failed to set MAC padding duration");
6617 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07006618
6619 if (sta_set_mu_edca_override(dut, intf, 0)) {
6620 sigma_dut_print(dut, DUT_MSG_ERROR,
6621 "ErrorCode,Failed to set MU EDCA override disable");
6622 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07006623
6624 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
6625 sigma_dut_print(dut, DUT_MSG_ERROR,
6626 "Failed to set OM ctrl supp");
6627 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07006628
6629 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
6630 sigma_dut_print(dut, DUT_MSG_ERROR,
6631 "Failed to set Tx SU PPDU enable");
6632 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006633
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006634 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
6635 sigma_dut_print(dut, DUT_MSG_ERROR,
6636 "failed to send TB PPDU Tx cfg");
6637 }
6638
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07006639 if (sta_set_he_om_ctrl_reset(dut, intf)) {
6640 sigma_dut_print(dut, DUT_MSG_ERROR,
6641 "Failed to set OM ctrl reset");
6642 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08006643
6644 /* +HTC-HE support default on */
6645 if (sta_set_he_htc_supp(dut, intf, 1)) {
6646 sigma_dut_print(dut, DUT_MSG_ERROR,
6647 "Setting of +HTC-HE support failed");
6648 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07006649#endif /* NL80211_SUPPORT */
6650
Arif Hussain8d5b27b2018-05-14 14:31:03 -07006651 if (sta_set_tx_beamformee(dut, intf, 1)) {
6652 sigma_dut_print(dut, DUT_MSG_ERROR,
6653 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
6654 }
6655
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006656 /* Set nss to 1 and MCS 0-7 in case of testbed */
6657 if (type && strcasecmp(type, "Testbed") == 0) {
6658#ifdef NL80211_SUPPORT
6659 int ret;
6660#endif /* NL80211_SUPPORT */
6661
6662 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
6663 if (system(buf) != 0) {
6664 sigma_dut_print(dut, DUT_MSG_ERROR,
6665 "iwpriv %s nss failed", intf);
6666 }
6667
6668#ifdef NL80211_SUPPORT
6669 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
6670 if (ret) {
6671 sigma_dut_print(dut, DUT_MSG_ERROR,
6672 "Setting of MCS failed, ret:%d",
6673 ret);
6674 }
6675#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08006676
6677 /* Disable STBC as default */
6678 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006679
6680 /* Disable AMSDU as default */
6681 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08006682
6683#ifdef NL80211_SUPPORT
6684 /* HE fragmentation default off */
6685 if (sta_set_he_fragmentation(dut, intf,
6686 HE_FRAG_DISABLE)) {
6687 sigma_dut_print(dut, DUT_MSG_ERROR,
6688 "Setting of HE fragmentation failed");
6689 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08006690
6691 /* set the beamformee NSTS(maximum number of
6692 * space-time streams) to default testbed config
6693 */
6694 if (sta_set_beamformee_sts(dut, intf, 3)) {
6695 sigma_dut_print(dut, DUT_MSG_ERROR,
6696 "Failed to set BeamformeeSTS");
6697 }
6698
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08006699 /* +HTC-HE support default off */
6700 if (sta_set_he_htc_supp(dut, intf, 0)) {
6701 sigma_dut_print(dut, DUT_MSG_ERROR,
6702 "Setting of +HTC-HE support failed");
6703 }
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08006704#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006705
6706 /* Enable WEP/TKIP with HE capability in testbed */
6707 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
6708 sigma_dut_print(dut, DUT_MSG_ERROR,
6709 "Enabling HE config with WEP/TKIP failed");
6710 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006711 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006712
6713 /* Defaults in case of DUT */
6714 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07006715 /* Enable STBC by default */
6716 wcn_sta_set_stbc(dut, intf, "1");
6717
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006718 /* set nss to 2 */
6719 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
6720 if (system(buf) != 0) {
6721 sigma_dut_print(dut, DUT_MSG_ERROR,
6722 "iwpriv %s nss 2 failed", intf);
6723 }
Arif Hussainac6c5112018-05-25 17:34:00 -07006724 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006725
6726#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07006727 /* Set HE_MCS to 0-11 */
6728 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08006729 sigma_dut_print(dut, DUT_MSG_ERROR,
6730 "Setting of MCS failed");
6731 }
6732#endif /* NL80211_SUPPORT */
6733
6734 /* Disable WEP/TKIP with HE capability in DUT */
6735 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
6736 sigma_dut_print(dut, DUT_MSG_ERROR,
6737 "Enabling HE config with WEP/TKIP failed");
6738 }
6739 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006740 }
6741}
6742
6743
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006744static int cmd_sta_reset_default(struct sigma_dut *dut,
6745 struct sigma_conn *conn,
6746 struct sigma_cmd *cmd)
6747{
6748 int cmd_sta_p2p_reset(struct sigma_dut *dut, struct sigma_conn *conn,
6749 struct sigma_cmd *cmd);
6750 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006751 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006752 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006753 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05306754 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006755
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006756 if (!program)
6757 program = get_param(cmd, "prog");
6758 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006759 dut->device_type = STA_unknown;
6760 type = get_param(cmd, "type");
6761 if (type && strcasecmp(type, "Testbed") == 0)
6762 dut->device_type = STA_testbed;
6763 if (type && strcasecmp(type, "DUT") == 0)
6764 dut->device_type = STA_dut;
6765
6766 if (dut->program == PROGRAM_TDLS) {
6767 /* Clear TDLS testing mode */
6768 wpa_command(intf, "SET tdls_disabled 0");
6769 wpa_command(intf, "SET tdls_testing 0");
6770 dut->no_tpk_expiration = 0;
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05306771 if (get_driver_type() == DRIVER_WCN) {
6772 /* Enable the WCN driver in TDLS Explicit trigger mode
6773 */
6774 wpa_command(intf, "SET tdls_external_control 0");
6775 wpa_command(intf, "SET tdls_trigger_control 0");
6776 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006777 }
6778
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006779#ifdef MIRACAST
6780 if (dut->program == PROGRAM_WFD ||
6781 dut->program == PROGRAM_DISPLAYR2)
6782 miracast_sta_reset_default(dut, conn, cmd);
6783#endif /* MIRACAST */
6784
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006785 switch (get_driver_type()) {
6786 case DRIVER_ATHEROS:
6787 sta_reset_default_ath(dut, intf, type);
6788 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08006789 case DRIVER_WCN:
6790 sta_reset_default_wcn(dut, intf, type);
6791 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006792 default:
6793 break;
6794 }
6795
6796#ifdef ANDROID_NAN
6797 if (dut->program == PROGRAM_NAN)
6798 nan_cmd_sta_reset_default(dut, conn, cmd);
6799#endif /* ANDROID_NAN */
6800
Jouni Malinenba630452018-06-22 11:49:59 +03006801 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006802 unlink("SP/wi-fi.org/pps.xml");
6803 if (system("rm -r SP/*") != 0) {
6804 }
6805 unlink("next-client-cert.pem");
6806 unlink("next-client-key.pem");
6807 }
6808
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006809 /* For WPS program of the 60 GHz band the band type needs to be saved */
6810 if (dut->program == PROGRAM_WPS) {
6811 if (band && strcasecmp(band, "60GHz") == 0) {
6812 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02006813 /* For 60 GHz enable WPS for WPS TCs */
6814 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006815 } else {
6816 dut->band = WPS_BAND_NON_60G;
6817 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02006818 } else if (dut->program == PROGRAM_60GHZ) {
6819 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
6820 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006821 }
6822
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02006823 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006824 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02006825 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006826
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02006827 sigma_dut_print(dut, DUT_MSG_INFO,
6828 "WPS 60 GHz program, wps_disable = %d",
6829 dut->wps_disable);
6830
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006831 if (!dev_role) {
6832 send_resp(dut, conn, SIGMA_ERROR,
6833 "errorCode,Missing DevRole argument");
6834 return 0;
6835 }
6836
6837 if (strcasecmp(dev_role, "STA") == 0)
6838 dut->dev_role = DEVROLE_STA;
6839 else if (strcasecmp(dev_role, "PCP") == 0)
6840 dut->dev_role = DEVROLE_PCP;
6841 else {
6842 send_resp(dut, conn, SIGMA_ERROR,
6843 "errorCode,Unknown DevRole");
6844 return 0;
6845 }
6846
6847 if (dut->device_type == STA_unknown) {
6848 sigma_dut_print(dut, DUT_MSG_ERROR,
6849 "Device type is not STA testbed or DUT");
6850 send_resp(dut, conn, SIGMA_ERROR,
6851 "errorCode,Unknown device type");
6852 return 0;
6853 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02006854
6855 sigma_dut_print(dut, DUT_MSG_DEBUG,
6856 "Setting msdu_size to MAX: 7912");
6857 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
6858 get_station_ifname());
6859
6860 if (system(buf) != 0) {
6861 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
6862 buf);
6863 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
6864 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006865 }
6866
6867 wpa_command(intf, "WPS_ER_STOP");
6868 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05306869 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006870 wpa_command(intf, "SET radio_disabled 0");
6871
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006872 if (dut->wsc_fragment) {
6873 dut->wsc_fragment = 0;
6874 wpa_command(intf, "SET device_name Test client");
6875 wpa_command(intf, "SET manufacturer ");
6876 wpa_command(intf, "SET model_name ");
6877 wpa_command(intf, "SET model_number ");
6878 wpa_command(intf, "SET serial_number ");
6879 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02006880 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
6881 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
6882 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
6883 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006884
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006885 if (dut->tmp_mac_addr && dut->set_macaddr) {
6886 dut->tmp_mac_addr = 0;
6887 if (system(dut->set_macaddr) != 0) {
6888 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
6889 "temporary MAC address");
6890 }
6891 }
6892
6893 set_ps(intf, dut, 0);
6894
Jouni Malinenba630452018-06-22 11:49:59 +03006895 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
6896 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006897 wpa_command(intf, "SET interworking 1");
6898 wpa_command(intf, "SET hs20 1");
6899 }
6900
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08006901 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03006902 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08006903 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006904 wpa_command(intf, "SET pmf 1");
6905 } else {
6906 wpa_command(intf, "SET pmf 0");
6907 }
6908
6909 hs2_clear_credentials(intf);
6910 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
6911 wpa_command(intf, "SET access_network_type 15");
6912
6913 static_ip_file(0, NULL, NULL, NULL);
6914 kill_dhcp_client(dut, intf);
6915 clear_ip_addr(dut, intf);
6916
6917 dut->er_oper_performed = 0;
6918 dut->er_oper_bssid[0] = '\0';
6919
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07006920 if (dut->program == PROGRAM_LOC) {
6921 /* Disable Interworking by default */
6922 wpa_command(get_station_ifname(), "SET interworking 0");
6923 }
6924
Ashwini Patil00402582017-04-13 12:29:39 +05306925 if (dut->program == PROGRAM_MBO) {
6926 free(dut->non_pref_ch_list);
6927 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05306928 free(dut->btm_query_cand_list);
6929 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05306930 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05306931 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05306932 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306933 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05306934 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05306935 }
6936
Jouni Malinen3c367e82017-06-23 17:01:47 +03006937 free(dut->rsne_override);
6938 dut->rsne_override = NULL;
6939
Jouni Malinen68143132017-09-02 02:34:08 +03006940 free(dut->sae_commit_override);
6941 dut->sae_commit_override = NULL;
6942
Jouni Malinend86e5822017-08-29 03:55:32 +03006943 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02006944 free(dut->dpp_peer_uri);
6945 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02006946 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02006947 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03006948
Jouni Malinenfac9cad2017-10-10 18:35:55 +03006949 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
6950
vamsi krishnaa2799492017-12-05 14:28:01 +05306951 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306952 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05306953 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05306954 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
6955 dut->fils_hlp = 0;
6956#ifdef ANDROID
6957 hlp_thread_cleanup(dut);
6958#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05306959 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306960
Sunil Dutt076081f2018-02-05 19:45:50 +05306961#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05306962 if (get_driver_type() == DRIVER_WCN &&
6963 dut->config_rsnie == 1) {
6964 dut->config_rsnie = 0;
6965 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05306966 }
6967#endif /* NL80211_SUPPORT */
6968
Sunil Duttfebf8a82018-02-09 18:50:13 +05306969 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
6970 dut->dev_role = DEVROLE_STA_CFON;
6971 return sta_cfon_reset_default(dut, conn, cmd);
6972 }
6973
Jouni Malinen439352d2018-09-13 03:42:23 +03006974 wpa_command(intf, "SET setband AUTO");
6975
Sunil Duttfebf8a82018-02-09 18:50:13 +05306976 if (dut->program != PROGRAM_VHT)
6977 return cmd_sta_p2p_reset(dut, conn, cmd);
6978
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08006979 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006980}
6981
6982
6983static int cmd_sta_get_events(struct sigma_dut *dut, struct sigma_conn *conn,
6984 struct sigma_cmd *cmd)
6985{
6986 const char *program = get_param(cmd, "Program");
6987
6988 if (program == NULL)
6989 return -1;
6990#ifdef ANDROID_NAN
6991 if (strcasecmp(program, "NAN") == 0)
6992 return nan_cmd_sta_get_events(dut, conn, cmd);
6993#endif /* ANDROID_NAN */
6994 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6995 return 0;
6996}
6997
6998
Jouni Malinen82905202018-04-29 17:20:10 +03006999static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
7000 struct sigma_cmd *cmd)
7001{
7002 const char *url = get_param(cmd, "url");
7003 const char *method = get_param(cmd, "method");
7004 pid_t pid;
7005 int status;
7006
7007 if (!url || !method)
7008 return -1;
7009
7010 /* TODO: Add support for method,post */
7011 if (strcasecmp(method, "get") != 0) {
7012 send_resp(dut, conn, SIGMA_ERROR,
7013 "ErrorCode,Unsupported method");
7014 return 0;
7015 }
7016
7017 pid = fork();
7018 if (pid < 0) {
7019 perror("fork");
7020 return -1;
7021 }
7022
7023 if (pid == 0) {
7024 char * argv[5] = { "wget", "-O", "/dev/null",
7025 (char *) url, NULL };
7026
7027 execv("/usr/bin/wget", argv);
7028 perror("execv");
7029 exit(0);
7030 return -1;
7031 }
7032
7033 if (waitpid(pid, &status, 0) < 0) {
7034 perror("waitpid");
7035 return -1;
7036 }
7037
7038 if (WIFEXITED(status)) {
7039 const char *errmsg;
7040
7041 if (WEXITSTATUS(status) == 0)
7042 return 1;
7043 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
7044 WEXITSTATUS(status));
7045 switch (WEXITSTATUS(status)) {
7046 case 4:
7047 errmsg = "errmsg,Network failure";
7048 break;
7049 case 8:
7050 errmsg = "errmsg,Server issued an error response";
7051 break;
7052 default:
7053 errmsg = "errmsg,Unknown failure from wget";
7054 break;
7055 }
7056 send_resp(dut, conn, SIGMA_ERROR, errmsg);
7057 return 0;
7058 }
7059
7060 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
7061 return 0;
7062}
7063
7064
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007065static int cmd_sta_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
7066 struct sigma_cmd *cmd)
7067{
7068 const char *program = get_param(cmd, "Prog");
7069
Jouni Malinen82905202018-04-29 17:20:10 +03007070 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007071 return -1;
7072#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03007073 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007074 return nan_cmd_sta_exec_action(dut, conn, cmd);
7075#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03007076
7077 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07007078 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03007079
7080 if (get_param(cmd, "url"))
7081 return sta_exec_action_url(dut, conn, cmd);
7082
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007083 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7084 return 0;
7085}
7086
7087
7088static int cmd_sta_set_11n(struct sigma_dut *dut, struct sigma_conn *conn,
7089 struct sigma_cmd *cmd)
7090{
7091 const char *intf = get_param(cmd, "Interface");
7092 const char *val, *mcs32, *rate;
7093
7094 val = get_param(cmd, "GREENFIELD");
7095 if (val) {
7096 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
7097 /* Enable GD */
7098 send_resp(dut, conn, SIGMA_ERROR,
7099 "ErrorCode,GF not supported");
7100 return 0;
7101 }
7102 }
7103
7104 val = get_param(cmd, "SGI20");
7105 if (val) {
7106 switch (get_driver_type()) {
7107 case DRIVER_ATHEROS:
7108 ath_sta_set_sgi(dut, intf, val);
7109 break;
7110 default:
7111 send_resp(dut, conn, SIGMA_ERROR,
7112 "ErrorCode,SGI20 not supported");
7113 return 0;
7114 }
7115 }
7116
7117 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
7118 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
7119 if (mcs32 && rate) {
7120 /* TODO */
7121 send_resp(dut, conn, SIGMA_ERROR,
7122 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
7123 return 0;
7124 } else if (mcs32 && !rate) {
7125 /* TODO */
7126 send_resp(dut, conn, SIGMA_ERROR,
7127 "ErrorCode,MCS32 not supported");
7128 return 0;
7129 } else if (!mcs32 && rate) {
7130 switch (get_driver_type()) {
7131 case DRIVER_ATHEROS:
priyadharshini gowthamane5e25172015-12-08 14:53:48 -08007132 novap_reset(dut, intf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007133 ath_sta_set_11nrates(dut, intf, rate);
7134 break;
7135 default:
7136 send_resp(dut, conn, SIGMA_ERROR,
7137 "ErrorCode,MCS32_FIXEDRATE not supported");
7138 return 0;
7139 }
7140 }
7141
7142 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7143}
7144
7145
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007146static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
7147 int mcs_config)
7148{
7149#ifdef NL80211_SUPPORT
7150 int ret;
7151
7152 switch (mcs_config) {
7153 case HE_80_MCS0_7:
7154 case HE_80_MCS0_9:
7155 case HE_80_MCS0_11:
7156 ret = sta_set_he_mcs(dut, intf, mcs_config);
7157 if (ret) {
7158 sigma_dut_print(dut, DUT_MSG_ERROR,
7159 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
7160 mcs_config, ret);
7161 }
7162 break;
7163 default:
7164 sigma_dut_print(dut, DUT_MSG_ERROR,
7165 "cmd_set_max_he_mcs: Invalid mcs %d",
7166 mcs_config);
7167 break;
7168 }
7169#else /* NL80211_SUPPORT */
7170 sigma_dut_print(dut, DUT_MSG_ERROR,
7171 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
7172#endif /* NL80211_SUPPORT */
7173}
7174
7175
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007176static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
7177 struct sigma_conn *conn,
7178 struct sigma_cmd *cmd)
7179{
7180 const char *intf = get_param(cmd, "Interface");
7181 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07007182 const char *program;
Arif Hussaind13d6952018-07-02 16:23:47 -07007183 char buf[60];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007184 int tkip = -1;
7185 int wep = -1;
7186
Arif Hussaina37e9552018-06-20 17:05:59 -07007187 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007188 val = get_param(cmd, "SGI80");
7189 if (val) {
7190 int sgi80;
7191
7192 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7193 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d", intf, sgi80);
7194 if (system(buf) != 0) {
7195 sigma_dut_print(dut, DUT_MSG_ERROR,
7196 "iwpriv shortgi failed");
7197 }
7198 }
7199
7200 val = get_param(cmd, "TxBF");
7201 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007202 switch (get_driver_type()) {
7203 case DRIVER_WCN:
7204 if (sta_set_tx_beamformee(dut, intf, 1)) {
7205 send_resp(dut, conn, SIGMA_ERROR,
7206 "ErrorCode,Failed to set TX beamformee enable");
7207 return 0;
7208 }
7209 break;
7210 case DRIVER_ATHEROS:
7211 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfee 1",
7212 intf);
7213 if (system(buf) != 0) {
7214 send_resp(dut, conn, SIGMA_ERROR,
7215 "ErrorCode,Setting vhtsubfee failed");
7216 return 0;
7217 }
7218
7219 snprintf(buf, sizeof(buf), "iwpriv %s vhtsubfer 1",
7220 intf);
7221 if (system(buf) != 0) {
7222 send_resp(dut, conn, SIGMA_ERROR,
7223 "ErrorCode,Setting vhtsubfer failed");
7224 return 0;
7225 }
7226 break;
7227 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007228 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07007229 "Unsupported driver type");
7230 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007231 }
7232 }
7233
7234 val = get_param(cmd, "MU_TxBF");
7235 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
7236 switch (get_driver_type()) {
7237 case DRIVER_ATHEROS:
7238 ath_sta_set_txsp_stream(dut, intf, "1SS");
7239 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Sunil Duttae9e5d12018-06-29 11:50:47 +05307240 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfee 1",
7241 intf);
7242 if (system(buf) != 0) {
7243 sigma_dut_print(dut, DUT_MSG_ERROR,
7244 "iwpriv vhtmubfee failed");
7245 }
7246 snprintf(buf, sizeof(buf), "iwpriv %s vhtmubfer 1",
7247 intf);
7248 if (system(buf) != 0) {
7249 sigma_dut_print(dut, DUT_MSG_ERROR,
7250 "iwpriv vhtmubfer failed");
7251 }
7252 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007253 case DRIVER_WCN:
7254 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
7255 send_resp(dut, conn, SIGMA_ERROR,
7256 "ErrorCode,Failed to set RX/TXSP_STREAM");
7257 return 0;
7258 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05307259 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007260 default:
7261 sigma_dut_print(dut, DUT_MSG_ERROR,
7262 "Setting SP_STREAM not supported");
7263 break;
7264 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007265 }
7266
7267 val = get_param(cmd, "LDPC");
7268 if (val) {
7269 int ldpc;
7270
7271 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7272 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, ldpc);
7273 if (system(buf) != 0) {
7274 sigma_dut_print(dut, DUT_MSG_ERROR,
7275 "iwpriv ldpc failed");
7276 }
7277 }
7278
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08007279 val = get_param(cmd, "BCC");
7280 if (val) {
7281 int bcc;
7282
7283 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7284 /* use LDPC iwpriv itself to set bcc coding, bcc coding
7285 * is mutually exclusive to bcc */
7286 snprintf(buf, sizeof(buf), "iwpriv %s ldpc %d", intf, !bcc);
7287 if (system(buf) != 0) {
7288 sigma_dut_print(dut, DUT_MSG_ERROR,
7289 "Enabling/Disabling of BCC failed");
7290 }
7291 }
7292
Arif Hussain7b47d2d2018-05-09 10:44:02 -07007293 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
7294 if (val && dut->sta_nss == 1)
7295 cmd_set_max_he_mcs(dut, intf, atoi(val));
7296
7297 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
7298 if (val && dut->sta_nss == 2)
7299 cmd_set_max_he_mcs(dut, intf, atoi(val));
7300
Arif Hussainac6c5112018-05-25 17:34:00 -07007301 val = get_param(cmd, "MCS_FixedRate");
7302 if (val) {
7303#ifdef NL80211_SUPPORT
7304 int mcs, ratecode = 0;
7305 enum he_mcs_config mcs_config;
7306 int ret;
7307
7308 ratecode = (0x07 & dut->sta_nss) << 5;
7309 mcs = atoi(val);
7310 /* Add the MCS to the ratecode */
7311 if (mcs >= 0 && mcs <= 11) {
7312 ratecode += mcs;
7313 if (dut->device_type == STA_testbed &&
7314 mcs > 7 && mcs <= 11) {
7315 if (mcs <= 9)
7316 mcs_config = HE_80_MCS0_9;
7317 else
7318 mcs_config = HE_80_MCS0_11;
7319 ret = sta_set_he_mcs(dut, intf, mcs_config);
7320 if (ret) {
7321 sigma_dut_print(dut, DUT_MSG_ERROR,
7322 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
7323 mcs, mcs_config, ret);
7324 }
7325 }
7326 snprintf(buf, sizeof(buf),
7327 "iwpriv %s set_11ax_rate 0x%03x",
7328 intf, ratecode);
7329 if (system(buf) != 0) {
7330 sigma_dut_print(dut, DUT_MSG_ERROR,
7331 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
7332 ratecode);
7333 }
7334 } else {
7335 sigma_dut_print(dut, DUT_MSG_ERROR,
7336 "MCS_FixedRate: HE MCS %d not supported",
7337 mcs);
7338 }
7339#else /* NL80211_SUPPORT */
7340 sigma_dut_print(dut, DUT_MSG_ERROR,
7341 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
7342#endif /* NL80211_SUPPORT */
7343 }
7344
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007345 val = get_param(cmd, "opt_md_notif_ie");
7346 if (val) {
7347 char *result = NULL;
7348 char delim[] = ";";
7349 char token[30];
7350 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307351 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007352
Peng Xub8fc5cc2017-05-10 17:27:28 -07007353 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307354 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007355
7356 /* Extract the NSS information */
7357 if (result) {
7358 value = atoi(result);
7359 switch (value) {
7360 case 1:
7361 config_val = 1;
7362 break;
7363 case 2:
7364 config_val = 3;
7365 break;
7366 case 3:
7367 config_val = 7;
7368 break;
7369 case 4:
7370 config_val = 15;
7371 break;
7372 default:
7373 config_val = 3;
7374 break;
7375 }
7376
7377 snprintf(buf, sizeof(buf), "iwpriv %s rxchainmask %d",
7378 intf, config_val);
7379 if (system(buf) != 0) {
7380 sigma_dut_print(dut, DUT_MSG_ERROR,
7381 "iwpriv rxchainmask failed");
7382 }
7383
7384 snprintf(buf, sizeof(buf), "iwpriv %s txchainmask %d",
7385 intf, config_val);
7386 if (system(buf) != 0) {
7387 sigma_dut_print(dut, DUT_MSG_ERROR,
7388 "iwpriv txchainmask failed");
7389 }
7390 }
7391
7392 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307393 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007394 if (result) {
7395 value = atoi(result);
7396 switch (value) {
7397 case 20:
7398 config_val = 0;
7399 break;
7400 case 40:
7401 config_val = 1;
7402 break;
7403 case 80:
7404 config_val = 2;
7405 break;
7406 case 160:
7407 config_val = 3;
7408 break;
7409 default:
7410 config_val = 2;
7411 break;
7412 }
7413
7414 dut->chwidth = config_val;
7415
7416 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
7417 intf, config_val);
7418 if (system(buf) != 0) {
7419 sigma_dut_print(dut, DUT_MSG_ERROR,
7420 "iwpriv chwidth failed");
7421 }
7422 }
7423
7424 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", intf);
7425 if (system(buf) != 0) {
7426 sigma_dut_print(dut, DUT_MSG_ERROR,
7427 "iwpriv opmode_notify failed");
7428 }
7429 }
7430
7431 val = get_param(cmd, "nss_mcs_cap");
7432 if (val) {
7433 int nss, mcs;
7434 char token[20];
7435 char *result = NULL;
7436 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307437 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007438
Peng Xub8fc5cc2017-05-10 17:27:28 -07007439 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307440 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307441 if (!result) {
7442 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007443 "NSS not specified");
7444 send_resp(dut, conn, SIGMA_ERROR,
7445 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307446 return 0;
7447 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007448 nss = atoi(result);
7449
7450 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
7451 if (system(buf) != 0) {
7452 sigma_dut_print(dut, DUT_MSG_ERROR,
7453 "iwpriv nss failed");
7454 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007455 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007456
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307457 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007458 if (result == NULL) {
7459 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007460 "MCS not specified");
7461 send_resp(dut, conn, SIGMA_ERROR,
7462 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007463 return 0;
7464 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307465 result = strtok_r(result, "-", &saveptr);
7466 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307467 if (!result) {
7468 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007469 "MCS not specified");
7470 send_resp(dut, conn, SIGMA_ERROR,
7471 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05307472 return 0;
7473 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007474 mcs = atoi(result);
7475
Arif Hussaina37e9552018-06-20 17:05:59 -07007476 if (program && strcasecmp(program, "HE") == 0) {
7477#ifdef NL80211_SUPPORT
7478 enum he_mcs_config mcs_config;
7479 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007480
Arif Hussaina37e9552018-06-20 17:05:59 -07007481 if (mcs >= 0 && mcs <= 7) {
7482 mcs_config = HE_80_MCS0_7;
7483 } else if (mcs > 7 && mcs <= 9) {
7484 mcs_config = HE_80_MCS0_9;
7485 } else if (mcs > 9 && mcs <= 11) {
7486 mcs_config = HE_80_MCS0_11;
7487 } else {
7488 sigma_dut_print(dut, DUT_MSG_ERROR,
7489 "nss_mcs_cap: HE: Invalid mcs: %d",
7490 mcs);
7491 send_resp(dut, conn, SIGMA_ERROR,
7492 "errorCode,Invalid MCS");
7493 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007494 }
Arif Hussaina37e9552018-06-20 17:05:59 -07007495
7496 ret = sta_set_he_mcs(dut, intf, mcs_config);
7497 if (ret) {
7498 sigma_dut_print(dut, DUT_MSG_ERROR,
7499 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
7500 mcs_config, ret);
7501 send_resp(dut, conn, SIGMA_ERROR,
7502 "errorCode,Failed to set MCS");
7503 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007504 }
Arif Hussaina37e9552018-06-20 17:05:59 -07007505#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007506 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07007507 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
7508#endif /* NL80211_SUPPORT */
7509 } else {
7510 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
7511 intf, mcs);
7512 if (system(buf) != 0) {
7513 sigma_dut_print(dut, DUT_MSG_ERROR,
7514 "iwpriv mcs failed");
7515 }
7516
7517 switch (nss) {
7518 case 1:
7519 switch (mcs) {
7520 case 7:
7521 vht_mcsmap = 0xfffc;
7522 break;
7523 case 8:
7524 vht_mcsmap = 0xfffd;
7525 break;
7526 case 9:
7527 vht_mcsmap = 0xfffe;
7528 break;
7529 default:
7530 vht_mcsmap = 0xfffe;
7531 break;
7532 }
7533 break;
7534 case 2:
7535 switch (mcs) {
7536 case 7:
7537 vht_mcsmap = 0xfff0;
7538 break;
7539 case 8:
7540 vht_mcsmap = 0xfff5;
7541 break;
7542 case 9:
7543 vht_mcsmap = 0xfffa;
7544 break;
7545 default:
7546 vht_mcsmap = 0xfffa;
7547 break;
7548 }
7549 break;
7550 case 3:
7551 switch (mcs) {
7552 case 7:
7553 vht_mcsmap = 0xffc0;
7554 break;
7555 case 8:
7556 vht_mcsmap = 0xffd5;
7557 break;
7558 case 9:
7559 vht_mcsmap = 0xffea;
7560 break;
7561 default:
7562 vht_mcsmap = 0xffea;
7563 break;
7564 }
7565 break;
7566 default:
7567 vht_mcsmap = 0xffea;
7568 break;
7569 }
7570 snprintf(buf, sizeof(buf),
7571 "iwpriv %s vht_mcsmap 0x%04x",
7572 intf, vht_mcsmap);
7573 if (system(buf) != 0) {
7574 sigma_dut_print(dut, DUT_MSG_ERROR,
7575 "iwpriv vht_mcsmap failed");
7576 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007577 }
7578 }
7579
7580 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
7581
7582 val = get_param(cmd, "Vht_tkip");
7583 if (val)
7584 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7585
7586 val = get_param(cmd, "Vht_wep");
7587 if (val)
7588 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
7589
7590 if (tkip != -1 || wep != -1) {
7591 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
7592 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 1",
7593 intf);
7594 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
7595 snprintf(buf, sizeof(buf), "iwpriv %s htweptkip 0",
7596 intf);
7597 } else {
7598 sigma_dut_print(dut, DUT_MSG_ERROR,
7599 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
7600 return 0;
7601 }
7602
7603 if (system(buf) != 0) {
7604 sigma_dut_print(dut, DUT_MSG_ERROR,
7605 "iwpriv htweptkip failed");
7606 }
7607 }
7608
Arif Hussain55f00da2018-07-03 08:28:26 -07007609 val = get_param(cmd, "txBandwidth");
7610 if (val) {
7611 switch (get_driver_type()) {
7612 case DRIVER_WCN:
7613 if (wcn_sta_set_width(dut, intf, val) < 0) {
7614 send_resp(dut, conn, SIGMA_ERROR,
7615 "ErrorCode,Failed to set txBandwidth");
7616 return 0;
7617 }
7618 break;
7619 case DRIVER_ATHEROS:
7620 if (ath_set_width(dut, conn, intf, val) < 0) {
7621 send_resp(dut, conn, SIGMA_ERROR,
7622 "ErrorCode,Failed to set txBandwidth");
7623 return 0;
7624 }
7625 break;
7626 default:
7627 sigma_dut_print(dut, DUT_MSG_ERROR,
7628 "Setting txBandwidth not supported");
7629 break;
7630 }
7631 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007632
Arif Hussain9765f7d2018-07-03 08:28:26 -07007633 val = get_param(cmd, "BeamformeeSTS");
7634 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07007635 if (sta_set_tx_beamformee(dut, intf, 1)) {
7636 send_resp(dut, conn, SIGMA_ERROR,
7637 "ErrorCode,Failed to set TX beamformee enable");
7638 return 0;
7639 }
7640
Arif Hussain9765f7d2018-07-03 08:28:26 -07007641 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
7642 send_resp(dut, conn, SIGMA_ERROR,
7643 "ErrorCode,Failed to set BeamformeeSTS");
7644 return 0;
7645 }
7646 }
7647
Arif Hussain68d23f52018-07-11 13:39:08 -07007648 val = get_param(cmd, "Trig_MAC_Padding_Dur");
7649 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007650#ifdef NL80211_SUPPORT
7651 enum qca_wlan_he_mac_padding_dur set_val;
7652
7653 switch (atoi(val)) {
7654 case 16:
7655 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
7656 break;
7657 case 8:
7658 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
7659 break;
7660 default:
7661 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
7662 break;
7663 }
7664 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007665 send_resp(dut, conn, SIGMA_ERROR,
7666 "ErrorCode,Failed to set MAC padding duration");
7667 return 0;
7668 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007669#else /* NL80211_SUPPORT */
7670 sigma_dut_print(dut, DUT_MSG_ERROR,
7671 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
7672#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007673 }
7674
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007675 val = get_param(cmd, "MU_EDCA");
7676 if (val && (strcasecmp(val, "Override") == 0)) {
7677 if (sta_set_mu_edca_override(dut, intf, 1)) {
7678 send_resp(dut, conn, SIGMA_ERROR,
7679 "ErrorCode,Failed to set MU EDCA override");
7680 return 0;
7681 }
7682 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07007683
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007684 val = get_param(cmd, "OMControl");
7685 if (val) {
7686 int set_val = 1;
7687
7688 if (strcasecmp(val, "Enable") == 0)
7689 set_val = 1;
7690 else if (strcasecmp(val, "Disable") == 0)
7691 set_val = 0;
7692
7693 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
7694 send_resp(dut, conn, SIGMA_ERROR,
7695 "ErrorCode,Failed to set OM ctrl supp");
7696 return 0;
7697 }
7698 }
7699
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07007700 val = get_param(cmd, "ADDBAResp_BufSize");
7701 if (val) {
7702 int buf_size;
7703
7704 if (strcasecmp(val, "gt64") == 0)
7705 buf_size = 256;
7706 else
7707 buf_size = 64;
7708 if (get_driver_type() == DRIVER_WCN &&
7709 sta_set_addba_buf_size(dut, intf, buf_size)) {
7710 send_resp(dut, conn, SIGMA_ERROR,
7711 "ErrorCode,set addbaresp_buff_size failed");
7712 return 0;
7713 }
7714 }
7715
7716 val = get_param(cmd, "ADDBAReq_BufSize");
7717 if (val) {
7718 int buf_size;
7719
7720 if (strcasecmp(val, "gt64") == 0)
7721 buf_size = 256;
7722 else
7723 buf_size = 64;
7724 if (get_driver_type() == DRIVER_WCN &&
7725 sta_set_addba_buf_size(dut, intf, buf_size)) {
7726 send_resp(dut, conn, SIGMA_ERROR,
7727 "ErrorCode,set addbareq_buff_size failed");
7728 return 0;
7729 }
7730 }
7731
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007732 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7733}
7734
7735
7736static int sta_set_wireless_60g(struct sigma_dut *dut,
7737 struct sigma_conn *conn,
7738 struct sigma_cmd *cmd)
7739{
7740 const char *dev_role = get_param(cmd, "DevRole");
7741
7742 if (!dev_role) {
7743 send_resp(dut, conn, SIGMA_INVALID,
7744 "ErrorCode,DevRole not specified");
7745 return 0;
7746 }
7747
7748 if (strcasecmp(dev_role, "PCP") == 0)
7749 return sta_set_60g_pcp(dut, conn, cmd);
7750 if (strcasecmp(dev_role, "STA") == 0)
7751 return sta_set_60g_sta(dut, conn, cmd);
7752 send_resp(dut, conn, SIGMA_INVALID,
7753 "ErrorCode,DevRole not supported");
7754 return 0;
7755}
7756
7757
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307758static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
7759 struct sigma_cmd *cmd)
7760{
7761 int status;
7762 const char *intf = get_param(cmd, "Interface");
7763 const char *val = get_param(cmd, "DevRole");
7764
7765 if (val && strcasecmp(val, "STA-CFON") == 0) {
7766 status = sta_cfon_set_wireless(dut, conn, cmd);
7767 if (status)
7768 return status;
7769 }
7770 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
7771}
7772
7773
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007774static int cmd_sta_set_wireless(struct sigma_dut *dut, struct sigma_conn *conn,
7775 struct sigma_cmd *cmd)
7776{
7777 const char *val;
7778
7779 val = get_param(cmd, "Program");
7780 if (val) {
7781 if (strcasecmp(val, "11n") == 0)
7782 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08007783 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007784 return cmd_sta_set_wireless_vht(dut, conn, cmd);
7785 if (strcasecmp(val, "60ghz") == 0)
7786 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307787 if (strcasecmp(val, "OCE") == 0)
7788 return sta_set_wireless_oce(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007789 send_resp(dut, conn, SIGMA_ERROR,
7790 "ErrorCode,Program value not supported");
7791 } else {
7792 send_resp(dut, conn, SIGMA_ERROR,
7793 "ErrorCode,Program argument not available");
7794 }
7795
7796 return 0;
7797}
7798
7799
7800static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
7801 int tid)
7802{
7803 char buf[100];
7804 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
7805
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05307806 if (tid < 0 ||
7807 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
7808 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
7809 return;
7810 }
7811
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007812 /*
7813 * Two ways to ensure that addba request with a
7814 * non zero TID could be sent out. EV 117296
7815 */
7816 snprintf(buf, sizeof(buf),
7817 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
7818 tid);
7819 if (system(buf) != 0) {
7820 sigma_dut_print(dut, DUT_MSG_ERROR,
7821 "Ping did not send out");
7822 }
7823
7824 snprintf(buf, sizeof(buf),
7825 "iwconfig %s | grep Access | awk '{print $6}' > %s",
7826 intf, VI_QOS_TMP_FILE);
7827 if (system(buf) != 0)
7828 return;
7829
7830 snprintf(buf, sizeof(buf),
7831 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
7832 intf, VI_QOS_TMP_FILE);
7833 if (system(buf) != 0)
7834 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
7835
7836 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
7837 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
7838 if (system(buf) != 0) {
7839 sigma_dut_print(dut, DUT_MSG_ERROR,
7840 "VI_QOS_TEMP_FILE generation error failed");
7841 }
7842 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
7843 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
7844 if (system(buf) != 0) {
7845 sigma_dut_print(dut, DUT_MSG_ERROR,
7846 "VI_QOS_FILE generation failed");
7847 }
7848
7849 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
7850 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
7851 if (system(buf) != 0) {
7852 sigma_dut_print(dut, DUT_MSG_ERROR,
7853 "VI_QOS_FILE generation failed");
7854 }
7855
7856 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
7857 if (system(buf) != 0) {
7858 }
7859}
7860
7861
7862static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
7863 struct sigma_cmd *cmd)
7864{
7865 const char *intf = get_param(cmd, "Interface");
7866 const char *val;
7867 int tid = 0;
7868 char buf[100];
7869
7870 val = get_param(cmd, "TID");
7871 if (val) {
7872 tid = atoi(val);
7873 if (tid)
7874 ath_sta_inject_frame(dut, intf, tid);
7875 }
7876
7877 /* Command sequence for ADDBA request on Peregrine based devices */
7878 snprintf(buf, sizeof(buf), "iwpriv %s setaddbaoper 1", intf);
7879 if (system(buf) != 0) {
7880 sigma_dut_print(dut, DUT_MSG_ERROR,
7881 "iwpriv setaddbaoper failed");
7882 }
7883
7884 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
7885 if (system(buf) != 0) {
7886 sigma_dut_print(dut, DUT_MSG_ERROR,
7887 "wifitool senddelba failed");
7888 }
7889
7890 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
7891 if (system(buf) != 0) {
7892 sigma_dut_print(dut, DUT_MSG_ERROR,
7893 "wifitool sendaddba failed");
7894 }
7895
7896 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
7897
7898 return 1;
7899}
7900
7901
Lior David9981b512017-01-20 13:16:40 +02007902#ifdef __linux__
7903
7904static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
7905 int agg_size)
7906{
7907 char dir[128], buf[128];
7908 FILE *f;
7909 regex_t re;
7910 regmatch_t m[2];
7911 int rc, ret = -1, vring_id, found;
7912
7913 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
7914 sigma_dut_print(dut, DUT_MSG_ERROR,
7915 "failed to get wil6210 debugfs dir");
7916 return -1;
7917 }
7918
7919 snprintf(buf, sizeof(buf), "%s/vrings", dir);
7920 f = fopen(buf, "r");
7921 if (!f) {
7922 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02007923 /* newer wil6210 driver renamed file to "rings" */
7924 snprintf(buf, sizeof(buf), "%s/rings", dir);
7925 f = fopen(buf, "r");
7926 if (!f) {
7927 sigma_dut_print(dut, DUT_MSG_ERROR,
7928 "failed to open: %s", buf);
7929 return -1;
7930 }
Lior David9981b512017-01-20 13:16:40 +02007931 }
7932
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02007933 /* can be either VRING tx... or RING... */
7934 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02007935 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
7936 goto out;
7937 }
7938
7939 /* find TX VRING for the mac address */
7940 found = 0;
7941 while (fgets(buf, sizeof(buf), f)) {
7942 if (strcasestr(buf, dest_mac)) {
7943 found = 1;
7944 break;
7945 }
7946 }
7947
7948 if (!found) {
7949 sigma_dut_print(dut, DUT_MSG_ERROR,
7950 "no TX VRING for %s", dest_mac);
7951 goto out;
7952 }
7953
7954 /* extract VRING ID, "VRING tx_<id> = {" */
7955 if (!fgets(buf, sizeof(buf), f)) {
7956 sigma_dut_print(dut, DUT_MSG_ERROR,
7957 "no VRING start line for %s", dest_mac);
7958 goto out;
7959 }
7960
7961 rc = regexec(&re, buf, 2, m, 0);
7962 regfree(&re);
7963 if (rc || m[1].rm_so < 0) {
7964 sigma_dut_print(dut, DUT_MSG_ERROR,
7965 "no VRING TX ID for %s", dest_mac);
7966 goto out;
7967 }
7968 buf[m[1].rm_eo] = 0;
7969 vring_id = atoi(&buf[m[1].rm_so]);
7970
7971 /* send the addba command */
7972 fclose(f);
7973 snprintf(buf, sizeof(buf), "%s/back", dir);
7974 f = fopen(buf, "w");
7975 if (!f) {
7976 sigma_dut_print(dut, DUT_MSG_ERROR,
7977 "failed to open: %s", buf);
7978 return -1;
7979 }
7980
7981 fprintf(f, "add %d %d\n", vring_id, agg_size);
7982
7983 ret = 0;
7984
7985out:
7986 fclose(f);
7987
7988 return ret;
7989}
7990
7991
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02007992int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7993 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007994{
7995 const char *val;
7996 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007997
7998 val = get_param(cmd, "TID");
7999 if (val) {
8000 tid = atoi(val);
8001 if (tid != 0) {
8002 sigma_dut_print(dut, DUT_MSG_ERROR,
8003 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
8004 tid);
8005 }
8006 }
8007
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008008 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008009 if (!val) {
8010 sigma_dut_print(dut, DUT_MSG_ERROR,
8011 "Currently not supporting addba for 60G without Dest_mac");
8012 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
8013 }
8014
Lior David9981b512017-01-20 13:16:40 +02008015 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008016 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008017
8018 return 1;
8019}
8020
Lior David9981b512017-01-20 13:16:40 +02008021#endif /* __linux__ */
8022
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008023
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008024static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8025 struct sigma_cmd *cmd)
8026{
8027#ifdef NL80211_SUPPORT
8028 const char *intf = get_param(cmd, "Interface");
8029 const char *val;
8030 int tid = -1;
8031 int bufsize = 64;
8032 struct nl_msg *msg;
8033 int ret = 0;
8034 struct nlattr *params;
8035 int ifindex;
8036
8037 val = get_param(cmd, "TID");
8038 if (val)
8039 tid = atoi(val);
8040
8041 if (tid == -1) {
8042 send_resp(dut, conn, SIGMA_ERROR,
8043 "ErrorCode,sta_send_addba tid invalid");
8044 return 0;
8045 }
8046
8047 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
8048
8049 ifindex = if_nametoindex(intf);
8050 if (ifindex == 0) {
8051 sigma_dut_print(dut, DUT_MSG_ERROR,
8052 "%s: Index for interface %s failed",
8053 __func__, intf);
8054 send_resp(dut, conn, SIGMA_ERROR,
8055 "ErrorCode,sta_send_addba interface invalid");
8056 return 0;
8057 }
8058
8059 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8060 NL80211_CMD_VENDOR)) ||
8061 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8062 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8063 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8064 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8065 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8066 nla_put_u8(msg,
8067 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
8068 QCA_WLAN_ADD_BA) ||
8069 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
8070 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07008071 nla_put_u16(msg,
8072 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
8073 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008074 sigma_dut_print(dut, DUT_MSG_ERROR,
8075 "%s: err in adding vendor_cmd and vendor_data",
8076 __func__);
8077 nlmsg_free(msg);
8078 send_resp(dut, conn, SIGMA_ERROR,
8079 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
8080 return 0;
8081 }
8082 nla_nest_end(msg, params);
8083
8084 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8085 if (ret) {
8086 sigma_dut_print(dut, DUT_MSG_ERROR,
8087 "%s: err in send_and_recv_msgs, ret=%d",
8088 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05308089 if (ret == -EOPNOTSUPP)
8090 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008091 send_resp(dut, conn, SIGMA_ERROR,
8092 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
8093 return 0;
8094 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008095#else /* NL80211_SUPPORT */
8096 sigma_dut_print(dut, DUT_MSG_ERROR,
8097 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008098#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05308099
8100 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008101}
8102
8103
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008104static int cmd_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
8105 struct sigma_cmd *cmd)
8106{
8107 switch (get_driver_type()) {
8108 case DRIVER_ATHEROS:
8109 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08008110 case DRIVER_WCN:
8111 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02008112#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008113 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02008114 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02008115#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008116 default:
8117 /*
8118 * There is no driver specific implementation for other drivers.
8119 * Ignore the command and report COMPLETE since the following
8120 * throughput test operation will end up sending ADDBA anyway.
8121 */
8122 return 1;
8123 }
8124}
8125
8126
8127int inject_eth_frame(int s, const void *data, size_t len,
8128 unsigned short ethtype, char *dst, char *src)
8129{
8130 struct iovec iov[4] = {
8131 {
8132 .iov_base = dst,
8133 .iov_len = ETH_ALEN,
8134 },
8135 {
8136 .iov_base = src,
8137 .iov_len = ETH_ALEN,
8138 },
8139 {
8140 .iov_base = &ethtype,
8141 .iov_len = sizeof(unsigned short),
8142 },
8143 {
8144 .iov_base = (void *) data,
8145 .iov_len = len,
8146 }
8147 };
8148 struct msghdr msg = {
8149 .msg_name = NULL,
8150 .msg_namelen = 0,
8151 .msg_iov = iov,
8152 .msg_iovlen = 4,
8153 .msg_control = NULL,
8154 .msg_controllen = 0,
8155 .msg_flags = 0,
8156 };
8157
8158 return sendmsg(s, &msg, 0);
8159}
8160
8161#if defined(__linux__) || defined(__QNXNTO__)
8162
8163int inject_frame(int s, const void *data, size_t len, int encrypt)
8164{
8165#define IEEE80211_RADIOTAP_F_WEP 0x04
8166#define IEEE80211_RADIOTAP_F_FRAG 0x08
8167 unsigned char rtap_hdr[] = {
8168 0x00, 0x00, /* radiotap version */
8169 0x0e, 0x00, /* radiotap length */
8170 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
8171 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
8172 0x00, /* padding */
8173 0x00, 0x00, /* RX and TX flags to indicate that */
8174 0x00, 0x00, /* this is the injected frame directly */
8175 };
8176 struct iovec iov[2] = {
8177 {
8178 .iov_base = &rtap_hdr,
8179 .iov_len = sizeof(rtap_hdr),
8180 },
8181 {
8182 .iov_base = (void *) data,
8183 .iov_len = len,
8184 }
8185 };
8186 struct msghdr msg = {
8187 .msg_name = NULL,
8188 .msg_namelen = 0,
8189 .msg_iov = iov,
8190 .msg_iovlen = 2,
8191 .msg_control = NULL,
8192 .msg_controllen = 0,
8193 .msg_flags = 0,
8194 };
8195
8196 if (encrypt)
8197 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
8198
8199 return sendmsg(s, &msg, 0);
8200}
8201
8202
8203int open_monitor(const char *ifname)
8204{
8205#ifdef __QNXNTO__
8206 struct sockaddr_dl ll;
8207 int s;
8208
8209 memset(&ll, 0, sizeof(ll));
8210 ll.sdl_family = AF_LINK;
8211 ll.sdl_index = if_nametoindex(ifname);
8212 if (ll.sdl_index == 0) {
8213 perror("if_nametoindex");
8214 return -1;
8215 }
8216 s = socket(PF_INET, SOCK_RAW, 0);
8217#else /* __QNXNTO__ */
8218 struct sockaddr_ll ll;
8219 int s;
8220
8221 memset(&ll, 0, sizeof(ll));
8222 ll.sll_family = AF_PACKET;
8223 ll.sll_ifindex = if_nametoindex(ifname);
8224 if (ll.sll_ifindex == 0) {
8225 perror("if_nametoindex");
8226 return -1;
8227 }
8228 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
8229#endif /* __QNXNTO__ */
8230 if (s < 0) {
8231 perror("socket[PF_PACKET,SOCK_RAW]");
8232 return -1;
8233 }
8234
8235 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
8236 perror("monitor socket bind");
8237 close(s);
8238 return -1;
8239 }
8240
8241 return s;
8242}
8243
8244
8245static int hex2num(char c)
8246{
8247 if (c >= '0' && c <= '9')
8248 return c - '0';
8249 if (c >= 'a' && c <= 'f')
8250 return c - 'a' + 10;
8251 if (c >= 'A' && c <= 'F')
8252 return c - 'A' + 10;
8253 return -1;
8254}
8255
8256
8257int hwaddr_aton(const char *txt, unsigned char *addr)
8258{
8259 int i;
8260
8261 for (i = 0; i < 6; i++) {
8262 int a, b;
8263
8264 a = hex2num(*txt++);
8265 if (a < 0)
8266 return -1;
8267 b = hex2num(*txt++);
8268 if (b < 0)
8269 return -1;
8270 *addr++ = (a << 4) | b;
8271 if (i < 5 && *txt++ != ':')
8272 return -1;
8273 }
8274
8275 return 0;
8276}
8277
8278#endif /* defined(__linux__) || defined(__QNXNTO__) */
8279
8280enum send_frame_type {
8281 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
8282};
8283enum send_frame_protection {
8284 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
8285};
8286
8287
8288static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
8289 enum send_frame_type frame,
8290 enum send_frame_protection protected,
8291 const char *dest)
8292{
8293#ifdef __linux__
8294 unsigned char buf[1000], *pos;
8295 int s, res;
8296 char bssid[20], addr[20];
8297 char result[32], ssid[100];
8298 size_t ssid_len;
8299
8300 if (get_wpa_status(get_station_ifname(), "wpa_state", result,
8301 sizeof(result)) < 0 ||
8302 strncmp(result, "COMPLETED", 9) != 0) {
8303 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
8304 return 0;
8305 }
8306
8307 if (get_wpa_status(get_station_ifname(), "bssid", bssid, sizeof(bssid))
8308 < 0) {
8309 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8310 "current BSSID");
8311 return 0;
8312 }
8313
8314 if (get_wpa_status(get_station_ifname(), "address", addr, sizeof(addr))
8315 < 0) {
8316 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8317 "own MAC address");
8318 return 0;
8319 }
8320
8321 if (get_wpa_status(get_station_ifname(), "ssid", ssid, sizeof(ssid))
8322 < 0) {
8323 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
8324 "current SSID");
8325 return 0;
8326 }
8327 ssid_len = strlen(ssid);
8328
8329 pos = buf;
8330
8331 /* Frame Control */
8332 switch (frame) {
8333 case DISASSOC:
8334 *pos++ = 0xa0;
8335 break;
8336 case DEAUTH:
8337 *pos++ = 0xc0;
8338 break;
8339 case SAQUERY:
8340 *pos++ = 0xd0;
8341 break;
8342 case AUTH:
8343 *pos++ = 0xb0;
8344 break;
8345 case ASSOCREQ:
8346 *pos++ = 0x00;
8347 break;
8348 case REASSOCREQ:
8349 *pos++ = 0x20;
8350 break;
8351 case DLS_REQ:
8352 *pos++ = 0xd0;
8353 break;
8354 }
8355
8356 if (protected == INCORRECT_KEY)
8357 *pos++ = 0x40; /* Set Protected field to 1 */
8358 else
8359 *pos++ = 0x00;
8360
8361 /* Duration */
8362 *pos++ = 0x00;
8363 *pos++ = 0x00;
8364
8365 /* addr1 = DA (current AP) */
8366 hwaddr_aton(bssid, pos);
8367 pos += 6;
8368 /* addr2 = SA (own address) */
8369 hwaddr_aton(addr, pos);
8370 pos += 6;
8371 /* addr3 = BSSID (current AP) */
8372 hwaddr_aton(bssid, pos);
8373 pos += 6;
8374
8375 /* Seq# (to be filled by driver/mac80211) */
8376 *pos++ = 0x00;
8377 *pos++ = 0x00;
8378
8379 if (protected == INCORRECT_KEY) {
8380 /* CCMP parameters */
8381 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
8382 pos += 8;
8383 }
8384
8385 if (protected == INCORRECT_KEY) {
8386 switch (frame) {
8387 case DEAUTH:
8388 /* Reason code (encrypted) */
8389 memcpy(pos, "\xa7\x39", 2);
8390 pos += 2;
8391 break;
8392 case DISASSOC:
8393 /* Reason code (encrypted) */
8394 memcpy(pos, "\xa7\x39", 2);
8395 pos += 2;
8396 break;
8397 case SAQUERY:
8398 /* Category|Action|TransID (encrypted) */
8399 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
8400 pos += 4;
8401 break;
8402 default:
8403 return -1;
8404 }
8405
8406 /* CCMP MIC */
8407 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
8408 pos += 8;
8409 } else {
8410 switch (frame) {
8411 case DEAUTH:
8412 /* reason code = 8 */
8413 *pos++ = 0x08;
8414 *pos++ = 0x00;
8415 break;
8416 case DISASSOC:
8417 /* reason code = 8 */
8418 *pos++ = 0x08;
8419 *pos++ = 0x00;
8420 break;
8421 case SAQUERY:
8422 /* Category - SA Query */
8423 *pos++ = 0x08;
8424 /* SA query Action - Request */
8425 *pos++ = 0x00;
8426 /* Transaction ID */
8427 *pos++ = 0x12;
8428 *pos++ = 0x34;
8429 break;
8430 case AUTH:
8431 /* Auth Alg (Open) */
8432 *pos++ = 0x00;
8433 *pos++ = 0x00;
8434 /* Seq# */
8435 *pos++ = 0x01;
8436 *pos++ = 0x00;
8437 /* Status code */
8438 *pos++ = 0x00;
8439 *pos++ = 0x00;
8440 break;
8441 case ASSOCREQ:
8442 /* Capability Information */
8443 *pos++ = 0x31;
8444 *pos++ = 0x04;
8445 /* Listen Interval */
8446 *pos++ = 0x0a;
8447 *pos++ = 0x00;
8448 /* SSID */
8449 *pos++ = 0x00;
8450 *pos++ = ssid_len;
8451 memcpy(pos, ssid, ssid_len);
8452 pos += ssid_len;
8453 /* Supported Rates */
8454 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
8455 10);
8456 pos += 10;
8457 /* Extended Supported Rates */
8458 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
8459 pos += 6;
8460 /* RSN */
8461 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
8462 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
8463 "\x00\x00\x00\x00\x0f\xac\x06", 28);
8464 pos += 28;
8465 break;
8466 case REASSOCREQ:
8467 /* Capability Information */
8468 *pos++ = 0x31;
8469 *pos++ = 0x04;
8470 /* Listen Interval */
8471 *pos++ = 0x0a;
8472 *pos++ = 0x00;
8473 /* Current AP */
8474 hwaddr_aton(bssid, pos);
8475 pos += 6;
8476 /* SSID */
8477 *pos++ = 0x00;
8478 *pos++ = ssid_len;
8479 memcpy(pos, ssid, ssid_len);
8480 pos += ssid_len;
8481 /* Supported Rates */
8482 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
8483 10);
8484 pos += 10;
8485 /* Extended Supported Rates */
8486 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
8487 pos += 6;
8488 /* RSN */
8489 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
8490 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
8491 "\x00\x00\x00\x00\x0f\xac\x06", 28);
8492 pos += 28;
8493 break;
8494 case DLS_REQ:
8495 /* Category - DLS */
8496 *pos++ = 0x02;
8497 /* DLS Action - Request */
8498 *pos++ = 0x00;
8499 /* Destination MACAddress */
8500 if (dest)
8501 hwaddr_aton(dest, pos);
8502 else
8503 memset(pos, 0, 6);
8504 pos += 6;
8505 /* Source MACAddress */
8506 hwaddr_aton(addr, pos);
8507 pos += 6;
8508 /* Capability Information */
8509 *pos++ = 0x10; /* Privacy */
8510 *pos++ = 0x06; /* QoS */
8511 /* DLS Timeout Value */
8512 *pos++ = 0x00;
8513 *pos++ = 0x01;
8514 /* Supported rates */
8515 *pos++ = 0x01;
8516 *pos++ = 0x08;
8517 *pos++ = 0x0c; /* 6 Mbps */
8518 *pos++ = 0x12; /* 9 Mbps */
8519 *pos++ = 0x18; /* 12 Mbps */
8520 *pos++ = 0x24; /* 18 Mbps */
8521 *pos++ = 0x30; /* 24 Mbps */
8522 *pos++ = 0x48; /* 36 Mbps */
8523 *pos++ = 0x60; /* 48 Mbps */
8524 *pos++ = 0x6c; /* 54 Mbps */
8525 /* TODO: Extended Supported Rates */
8526 /* TODO: HT Capabilities */
8527 break;
8528 }
8529 }
8530
8531 s = open_monitor("sigmadut");
8532 if (s < 0) {
8533 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
8534 "monitor socket");
8535 return 0;
8536 }
8537
8538 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
8539 if (res < 0) {
8540 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
8541 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308542 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008543 return 0;
8544 }
8545 if (res < pos - buf) {
8546 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
8547 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308548 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008549 return 0;
8550 }
8551
8552 close(s);
8553
8554 return 1;
8555#else /* __linux__ */
8556 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
8557 "yet supported");
8558 return 0;
8559#endif /* __linux__ */
8560}
8561
8562
8563static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
8564 struct sigma_conn *conn,
8565 struct sigma_cmd *cmd)
8566{
8567 const char *intf = get_param(cmd, "Interface");
8568 const char *sta, *val;
8569 unsigned char addr[ETH_ALEN];
8570 char buf[100];
8571
8572 sta = get_param(cmd, "peer");
8573 if (sta == NULL)
8574 sta = get_param(cmd, "station");
8575 if (sta == NULL) {
8576 send_resp(dut, conn, SIGMA_ERROR,
8577 "ErrorCode,Missing peer address");
8578 return 0;
8579 }
8580 if (hwaddr_aton(sta, addr) < 0) {
8581 send_resp(dut, conn, SIGMA_ERROR,
8582 "ErrorCode,Invalid peer address");
8583 return 0;
8584 }
8585
8586 val = get_param(cmd, "type");
8587 if (val == NULL)
8588 return -1;
8589
8590 if (strcasecmp(val, "DISCOVERY") == 0) {
8591 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
8592 if (wpa_command(intf, buf) < 0) {
8593 send_resp(dut, conn, SIGMA_ERROR,
8594 "ErrorCode,Failed to send TDLS discovery");
8595 return 0;
8596 }
8597 return 1;
8598 }
8599
8600 if (strcasecmp(val, "SETUP") == 0) {
8601 int status = 0, timeout = 0;
8602
8603 val = get_param(cmd, "Status");
8604 if (val)
8605 status = atoi(val);
8606
8607 val = get_param(cmd, "Timeout");
8608 if (val)
8609 timeout = atoi(val);
8610
8611 if (status != 0 && status != 37) {
8612 send_resp(dut, conn, SIGMA_ERROR,
8613 "ErrorCode,Unsupported status value");
8614 return 0;
8615 }
8616
8617 if (timeout != 0 && timeout != 301) {
8618 send_resp(dut, conn, SIGMA_ERROR,
8619 "ErrorCode,Unsupported timeout value");
8620 return 0;
8621 }
8622
8623 if (status && timeout) {
8624 send_resp(dut, conn, SIGMA_ERROR,
8625 "ErrorCode,Unsupported timeout+status "
8626 "combination");
8627 return 0;
8628 }
8629
8630 if (status == 37 &&
8631 wpa_command(intf, "SET tdls_testing 0x200")) {
8632 send_resp(dut, conn, SIGMA_ERROR,
8633 "ErrorCode,Failed to enable "
8634 "decline setup response test mode");
8635 return 0;
8636 }
8637
8638 if (timeout == 301) {
8639 int res;
8640 if (dut->no_tpk_expiration)
8641 res = wpa_command(intf,
8642 "SET tdls_testing 0x108");
8643 else
8644 res = wpa_command(intf,
8645 "SET tdls_testing 0x8");
8646 if (res) {
8647 send_resp(dut, conn, SIGMA_ERROR,
8648 "ErrorCode,Failed to set short TPK "
8649 "lifetime");
8650 return 0;
8651 }
8652 }
8653
8654 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
8655 if (wpa_command(intf, buf) < 0) {
8656 send_resp(dut, conn, SIGMA_ERROR,
8657 "ErrorCode,Failed to send TDLS setup");
8658 return 0;
8659 }
8660 return 1;
8661 }
8662
8663 if (strcasecmp(val, "TEARDOWN") == 0) {
8664 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
8665 if (wpa_command(intf, buf) < 0) {
8666 send_resp(dut, conn, SIGMA_ERROR,
8667 "ErrorCode,Failed to send TDLS teardown");
8668 return 0;
8669 }
8670 return 1;
8671 }
8672
8673 send_resp(dut, conn, SIGMA_ERROR,
8674 "ErrorCode,Unsupported TDLS frame");
8675 return 0;
8676}
8677
8678
8679static int sta_ap_known(const char *ifname, const char *bssid)
8680{
8681 char buf[4096];
8682
Jouni Malinendd32f192018-09-15 02:55:19 +03008683 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008684 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
8685 return 0;
8686 if (strncmp(buf, "id=", 3) != 0)
8687 return 0;
8688 return 1;
8689}
8690
8691
8692static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
8693 const char *bssid)
8694{
8695 int res;
8696 struct wpa_ctrl *ctrl;
8697 char buf[256];
8698
8699 if (sta_ap_known(ifname, bssid))
8700 return 0;
8701 sigma_dut_print(dut, DUT_MSG_DEBUG,
8702 "AP not in BSS table - start scan");
8703
8704 ctrl = open_wpa_mon(ifname);
8705 if (ctrl == NULL) {
8706 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
8707 "wpa_supplicant monitor connection");
8708 return -1;
8709 }
8710
8711 if (wpa_command(ifname, "SCAN") < 0) {
8712 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
8713 wpa_ctrl_detach(ctrl);
8714 wpa_ctrl_close(ctrl);
8715 return -1;
8716 }
8717
8718 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
8719 buf, sizeof(buf));
8720
8721 wpa_ctrl_detach(ctrl);
8722 wpa_ctrl_close(ctrl);
8723
8724 if (res < 0) {
8725 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
8726 return -1;
8727 }
8728
8729 if (sta_ap_known(ifname, bssid))
8730 return 0;
8731 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
8732 return -1;
8733}
8734
8735
8736static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
8737 struct sigma_conn *conn,
8738 struct sigma_cmd *cmd,
8739 const char *intf)
8740{
8741 char buf[200];
8742
8743 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
8744 if (system(buf) != 0) {
8745 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
8746 "ndsend");
8747 return 0;
8748 }
8749
8750 return 1;
8751}
8752
8753
8754static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
8755 struct sigma_conn *conn,
8756 struct sigma_cmd *cmd,
8757 const char *intf)
8758{
8759 char buf[200];
8760 const char *ip = get_param(cmd, "SenderIP");
8761
Peng Xu26b356d2017-10-04 17:58:16 -07008762 if (!ip)
8763 return 0;
8764
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008765 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
8766 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8767 if (system(buf) == 0) {
8768 sigma_dut_print(dut, DUT_MSG_INFO,
8769 "Neighbor Solicitation got a response "
8770 "for %s@%s", ip, intf);
8771 }
8772
8773 return 1;
8774}
8775
8776
8777static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
8778 struct sigma_conn *conn,
8779 struct sigma_cmd *cmd,
8780 const char *ifname)
8781{
8782 char buf[200];
8783 const char *ip = get_param(cmd, "SenderIP");
8784
8785 if (ip == NULL) {
8786 send_resp(dut, conn, SIGMA_ERROR,
8787 "ErrorCode,Missing SenderIP parameter");
8788 return 0;
8789 }
8790 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
8791 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8792 if (system(buf) != 0) {
8793 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
8794 "for %s@%s", ip, ifname);
8795 }
8796
8797 return 1;
8798}
8799
8800
8801static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
8802 struct sigma_conn *conn,
8803 struct sigma_cmd *cmd,
8804 const char *ifname)
8805{
8806 char buf[200];
8807 char ip[16];
8808 int s;
Peng Xub3756882017-10-04 14:39:09 -07008809 struct ifreq ifr;
8810 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008811
8812 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -07008813 if (s < 0) {
8814 perror("socket");
8815 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008816 }
8817
Peng Xub3756882017-10-04 14:39:09 -07008818 memset(&ifr, 0, sizeof(ifr));
8819 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
8820 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
8821 sigma_dut_print(dut, DUT_MSG_INFO,
8822 "Failed to get %s IP address: %s",
8823 ifname, strerror(errno));
8824 close(s);
8825 return -1;
8826 }
8827 close(s);
8828
8829 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
8830 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
8831
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008832 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
8833 ip);
8834 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
8835 if (system(buf) != 0) {
8836 }
8837
8838 return 1;
8839}
8840
8841
8842static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
8843 struct sigma_conn *conn,
8844 struct sigma_cmd *cmd,
8845 const char *ifname)
8846{
8847 char buf[200], addr[20];
8848 char dst[ETH_ALEN], src[ETH_ALEN];
8849 short ethtype = htons(ETH_P_ARP);
8850 char *pos;
8851 int s, res;
8852 const char *val;
8853 struct sockaddr_in taddr;
8854
8855 val = get_param(cmd, "dest");
8856 if (val)
8857 hwaddr_aton(val, (unsigned char *) dst);
8858
8859 val = get_param(cmd, "DestIP");
8860 if (val)
8861 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -07008862 else
8863 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008864
8865 if (get_wpa_status(get_station_ifname(), "address", addr,
8866 sizeof(addr)) < 0)
8867 return -2;
8868 hwaddr_aton(addr, (unsigned char *) src);
8869
8870 pos = buf;
8871 *pos++ = 0x00;
8872 *pos++ = 0x01;
8873 *pos++ = 0x08;
8874 *pos++ = 0x00;
8875 *pos++ = 0x06;
8876 *pos++ = 0x04;
8877 *pos++ = 0x00;
8878 *pos++ = 0x02;
8879 memcpy(pos, src, ETH_ALEN);
8880 pos += ETH_ALEN;
8881 memcpy(pos, &taddr.sin_addr, 4);
8882 pos += 4;
8883 memcpy(pos, dst, ETH_ALEN);
8884 pos += ETH_ALEN;
8885 memcpy(pos, &taddr.sin_addr, 4);
8886 pos += 4;
8887
8888 s = open_monitor(get_station_ifname());
8889 if (s < 0) {
8890 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
8891 "monitor socket");
8892 return 0;
8893 }
8894
8895 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
8896 if (res < 0) {
8897 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
8898 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05308899 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008900 return 0;
8901 }
8902
8903 close(s);
8904
8905 return 1;
8906}
8907
8908
8909static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
8910 struct sigma_conn *conn,
8911 struct sigma_cmd *cmd,
8912 const char *intf, const char *dest)
8913{
8914 char buf[100];
8915
8916 if (if_nametoindex("sigmadut") == 0) {
8917 snprintf(buf, sizeof(buf),
8918 "iw dev %s interface add sigmadut type monitor",
8919 get_station_ifname());
8920 if (system(buf) != 0 ||
8921 if_nametoindex("sigmadut") == 0) {
8922 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
8923 "monitor interface with '%s'", buf);
8924 return -2;
8925 }
8926 }
8927
8928 if (system("ifconfig sigmadut up") != 0) {
8929 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
8930 "monitor interface up");
8931 return -2;
8932 }
8933
8934 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
8935}
8936
8937
8938static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
8939 struct sigma_conn *conn,
8940 struct sigma_cmd *cmd)
8941{
8942 const char *intf = get_param(cmd, "Interface");
8943 const char *dest = get_param(cmd, "Dest");
8944 const char *type = get_param(cmd, "FrameName");
8945 const char *val;
8946 char buf[200], *pos, *end;
8947 int count, count2;
8948
8949 if (type == NULL)
8950 type = get_param(cmd, "Type");
8951
8952 if (intf == NULL || dest == NULL || type == NULL)
8953 return -1;
8954
8955 if (strcasecmp(type, "NeighAdv") == 0)
8956 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
8957
8958 if (strcasecmp(type, "NeighSolicitReq") == 0)
8959 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
8960
8961 if (strcasecmp(type, "ARPProbe") == 0)
8962 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
8963
8964 if (strcasecmp(type, "ARPAnnounce") == 0)
8965 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
8966
8967 if (strcasecmp(type, "ARPReply") == 0)
8968 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
8969
8970 if (strcasecmp(type, "DLS-request") == 0 ||
8971 strcasecmp(type, "DLSrequest") == 0)
8972 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
8973 dest);
8974
8975 if (strcasecmp(type, "ANQPQuery") != 0 &&
8976 strcasecmp(type, "Query") != 0) {
8977 send_resp(dut, conn, SIGMA_ERROR,
8978 "ErrorCode,Unsupported HS 2.0 send frame type");
8979 return 0;
8980 }
8981
8982 if (sta_scan_ap(dut, intf, dest) < 0) {
8983 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
8984 "the requested AP");
8985 return 0;
8986 }
8987
8988 pos = buf;
8989 end = buf + sizeof(buf);
8990 count = 0;
8991 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
8992
8993 val = get_param(cmd, "ANQP_CAP_LIST");
8994 if (val && atoi(val)) {
8995 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
8996 count++;
8997 }
8998
8999 val = get_param(cmd, "VENUE_NAME");
9000 if (val && atoi(val)) {
9001 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
9002 count++;
9003 }
9004
9005 val = get_param(cmd, "NETWORK_AUTH_TYPE");
9006 if (val && atoi(val)) {
9007 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
9008 count++;
9009 }
9010
9011 val = get_param(cmd, "ROAMING_CONS");
9012 if (val && atoi(val)) {
9013 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
9014 count++;
9015 }
9016
9017 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
9018 if (val && atoi(val)) {
9019 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
9020 count++;
9021 }
9022
9023 val = get_param(cmd, "NAI_REALM_LIST");
9024 if (val && atoi(val)) {
9025 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
9026 count++;
9027 }
9028
9029 val = get_param(cmd, "3GPP_INFO");
9030 if (val && atoi(val)) {
9031 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
9032 count++;
9033 }
9034
9035 val = get_param(cmd, "DOMAIN_LIST");
9036 if (val && atoi(val)) {
9037 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
9038 count++;
9039 }
9040
Jouni Malinen34cf9532018-04-29 19:26:33 +03009041 val = get_param(cmd, "Venue_URL");
9042 if (val && atoi(val)) {
9043 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
9044 count++;
9045 }
9046
Jouni Malinend3bca5d2018-04-29 17:25:23 +03009047 val = get_param(cmd, "Advice_Of_Charge");
9048 if (val && atoi(val)) {
9049 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
9050 count++;
9051 }
9052
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009053 if (count && wpa_command(intf, buf)) {
9054 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
9055 return 0;
9056 }
9057
9058 pos = buf;
9059 end = buf + sizeof(buf);
9060 count2 = 0;
9061 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
9062
9063 val = get_param(cmd, "HS_CAP_LIST");
9064 if (val && atoi(val)) {
9065 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
9066 count2++;
9067 }
9068
9069 val = get_param(cmd, "OPER_NAME");
9070 if (val && atoi(val)) {
9071 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
9072 count2++;
9073 }
9074
9075 val = get_param(cmd, "WAN_METRICS");
9076 if (!val)
9077 val = get_param(cmd, "WAN_MAT");
9078 if (!val)
9079 val = get_param(cmd, "WAN_MET");
9080 if (val && atoi(val)) {
9081 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
9082 count2++;
9083 }
9084
9085 val = get_param(cmd, "CONNECTION_CAPABILITY");
9086 if (val && atoi(val)) {
9087 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
9088 count2++;
9089 }
9090
9091 val = get_param(cmd, "OP_CLASS");
9092 if (val && atoi(val)) {
9093 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
9094 count2++;
9095 }
9096
9097 val = get_param(cmd, "OSU_PROVIDER_LIST");
9098 if (val && atoi(val)) {
9099 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
9100 count2++;
9101 }
9102
Jouni Malinenf67afec2018-04-29 19:24:58 +03009103 val = get_param(cmd, "OPER_ICON_METADATA");
9104 if (!val)
9105 val = get_param(cmd, "OPERATOR_ICON_METADATA");
9106 if (val && atoi(val)) {
9107 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
9108 count2++;
9109 }
9110
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009111 if (count && count2) {
9112 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
9113 "second query");
9114 sleep(1);
9115 }
9116
9117 if (count2 && wpa_command(intf, buf)) {
9118 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
9119 "failed");
9120 return 0;
9121 }
9122
9123 val = get_param(cmd, "NAI_HOME_REALM_LIST");
9124 if (val) {
9125 if (count || count2) {
9126 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9127 "sending out second query");
9128 sleep(1);
9129 }
9130
9131 if (strcmp(val, "1") == 0)
9132 val = "mail.example.com";
9133 snprintf(buf, end - pos,
9134 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
9135 dest, val);
9136 if (wpa_command(intf, buf)) {
9137 send_resp(dut, conn, SIGMA_ERROR,
9138 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
9139 "failed");
9140 return 0;
9141 }
9142 }
9143
9144 val = get_param(cmd, "ICON_REQUEST");
9145 if (val) {
9146 if (count || count2) {
9147 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
9148 "sending out second query");
9149 sleep(1);
9150 }
9151
9152 snprintf(buf, end - pos,
9153 "HS20_ICON_REQUEST %s %s", dest, val);
9154 if (wpa_command(intf, buf)) {
9155 send_resp(dut, conn, SIGMA_ERROR,
9156 "ErrorCode,HS20_ICON_REQUEST failed");
9157 return 0;
9158 }
9159 }
9160
9161 return 1;
9162}
9163
9164
9165static int ath_sta_send_frame_vht(struct sigma_dut *dut,
9166 struct sigma_conn *conn,
9167 struct sigma_cmd *cmd)
9168{
9169 const char *val;
9170 char *ifname;
9171 char buf[100];
9172 int chwidth, nss;
9173
9174 val = get_param(cmd, "framename");
9175 if (!val)
9176 return -1;
9177 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9178
9179 /* Command sequence to generate Op mode notification */
9180 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
9181 ifname = get_station_ifname();
9182
9183 /* Disable STBC */
9184 snprintf(buf, sizeof(buf),
9185 "iwpriv %s tx_stbc 0", ifname);
9186 if (system(buf) != 0) {
9187 sigma_dut_print(dut, DUT_MSG_ERROR,
9188 "iwpriv tx_stbc 0 failed!");
9189 }
9190
9191 /* Extract Channel width */
9192 val = get_param(cmd, "Channel_width");
9193 if (val) {
9194 switch (atoi(val)) {
9195 case 20:
9196 chwidth = 0;
9197 break;
9198 case 40:
9199 chwidth = 1;
9200 break;
9201 case 80:
9202 chwidth = 2;
9203 break;
9204 case 160:
9205 chwidth = 3;
9206 break;
9207 default:
9208 chwidth = 2;
9209 break;
9210 }
9211
9212 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
9213 ifname, chwidth);
9214 if (system(buf) != 0) {
9215 sigma_dut_print(dut, DUT_MSG_ERROR,
9216 "iwpriv chwidth failed!");
9217 }
9218 }
9219
9220 /* Extract NSS */
9221 val = get_param(cmd, "NSS");
9222 if (val) {
9223 switch (atoi(val)) {
9224 case 1:
9225 nss = 1;
9226 break;
9227 case 2:
9228 nss = 3;
9229 break;
9230 case 3:
9231 nss = 7;
9232 break;
9233 default:
9234 /* We do not support NSS > 3 */
9235 nss = 3;
9236 break;
9237 }
9238 snprintf(buf, sizeof(buf),
9239 "iwpriv %s rxchainmask %d", ifname, nss);
9240 if (system(buf) != 0) {
9241 sigma_dut_print(dut, DUT_MSG_ERROR,
9242 "iwpriv rxchainmask failed!");
9243 }
9244 }
9245
9246 /* Opmode notify */
9247 snprintf(buf, sizeof(buf), "iwpriv %s opmode_notify 1", ifname);
9248 if (system(buf) != 0) {
9249 sigma_dut_print(dut, DUT_MSG_ERROR,
9250 "iwpriv opmode_notify failed!");
9251 } else {
9252 sigma_dut_print(dut, DUT_MSG_INFO,
9253 "Sent out the notify frame!");
9254 }
9255 }
9256
9257 return 1;
9258}
9259
9260
9261static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
9262 struct sigma_conn *conn,
9263 struct sigma_cmd *cmd)
9264{
9265 switch (get_driver_type()) {
9266 case DRIVER_ATHEROS:
9267 return ath_sta_send_frame_vht(dut, conn, cmd);
9268 default:
9269 send_resp(dut, conn, SIGMA_ERROR,
9270 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
9271 return 0;
9272 }
9273}
9274
9275
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009276static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
9277 struct sigma_cmd *cmd)
9278{
9279 const char *val;
9280 const char *intf = get_param(cmd, "Interface");
9281
9282 val = get_param(cmd, "framename");
9283 if (!val)
9284 return -1;
9285 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
9286
9287 /* Command sequence to generate Op mode notification */
9288 if (val && strcasecmp(val, "action") == 0) {
9289 val = get_param(cmd, "PPDUTxType");
9290 if (val && strcasecmp(val, "TB") == 0) {
9291 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
9292 sigma_dut_print(dut, DUT_MSG_ERROR,
9293 "failed to send TB PPDU Tx cfg");
9294 send_resp(dut, conn, SIGMA_ERROR,
9295 "ErrorCode,set TB PPDU Tx cfg failed");
9296 return 0;
9297 }
9298 return 1;
9299 }
9300
9301 sigma_dut_print(dut, DUT_MSG_ERROR,
9302 "Action Tx type is not defined");
9303 }
9304
9305 return 1;
9306}
9307
9308
9309static int cmd_sta_send_frame_he(struct sigma_dut *dut,
9310 struct sigma_conn *conn,
9311 struct sigma_cmd *cmd)
9312{
9313 switch (get_driver_type()) {
9314 case DRIVER_WCN:
9315 return wcn_sta_send_frame_he(dut, conn, cmd);
9316 default:
9317 send_resp(dut, conn, SIGMA_ERROR,
9318 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
9319 return 0;
9320 }
9321}
9322
9323
Lior David0fe101e2017-03-09 16:09:50 +02009324#ifdef __linux__
9325int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9326 struct sigma_cmd *cmd)
9327{
9328 const char *frame_name = get_param(cmd, "framename");
9329 const char *mac = get_param(cmd, "dest_mac");
9330
9331 if (!frame_name || !mac) {
9332 sigma_dut_print(dut, DUT_MSG_ERROR,
9333 "framename and dest_mac must be provided");
9334 return -1;
9335 }
9336
9337 if (strcasecmp(frame_name, "brp") == 0) {
9338 const char *l_rx = get_param(cmd, "L-RX");
9339 int l_rx_i;
9340
9341 if (!l_rx) {
9342 sigma_dut_print(dut, DUT_MSG_ERROR,
9343 "L-RX must be provided");
9344 return -1;
9345 }
9346 l_rx_i = atoi(l_rx);
9347
9348 sigma_dut_print(dut, DUT_MSG_INFO,
9349 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
9350 mac, l_rx);
9351 if (l_rx_i != 16) {
9352 sigma_dut_print(dut, DUT_MSG_ERROR,
9353 "unsupported L-RX: %s", l_rx);
9354 return -1;
9355 }
9356
9357 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
9358 return -1;
9359 } else if (strcasecmp(frame_name, "ssw") == 0) {
9360 sigma_dut_print(dut, DUT_MSG_INFO,
9361 "dev_send_frame: SLS, dest_mac %s", mac);
9362 if (wil6210_send_sls(dut, mac))
9363 return -1;
9364 } else {
9365 sigma_dut_print(dut, DUT_MSG_ERROR,
9366 "unsupported frame type: %s", frame_name);
9367 return -1;
9368 }
9369
9370 return 1;
9371}
9372#endif /* __linux__ */
9373
9374
9375static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
9376 struct sigma_conn *conn,
9377 struct sigma_cmd *cmd)
9378{
9379 switch (get_driver_type()) {
9380#ifdef __linux__
9381 case DRIVER_WIL6210:
9382 return wil6210_send_frame_60g(dut, conn, cmd);
9383#endif /* __linux__ */
9384 default:
9385 send_resp(dut, conn, SIGMA_ERROR,
9386 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
9387 return 0;
9388 }
9389}
9390
9391
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309392static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
9393 const char *intf, struct sigma_cmd *cmd)
9394{
9395 const char *val, *addr;
9396 char buf[100];
9397
9398 addr = get_param(cmd, "DestMac");
9399 if (!addr) {
9400 send_resp(dut, conn, SIGMA_INVALID,
9401 "ErrorCode,AP MAC address is missing");
9402 return 0;
9403 }
9404
9405 val = get_param(cmd, "ANQPQuery_ID");
9406 if (!val) {
9407 send_resp(dut, conn, SIGMA_INVALID,
9408 "ErrorCode,Missing ANQPQuery_ID");
9409 return 0;
9410 }
9411
9412 if (strcasecmp(val, "NeighborReportReq") == 0) {
9413 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
9414 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
9415 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
9416 } else {
9417 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
9418 val);
9419 send_resp(dut, conn, SIGMA_INVALID,
9420 "ErrorCode,Invalid ANQPQuery_ID");
9421 return 0;
9422 }
9423
Ashwini Patild174f2c2017-04-13 16:49:46 +05309424 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
9425 * (Address3 = Wildcard BSSID when sent to not-associated AP;
9426 * if associated, AP BSSID).
9427 */
9428 if (wpa_command(intf, "SET gas_address3 1") < 0) {
9429 send_resp(dut, conn, SIGMA_ERROR,
9430 "ErrorCode,Failed to set gas_address3");
9431 return 0;
9432 }
9433
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309434 if (wpa_command(intf, buf) < 0) {
9435 send_resp(dut, conn, SIGMA_ERROR,
9436 "ErrorCode,Failed to send ANQP query");
9437 return 0;
9438 }
9439
9440 return 1;
9441}
9442
9443
9444static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
9445 struct sigma_conn *conn,
9446 const char *intf,
9447 struct sigma_cmd *cmd)
9448{
9449 const char *val = get_param(cmd, "FrameName");
9450
9451 if (val && strcasecmp(val, "ANQPQuery") == 0)
9452 return mbo_send_anqp_query(dut, conn, intf, cmd);
9453
9454 return 2;
9455}
9456
9457
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009458int cmd_sta_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9459 struct sigma_cmd *cmd)
9460{
9461 const char *intf = get_param(cmd, "Interface");
9462 const char *val;
9463 enum send_frame_type frame;
9464 enum send_frame_protection protected;
9465 char buf[100];
9466 unsigned char addr[ETH_ALEN];
9467 int res;
9468
9469 val = get_param(cmd, "program");
9470 if (val == NULL)
9471 val = get_param(cmd, "frame");
9472 if (val && strcasecmp(val, "TDLS") == 0)
9473 return cmd_sta_send_frame_tdls(dut, conn, cmd);
9474 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +03009475 strcasecmp(val, "HS2-R2") == 0 ||
9476 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009477 return cmd_sta_send_frame_hs2(dut, conn, cmd);
9478 if (val && strcasecmp(val, "VHT") == 0)
9479 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009480 if (val && strcasecmp(val, "HE") == 0)
9481 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009482 if (val && strcasecmp(val, "LOC") == 0)
9483 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +02009484 if (val && strcasecmp(val, "60GHz") == 0)
9485 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +05309486 if (val && strcasecmp(val, "MBO") == 0) {
9487 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
9488 if (res != 2)
9489 return res;
9490 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009491
9492 val = get_param(cmd, "TD_DISC");
9493 if (val) {
9494 if (hwaddr_aton(val, addr) < 0)
9495 return -1;
9496 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
9497 if (wpa_command(intf, buf) < 0) {
9498 send_resp(dut, conn, SIGMA_ERROR,
9499 "ErrorCode,Failed to send TDLS discovery");
9500 return 0;
9501 }
9502 return 1;
9503 }
9504
9505 val = get_param(cmd, "TD_Setup");
9506 if (val) {
9507 if (hwaddr_aton(val, addr) < 0)
9508 return -1;
9509 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
9510 if (wpa_command(intf, buf) < 0) {
9511 send_resp(dut, conn, SIGMA_ERROR,
9512 "ErrorCode,Failed to start TDLS setup");
9513 return 0;
9514 }
9515 return 1;
9516 }
9517
9518 val = get_param(cmd, "TD_TearDown");
9519 if (val) {
9520 if (hwaddr_aton(val, addr) < 0)
9521 return -1;
9522 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
9523 if (wpa_command(intf, buf) < 0) {
9524 send_resp(dut, conn, SIGMA_ERROR,
9525 "ErrorCode,Failed to tear down TDLS link");
9526 return 0;
9527 }
9528 return 1;
9529 }
9530
9531 val = get_param(cmd, "TD_ChannelSwitch");
9532 if (val) {
9533 /* TODO */
9534 send_resp(dut, conn, SIGMA_ERROR,
9535 "ErrorCode,TD_ChannelSwitch not yet supported");
9536 return 0;
9537 }
9538
9539 val = get_param(cmd, "TD_NF");
9540 if (val) {
9541 /* TODO */
9542 send_resp(dut, conn, SIGMA_ERROR,
9543 "ErrorCode,TD_NF not yet supported");
9544 return 0;
9545 }
9546
9547 val = get_param(cmd, "PMFFrameType");
9548 if (val == NULL)
9549 val = get_param(cmd, "FrameName");
9550 if (val == NULL)
9551 val = get_param(cmd, "Type");
9552 if (val == NULL)
9553 return -1;
9554 if (strcasecmp(val, "disassoc") == 0)
9555 frame = DISASSOC;
9556 else if (strcasecmp(val, "deauth") == 0)
9557 frame = DEAUTH;
9558 else if (strcasecmp(val, "saquery") == 0)
9559 frame = SAQUERY;
9560 else if (strcasecmp(val, "auth") == 0)
9561 frame = AUTH;
9562 else if (strcasecmp(val, "assocreq") == 0)
9563 frame = ASSOCREQ;
9564 else if (strcasecmp(val, "reassocreq") == 0)
9565 frame = REASSOCREQ;
9566 else if (strcasecmp(val, "neigreq") == 0) {
9567 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
9568
9569 val = get_param(cmd, "ssid");
9570 if (val == NULL)
9571 return -1;
9572
9573 res = send_neighbor_request(dut, intf, val);
9574 if (res) {
9575 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9576 "Failed to send neighbor report request");
9577 return 0;
9578 }
9579
9580 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309581 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
9582 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009583 sigma_dut_print(dut, DUT_MSG_DEBUG,
9584 "Got Transition Management Query");
9585
Ashwini Patil5acd7382017-04-13 15:55:04 +05309586 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009587 if (res) {
9588 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9589 "Failed to send Transition Management Query");
9590 return 0;
9591 }
9592
9593 return 1;
9594 } else {
9595 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9596 "PMFFrameType");
9597 return 0;
9598 }
9599
9600 val = get_param(cmd, "PMFProtected");
9601 if (val == NULL)
9602 val = get_param(cmd, "Protected");
9603 if (val == NULL)
9604 return -1;
9605 if (strcasecmp(val, "Correct-key") == 0 ||
9606 strcasecmp(val, "CorrectKey") == 0)
9607 protected = CORRECT_KEY;
9608 else if (strcasecmp(val, "IncorrectKey") == 0)
9609 protected = INCORRECT_KEY;
9610 else if (strcasecmp(val, "Unprotected") == 0)
9611 protected = UNPROTECTED;
9612 else {
9613 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9614 "PMFProtected");
9615 return 0;
9616 }
9617
9618 if (protected != UNPROTECTED &&
9619 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
9620 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
9621 "PMFProtected for auth/assocreq/reassocreq");
9622 return 0;
9623 }
9624
9625 if (if_nametoindex("sigmadut") == 0) {
9626 snprintf(buf, sizeof(buf),
9627 "iw dev %s interface add sigmadut type monitor",
9628 get_station_ifname());
9629 if (system(buf) != 0 ||
9630 if_nametoindex("sigmadut") == 0) {
9631 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
9632 "monitor interface with '%s'", buf);
9633 return -2;
9634 }
9635 }
9636
9637 if (system("ifconfig sigmadut up") != 0) {
9638 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
9639 "monitor interface up");
9640 return -2;
9641 }
9642
9643 return sta_inject_frame(dut, conn, frame, protected, NULL);
9644}
9645
9646
9647static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
9648 struct sigma_conn *conn,
9649 struct sigma_cmd *cmd,
9650 const char *ifname)
9651{
9652 char buf[200];
9653 const char *val;
9654
9655 val = get_param(cmd, "ClearARP");
9656 if (val && atoi(val) == 1) {
9657 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
9658 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9659 if (system(buf) != 0) {
9660 send_resp(dut, conn, SIGMA_ERROR,
9661 "errorCode,Failed to clear ARP cache");
9662 return 0;
9663 }
9664 }
9665
9666 return 1;
9667}
9668
9669
9670int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
9671 struct sigma_cmd *cmd)
9672{
9673 const char *intf = get_param(cmd, "Interface");
9674 const char *val;
9675
9676 if (intf == NULL)
9677 return -1;
9678
9679 val = get_param(cmd, "program");
9680 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +03009681 strcasecmp(val, "HS2-R2") == 0 ||
9682 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009683 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
9684
9685 return -1;
9686}
9687
9688
9689static int cmd_sta_set_macaddr(struct sigma_dut *dut, struct sigma_conn *conn,
9690 struct sigma_cmd *cmd)
9691{
9692 const char *intf = get_param(cmd, "Interface");
9693 const char *mac = get_param(cmd, "MAC");
9694
9695 if (intf == NULL || mac == NULL)
9696 return -1;
9697
9698 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
9699 "interface %s to %s", intf, mac);
9700
9701 if (dut->set_macaddr) {
9702 char buf[128];
9703 int res;
9704 if (strcasecmp(mac, "default") == 0) {
9705 res = snprintf(buf, sizeof(buf), "%s",
9706 dut->set_macaddr);
9707 dut->tmp_mac_addr = 0;
9708 } else {
9709 res = snprintf(buf, sizeof(buf), "%s %s",
9710 dut->set_macaddr, mac);
9711 dut->tmp_mac_addr = 1;
9712 }
9713 if (res < 0 || res >= (int) sizeof(buf))
9714 return -1;
9715 if (system(buf) != 0) {
9716 send_resp(dut, conn, SIGMA_ERROR,
9717 "errorCode,Failed to set MAC "
9718 "address");
9719 return 0;
9720 }
9721 return 1;
9722 }
9723
9724 if (strcasecmp(mac, "default") == 0)
9725 return 1;
9726
9727 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
9728 "command");
9729 return 0;
9730}
9731
9732
9733static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
9734 struct sigma_conn *conn, const char *intf,
9735 int val)
9736{
9737 char buf[200];
9738 int res;
9739
9740 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
9741 intf, val);
9742 if (res < 0 || res >= (int) sizeof(buf))
9743 return -1;
9744 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9745 if (system(buf) != 0) {
9746 send_resp(dut, conn, SIGMA_ERROR,
9747 "errorCode,Failed to configure offchannel mode");
9748 return 0;
9749 }
9750
9751 return 1;
9752}
9753
9754
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009755static int off_chan_val(enum sec_ch_offset off)
9756{
9757 switch (off) {
9758 case SEC_CH_NO:
9759 return 0;
9760 case SEC_CH_40ABOVE:
9761 return 40;
9762 case SEC_CH_40BELOW:
9763 return -40;
9764 }
9765
9766 return 0;
9767}
9768
9769
9770static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
9771 const char *intf, int off_ch_num,
9772 enum sec_ch_offset sec)
9773{
9774 char buf[200];
9775 int res;
9776
9777 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
9778 intf, off_ch_num);
9779 if (res < 0 || res >= (int) sizeof(buf))
9780 return -1;
9781 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9782 if (system(buf) != 0) {
9783 send_resp(dut, conn, SIGMA_ERROR,
9784 "errorCode,Failed to set offchan");
9785 return 0;
9786 }
9787
9788 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
9789 intf, off_chan_val(sec));
9790 if (res < 0 || res >= (int) sizeof(buf))
9791 return -1;
9792 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9793 if (system(buf) != 0) {
9794 send_resp(dut, conn, SIGMA_ERROR,
9795 "errorCode,Failed to set sec chan offset");
9796 return 0;
9797 }
9798
9799 return 1;
9800}
9801
9802
9803static int tdls_set_offchannel_offset(struct sigma_dut *dut,
9804 struct sigma_conn *conn,
9805 const char *intf, int off_ch_num,
9806 enum sec_ch_offset sec)
9807{
9808 char buf[200];
9809 int res;
9810
9811 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
9812 off_ch_num);
9813 if (res < 0 || res >= (int) sizeof(buf))
9814 return -1;
9815 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9816
9817 if (wpa_command(intf, buf) < 0) {
9818 send_resp(dut, conn, SIGMA_ERROR,
9819 "ErrorCode,Failed to set offchan");
9820 return 0;
9821 }
9822 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
9823 off_chan_val(sec));
9824 if (res < 0 || res >= (int) sizeof(buf))
9825 return -1;
9826
9827 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9828
9829 if (wpa_command(intf, buf) < 0) {
9830 send_resp(dut, conn, SIGMA_ERROR,
9831 "ErrorCode,Failed to set sec chan offset");
9832 return 0;
9833 }
9834
9835 return 1;
9836}
9837
9838
9839static int tdls_set_offchannel_mode(struct sigma_dut *dut,
9840 struct sigma_conn *conn,
9841 const char *intf, int val)
9842{
9843 char buf[200];
9844 int res;
9845
9846 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
9847 val);
9848 if (res < 0 || res >= (int) sizeof(buf))
9849 return -1;
9850 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
9851
9852 if (wpa_command(intf, buf) < 0) {
9853 send_resp(dut, conn, SIGMA_ERROR,
9854 "ErrorCode,Failed to configure offchannel mode");
9855 return 0;
9856 }
9857
9858 return 1;
9859}
9860
9861
9862static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
9863 struct sigma_conn *conn,
9864 struct sigma_cmd *cmd)
9865{
9866 const char *val;
9867 enum {
9868 CHSM_NOT_SET,
9869 CHSM_ENABLE,
9870 CHSM_DISABLE,
9871 CHSM_REJREQ,
9872 CHSM_UNSOLRESP
9873 } chsm = CHSM_NOT_SET;
9874 int off_ch_num = -1;
9875 enum sec_ch_offset sec_ch = SEC_CH_NO;
9876 int res;
9877
9878 val = get_param(cmd, "Uapsd");
9879 if (val) {
9880 char buf[100];
9881 if (strcasecmp(val, "Enable") == 0)
9882 snprintf(buf, sizeof(buf), "SET ps 99");
9883 else if (strcasecmp(val, "Disable") == 0)
9884 snprintf(buf, sizeof(buf), "SET ps 98");
9885 else {
9886 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
9887 "Unsupported uapsd parameter value");
9888 return 0;
9889 }
9890 if (wpa_command(intf, buf)) {
9891 send_resp(dut, conn, SIGMA_ERROR,
9892 "ErrorCode,Failed to change U-APSD "
9893 "powersave mode");
9894 return 0;
9895 }
9896 }
9897
9898 val = get_param(cmd, "TPKTIMER");
9899 if (val && strcasecmp(val, "DISABLE") == 0) {
9900 if (wpa_command(intf, "SET tdls_testing 0x100")) {
9901 send_resp(dut, conn, SIGMA_ERROR,
9902 "ErrorCode,Failed to enable no TPK "
9903 "expiration test mode");
9904 return 0;
9905 }
9906 dut->no_tpk_expiration = 1;
9907 }
9908
9909 val = get_param(cmd, "ChSwitchMode");
9910 if (val) {
9911 if (strcasecmp(val, "Enable") == 0 ||
9912 strcasecmp(val, "Initiate") == 0)
9913 chsm = CHSM_ENABLE;
9914 else if (strcasecmp(val, "Disable") == 0 ||
9915 strcasecmp(val, "passive") == 0)
9916 chsm = CHSM_DISABLE;
9917 else if (strcasecmp(val, "RejReq") == 0)
9918 chsm = CHSM_REJREQ;
9919 else if (strcasecmp(val, "UnSolResp") == 0)
9920 chsm = CHSM_UNSOLRESP;
9921 else {
9922 send_resp(dut, conn, SIGMA_ERROR,
9923 "ErrorCode,Unknown ChSwitchMode value");
9924 return 0;
9925 }
9926 }
9927
9928 val = get_param(cmd, "OffChNum");
9929 if (val) {
9930 off_ch_num = atoi(val);
9931 if (off_ch_num == 0) {
9932 send_resp(dut, conn, SIGMA_ERROR,
9933 "ErrorCode,Invalid OffChNum");
9934 return 0;
9935 }
9936 }
9937
9938 val = get_param(cmd, "SecChOffset");
9939 if (val) {
9940 if (strcmp(val, "20") == 0)
9941 sec_ch = SEC_CH_NO;
9942 else if (strcasecmp(val, "40above") == 0)
9943 sec_ch = SEC_CH_40ABOVE;
9944 else if (strcasecmp(val, "40below") == 0)
9945 sec_ch = SEC_CH_40BELOW;
9946 else {
9947 send_resp(dut, conn, SIGMA_ERROR,
9948 "ErrorCode,Unknown SecChOffset value");
9949 return 0;
9950 }
9951 }
9952
9953 if (chsm == CHSM_NOT_SET) {
9954 /* no offchannel changes requested */
9955 return 1;
9956 }
9957
9958 if (strcmp(intf, get_main_ifname()) != 0 &&
9959 strcmp(intf, get_station_ifname()) != 0) {
9960 send_resp(dut, conn, SIGMA_ERROR,
9961 "ErrorCode,Unknown interface");
9962 return 0;
9963 }
9964
9965 switch (chsm) {
9966 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +03009967 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009968 break;
9969 case CHSM_ENABLE:
9970 if (off_ch_num < 0) {
9971 send_resp(dut, conn, SIGMA_ERROR,
9972 "ErrorCode,Missing OffChNum argument");
9973 return 0;
9974 }
9975 if (wifi_chip_type == DRIVER_WCN) {
9976 res = tdls_set_offchannel_offset(dut, conn, intf,
9977 off_ch_num, sec_ch);
9978 } else {
9979 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
9980 sec_ch);
9981 }
9982 if (res != 1)
9983 return res;
9984 if (wifi_chip_type == DRIVER_WCN)
9985 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
9986 else
9987 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
9988 break;
9989 case CHSM_DISABLE:
9990 if (wifi_chip_type == DRIVER_WCN)
9991 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
9992 else
9993 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
9994 break;
9995 case CHSM_REJREQ:
9996 if (wifi_chip_type == DRIVER_WCN)
9997 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
9998 else
9999 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
10000 break;
10001 case CHSM_UNSOLRESP:
10002 if (off_ch_num < 0) {
10003 send_resp(dut, conn, SIGMA_ERROR,
10004 "ErrorCode,Missing OffChNum argument");
10005 return 0;
10006 }
10007 if (wifi_chip_type == DRIVER_WCN) {
10008 res = tdls_set_offchannel_offset(dut, conn, intf,
10009 off_ch_num, sec_ch);
10010 } else {
10011 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
10012 sec_ch);
10013 }
10014 if (res != 1)
10015 return res;
10016 if (wifi_chip_type == DRIVER_WCN)
10017 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
10018 else
10019 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
10020 break;
10021 }
10022
10023 return res;
10024}
10025
10026
10027static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10028 struct sigma_conn *conn,
10029 struct sigma_cmd *cmd)
10030{
10031 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053010032 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010033
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080010034 novap_reset(dut, intf);
10035
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010036 val = get_param(cmd, "nss_mcs_opt");
10037 if (val) {
10038 /* String (nss_operating_mode; mcs_operating_mode) */
10039 int nss, mcs;
10040 char buf[50];
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010041 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010042
10043 token = strdup(val);
10044 if (!token)
10045 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010046 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053010047 if (!result) {
10048 sigma_dut_print(dut, DUT_MSG_ERROR,
10049 "VHT NSS not specified");
10050 goto failed;
10051 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010052 if (strcasecmp(result, "def") != 0) {
10053 nss = atoi(result);
10054 if (nss == 4)
10055 ath_disable_txbf(dut, intf);
10056 snprintf(buf, sizeof(buf), "iwpriv %s nss %d",
10057 intf, nss);
10058 if (system(buf) != 0) {
10059 sigma_dut_print(dut, DUT_MSG_ERROR,
10060 "iwpriv nss failed");
10061 goto failed;
10062 }
10063 }
10064
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010065 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053010066 if (!result) {
10067 sigma_dut_print(dut, DUT_MSG_ERROR,
10068 "VHT MCS not specified");
10069 goto failed;
10070 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010071 if (strcasecmp(result, "def") == 0) {
10072 snprintf(buf, sizeof(buf), "iwpriv %s set11NRates 0",
10073 intf);
10074 if (system(buf) != 0) {
10075 sigma_dut_print(dut, DUT_MSG_ERROR,
10076 "iwpriv set11NRates failed");
10077 goto failed;
10078 }
10079
10080 } else {
10081 mcs = atoi(result);
10082 snprintf(buf, sizeof(buf), "iwpriv %s vhtmcs %d",
10083 intf, mcs);
10084 if (system(buf) != 0) {
10085 sigma_dut_print(dut, DUT_MSG_ERROR,
10086 "iwpriv vhtmcs failed");
10087 goto failed;
10088 }
10089 }
10090 /* Channel width gets messed up, fix this */
10091 snprintf(buf, sizeof(buf), "iwpriv %s chwidth %d",
10092 intf, dut->chwidth);
10093 if (system(buf) != 0) {
10094 sigma_dut_print(dut, DUT_MSG_ERROR,
10095 "iwpriv chwidth failed");
10096 }
10097 }
10098
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053010099 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010100 return 1;
10101failed:
10102 free(token);
10103 return 0;
10104}
10105
10106
10107static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
10108 struct sigma_conn *conn,
10109 struct sigma_cmd *cmd)
10110{
10111 switch (get_driver_type()) {
10112 case DRIVER_ATHEROS:
10113 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
10114 default:
10115 send_resp(dut, conn, SIGMA_ERROR,
10116 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
10117 return 0;
10118 }
10119}
10120
10121
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010122static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
10123 struct sigma_conn *conn,
10124 struct sigma_cmd *cmd)
10125{
10126 const char *val;
10127 char *token = NULL, *result;
10128 char buf[60];
10129
10130 val = get_param(cmd, "nss_mcs_opt");
10131 if (val) {
10132 /* String (nss_operating_mode; mcs_operating_mode) */
10133 int nss, mcs, ratecode;
10134 char *saveptr;
10135
10136 token = strdup(val);
10137 if (!token)
10138 return -2;
10139
10140 result = strtok_r(token, ";", &saveptr);
10141 if (!result) {
10142 sigma_dut_print(dut, DUT_MSG_ERROR,
10143 "HE NSS not specified");
10144 goto failed;
10145 }
10146 nss = 1;
10147 if (strcasecmp(result, "def") != 0)
10148 nss = atoi(result);
10149
10150 result = strtok_r(NULL, ";", &saveptr);
10151 if (!result) {
10152 sigma_dut_print(dut, DUT_MSG_ERROR,
10153 "HE MCS not specified");
10154 goto failed;
10155 }
10156 mcs = 7;
10157 if (strcasecmp(result, "def") != 0)
10158 mcs = atoi(result);
10159
Arif Hussain557bf412018-05-25 17:29:36 -070010160 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010161 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070010162 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010163 } else if (nss > 2) {
10164 sigma_dut_print(dut, DUT_MSG_ERROR,
10165 "HE NSS %d not supported", nss);
10166 goto failed;
10167 }
10168
Arif Hussain557bf412018-05-25 17:29:36 -070010169 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
10170 if (system(buf) != 0) {
10171 sigma_dut_print(dut, DUT_MSG_ERROR,
10172 "nss_mcs_opt: iwpriv %s nss %d failed",
10173 intf, nss);
10174 goto failed;
10175 }
Arif Hussainac6c5112018-05-25 17:34:00 -070010176 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070010177
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010178 /* Add the MCS to the ratecode */
10179 if (mcs >= 0 && mcs <= 11) {
10180 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070010181#ifdef NL80211_SUPPORT
10182 if (dut->device_type == STA_testbed) {
10183 enum he_mcs_config mcs_config;
10184 int ret;
10185
10186 if (mcs <= 7)
10187 mcs_config = HE_80_MCS0_7;
10188 else if (mcs <= 9)
10189 mcs_config = HE_80_MCS0_9;
10190 else
10191 mcs_config = HE_80_MCS0_11;
10192 ret = sta_set_he_mcs(dut, intf, mcs_config);
10193 if (ret) {
10194 sigma_dut_print(dut, DUT_MSG_ERROR,
10195 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10196 mcs, mcs_config, ret);
10197 goto failed;
10198 }
10199 }
10200#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010201 } else {
10202 sigma_dut_print(dut, DUT_MSG_ERROR,
10203 "HE MCS %d not supported", mcs);
10204 goto failed;
10205 }
10206 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
10207 intf, ratecode);
10208 if (system(buf) != 0) {
10209 sigma_dut_print(dut, DUT_MSG_ERROR,
10210 "iwpriv setting of 11ax rates failed");
10211 goto failed;
10212 }
10213 free(token);
10214 }
10215
10216 val = get_param(cmd, "GI");
10217 if (val) {
10218 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010219 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010220 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010221 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
10222 intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010223 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070010224 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
10225 intf);
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010226 } else {
10227 send_resp(dut, conn, SIGMA_ERROR,
10228 "errorCode,GI value not supported");
10229 return 0;
10230 }
10231 if (system(buf) != 0) {
10232 send_resp(dut, conn, SIGMA_ERROR,
10233 "errorCode,Failed to set shortgi");
10234 return 0;
10235 }
10236 }
10237
Subhani Shaik8e7a3052018-04-24 14:03:00 -070010238 val = get_param(cmd, "LTF");
10239 if (val) {
10240#ifdef NL80211_SUPPORT
10241 if (strcmp(val, "3.2") == 0) {
10242 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
10243 } if (strcmp(val, "6.4") == 0) {
10244 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
10245 } else if (strcmp(val, "12.8") == 0) {
10246 sta_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
10247 } else {
10248 send_resp(dut, conn, SIGMA_ERROR,
10249 "errorCode, LTF value not supported");
10250 return 0;
10251 }
10252#else /* NL80211_SUPPORT */
10253 sigma_dut_print(dut, DUT_MSG_ERROR,
10254 "LTF cannot be set without NL80211_SUPPORT defined");
10255 return -2;
10256#endif /* NL80211_SUPPORT */
10257 }
10258
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070010259 val = get_param(cmd, "TxSUPPDU");
10260 if (val) {
10261 int set_val = 1;
10262
10263 if (strcasecmp(val, "Enable") == 0)
10264 set_val = 1;
10265 else if (strcasecmp(val, "Disable") == 0)
10266 set_val = 0;
10267
10268 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
10269 send_resp(dut, conn, SIGMA_ERROR,
10270 "ErrorCode,Failed to set Tx SU PPDU config");
10271 return 0;
10272 }
10273 }
10274
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070010275 val = get_param(cmd, "OMCtrl_RxNSS");
10276 if (val) {
10277 /*
10278 * OMCtrl_RxNSS uses the IEEE 802.11 standard values for Nss,
10279 * i.e., 0 for 1Nss, 1 for Nss 2, etc. The driver checks for
10280 * the actual Nss value hence add 1 to the set value.
10281 */
10282 int set_val = atoi(val) + 1;
10283
10284 if (sta_set_he_om_ctrl_nss(dut, intf, set_val)) {
10285 send_resp(dut, conn, SIGMA_ERROR,
10286 "ErrorCode,Failed to set OM ctrl NSS config");
10287 return 0;
10288 }
10289 }
10290
10291 val = get_param(cmd, "OMCtrl_ChnlWidth");
10292 if (val) {
10293 int set_val = atoi(val);
10294
10295 if (sta_set_he_om_ctrl_bw(dut, intf,
10296 (enum qca_wlan_he_om_ctrl_ch_bw)
10297 set_val)) {
10298 send_resp(dut, conn, SIGMA_ERROR,
10299 "ErrorCode,Failed to set OM ctrl BW config");
10300 return 0;
10301 }
10302 }
10303
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080010304 val = get_param(cmd, "Powersave");
10305 if (val) {
10306 char buf[60];
10307
10308 if (strcasecmp(val, "off") == 0) {
10309 snprintf(buf, sizeof(buf),
10310 "iwpriv %s setPower 2", intf);
10311 if (system(buf) != 0) {
10312 sigma_dut_print(dut, DUT_MSG_ERROR,
10313 "iwpriv setPower 2 failed");
10314 return 0;
10315 }
10316 } else if (strcasecmp(val, "on") == 0) {
10317 snprintf(buf, sizeof(buf),
10318 "iwpriv %s setPower 1", intf);
10319 if (system(buf) != 0) {
10320 sigma_dut_print(dut, DUT_MSG_ERROR,
10321 "iwpriv setPower 1 failed");
10322 return 0;
10323 }
10324 } else {
10325 sigma_dut_print(dut, DUT_MSG_ERROR,
10326 "Unsupported Powersave value '%s'",
10327 val);
10328 return -1;
10329 }
10330 }
10331
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010332 return 1;
10333
10334failed:
10335 free(token);
10336 return -2;
10337}
10338
10339
10340static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
10341 struct sigma_conn *conn,
10342 struct sigma_cmd *cmd)
10343{
10344 switch (get_driver_type()) {
10345 case DRIVER_WCN:
10346 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
10347 default:
10348 send_resp(dut, conn, SIGMA_ERROR,
10349 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
10350 return 0;
10351 }
10352}
10353
10354
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080010355static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
10356 struct sigma_conn *conn,
10357 struct sigma_cmd *cmd)
10358{
10359 const char *val;
10360
10361 val = get_param(cmd, "powersave");
10362 if (val) {
10363 char buf[60];
10364
10365 if (strcasecmp(val, "off") == 0) {
10366 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
10367 intf);
10368 if (system(buf) != 0) {
10369 sigma_dut_print(dut, DUT_MSG_ERROR,
10370 "iwpriv setPower 2 failed");
10371 return 0;
10372 }
10373 } else if (strcasecmp(val, "on") == 0) {
10374 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
10375 intf);
10376 if (system(buf) != 0) {
10377 sigma_dut_print(dut, DUT_MSG_ERROR,
10378 "iwpriv setPower 1 failed");
10379 return 0;
10380 }
10381 } else {
10382 sigma_dut_print(dut, DUT_MSG_ERROR,
10383 "Unsupported power save config");
10384 return -1;
10385 }
10386 return 1;
10387 }
10388
10389 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
10390
10391 return 0;
10392}
10393
10394
Ashwini Patil5acd7382017-04-13 15:55:04 +053010395static int btm_query_candidate_list(struct sigma_dut *dut,
10396 struct sigma_conn *conn,
10397 struct sigma_cmd *cmd)
10398{
10399 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
10400 int len, ret;
10401 char buf[10];
10402
10403 /*
10404 * Neighbor Report elements format:
10405 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
10406 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
10407 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
10408 */
10409
10410 bssid = get_param(cmd, "Nebor_BSSID");
10411 if (!bssid) {
10412 send_resp(dut, conn, SIGMA_INVALID,
10413 "errorCode,Nebor_BSSID is missing");
10414 return 0;
10415 }
10416
10417 info = get_param(cmd, "Nebor_Bssid_Info");
10418 if (!info) {
10419 sigma_dut_print(dut, DUT_MSG_INFO,
10420 "Using default value for Nebor_Bssid_Info: %s",
10421 DEFAULT_NEIGHBOR_BSSID_INFO);
10422 info = DEFAULT_NEIGHBOR_BSSID_INFO;
10423 }
10424
10425 op_class = get_param(cmd, "Nebor_Op_Class");
10426 if (!op_class) {
10427 send_resp(dut, conn, SIGMA_INVALID,
10428 "errorCode,Nebor_Op_Class is missing");
10429 return 0;
10430 }
10431
10432 ch = get_param(cmd, "Nebor_Op_Ch");
10433 if (!ch) {
10434 send_resp(dut, conn, SIGMA_INVALID,
10435 "errorCode,Nebor_Op_Ch is missing");
10436 return 0;
10437 }
10438
10439 phy_type = get_param(cmd, "Nebor_Phy_Type");
10440 if (!phy_type) {
10441 sigma_dut_print(dut, DUT_MSG_INFO,
10442 "Using default value for Nebor_Phy_Type: %s",
10443 DEFAULT_NEIGHBOR_PHY_TYPE);
10444 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
10445 }
10446
10447 /* Parse optional subelements */
10448 buf[0] = '\0';
10449 pref = get_param(cmd, "Nebor_Pref");
10450 if (pref) {
10451 /* hexdump for preferrence subelement */
10452 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
10453 if (ret < 0 || ret >= (int) sizeof(buf)) {
10454 sigma_dut_print(dut, DUT_MSG_ERROR,
10455 "snprintf failed for optional subelement ret: %d",
10456 ret);
10457 send_resp(dut, conn, SIGMA_ERROR,
10458 "errorCode,snprintf failed for subelement");
10459 return 0;
10460 }
10461 }
10462
10463 if (!dut->btm_query_cand_list) {
10464 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
10465 if (!dut->btm_query_cand_list) {
10466 send_resp(dut, conn, SIGMA_ERROR,
10467 "errorCode,Failed to allocate memory for btm_query_cand_list");
10468 return 0;
10469 }
10470 }
10471
10472 len = strlen(dut->btm_query_cand_list);
10473 ret = snprintf(dut->btm_query_cand_list + len,
10474 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
10475 bssid, info, op_class, ch, phy_type, buf);
10476 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
10477 sigma_dut_print(dut, DUT_MSG_ERROR,
10478 "snprintf failed for neighbor report list ret: %d",
10479 ret);
10480 send_resp(dut, conn, SIGMA_ERROR,
10481 "errorCode,snprintf failed for neighbor report");
10482 free(dut->btm_query_cand_list);
10483 dut->btm_query_cand_list = NULL;
10484 return 0;
10485 }
10486
10487 return 1;
10488}
10489
10490
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080010491static int cmd_sta_set_power_save(struct sigma_dut *dut,
10492 struct sigma_conn *conn,
10493 struct sigma_cmd *cmd)
10494{
10495 const char *intf = get_param(cmd, "interface");
10496 const char *prog = get_param(cmd, "program");
10497
10498 if (!intf || !prog)
10499 return -1;
10500
10501 if ((get_driver_type() == DRIVER_WCN) && (strcasecmp(prog, "HE") == 0))
10502 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
10503
10504 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
10505 return 0;
10506}
10507
10508
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010509static int cmd_sta_set_rfeature(struct sigma_dut *dut, struct sigma_conn *conn,
10510 struct sigma_cmd *cmd)
10511{
10512 const char *intf = get_param(cmd, "Interface");
10513 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010514 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010515
10516 if (intf == NULL || prog == NULL)
10517 return -1;
10518
Ashwini Patil5acd7382017-04-13 15:55:04 +053010519 /* BSS Transition candidate list for BTM query */
10520 val = get_param(cmd, "Nebor_BSSID");
10521 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
10522 return 0;
10523
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010524 if (strcasecmp(prog, "TDLS") == 0)
10525 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
10526
10527 if (strcasecmp(prog, "VHT") == 0)
10528 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
10529
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080010530 if (strcasecmp(prog, "HE") == 0)
10531 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
10532
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010533 if (strcasecmp(prog, "MBO") == 0) {
10534 val = get_param(cmd, "Cellular_Data_Cap");
10535 if (val &&
10536 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
10537 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053010538
10539 val = get_param(cmd, "Ch_Pref");
10540 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
10541 return 0;
10542
Ashwini Patil68d02cd2017-01-10 15:39:16 +053010543 return 1;
10544 }
10545
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010546 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
10547 return 0;
10548}
10549
10550
10551static int cmd_sta_set_radio(struct sigma_dut *dut, struct sigma_conn *conn,
10552 struct sigma_cmd *cmd)
10553{
10554 const char *intf = get_param(cmd, "Interface");
10555 const char *mode = get_param(cmd, "Mode");
10556 int res;
10557
10558 if (intf == NULL || mode == NULL)
10559 return -1;
10560
10561 if (strcasecmp(mode, "On") == 0)
10562 res = wpa_command(intf, "SET radio_disabled 0");
10563 else if (strcasecmp(mode, "Off") == 0)
10564 res = wpa_command(intf, "SET radio_disabled 1");
10565 else
10566 return -1;
10567
10568 if (res) {
10569 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
10570 "radio mode");
10571 return 0;
10572 }
10573
10574 return 1;
10575}
10576
10577
10578static int cmd_sta_set_pwrsave(struct sigma_dut *dut, struct sigma_conn *conn,
10579 struct sigma_cmd *cmd)
10580{
10581 const char *intf = get_param(cmd, "Interface");
10582 const char *mode = get_param(cmd, "Mode");
10583 int res;
10584
10585 if (intf == NULL || mode == NULL)
10586 return -1;
10587
10588 if (strcasecmp(mode, "On") == 0)
10589 res = set_ps(intf, dut, 1);
10590 else if (strcasecmp(mode, "Off") == 0)
10591 res = set_ps(intf, dut, 0);
10592 else
10593 return -1;
10594
10595 if (res) {
10596 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
10597 "power save mode");
10598 return 0;
10599 }
10600
10601 return 1;
10602}
10603
10604
10605static int cmd_sta_bssid_pool(struct sigma_dut *dut, struct sigma_conn *conn,
10606 struct sigma_cmd *cmd)
10607{
10608 const char *intf = get_param(cmd, "Interface");
10609 const char *val, *bssid;
10610 int res;
10611 char *buf;
10612 size_t buf_len;
10613
10614 val = get_param(cmd, "BSSID_FILTER");
10615 if (val == NULL)
10616 return -1;
10617
10618 bssid = get_param(cmd, "BSSID_List");
10619 if (atoi(val) == 0 || bssid == NULL) {
10620 /* Disable BSSID filter */
10621 if (wpa_command(intf, "SET bssid_filter ")) {
10622 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
10623 "to disable BSSID filter");
10624 return 0;
10625 }
10626
10627 return 1;
10628 }
10629
10630 buf_len = 100 + strlen(bssid);
10631 buf = malloc(buf_len);
10632 if (buf == NULL)
10633 return -1;
10634
10635 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
10636 res = wpa_command(intf, buf);
10637 free(buf);
10638 if (res) {
10639 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
10640 "BSSID filter");
10641 return 0;
10642 }
10643
10644 return 1;
10645}
10646
10647
10648static int cmd_sta_reset_parm(struct sigma_dut *dut, struct sigma_conn *conn,
10649 struct sigma_cmd *cmd)
10650{
10651 const char *intf = get_param(cmd, "Interface");
10652 const char *val;
10653
10654 /* TODO: ARP */
10655
10656 val = get_param(cmd, "HS2_CACHE_PROFILE");
10657 if (val && strcasecmp(val, "All") == 0)
10658 hs2_clear_credentials(intf);
10659
10660 return 1;
10661}
10662
10663
10664static int cmd_sta_get_key(struct sigma_dut *dut, struct sigma_conn *conn,
10665 struct sigma_cmd *cmd)
10666{
10667 const char *intf = get_param(cmd, "Interface");
10668 const char *key_type = get_param(cmd, "KeyType");
10669 char buf[100], resp[200];
10670
10671 if (key_type == NULL)
10672 return -1;
10673
10674 if (strcasecmp(key_type, "GTK") == 0) {
10675 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
10676 strncmp(buf, "FAIL", 4) == 0) {
10677 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10678 "not fetch current GTK");
10679 return 0;
10680 }
10681 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
10682 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10683 return 0;
10684 } else {
10685 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
10686 "KeyType");
10687 return 0;
10688 }
10689
10690 return 1;
10691}
10692
10693
10694static int hs2_set_policy(struct sigma_dut *dut)
10695{
10696#ifdef ANDROID
10697 system("ip rule del prio 23000");
10698 if (system("ip rule add from all lookup main prio 23000") != 0) {
10699 sigma_dut_print(dut, DUT_MSG_ERROR,
10700 "Failed to run:ip rule add from all lookup main prio");
10701 return -1;
10702 }
10703 if (system("ip route flush cache") != 0) {
10704 sigma_dut_print(dut, DUT_MSG_ERROR,
10705 "Failed to run ip route flush cache");
10706 return -1;
10707 }
10708 return 1;
10709#else /* ANDROID */
10710 return 0;
10711#endif /* ANDROID */
10712}
10713
10714
10715static int cmd_sta_hs2_associate(struct sigma_dut *dut,
10716 struct sigma_conn *conn,
10717 struct sigma_cmd *cmd)
10718{
10719 const char *intf = get_param(cmd, "Interface");
10720 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030010721 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010722 struct wpa_ctrl *ctrl;
10723 int res;
10724 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
10725 int tries = 0;
10726 int ignore_blacklist = 0;
10727 const char *events[] = {
10728 "CTRL-EVENT-CONNECTED",
10729 "INTERWORKING-BLACKLISTED",
10730 "INTERWORKING-NO-MATCH",
10731 NULL
10732 };
10733
10734 start_sta_mode(dut);
10735
Jouni Malinen439352d2018-09-13 03:42:23 +030010736 if (band) {
10737 if (strcmp(band, "2.4") == 0) {
10738 wpa_command(intf, "SET setband 2G");
10739 } else if (strcmp(band, "5") == 0) {
10740 wpa_command(intf, "SET setband 5G");
10741 } else {
10742 send_resp(dut, conn, SIGMA_ERROR,
10743 "errorCode,Unsupported band");
10744 return 0;
10745 }
10746 }
10747
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010748 blacklisted[0] = '\0';
10749 if (val && atoi(val))
10750 ignore_blacklist = 1;
10751
10752try_again:
10753 ctrl = open_wpa_mon(intf);
10754 if (ctrl == NULL) {
10755 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
10756 "wpa_supplicant monitor connection");
10757 return -2;
10758 }
10759
10760 tries++;
10761 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
10762 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
10763 "Interworking connection");
10764 wpa_ctrl_detach(ctrl);
10765 wpa_ctrl_close(ctrl);
10766 return 0;
10767 }
10768
10769 buf[0] = '\0';
10770 while (1) {
10771 char *pos;
10772 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
10773 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
10774 if (!pos)
10775 break;
10776 pos += 25;
10777 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
10778 pos);
10779 if (!blacklisted[0])
10780 memcpy(blacklisted, pos, strlen(pos) + 1);
10781 }
10782
10783 if (ignore_blacklist && blacklisted[0]) {
10784 char *end;
10785 end = strchr(blacklisted, ' ');
10786 if (end)
10787 *end = '\0';
10788 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
10789 blacklisted);
10790 snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
10791 blacklisted);
10792 if (wpa_command(intf, buf)) {
10793 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
10794 wpa_ctrl_detach(ctrl);
10795 wpa_ctrl_close(ctrl);
10796 return 0;
10797 }
10798 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
10799 buf, sizeof(buf));
10800 }
10801
10802 wpa_ctrl_detach(ctrl);
10803 wpa_ctrl_close(ctrl);
10804
10805 if (res < 0) {
10806 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
10807 "connect");
10808 return 0;
10809 }
10810
10811 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
10812 strstr(buf, "INTERWORKING-BLACKLISTED")) {
10813 if (tries < 2) {
10814 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
10815 goto try_again;
10816 }
10817 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
10818 "matching credentials found");
10819 return 0;
10820 }
10821
10822 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
10823 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
10824 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
10825 "get current BSSID/SSID");
10826 return 0;
10827 }
10828
10829 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
10830 send_resp(dut, conn, SIGMA_COMPLETE, resp);
10831 hs2_set_policy(dut);
10832 return 0;
10833}
10834
10835
Jouni Malinenb639f1c2018-09-13 02:39:46 +030010836static int cmd_sta_hs2_venue_info(struct sigma_dut *dut,
10837 struct sigma_conn *conn,
10838 struct sigma_cmd *cmd)
10839{
10840 const char *intf = get_param(cmd, "Interface");
10841 const char *display = get_param(cmd, "Display");
10842 struct wpa_ctrl *ctrl;
10843 char buf[300], params[400], *pos;
10844 char bssid[20];
10845 int info_avail = 0;
10846 unsigned int old_timeout;
10847 int res;
10848
10849 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
10850 send_resp(dut, conn, SIGMA_ERROR,
10851 "ErrorCode,Could not get current BSSID");
10852 return 0;
10853 }
10854 ctrl = open_wpa_mon(intf);
10855 if (!ctrl) {
10856 sigma_dut_print(dut, DUT_MSG_ERROR,
10857 "Failed to open wpa_supplicant monitor connection");
10858 return -2;
10859 }
10860
10861 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
10862 wpa_command(intf, buf);
10863
10864 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
10865 if (res < 0) {
10866 send_resp(dut, conn, SIGMA_ERROR,
10867 "ErrorCode,Could not complete GAS query");
10868 goto fail;
10869 }
10870
10871 old_timeout = dut->default_timeout;
10872 dut->default_timeout = 2;
10873 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
10874 dut->default_timeout = old_timeout;
10875 if (res < 0)
10876 goto done;
10877 pos = strchr(buf, ' ');
10878 if (!pos)
10879 goto done;
10880 pos++;
10881 pos = strchr(pos, ' ');
10882 if (!pos)
10883 goto done;
10884 pos++;
10885 info_avail = 1;
10886 snprintf(params, sizeof(params), "browser %s", pos);
10887
10888 if (display && strcasecmp(display, "Yes") == 0) {
10889 pid_t pid;
10890
10891 pid = fork();
10892 if (pid < 0) {
10893 perror("fork");
10894 return -1;
10895 }
10896
10897 if (pid == 0) {
10898 run_hs20_osu(dut, params);
10899 exit(0);
10900 }
10901 }
10902
10903done:
10904 snprintf(buf, sizeof(buf), "Info_available,%s",
10905 info_avail ? "Yes" : "No");
10906 send_resp(dut, conn, SIGMA_COMPLETE, buf);
10907fail:
10908 wpa_ctrl_detach(ctrl);
10909 wpa_ctrl_close(ctrl);
10910 return 0;
10911}
10912
10913
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010914static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
10915 struct sigma_conn *conn,
10916 const char *ifname,
10917 struct sigma_cmd *cmd)
10918{
10919 const char *val;
10920 int id;
10921
10922 id = add_cred(ifname);
10923 if (id < 0)
10924 return -2;
10925 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
10926
10927 val = get_param(cmd, "prefer");
10928 if (val && atoi(val) > 0)
10929 set_cred(ifname, id, "priority", "1");
10930
10931 val = get_param(cmd, "REALM");
10932 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
10933 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10934 "realm");
10935 return 0;
10936 }
10937
10938 val = get_param(cmd, "HOME_FQDN");
10939 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
10940 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10941 "home_fqdn");
10942 return 0;
10943 }
10944
10945 val = get_param(cmd, "Username");
10946 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
10947 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10948 "username");
10949 return 0;
10950 }
10951
10952 val = get_param(cmd, "Password");
10953 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
10954 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
10955 "password");
10956 return 0;
10957 }
10958
10959 val = get_param(cmd, "ROOT_CA");
10960 if (val) {
10961 char fname[200];
10962 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
10963#ifdef __linux__
10964 if (!file_exists(fname)) {
10965 char msg[300];
10966 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
10967 "file (%s) not found", fname);
10968 send_resp(dut, conn, SIGMA_ERROR, msg);
10969 return 0;
10970 }
10971#endif /* __linux__ */
10972 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
10973 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
10974 "not set root CA");
10975 return 0;
10976 }
10977 }
10978
10979 return 1;
10980}
10981
10982
10983static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
10984{
10985 FILE *in, *out;
10986 char buf[500];
10987 int found = 0;
10988
10989 in = fopen("devdetail.xml", "r");
10990 if (in == NULL)
10991 return -1;
10992 out = fopen("devdetail.xml.tmp", "w");
10993 if (out == NULL) {
10994 fclose(in);
10995 return -1;
10996 }
10997
10998 while (fgets(buf, sizeof(buf), in)) {
10999 char *pos = strstr(buf, "<IMSI>");
11000 if (pos) {
11001 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
11002 imsi);
11003 pos += 6;
11004 *pos = '\0';
11005 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
11006 found++;
11007 } else {
11008 fprintf(out, "%s", buf);
11009 }
11010 }
11011
11012 fclose(out);
11013 fclose(in);
11014 if (found)
11015 rename("devdetail.xml.tmp", "devdetail.xml");
11016 else
11017 unlink("devdetail.xml.tmp");
11018
11019 return 0;
11020}
11021
11022
11023static int sta_add_credential_sim(struct sigma_dut *dut,
11024 struct sigma_conn *conn,
11025 const char *ifname, struct sigma_cmd *cmd)
11026{
11027 const char *val, *imsi = NULL;
11028 int id;
11029 char buf[200];
11030 int res;
11031 const char *pos;
11032 size_t mnc_len;
11033 char plmn_mcc[4];
11034 char plmn_mnc[4];
11035
11036 id = add_cred(ifname);
11037 if (id < 0)
11038 return -2;
11039 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
11040
11041 val = get_param(cmd, "prefer");
11042 if (val && atoi(val) > 0)
11043 set_cred(ifname, id, "priority", "1");
11044
11045 val = get_param(cmd, "PLMN_MCC");
11046 if (val == NULL) {
11047 send_resp(dut, conn, SIGMA_ERROR,
11048 "errorCode,Missing PLMN_MCC");
11049 return 0;
11050 }
11051 if (strlen(val) != 3) {
11052 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
11053 return 0;
11054 }
11055 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
11056
11057 val = get_param(cmd, "PLMN_MNC");
11058 if (val == NULL) {
11059 send_resp(dut, conn, SIGMA_ERROR,
11060 "errorCode,Missing PLMN_MNC");
11061 return 0;
11062 }
11063 if (strlen(val) != 2 && strlen(val) != 3) {
11064 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
11065 return 0;
11066 }
11067 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
11068
11069 val = get_param(cmd, "IMSI");
11070 if (val == NULL) {
11071 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
11072 "IMSI");
11073 return 0;
11074 }
11075
11076 imsi = pos = val;
11077
11078 if (strncmp(plmn_mcc, pos, 3) != 0) {
11079 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
11080 return 0;
11081 }
11082 pos += 3;
11083
11084 mnc_len = strlen(plmn_mnc);
11085 if (mnc_len < 2) {
11086 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
11087 return 0;
11088 }
11089
11090 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
11091 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
11092 return 0;
11093 }
11094 pos += mnc_len;
11095
11096 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
11097 if (res < 0 || res >= (int) sizeof(buf))
11098 return -1;
11099 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
11100 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11101 "not set IMSI");
11102 return 0;
11103 }
11104
11105 val = get_param(cmd, "Password");
11106 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
11107 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11108 "not set password");
11109 return 0;
11110 }
11111
Jouni Malinenba630452018-06-22 11:49:59 +030011112 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011113 /*
11114 * Set provisioning_sp for the test cases where SIM/USIM
11115 * provisioning is used.
11116 */
11117 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
11118 "wi-fi.org") < 0) {
11119 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11120 "not set provisioning_sp");
11121 return 0;
11122 }
11123
11124 update_devdetail_imsi(dut, imsi);
11125 }
11126
11127 return 1;
11128}
11129
11130
11131static int sta_add_credential_cert(struct sigma_dut *dut,
11132 struct sigma_conn *conn,
11133 const char *ifname,
11134 struct sigma_cmd *cmd)
11135{
11136 const char *val;
11137 int id;
11138
11139 id = add_cred(ifname);
11140 if (id < 0)
11141 return -2;
11142 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
11143
11144 val = get_param(cmd, "prefer");
11145 if (val && atoi(val) > 0)
11146 set_cred(ifname, id, "priority", "1");
11147
11148 val = get_param(cmd, "REALM");
11149 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
11150 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11151 "realm");
11152 return 0;
11153 }
11154
11155 val = get_param(cmd, "HOME_FQDN");
11156 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
11157 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11158 "home_fqdn");
11159 return 0;
11160 }
11161
11162 val = get_param(cmd, "Username");
11163 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
11164 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
11165 "username");
11166 return 0;
11167 }
11168
11169 val = get_param(cmd, "clientCertificate");
11170 if (val) {
11171 char fname[200];
11172 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
11173#ifdef __linux__
11174 if (!file_exists(fname)) {
11175 char msg[300];
11176 snprintf(msg, sizeof(msg),
11177 "ErrorCode,clientCertificate "
11178 "file (%s) not found", fname);
11179 send_resp(dut, conn, SIGMA_ERROR, msg);
11180 return 0;
11181 }
11182#endif /* __linux__ */
11183 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
11184 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11185 "not set client_cert");
11186 return 0;
11187 }
11188 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
11189 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11190 "not set private_key");
11191 return 0;
11192 }
11193 }
11194
11195 val = get_param(cmd, "ROOT_CA");
11196 if (val) {
11197 char fname[200];
11198 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
11199#ifdef __linux__
11200 if (!file_exists(fname)) {
11201 char msg[300];
11202 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
11203 "file (%s) not found", fname);
11204 send_resp(dut, conn, SIGMA_ERROR, msg);
11205 return 0;
11206 }
11207#endif /* __linux__ */
11208 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
11209 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
11210 "not set root CA");
11211 return 0;
11212 }
11213 }
11214
11215 return 1;
11216}
11217
11218
11219static int cmd_sta_add_credential(struct sigma_dut *dut,
11220 struct sigma_conn *conn,
11221 struct sigma_cmd *cmd)
11222{
11223 const char *intf = get_param(cmd, "Interface");
11224 const char *type;
11225
11226 start_sta_mode(dut);
11227
11228 type = get_param(cmd, "Type");
11229 if (!type)
11230 return -1;
11231
11232 if (strcasecmp(type, "uname_pwd") == 0)
11233 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
11234
11235 if (strcasecmp(type, "sim") == 0)
11236 return sta_add_credential_sim(dut, conn, intf, cmd);
11237
11238 if (strcasecmp(type, "cert") == 0)
11239 return sta_add_credential_cert(dut, conn, intf, cmd);
11240
11241 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
11242 "type");
11243 return 0;
11244}
11245
11246
11247static int cmd_sta_scan(struct sigma_dut *dut, struct sigma_conn *conn,
11248 struct sigma_cmd *cmd)
11249{
11250 const char *intf = get_param(cmd, "Interface");
vamsi krishna89ad8c62017-09-19 12:51:18 +053011251 const char *val, *bssid, *ssid;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011252 char buf[100];
vamsi krishna89ad8c62017-09-19 12:51:18 +053011253 char ssid_hex[65];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011254 int res;
11255
11256 val = get_param(cmd, "HESSID");
11257 if (val) {
11258 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
11259 if (res < 0 || res >= (int) sizeof(buf))
11260 return -1;
11261 wpa_command(intf, buf);
11262 }
11263
11264 val = get_param(cmd, "ACCS_NET_TYPE");
11265 if (val) {
11266 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
11267 val);
11268 if (res < 0 || res >= (int) sizeof(buf))
11269 return -1;
11270 wpa_command(intf, buf);
11271 }
11272
vamsi krishna89ad8c62017-09-19 12:51:18 +053011273 bssid = get_param(cmd, "Bssid");
11274 ssid = get_param(cmd, "Ssid");
11275
11276 if (ssid) {
11277 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
11278 send_resp(dut, conn, SIGMA_ERROR,
11279 "ErrorCode,Too long SSID");
11280 return 0;
11281 }
11282 ascii2hexstr(ssid, ssid_hex);
11283 }
11284
11285 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s",
11286 bssid ? " bssid=": "",
11287 bssid ? bssid : "",
11288 ssid ? " ssid " : "",
11289 ssid ? ssid_hex : "");
11290 if (res < 0 || res >= (int) sizeof(buf))
11291 return -1;
11292
11293 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011294 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
11295 "scan");
11296 return 0;
11297 }
11298
11299 return 1;
11300}
11301
11302
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020011303static int cmd_sta_scan_bss(struct sigma_dut *dut, struct sigma_conn *conn,
11304 struct sigma_cmd *cmd)
11305{
11306 const char *intf = get_param(cmd, "Interface");
11307 const char *bssid;
11308 char buf[4096], *pos;
11309 int freq, chan;
11310 char *ssid;
11311 char resp[100];
11312 int res;
11313 struct wpa_ctrl *ctrl;
11314
11315 bssid = get_param(cmd, "BSSID");
11316 if (!bssid) {
11317 send_resp(dut, conn, SIGMA_INVALID,
11318 "errorCode,BSSID argument is missing");
11319 return 0;
11320 }
11321
11322 ctrl = open_wpa_mon(intf);
11323 if (!ctrl) {
11324 sigma_dut_print(dut, DUT_MSG_ERROR,
11325 "Failed to open wpa_supplicant monitor connection");
11326 return -1;
11327 }
11328
11329 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
11330 send_resp(dut, conn, SIGMA_ERROR,
11331 "errorCode,Could not start scan");
11332 wpa_ctrl_detach(ctrl);
11333 wpa_ctrl_close(ctrl);
11334 return 0;
11335 }
11336
11337 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
11338 buf, sizeof(buf));
11339
11340 wpa_ctrl_detach(ctrl);
11341 wpa_ctrl_close(ctrl);
11342
11343 if (res < 0) {
11344 send_resp(dut, conn, SIGMA_ERROR,
11345 "errorCode,Scan did not complete");
11346 return 0;
11347 }
11348
11349 snprintf(buf, sizeof(buf), "BSS %s", bssid);
11350 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
11351 strncmp(buf, "id=", 3) != 0) {
11352 send_resp(dut, conn, SIGMA_ERROR,
11353 "errorCode,Specified BSSID not found");
11354 return 0;
11355 }
11356
11357 pos = strstr(buf, "\nfreq=");
11358 if (!pos) {
11359 send_resp(dut, conn, SIGMA_ERROR,
11360 "errorCode,Channel not found");
11361 return 0;
11362 }
11363 freq = atoi(pos + 6);
11364 chan = freq_to_channel(freq);
11365
11366 pos = strstr(buf, "\nssid=");
11367 if (!pos) {
11368 send_resp(dut, conn, SIGMA_ERROR,
11369 "errorCode,SSID not found");
11370 return 0;
11371 }
11372 ssid = pos + 6;
11373 pos = strchr(ssid, '\n');
11374 if (pos)
11375 *pos = '\0';
11376 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
11377 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11378 return 0;
11379}
11380
11381
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011382static int cmd_sta_set_systime(struct sigma_dut *dut, struct sigma_conn *conn,
11383 struct sigma_cmd *cmd)
11384{
11385#ifdef __linux__
11386 struct timeval tv;
11387 struct tm tm;
11388 time_t t;
11389 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053011390 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011391
11392 wpa_command(get_station_ifname(), "PMKSA_FLUSH");
11393
11394 memset(&tm, 0, sizeof(tm));
11395 val = get_param(cmd, "seconds");
11396 if (val)
11397 tm.tm_sec = atoi(val);
11398 val = get_param(cmd, "minutes");
11399 if (val)
11400 tm.tm_min = atoi(val);
11401 val = get_param(cmd, "hours");
11402 if (val)
11403 tm.tm_hour = atoi(val);
11404 val = get_param(cmd, "date");
11405 if (val)
11406 tm.tm_mday = atoi(val);
11407 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053011408 if (val) {
11409 v = atoi(val);
11410 if (v < 1 || v > 12) {
11411 send_resp(dut, conn, SIGMA_INVALID,
11412 "errorCode,Invalid month");
11413 return 0;
11414 }
11415 tm.tm_mon = v - 1;
11416 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011417 val = get_param(cmd, "year");
11418 if (val) {
11419 int year = atoi(val);
11420#ifdef ANDROID
11421 if (year > 2035)
11422 year = 2035; /* years beyond 2035 not supported */
11423#endif /* ANDROID */
11424 tm.tm_year = year - 1900;
11425 }
11426 t = mktime(&tm);
11427 if (t == (time_t) -1) {
11428 send_resp(dut, conn, SIGMA_ERROR,
11429 "errorCode,Invalid date or time");
11430 return 0;
11431 }
11432
11433 memset(&tv, 0, sizeof(tv));
11434 tv.tv_sec = t;
11435
11436 if (settimeofday(&tv, NULL) < 0) {
11437 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
11438 strerror(errno));
11439 send_resp(dut, conn, SIGMA_ERROR,
11440 "errorCode,Failed to set time");
11441 return 0;
11442 }
11443
11444 return 1;
11445#endif /* __linux__ */
11446
11447 return -1;
11448}
11449
11450
11451static int cmd_sta_osu(struct sigma_dut *dut, struct sigma_conn *conn,
11452 struct sigma_cmd *cmd)
11453{
11454 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011455 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011456 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011457 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011458 int res;
11459 struct wpa_ctrl *ctrl;
11460
11461 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011462 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011463
11464 val = get_param(cmd, "ProdESSAssoc");
11465 if (val)
11466 prod_ess_assoc = atoi(val);
11467
11468 kill_dhcp_client(dut, intf);
11469 if (start_dhcp_client(dut, intf) < 0)
11470 return -2;
11471
11472 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
11473 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
11474 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011475 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011476 prod_ess_assoc ? "" : "-N",
11477 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030011478 name ? "'" : "",
11479 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
11480 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011481
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053011482 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011483 if (run_hs20_osu(dut, buf) < 0) {
11484 FILE *f;
11485
11486 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
11487
11488 f = fopen("hs20-osu-client.res", "r");
11489 if (f) {
11490 char resp[400], res[300], *pos;
11491 if (!fgets(res, sizeof(res), f))
11492 res[0] = '\0';
11493 pos = strchr(res, '\n');
11494 if (pos)
11495 *pos = '\0';
11496 fclose(f);
11497 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
11498 res);
11499 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
11500 if (system(resp) != 0) {
11501 }
11502 snprintf(resp, sizeof(resp),
11503 "SSID,,BSSID,,failureReason,%s", res);
11504 send_resp(dut, conn, SIGMA_COMPLETE, resp);
11505 return 0;
11506 }
11507
11508 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11509 return 0;
11510 }
11511
11512 if (!prod_ess_assoc)
11513 goto report;
11514
11515 ctrl = open_wpa_mon(intf);
11516 if (ctrl == NULL) {
11517 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11518 "wpa_supplicant monitor connection");
11519 return -1;
11520 }
11521
11522 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
11523 buf, sizeof(buf));
11524
11525 wpa_ctrl_detach(ctrl);
11526 wpa_ctrl_close(ctrl);
11527
11528 if (res < 0) {
11529 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
11530 "network after OSU");
11531 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11532 return 0;
11533 }
11534
11535report:
11536 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
11537 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
11538 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
11539 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
11540 return 0;
11541 }
11542
11543 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
11544 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011545 return 0;
11546}
11547
11548
11549static int cmd_sta_policy_update(struct sigma_dut *dut, struct sigma_conn *conn,
11550 struct sigma_cmd *cmd)
11551{
11552 const char *val;
11553 int timeout = 120;
11554
11555 val = get_param(cmd, "PolicyUpdate");
11556 if (val == NULL || atoi(val) == 0)
11557 return 1; /* No operation requested */
11558
11559 val = get_param(cmd, "Timeout");
11560 if (val)
11561 timeout = atoi(val);
11562
11563 if (timeout) {
11564 /* TODO: time out the command and return
11565 * PolicyUpdateStatus,TIMEOUT if needed. */
11566 }
11567
11568 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
11569 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
11570 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
11571 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
11572 return 0;
11573 }
11574
11575 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
11576 return 0;
11577}
11578
11579
11580static int cmd_sta_er_config(struct sigma_dut *dut, struct sigma_conn *conn,
11581 struct sigma_cmd *cmd)
11582{
11583 struct wpa_ctrl *ctrl;
11584 const char *intf = get_param(cmd, "Interface");
11585 const char *bssid = get_param(cmd, "Bssid");
11586 const char *ssid = get_param(cmd, "SSID");
11587 const char *security = get_param(cmd, "Security");
11588 const char *passphrase = get_param(cmd, "Passphrase");
11589 const char *pin = get_param(cmd, "PIN");
11590 char buf[1000];
11591 char ssid_hex[200], passphrase_hex[200];
11592 const char *keymgmt, *cipher;
11593
11594 if (intf == NULL)
11595 intf = get_main_ifname();
11596
11597 if (!bssid) {
11598 send_resp(dut, conn, SIGMA_ERROR,
11599 "ErrorCode,Missing Bssid argument");
11600 return 0;
11601 }
11602
11603 if (!ssid) {
11604 send_resp(dut, conn, SIGMA_ERROR,
11605 "ErrorCode,Missing SSID argument");
11606 return 0;
11607 }
11608
11609 if (!security) {
11610 send_resp(dut, conn, SIGMA_ERROR,
11611 "ErrorCode,Missing Security argument");
11612 return 0;
11613 }
11614
11615 if (!passphrase) {
11616 send_resp(dut, conn, SIGMA_ERROR,
11617 "ErrorCode,Missing Passphrase argument");
11618 return 0;
11619 }
11620
11621 if (!pin) {
11622 send_resp(dut, conn, SIGMA_ERROR,
11623 "ErrorCode,Missing PIN argument");
11624 return 0;
11625 }
11626
vamsi krishna8c9c1562017-05-12 15:51:46 +053011627 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
11628 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011629 send_resp(dut, conn, SIGMA_ERROR,
11630 "ErrorCode,Too long SSID/passphrase");
11631 return 0;
11632 }
11633
11634 ctrl = open_wpa_mon(intf);
11635 if (ctrl == NULL) {
11636 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11637 "wpa_supplicant monitor connection");
11638 return -2;
11639 }
11640
11641 if (strcasecmp(security, "wpa2-psk") == 0) {
11642 keymgmt = "WPA2PSK";
11643 cipher = "CCMP";
11644 } else {
11645 wpa_ctrl_detach(ctrl);
11646 wpa_ctrl_close(ctrl);
11647 send_resp(dut, conn, SIGMA_ERROR,
11648 "ErrorCode,Unsupported Security value");
11649 return 0;
11650 }
11651
11652 ascii2hexstr(ssid, ssid_hex);
11653 ascii2hexstr(passphrase, passphrase_hex);
11654 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
11655 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
11656
11657 if (wpa_command(intf, buf) < 0) {
11658 wpa_ctrl_detach(ctrl);
11659 wpa_ctrl_close(ctrl);
11660 send_resp(dut, conn, SIGMA_ERROR,
11661 "ErrorCode,Failed to start registrar");
11662 return 0;
11663 }
11664
11665 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
11666 dut->er_oper_performed = 1;
11667
11668 return wps_connection_event(dut, conn, ctrl, intf, 0);
11669}
11670
11671
11672static int cmd_sta_wps_connect_pw_token(struct sigma_dut *dut,
11673 struct sigma_conn *conn,
11674 struct sigma_cmd *cmd)
11675{
11676 struct wpa_ctrl *ctrl;
11677 const char *intf = get_param(cmd, "Interface");
11678 const char *bssid = get_param(cmd, "Bssid");
11679 char buf[100];
11680
11681 if (!bssid) {
11682 send_resp(dut, conn, SIGMA_ERROR,
11683 "ErrorCode,Missing Bssid argument");
11684 return 0;
11685 }
11686
11687 ctrl = open_wpa_mon(intf);
11688 if (ctrl == NULL) {
11689 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
11690 "wpa_supplicant monitor connection");
11691 return -2;
11692 }
11693
11694 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
11695
11696 if (wpa_command(intf, buf) < 0) {
11697 wpa_ctrl_detach(ctrl);
11698 wpa_ctrl_close(ctrl);
11699 send_resp(dut, conn, SIGMA_ERROR,
11700 "ErrorCode,Failed to start registrar");
11701 return 0;
11702 }
11703
11704 return wps_connection_event(dut, conn, ctrl, intf, 0);
11705}
11706
11707
vamsi krishna9b144002017-09-20 13:28:13 +053011708static int cmd_start_wps_registration(struct sigma_dut *dut,
11709 struct sigma_conn *conn,
11710 struct sigma_cmd *cmd)
11711{
11712 struct wpa_ctrl *ctrl;
11713 const char *intf = get_param(cmd, "Interface");
11714 const char *role, *method;
11715 int res;
11716 char buf[256];
11717 const char *events[] = {
11718 "CTRL-EVENT-CONNECTED",
11719 "WPS-OVERLAP-DETECTED",
11720 "WPS-TIMEOUT",
11721 "WPS-FAIL",
11722 NULL
11723 };
11724
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020011725 /* 60G WPS tests do not pass Interface parameter */
11726 if (!intf)
11727 intf = get_main_ifname();
11728
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020011729 if (dut->force_rsn_ie) {
11730 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
11731 dut->force_rsn_ie);
11732 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
11733 sigma_dut_print(dut, DUT_MSG_INFO,
11734 "Failed to force RSN_IE");
11735 return SIGMA_DUT_ERROR_CALLER_SEND_STATUS;
11736 }
11737 }
11738
vamsi krishna9b144002017-09-20 13:28:13 +053011739 ctrl = open_wpa_mon(intf);
11740 if (!ctrl) {
11741 sigma_dut_print(dut, DUT_MSG_ERROR,
11742 "Failed to open wpa_supplicant monitor connection");
11743 return -2;
11744 }
11745
11746 role = get_param(cmd, "WpsRole");
11747 if (!role) {
11748 send_resp(dut, conn, SIGMA_INVALID,
11749 "ErrorCode,WpsRole not provided");
11750 goto fail;
11751 }
11752
11753 if (strcasecmp(role, "Enrollee") == 0) {
11754 method = get_param(cmd, "WpsConfigMethod");
11755 if (!method) {
11756 send_resp(dut, conn, SIGMA_INVALID,
11757 "ErrorCode,WpsConfigMethod not provided");
11758 goto fail;
11759 }
11760 if (strcasecmp(method, "PBC") == 0) {
11761 if (wpa_command(intf, "WPS_PBC") < 0) {
11762 send_resp(dut, conn, SIGMA_ERROR,
11763 "ErrorCode,Failed to enable PBC");
11764 goto fail;
11765 }
11766 } else {
11767 /* TODO: PIN method */
11768 send_resp(dut, conn, SIGMA_ERROR,
11769 "ErrorCode,Unsupported WpsConfigMethod value");
11770 goto fail;
11771 }
11772 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
11773 if (res < 0) {
11774 send_resp(dut, conn, SIGMA_ERROR,
11775 "ErrorCode,WPS connection did not complete");
11776 goto fail;
11777 }
11778 if (strstr(buf, "WPS-TIMEOUT")) {
11779 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
11780 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
11781 send_resp(dut, conn, SIGMA_ERROR,
11782 "ErrorCode,OverlapSession");
11783 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
11784 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
11785 } else {
11786 send_resp(dut, conn, SIGMA_ERROR,
11787 "ErrorCode,WPS operation failed");
11788 }
11789 } else {
11790 /* TODO: Registrar role */
11791 send_resp(dut, conn, SIGMA_ERROR,
11792 "ErrorCode,Unsupported WpsRole value");
11793 }
11794
11795fail:
11796 wpa_ctrl_detach(ctrl);
11797 wpa_ctrl_close(ctrl);
11798 return 0;
11799}
11800
11801
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011802static int req_intf(struct sigma_cmd *cmd)
11803{
11804 return get_param(cmd, "interface") == NULL ? -1 : 0;
11805}
11806
11807
11808void sta_register_cmds(void)
11809{
11810 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
11811 cmd_sta_get_ip_config);
11812 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
11813 cmd_sta_set_ip_config);
11814 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
11815 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
11816 cmd_sta_get_mac_address);
11817 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
11818 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
11819 cmd_sta_verify_ip_connection);
11820 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
11821 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
11822 cmd_sta_set_encryption);
11823 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
11824 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
11825 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
11826 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
11827 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
11828 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
11829 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
11830 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
11831 cmd_sta_set_eapakaprime);
11832 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
11833 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
11834 /* TODO: sta_set_ibss */
11835 /* TODO: sta_set_mode */
11836 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
11837 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
11838 /* TODO: sta_up_load */
11839 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
11840 cmd_sta_preset_testparameters);
11841 /* TODO: sta_set_system */
11842 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
11843 /* TODO: sta_set_rifs_test */
11844 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
11845 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
11846 /* TODO: sta_send_coexist_mgmt */
11847 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
11848 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
11849 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
11850 sigma_dut_reg_cmd("sta_reset_default", req_intf,
11851 cmd_sta_reset_default);
11852 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
11853 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
11854 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
11855 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
11856 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
11857 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
11858 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
11859 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
11860 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
11861 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030011862 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
11863 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011864 sigma_dut_reg_cmd("sta_add_credential", req_intf,
11865 cmd_sta_add_credential);
11866 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020011867 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011868 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
11869 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
11870 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
11871 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
11872 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
11873 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030011874 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011875 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
11876 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020011877 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053011878 cmd_start_wps_registration);
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011879 sigma_dut_reg_cmd("sta_set_power_save", req_intf,
11880 cmd_sta_set_power_save);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011881}