blob: 7198aebf2d132218c3bf46aa5c8402c7528afaff [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>
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030014#include <ctype.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015#ifdef __linux__
Lior Davidcc88b562017-01-03 18:52:09 +020016#include <regex.h>
17#include <dirent.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020018#include <sys/time.h>
19#include <netpacket/packet.h>
20#include <linux/if_ether.h>
21#ifdef ANDROID
22#include <cutils/properties.h>
23#include <android/log.h>
24#include "keystore_get.h"
25#else /* ANDROID */
26#include <ifaddrs.h>
27#endif /* ANDROID */
28#include <netdb.h>
29#endif /* __linux__ */
30#ifdef __QNXNTO__
31#include <net/if_dl.h>
32#endif /* __QNXNTO__ */
33#include "wpa_ctrl.h"
34#include "wpa_helpers.h"
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070035#include "miracast.h"
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070036#include "qca-vendor_copy.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020037
38/* Temporary files for sta_send_addba */
39#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
40#define VI_QOS_FILE "/tmp/vi-qos.txt"
41#define VI_QOS_REFFILE "/etc/vi-qos.txt"
42
43/*
44 * MTU for Ethernet need to take into account 8-byte SNAP header
45 * to be added when encapsulating Ethernet frame into 802.11
46 */
47#ifndef IEEE80211_MAX_DATA_LEN_DMG
48#define IEEE80211_MAX_DATA_LEN_DMG 7920
49#endif
50#ifndef IEEE80211_SNAP_LEN_DMG
51#define IEEE80211_SNAP_LEN_DMG 8
52#endif
53
Ashwini Patil00402582017-04-13 12:29:39 +053054#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053055#define NEIGHBOR_REPORT_SIZE 1000
56#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
57#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053058
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030059#define WIL_DEFAULT_BI 100
60
61/* default remain on channel time for transmitting frames (milliseconds) */
62#define WIL_TRANSMIT_FRAME_DEFAULT_ROC 500
63#define IEEE80211_P2P_ATTR_DEVICE_ID 3
64#define IEEE80211_P2P_ATTR_GROUP_ID 15
65
66/* describes tagged bytes in template frame file */
67struct template_frame_tag {
68 int num;
69 int offset;
70 size_t len;
71};
72
Jouni Malinencd4e3c32015-10-29 12:39:56 +020073extern char *sigma_wpas_ctrl;
74extern char *sigma_cert_path;
75extern enum driver_type wifi_chip_type;
76extern char *sigma_radio_ifname[];
77
Lior David0fe101e2017-03-09 16:09:50 +020078#ifdef __linux__
79#define WIL_WMI_MAX_PAYLOAD 248
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020080#define WIL_WMI_ESE_CFG_CMDID 0xa01
Lior David0fe101e2017-03-09 16:09:50 +020081#define WIL_WMI_BF_TRIG_CMDID 0x83a
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020082#define WIL_WMI_UNIT_TEST_CMDID 0x900
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030083#define WIL_WMI_P2P_CFG_CMDID 0x910
84#define WIL_WMI_START_LISTEN_CMDID 0x914
85#define WIL_WMI_DISCOVERY_STOP_CMDID 0x917
Lior David0fe101e2017-03-09 16:09:50 +020086
87struct wil_wmi_header {
88 uint8_t mid;
89 uint8_t reserved;
90 uint16_t cmd;
91 uint32_t ts;
92} __attribute__((packed));
93
94enum wil_wmi_bf_trig_type {
95 WIL_WMI_SLS,
96 WIL_WMI_BRP_RX,
97 WIL_WMI_BRP_TX,
98};
99
100struct wil_wmi_bf_trig_cmd {
101 /* enum wil_wmi_bf_trig_type */
102 uint32_t bf_type;
103 /* cid when type == WMI_BRP_RX */
104 uint32_t sta_id;
105 uint32_t reserved;
106 /* mac address when type = WIL_WMI_SLS */
107 uint8_t dest_mac[6];
108} __attribute__((packed));
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200109
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200110enum wil_wmi_sched_scheme_advertisment {
111 WIL_WMI_ADVERTISE_ESE_DISABLED,
112 WIL_WMI_ADVERTISE_ESE_IN_BEACON,
113 WIL_WMI_ADVERTISE_ESE_IN_ANNOUNCE_FRAME,
114};
115
116enum wil_wmi_ese_slot_type {
117 WIL_WMI_ESE_SP,
118 WIL_WMI_ESE_CBAP,
119 WIL_WMI_ESE_ANNOUNCE_NO_ACK,
120};
121
122struct wil_wmi_ese_slot {
123 /* offset from start of BI in microseconds */
124 uint32_t tbtt_offset;
125 uint8_t flags;
126 /* enum wil_wmi_ese_slot_type */
127 uint8_t slot_type;
128 /* duration in microseconds */
129 uint16_t duration;
130 /* frame exchange sequence duration, microseconds */
131 uint16_t tx_op;
132 /* time between 2 blocks for periodic allocation(microseconds) */
133 uint16_t period;
134 /* number of blocks in periodic allocation */
135 uint8_t num_blocks;
136 /* for semi-active allocations */
137 uint8_t idle_period;
138 uint8_t src_aid;
139 uint8_t dst_aid;
140 uint32_t reserved;
141} __attribute__((packed));
142
143#define WIL_WMI_MAX_ESE_SLOTS 4
144struct wil_wmi_ese_cfg {
145 uint8_t serial_num;
146 /* wil_wmi_sched_scheme_advertisment */
147 uint8_t ese_advertisment;
148 uint16_t flags;
149 uint8_t num_allocs;
150 uint8_t reserved[3];
151 uint64_t start_tbtt;
152 /* allocations list */
153 struct wil_wmi_ese_slot slots[WIL_WMI_MAX_ESE_SLOTS];
154} __attribute__((packed));
155
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200156#define WIL_WMI_UT_FORCE_MCS 6
157struct wil_wmi_force_mcs {
158 /* WIL_WMI_UT_HW_SYSAPI */
159 uint16_t module_id;
160 /* WIL_WMI_UT_FORCE_MCS */
161 uint16_t subtype_id;
162 /* cid (ignored in oob_mode, affects all stations) */
163 uint32_t cid;
164 /* 1 to force MCS, 0 to restore default behavior */
165 uint32_t force_enable;
166 /* MCS index, 0-12 */
167 uint32_t mcs;
168} __attribute__((packed));
169
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200170#define WIL_WMI_UT_HW_SYSAPI 10
171#define WIL_WMI_UT_FORCE_RSN_IE 0x29
172struct wil_wmi_force_rsn_ie {
173 /* WIL_WMI_UT_HW_SYSAPI */
174 uint16_t module_id;
175 /* WIL_WMI_UT_FORCE_RSN_IE */
176 uint16_t subtype_id;
177 /* 0 = no change, 1 = remove if exists, 2 = add if does not exist */
178 uint32_t state;
179} __attribute__((packed));
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300180
181enum wil_wmi_discovery_mode {
182 WMI_DISCOVERY_MODE_NON_OFFLOAD,
183 WMI_DISCOVERY_MODE_OFFLOAD,
184 WMI_DISCOVERY_MODE_PEER2PEER,
185};
186
187struct wil_wmi_p2p_cfg_cmd {
188 /* enum wil_wmi_discovery_mode */
189 uint8_t discovery_mode;
190 /* 0-based (wireless channel - 1) */
191 uint8_t channel;
192 /* set to WIL_DEFAULT_BI */
193 uint16_t bcon_interval;
194} __attribute__((packed));
Lior David0fe101e2017-03-09 16:09:50 +0200195#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200196
197#ifdef ANDROID
198
199static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
200
201#define ANDROID_KEYSTORE_GET 'g'
202#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
203
204static int android_keystore_get(char cmd, const char *key, unsigned char *val)
205{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200206 /* Android 4.3 changed keystore design, so need to use keystore_get() */
207#ifndef KEYSTORE_MESSAGE_SIZE
208#define KEYSTORE_MESSAGE_SIZE 65535
209#endif /* KEYSTORE_MESSAGE_SIZE */
210
211 ssize_t len;
212 uint8_t *value = NULL;
213
214 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
215 "keystore command '%c' key '%s' --> keystore_get",
216 cmd, key);
217
218 len = keystore_get(key, strlen(key), &value);
219 if (len < 0) {
220 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
221 "keystore_get() failed");
222 return -1;
223 }
224
225 if (len > KEYSTORE_MESSAGE_SIZE)
226 len = KEYSTORE_MESSAGE_SIZE;
227 memcpy(val, value, len);
228 free(value);
229 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200230}
231#endif /* ANDROID */
232
233
234int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
235{
236#ifdef __linux__
237 char buf[100];
238
239 if (wifi_chip_type == DRIVER_WCN) {
240 if (enabled) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530241 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
242 intf);
243 if (system(buf) != 0) {
244 snprintf(buf, sizeof(buf),
245 "iwpriv wlan0 dump 906");
246 if (system(buf) != 0)
247 goto set_power_save;
248 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200249 } else {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530250 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
251 intf);
252 if (system(buf) != 0) {
253 snprintf(buf, sizeof(buf),
254 "iwpriv wlan0 dump 905");
255 if (system(buf) != 0)
256 goto set_power_save;
257 snprintf(buf, sizeof(buf),
258 "iwpriv wlan0 dump 912");
259 if (system(buf) != 0)
260 goto set_power_save;
261 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200262 }
263
264 return 0;
265 }
266
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530267set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200268 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
269 intf, enabled ? "on" : "off");
270 if (system(buf) != 0) {
271 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
272 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530273 if (system(buf) != 0) {
274 sigma_dut_print(dut, DUT_MSG_ERROR,
275 "Failed to set power save %s",
276 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200277 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530278 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200279 }
280
281 return 0;
282#else /* __linux__ */
283 return -1;
284#endif /* __linux__ */
285}
286
287
Lior Davidcc88b562017-01-03 18:52:09 +0200288#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200289
Lior Davidcc88b562017-01-03 18:52:09 +0200290static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
291 size_t len)
292{
293 DIR *dir, *wil_dir;
294 struct dirent *entry;
295 int ret = -1;
296 const char *root_path = "/sys/kernel/debug/ieee80211";
297
298 dir = opendir(root_path);
299 if (!dir)
300 return -2;
301
302 while ((entry = readdir(dir))) {
303 if (strcmp(entry->d_name, ".") == 0 ||
304 strcmp(entry->d_name, "..") == 0)
305 continue;
306
307 if (snprintf(path, len, "%s/%s/wil6210",
308 root_path, entry->d_name) >= (int) len) {
309 ret = -3;
310 break;
311 }
312
313 wil_dir = opendir(path);
314 if (wil_dir) {
315 closedir(wil_dir);
316 ret = 0;
317 break;
318 }
319 }
320
321 closedir(dir);
322 return ret;
323}
Lior David0fe101e2017-03-09 16:09:50 +0200324
325
326static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
327 void *payload, uint16_t length)
328{
329 struct {
330 struct wil_wmi_header hdr;
331 char payload[WIL_WMI_MAX_PAYLOAD];
332 } __attribute__((packed)) cmd;
333 char buf[128], fname[128];
334 size_t towrite, written;
335 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300336 int res;
Lior David0fe101e2017-03-09 16:09:50 +0200337
338 if (length > WIL_WMI_MAX_PAYLOAD) {
339 sigma_dut_print(dut, DUT_MSG_ERROR,
340 "payload too large(%u, max %u)",
341 length, WIL_WMI_MAX_PAYLOAD);
342 return -1;
343 }
344
345 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
346 cmd.hdr.cmd = command;
347 memcpy(cmd.payload, payload, length);
348
349 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
350 sigma_dut_print(dut, DUT_MSG_ERROR,
351 "failed to get wil6210 debugfs dir");
352 return -1;
353 }
354
Jouni Malinen3aa72862019-05-29 23:14:51 +0300355 res = snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
356 if (res < 0 || res >= sizeof(fname))
357 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200358 f = fopen(fname, "wb");
359 if (!f) {
360 sigma_dut_print(dut, DUT_MSG_ERROR,
361 "failed to open: %s", fname);
362 return -1;
363 }
364
365 towrite = sizeof(cmd.hdr) + length;
366 written = fwrite(&cmd, 1, towrite, f);
367 fclose(f);
368 if (written != towrite) {
369 sigma_dut_print(dut, DUT_MSG_ERROR,
370 "failed to send wmi %u", command);
371 return -1;
372 }
373
374 return 0;
375}
376
377
378static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
379 const char *pattern, unsigned int *field)
380{
381 char buf[128], fname[128];
382 FILE *f;
383 regex_t re;
384 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +0300385 int rc, ret = -1, res;
Lior David0fe101e2017-03-09 16:09:50 +0200386
387 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
388 sigma_dut_print(dut, DUT_MSG_ERROR,
389 "failed to get wil6210 debugfs dir");
390 return -1;
391 }
392
Jouni Malinen3aa72862019-05-29 23:14:51 +0300393 res = snprintf(fname, sizeof(fname), "%s/stations", buf);
394 if (res < 0 || res >= sizeof(fname))
395 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200396 f = fopen(fname, "r");
397 if (!f) {
398 sigma_dut_print(dut, DUT_MSG_ERROR,
399 "failed to open: %s", fname);
400 return -1;
401 }
402
403 if (regcomp(&re, pattern, REG_EXTENDED)) {
404 sigma_dut_print(dut, DUT_MSG_ERROR,
405 "regcomp failed: %s", pattern);
406 goto out;
407 }
408
409 /*
410 * find the entry for the mac address
411 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
412 */
413 while (fgets(buf, sizeof(buf), f)) {
414 if (strcasestr(buf, bssid)) {
415 /* extract the field (CID/AID/state) */
416 rc = regexec(&re, buf, 2, m, 0);
417 if (!rc && (m[1].rm_so >= 0)) {
418 buf[m[1].rm_eo] = 0;
419 *field = atoi(&buf[m[1].rm_so]);
420 ret = 0;
421 break;
422 }
423 }
424 }
425
426 regfree(&re);
427 if (ret)
428 sigma_dut_print(dut, DUT_MSG_ERROR,
429 "could not extract field");
430
431out:
432 fclose(f);
433
434 return ret;
435}
436
437
438static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
439 unsigned int *cid)
440{
441 const char *pattern = "\\[([0-9]+)\\]";
442
443 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
444}
445
446
447static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
448 int l_rx)
449{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700450 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200451 unsigned int cid;
452
Rakesh Sunki556237d2017-03-30 14:49:31 -0700453 memset(&cmd, 0, sizeof(cmd));
454
Lior David0fe101e2017-03-09 16:09:50 +0200455 if (wil6210_get_cid(dut, mac, &cid))
456 return -1;
457
458 cmd.bf_type = WIL_WMI_BRP_RX;
459 cmd.sta_id = cid;
460 /* training length (l_rx) is ignored, FW always uses length 16 */
461 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
462 &cmd, sizeof(cmd));
463}
464
465
466static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
467{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700468 struct wil_wmi_bf_trig_cmd cmd;
469
470 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200471
472 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
473 return -1;
474
475 cmd.bf_type = WIL_WMI_SLS;
476 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
477 &cmd, sizeof(cmd));
478}
479
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200480
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200481int wil6210_set_ese(struct sigma_dut *dut, int count,
482 struct sigma_ese_alloc *allocs)
483{
484 struct wil_wmi_ese_cfg cmd = { };
485 int i;
486
487 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
488 return -1;
489
490 if (dut->ap_bcnint <= 0) {
491 sigma_dut_print(dut, DUT_MSG_ERROR,
492 "invalid beacon interval(%d), check test",
493 dut->ap_bcnint);
494 return -1;
495 }
496
497 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
498 cmd.flags = 0x1d;
499 cmd.num_allocs = count;
500 for (i = 0; i < count; i++) {
501 /*
502 * Convert percent from BI (BI specified in milliseconds)
503 * to absolute duration in microseconds.
504 */
505 cmd.slots[i].duration =
506 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
507 switch (allocs[i].type) {
508 case ESE_CBAP:
509 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
510 break;
511 case ESE_SP:
512 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
513 break;
514 default:
515 sigma_dut_print(dut, DUT_MSG_ERROR,
516 "invalid slot type(%d) at index %d",
517 allocs[i].type, i);
518 return -1;
519 }
520 cmd.slots[i].src_aid = allocs[i].src_aid;
521 cmd.slots[i].dst_aid = allocs[i].dst_aid;
522 sigma_dut_print(dut, DUT_MSG_INFO,
523 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
524 i, cmd.slots[i].duration,
525 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
526 cmd.slots[i].dst_aid);
527 }
528
529 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
530}
531
532
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200533int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
534{
535 struct wil_wmi_force_mcs cmd = { };
536
537 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
538 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
539 cmd.force_enable = (uint32_t) force;
540 cmd.mcs = (uint32_t) mcs;
541
542 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
543 &cmd, sizeof(cmd));
544}
545
546
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200547static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
548{
549 struct wil_wmi_force_rsn_ie cmd = { };
550
551 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
552 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
553 cmd.state = (uint32_t) state;
554
555 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
556 &cmd, sizeof(cmd));
557}
558
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300559
560/*
561 * this function is also used to configure generic remain-on-channel
562 */
563static int wil6210_p2p_cfg(struct sigma_dut *dut, int freq)
564{
565 struct wil_wmi_p2p_cfg_cmd cmd = { };
566 int channel = freq_to_channel(freq);
567
568 if (channel < 0)
569 return -1;
570 cmd.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD;
571 cmd.channel = channel - 1;
572 cmd.bcon_interval = WIL_DEFAULT_BI;
573 cmd.discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER;
574
575 return wil6210_wmi_send(dut, WIL_WMI_P2P_CFG_CMDID,
576 &cmd, sizeof(cmd));
577}
578
579
580static int wil6210_remain_on_channel(struct sigma_dut *dut, int freq)
581{
582 int ret = wil6210_p2p_cfg(dut, freq);
583
584 if (ret)
585 return ret;
586
587 ret = wil6210_wmi_send(dut, WIL_WMI_START_LISTEN_CMDID, NULL, 0);
588 if (!ret) {
589 /*
590 * wait a bit to allow FW to setup the radio
591 * especially important if we switch channels
592 */
593 usleep(500000);
594 }
595
596 return ret;
597}
598
599
600static int wil6210_stop_discovery(struct sigma_dut *dut)
601{
602 return wil6210_wmi_send(dut, WIL_WMI_DISCOVERY_STOP_CMDID, NULL, 0);
603}
604
605
606static int wil6210_transmit_frame(struct sigma_dut *dut, int freq,
607 int wait_duration,
608 const char *frame, size_t frame_len)
609{
610 char buf[128], fname[128];
611 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300612 int res = 0, r;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300613 size_t written;
614
615 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
616 sigma_dut_print(dut, DUT_MSG_ERROR,
617 "failed to get wil6210 debugfs dir");
618 return -1;
619 }
Jouni Malinen3aa72862019-05-29 23:14:51 +0300620 r = snprintf(fname, sizeof(fname), "%s/tx_mgmt", buf);
621 if (r < 0 || r >= sizeof(fname))
622 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300623
624 if (wil6210_remain_on_channel(dut, freq)) {
625 sigma_dut_print(dut, DUT_MSG_ERROR,
626 "failed to listen on channel");
627 return -1;
628 }
629
630 f = fopen(fname, "wb");
631 if (!f) {
632 sigma_dut_print(dut, DUT_MSG_ERROR,
633 "failed to open: %s", fname);
634 res = -1;
635 goto out_stop;
636 }
637 written = fwrite(frame, 1, frame_len, f);
638 fclose(f);
639
640 if (written != frame_len) {
641 sigma_dut_print(dut, DUT_MSG_ERROR,
642 "failed to transmit frame (got %zd, expected %zd)",
643 written, frame_len);
644 res = -1;
645 goto out_stop;
646 }
647
648 usleep(wait_duration * 1000);
649
650out_stop:
651 wil6210_stop_discovery(dut);
652 return res;
653}
654
655
656static int find_template_frame_tag(struct template_frame_tag *tags,
657 int total_tags, int tag_num)
658{
659 int i;
660
661 for (i = 0; i < total_tags; i++) {
662 if (tag_num == tags[i].num)
663 return i;
664 }
665
666 return -1;
667}
668
669
670static int replace_p2p_attribute(struct sigma_dut *dut, char *buf, size_t len,
671 int id, const char *value, size_t val_len)
672{
673 struct wfa_p2p_attribute *attr = (struct wfa_p2p_attribute *) buf;
674
675 if (len < 3 + val_len) {
676 sigma_dut_print(dut, DUT_MSG_ERROR,
677 "not enough space to replace P2P attribute");
678 return -1;
679 }
680
681 if (attr->len != val_len) {
682 sigma_dut_print(dut, DUT_MSG_ERROR,
683 "attribute length mismatch (need %zu have %hu)",
684 val_len, attr->len);
685 return -1;
686 }
687
688 if (attr->id != id) {
689 sigma_dut_print(dut, DUT_MSG_ERROR,
690 "incorrect attribute id (expected %d actual %d)",
691 id, attr->id);
692 return -1;
693 }
694
695 memcpy(attr->variable, value, val_len);
696
697 return 0;
698}
699
700
701static int parse_template_frame_file(struct sigma_dut *dut, const char *fname,
702 char *buf, size_t *length,
703 struct template_frame_tag *tags,
704 size_t *num_tags)
705{
706 char line[512];
707 FILE *f;
708 size_t offset = 0, tag_index = 0;
709 int num, index;
710 int in_tag = 0, tag_num = 0, tag_offset = 0;
711
712 if (*length < sizeof(struct ieee80211_hdr_3addr)) {
713 sigma_dut_print(dut, DUT_MSG_ERROR,
714 "supplied buffer is too small");
715 return -1;
716 }
717
718 f = fopen(fname, "r");
719 if (!f) {
720 sigma_dut_print(dut, DUT_MSG_ERROR,
721 "failed to open template file %s", fname);
722 return -1;
723 }
724
725 /*
726 * template file format: lines beginning with # are comments and
727 * ignored.
728 * It is possible to tag bytes in the frame to make it easy
729 * to replace fields in the template, espcially if they appear
730 * in variable-sized sections (such as IEs)
731 * This is done by a line beginning with $NUM where NUM is an integer
732 * tag number. It can be followed by space(s) and comment.
733 * The next line is considered the tagged bytes. The parser will fill
734 * the tag number, offset and length of the tagged bytes.
735 * rest of the lines contain frame bytes as sequence of hex digits,
736 * 2 digits for each byte. Spaces are allowed between bytes.
737 * On bytes lines only hex digits and spaces are allowed
738 */
739 while (!feof(f)) {
740 if (!fgets(line, sizeof(line), f))
741 break;
742 index = 0;
743 while (isspace((unsigned char) line[index]))
744 index++;
745 if (!line[index] || line[index] == '#')
746 continue;
747 if (line[index] == '$') {
748 if (tags) {
749 index++;
750 tag_num = strtol(&line[index], NULL, 0);
751 tag_offset = offset;
752 in_tag = 1;
753 }
754 continue;
755 }
756 while (line[index]) {
757 if (isspace((unsigned char) line[index])) {
758 index++;
759 continue;
760 }
761 num = hex_byte(&line[index]);
762 if (num < 0)
763 break;
764 buf[offset++] = num;
765 if (offset == *length)
766 goto out;
767 index += 2;
768 }
769
770 if (in_tag) {
771 if (tag_index < *num_tags) {
772 tags[tag_index].num = tag_num;
773 tags[tag_index].offset = tag_offset;
774 tags[tag_index].len = offset - tag_offset;
775 tag_index++;
776 } else {
777 sigma_dut_print(dut, DUT_MSG_INFO,
778 "too many tags, tag ignored");
779 }
780 in_tag = 0;
781 }
782 }
783
784 if (num_tags)
785 *num_tags = tag_index;
786out:
787 fclose(f);
788 if (offset < sizeof(struct ieee80211_hdr_3addr)) {
789 sigma_dut_print(dut, DUT_MSG_ERROR,
790 "template frame is too small");
791 return -1;
792 }
793
794 *length = offset;
795 return 0;
796}
797
Lior Davidcc88b562017-01-03 18:52:09 +0200798#endif /* __linux__ */
799
800
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200801static void static_ip_file(int proto, const char *addr, const char *mask,
802 const char *gw)
803{
804 if (proto) {
805 FILE *f = fopen("static-ip", "w");
806 if (f) {
807 fprintf(f, "%d %s %s %s\n", proto, addr,
808 mask ? mask : "N/A",
809 gw ? gw : "N/A");
810 fclose(f);
811 }
812 } else {
813 unlink("static-ip");
814 }
815}
816
817
818static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
819 const char *ssid)
820{
821#ifdef __linux__
822 char buf[100];
823
824 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
825 intf, ssid);
826 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
827
828 if (system(buf) != 0) {
829 sigma_dut_print(dut, DUT_MSG_ERROR,
830 "iwpriv neighbor request failed");
831 return -1;
832 }
833
834 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
835
836 return 0;
837#else /* __linux__ */
838 return -1;
839#endif /* __linux__ */
840}
841
842
843static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530844 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200845{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530846 const char *val;
847 int reason_code = 0;
848 char buf[1024];
849
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200850 /*
851 * In the earlier builds we used WNM_QUERY and in later
852 * builds used WNM_BSS_QUERY.
853 */
854
Ashwini Patil5acd7382017-04-13 15:55:04 +0530855 val = get_param(cmd, "BTMQuery_Reason_Code");
856 if (val)
857 reason_code = atoi(val);
858
859 val = get_param(cmd, "Cand_List");
860 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
861 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
862 dut->btm_query_cand_list);
863 free(dut->btm_query_cand_list);
864 dut->btm_query_cand_list = NULL;
865 } else {
866 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
867 }
868
869 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200870 sigma_dut_print(dut, DUT_MSG_ERROR,
871 "transition management query failed");
872 return -1;
873 }
874
875 sigma_dut_print(dut, DUT_MSG_DEBUG,
876 "transition management query sent");
877
878 return 0;
879}
880
881
882int is_ip_addr(const char *str)
883{
884 const char *pos = str;
885 struct in_addr addr;
886
887 while (*pos) {
888 if (*pos != '.' && (*pos < '0' || *pos > '9'))
889 return 0;
890 pos++;
891 }
892
893 return inet_aton(str, &addr);
894}
895
896
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200897int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
898 size_t buf_len)
899{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530900 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200901 char ip[16], mask[15], dns[16], sec_dns[16];
902 int is_dhcp = 0;
903 int s;
904#ifdef ANDROID
905 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530906#else /* ANDROID */
907 FILE *f;
908#ifdef __linux__
909 const char *str_ps;
910#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200911#endif /* ANDROID */
912
913 ip[0] = '\0';
914 mask[0] = '\0';
915 dns[0] = '\0';
916 sec_dns[0] = '\0';
917
918 s = socket(PF_INET, SOCK_DGRAM, 0);
919 if (s >= 0) {
920 struct ifreq ifr;
921 struct sockaddr_in saddr;
922
923 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700924 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200925 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
926 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
927 "%s IP address: %s",
928 ifname, strerror(errno));
929 } else {
930 memcpy(&saddr, &ifr.ifr_addr,
931 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700932 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200933 }
934
935 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
936 memcpy(&saddr, &ifr.ifr_addr,
937 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700938 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200939 }
940 close(s);
941 }
942
943#ifdef ANDROID
944 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
945 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
946 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
947 if (property_get(tmp, prop, NULL) != 0 &&
948 strcmp(prop, "ok") == 0) {
949 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
950 ifname);
951 if (property_get(tmp, prop, NULL) != 0 &&
952 strcmp(ip, prop) == 0)
953 is_dhcp = 1;
954 }
955 }
956
957 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700958 if (property_get(tmp, prop, NULL) != 0)
959 strlcpy(dns, prop, sizeof(dns));
960 else if (property_get("net.dns1", prop, NULL) != 0)
961 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200962
963 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -0700964 if (property_get(tmp, prop, NULL) != 0)
965 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200966#else /* ANDROID */
967#ifdef __linux__
Jouni Malinen016ae6c2019-11-04 17:00:01 +0200968 if (get_driver_type(dut) == DRIVER_OPENWRT)
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530969 str_ps = "ps -w";
970 else
971 str_ps = "ps ax";
972 snprintf(tmp, sizeof(tmp),
973 "%s | grep dhclient | grep -v grep | grep -q %s",
974 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200975 if (system(tmp) == 0)
976 is_dhcp = 1;
977 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530978 snprintf(tmp, sizeof(tmp),
979 "%s | grep udhcpc | grep -v grep | grep -q %s",
980 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200981 if (system(tmp) == 0)
982 is_dhcp = 1;
983 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +0530984 snprintf(tmp, sizeof(tmp),
985 "%s | grep dhcpcd | grep -v grep | grep -q %s",
986 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200987 if (system(tmp) == 0)
988 is_dhcp = 1;
989 }
990 }
991#endif /* __linux__ */
992
993 f = fopen("/etc/resolv.conf", "r");
994 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +0530995 char *pos, *pos2;
996
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200997 while (fgets(tmp, sizeof(tmp), f)) {
998 if (strncmp(tmp, "nameserver", 10) != 0)
999 continue;
1000 pos = tmp + 10;
1001 while (*pos == ' ' || *pos == '\t')
1002 pos++;
1003 pos2 = pos;
1004 while (*pos2) {
1005 if (*pos2 == '\n' || *pos2 == '\r') {
1006 *pos2 = '\0';
1007 break;
1008 }
1009 pos2++;
1010 }
Peng Xub8fc5cc2017-05-10 17:27:28 -07001011 if (!dns[0])
1012 strlcpy(dns, pos, sizeof(dns));
1013 else if (!sec_dns[0])
1014 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001015 }
1016 fclose(f);
1017 }
1018#endif /* ANDROID */
1019
1020 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
1021 is_dhcp, ip, mask, dns);
1022 buf[buf_len - 1] = '\0';
1023
1024 return 0;
1025}
1026
1027
1028
1029
1030int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
1031 size_t buf_len)
1032{
1033#ifdef __linux__
1034#ifdef ANDROID
1035 char cmd[200], result[1000], *pos, *end;
1036 FILE *f;
1037 size_t len;
1038
1039 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
1040 f = popen(cmd, "r");
1041 if (f == NULL)
1042 return -1;
1043 len = fread(result, 1, sizeof(result) - 1, f);
1044 pclose(f);
1045 if (len == 0)
1046 return -1;
1047 result[len] = '\0';
1048 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
1049
1050 pos = strstr(result, "inet6 ");
1051 if (pos == NULL)
1052 return -1;
1053 pos += 6;
1054 end = strchr(pos, ' ');
1055 if (end)
1056 *end = '\0';
1057 end = strchr(pos, '/');
1058 if (end)
1059 *end = '\0';
1060 snprintf(buf, buf_len, "ip,%s", pos);
1061 buf[buf_len - 1] = '\0';
1062 return 0;
1063#else /* ANDROID */
1064 struct ifaddrs *ifaddr, *ifa;
1065 int res, found = 0;
1066 char host[NI_MAXHOST];
1067
1068 if (getifaddrs(&ifaddr) < 0) {
1069 perror("getifaddrs");
1070 return -1;
1071 }
1072
1073 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1074 if (strcasecmp(ifname, ifa->ifa_name) != 0)
1075 continue;
1076 if (ifa->ifa_addr == NULL ||
1077 ifa->ifa_addr->sa_family != AF_INET6)
1078 continue;
1079
1080 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
1081 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1082 if (res != 0) {
1083 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
1084 gai_strerror(res));
1085 continue;
1086 }
1087 if (strncmp(host, "fe80::", 6) == 0)
1088 continue; /* skip link-local */
1089
1090 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
1091 found = 1;
1092 break;
1093 }
1094
1095 freeifaddrs(ifaddr);
1096
1097 if (found) {
1098 char *pos;
1099 pos = strchr(host, '%');
1100 if (pos)
1101 *pos = '\0';
1102 snprintf(buf, buf_len, "ip,%s", host);
1103 buf[buf_len - 1] = '\0';
1104 return 0;
1105 }
1106
1107#endif /* ANDROID */
1108#endif /* __linux__ */
1109 return -1;
1110}
1111
1112
Jouni Malinenf7222712019-06-13 01:50:21 +03001113static enum sigma_cmd_result cmd_sta_get_ip_config(struct sigma_dut *dut,
1114 struct sigma_conn *conn,
1115 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001116{
1117 const char *intf = get_param(cmd, "Interface");
1118 const char *ifname;
1119 char buf[200];
1120 const char *val;
1121 int type = 1;
1122
1123 if (intf == NULL)
1124 return -1;
1125
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001126 if (strcmp(intf, get_main_ifname(dut)) == 0)
1127 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001128 else
1129 ifname = intf;
1130
1131 /*
1132 * UCC may assume the IP address to be available immediately after
1133 * association without trying to run sta_get_ip_config multiple times.
1134 * Sigma CAPI does not specify this command as a block command that
1135 * would wait for the address to become available, but to pass tests
1136 * more reliably, it looks like such a wait may be needed here.
1137 */
1138 if (wait_ip_addr(dut, ifname, 15) < 0) {
1139 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
1140 "for sta_get_ip_config");
1141 /*
1142 * Try to continue anyway since many UCC tests do not really
1143 * care about the return value from here..
1144 */
1145 }
1146
1147 val = get_param(cmd, "Type");
1148 if (val)
1149 type = atoi(val);
1150 if (type == 2 || dut->last_set_ip_config_ipv6) {
1151 int i;
1152
1153 /*
1154 * Since we do not have proper wait for IPv6 addresses, use a
1155 * fixed two second delay here as a workaround for UCC script
1156 * assuming IPv6 address is available when this command returns.
1157 * Some scripts did not use Type,2 properly for IPv6, so include
1158 * also the cases where the previous sta_set_ip_config indicated
1159 * use of IPv6.
1160 */
1161 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
1162 for (i = 0; i < 10; i++) {
1163 sleep(1);
1164 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
1165 {
1166 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
1167 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1168#ifdef ANDROID
1169 sigma_dut_print(dut, DUT_MSG_INFO,
1170 "Adding IPv6 rule on Android");
1171 add_ipv6_rule(dut, intf);
1172#endif /* ANDROID */
1173
1174 return 0;
1175 }
1176 }
1177 }
1178 if (type == 1) {
1179 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
1180 return -2;
1181 } else if (type == 2) {
1182 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
1183 return -2;
1184 } else {
1185 send_resp(dut, conn, SIGMA_ERROR,
1186 "errorCode,Unsupported address type");
1187 return 0;
1188 }
1189
1190 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1191 return 0;
1192}
1193
1194
1195static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
1196{
1197#ifdef __linux__
1198 char buf[200];
1199 char path[128];
1200 struct stat s;
1201
1202#ifdef ANDROID
1203 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
1204#else /* ANDROID */
1205 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
1206#endif /* ANDROID */
1207 if (stat(path, &s) == 0) {
1208 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1209 sigma_dut_print(dut, DUT_MSG_INFO,
1210 "Kill previous DHCP client: %s", buf);
1211 if (system(buf) != 0)
1212 sigma_dut_print(dut, DUT_MSG_INFO,
1213 "Failed to kill DHCP client");
1214 unlink(path);
1215 sleep(1);
1216 } else {
1217 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
1218
1219 if (stat(path, &s) == 0) {
1220 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1221 sigma_dut_print(dut, DUT_MSG_INFO,
1222 "Kill previous DHCP client: %s", buf);
1223 if (system(buf) != 0)
1224 sigma_dut_print(dut, DUT_MSG_INFO,
1225 "Failed to kill DHCP client");
1226 unlink(path);
1227 sleep(1);
1228 }
1229 }
1230#endif /* __linux__ */
1231}
1232
1233
1234static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1235{
1236#ifdef __linux__
1237 char buf[200];
1238
1239#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301240 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1241 snprintf(buf, sizeof(buf),
1242 "/system/bin/dhcpcd -b %s", ifname);
1243 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1244 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301245 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1246 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1247 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1248 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301249 } else {
1250 sigma_dut_print(dut, DUT_MSG_ERROR,
1251 "DHCP client program missing");
1252 return 0;
1253 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001254#else /* ANDROID */
1255 snprintf(buf, sizeof(buf),
1256 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1257 ifname, ifname);
1258#endif /* ANDROID */
1259 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1260 if (system(buf) != 0) {
1261 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1262 if (system(buf) != 0) {
1263 sigma_dut_print(dut, DUT_MSG_INFO,
1264 "Failed to start DHCP client");
1265#ifndef ANDROID
1266 return -1;
1267#endif /* ANDROID */
1268 }
1269 }
1270#endif /* __linux__ */
1271
1272 return 0;
1273}
1274
1275
1276static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1277{
1278#ifdef __linux__
1279 char buf[200];
1280
1281 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1282 if (system(buf) != 0) {
1283 sigma_dut_print(dut, DUT_MSG_INFO,
1284 "Failed to clear IP addresses");
1285 return -1;
1286 }
1287#endif /* __linux__ */
1288
1289 return 0;
1290}
1291
1292
1293#ifdef ANDROID
1294static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1295{
1296 char cmd[200], *result, *pos;
1297 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301298 int tableid;
1299 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001300
1301 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1302 ifname);
1303 fp = popen(cmd, "r");
1304 if (fp == NULL)
1305 return -1;
1306
1307 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301308 if (result == NULL) {
1309 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001310 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301311 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001312
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301313 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001314 fclose(fp);
1315
1316 if (len == 0) {
1317 free(result);
1318 return -1;
1319 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301320 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001321
1322 pos = strstr(result, "table ");
1323 if (pos == NULL) {
1324 free(result);
1325 return -1;
1326 }
1327
1328 pos += strlen("table ");
1329 tableid = atoi(pos);
1330 if (tableid != 0) {
1331 if (system("ip -6 rule del prio 22000") != 0) {
1332 /* ignore any error */
1333 }
1334 snprintf(cmd, sizeof(cmd),
1335 "ip -6 rule add from all lookup %d prio 22000",
1336 tableid);
1337 if (system(cmd) != 0) {
1338 sigma_dut_print(dut, DUT_MSG_INFO,
1339 "Failed to run %s", cmd);
1340 free(result);
1341 return -1;
1342 }
1343 } else {
1344 sigma_dut_print(dut, DUT_MSG_INFO,
1345 "No Valid Table Id found %s", pos);
1346 free(result);
1347 return -1;
1348 }
1349 free(result);
1350
1351 return 0;
1352}
1353#endif /* ANDROID */
1354
1355
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301356int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1357 const char *ip, const char *mask)
1358{
1359 char buf[200];
1360
1361 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1362 ifname, ip, mask);
1363 return system(buf) == 0;
1364}
1365
1366
1367int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1368{
1369 char buf[200];
1370
1371 if (!is_ip_addr(gw)) {
1372 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1373 return -1;
1374 }
1375
1376 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1377 if (!dut->no_ip_addr_set && system(buf) != 0) {
1378 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1379 gw);
1380 if (system(buf) != 0)
1381 return 0;
1382 }
1383
1384 return 1;
1385}
1386
1387
Jouni Malinenf7222712019-06-13 01:50:21 +03001388static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1389 struct sigma_conn *conn,
1390 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001391{
1392 const char *intf = get_param(cmd, "Interface");
1393 const char *ifname;
1394 char buf[200];
1395 const char *val, *ip, *mask, *gw;
1396 int type = 1;
1397
1398 if (intf == NULL)
1399 return -1;
1400
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001401 if (strcmp(intf, get_main_ifname(dut)) == 0)
1402 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001403 else
1404 ifname = intf;
1405
1406 if (if_nametoindex(ifname) == 0) {
1407 send_resp(dut, conn, SIGMA_ERROR,
1408 "ErrorCode,Unknown interface");
1409 return 0;
1410 }
1411
1412 val = get_param(cmd, "Type");
1413 if (val) {
1414 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301415 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001416 send_resp(dut, conn, SIGMA_ERROR,
1417 "ErrorCode,Unsupported address type");
1418 return 0;
1419 }
1420 }
1421
1422 dut->last_set_ip_config_ipv6 = 0;
1423
1424 val = get_param(cmd, "dhcp");
1425 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1426 static_ip_file(0, NULL, NULL, NULL);
1427#ifdef __linux__
1428 if (type == 2) {
1429 dut->last_set_ip_config_ipv6 = 1;
1430 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1431 "stateless address autoconfiguration");
1432#ifdef ANDROID
1433 /*
1434 * This sleep is required as the assignment in case of
1435 * Android is taking time and is done by the kernel.
1436 * The subsequent ping for IPv6 is impacting HS20 test
1437 * case.
1438 */
1439 sleep(2);
1440 add_ipv6_rule(dut, intf);
1441#endif /* ANDROID */
1442 /* Assume this happens by default */
1443 return 1;
1444 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301445 if (type != 3) {
1446 kill_dhcp_client(dut, ifname);
1447 if (start_dhcp_client(dut, ifname) < 0)
1448 return -2;
1449 } else {
1450 sigma_dut_print(dut, DUT_MSG_DEBUG,
1451 "Using FILS HLP DHCPv4 Rapid Commit");
1452 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001453
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001454 return 1;
1455#endif /* __linux__ */
1456 return -2;
1457 }
1458
1459 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301460 if (!ip) {
1461 send_resp(dut, conn, SIGMA_INVALID,
1462 "ErrorCode,Missing IP address");
1463 return 0;
1464 }
1465
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001466 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301467 if (!mask) {
1468 send_resp(dut, conn, SIGMA_INVALID,
1469 "ErrorCode,Missing subnet mask");
1470 return 0;
1471 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001472
1473 if (type == 2) {
1474 int net = atoi(mask);
1475
1476 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1477 return -1;
1478
1479 if (dut->no_ip_addr_set) {
1480 snprintf(buf, sizeof(buf),
1481 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1482 ifname);
1483 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1484 if (system(buf) != 0) {
1485 sigma_dut_print(dut, DUT_MSG_DEBUG,
1486 "Failed to disable IPv6 address before association");
1487 }
1488 } else {
1489 snprintf(buf, sizeof(buf),
1490 "ip -6 addr del %s/%s dev %s",
1491 ip, mask, ifname);
1492 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1493 if (system(buf) != 0) {
1494 /*
1495 * This command may fail if the address being
1496 * deleted does not exist. Inaction here is
1497 * intentional.
1498 */
1499 }
1500
1501 snprintf(buf, sizeof(buf),
1502 "ip -6 addr add %s/%s dev %s",
1503 ip, mask, ifname);
1504 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1505 if (system(buf) != 0) {
1506 send_resp(dut, conn, SIGMA_ERROR,
1507 "ErrorCode,Failed to set IPv6 address");
1508 return 0;
1509 }
1510 }
1511
1512 dut->last_set_ip_config_ipv6 = 1;
1513 static_ip_file(6, ip, mask, NULL);
1514 return 1;
1515 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301516 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001517 return -1;
1518 }
1519
1520 kill_dhcp_client(dut, ifname);
1521
1522 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301523 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001524 send_resp(dut, conn, SIGMA_ERROR,
1525 "ErrorCode,Failed to set IP address");
1526 return 0;
1527 }
1528 }
1529
1530 gw = get_param(cmd, "defaultGateway");
1531 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301532 if (set_ipv4_gw(dut, gw) < 1) {
1533 send_resp(dut, conn, SIGMA_ERROR,
1534 "ErrorCode,Failed to set default gateway");
1535 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001536 }
1537 }
1538
1539 val = get_param(cmd, "primary-dns");
1540 if (val) {
1541 /* TODO */
1542 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1543 "setting", val);
1544 }
1545
1546 val = get_param(cmd, "secondary-dns");
1547 if (val) {
1548 /* TODO */
1549 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1550 "setting", val);
1551 }
1552
1553 static_ip_file(4, ip, mask, gw);
1554
1555 return 1;
1556}
1557
1558
Jouni Malinenf7222712019-06-13 01:50:21 +03001559static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1560 struct sigma_conn *conn,
1561 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001562{
1563 /* const char *intf = get_param(cmd, "Interface"); */
1564 /* TODO: could report more details here */
1565 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1566 return 0;
1567}
1568
1569
Jouni Malinenf7222712019-06-13 01:50:21 +03001570static enum sigma_cmd_result cmd_sta_get_mac_address(struct sigma_dut *dut,
1571 struct sigma_conn *conn,
1572 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001573{
1574 /* const char *intf = get_param(cmd, "Interface"); */
1575 char addr[20], resp[50];
1576
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301577 if (dut->dev_role == DEVROLE_STA_CFON)
1578 return sta_cfon_get_mac_address(dut, conn, cmd);
1579
Jouni Malinen9540e012019-11-05 17:08:42 +02001580 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001581 if (get_wpa_status(get_station_ifname(dut), "address",
1582 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001583 return -2;
1584
1585 snprintf(resp, sizeof(resp), "mac,%s", addr);
1586 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1587 return 0;
1588}
1589
1590
Jouni Malinenf7222712019-06-13 01:50:21 +03001591static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1592 struct sigma_conn *conn,
1593 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001594{
1595 /* const char *intf = get_param(cmd, "Interface"); */
1596 int connected = 0;
1597 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001598 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001599 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001600 sigma_dut_print(dut, DUT_MSG_INFO,
1601 "Could not get interface %s status",
1602 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001603 return -2;
1604 }
1605
1606 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1607 if (strncmp(result, "COMPLETED", 9) == 0)
1608 connected = 1;
1609
1610 if (connected)
1611 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1612 else
1613 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1614
1615 return 0;
1616}
1617
1618
Jouni Malinenf7222712019-06-13 01:50:21 +03001619static enum sigma_cmd_result
1620cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1621 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001622{
1623 /* const char *intf = get_param(cmd, "Interface"); */
1624 const char *dst, *timeout;
1625 int wait_time = 90;
1626 char buf[100];
1627 int res;
1628
1629 dst = get_param(cmd, "destination");
1630 if (dst == NULL || !is_ip_addr(dst))
1631 return -1;
1632
1633 timeout = get_param(cmd, "timeout");
1634 if (timeout) {
1635 wait_time = atoi(timeout);
1636 if (wait_time < 1)
1637 wait_time = 1;
1638 }
1639
1640 /* TODO: force renewal of IP lease if DHCP is enabled */
1641
1642 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1643 res = system(buf);
1644 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1645 if (res == 0)
1646 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1647 else if (res == 256)
1648 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1649 else
1650 return -2;
1651
1652 return 0;
1653}
1654
1655
Jouni Malinenf7222712019-06-13 01:50:21 +03001656static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1657 struct sigma_conn *conn,
1658 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001659{
1660 /* const char *intf = get_param(cmd, "Interface"); */
1661 char bssid[20], resp[50];
1662
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001663 if (get_wpa_status(get_station_ifname(dut), "bssid",
1664 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001665 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001666
1667 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1668 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1669 return 0;
1670}
1671
1672
1673#ifdef __SAMSUNG__
1674static int add_use_network(const char *ifname)
1675{
1676 char buf[100];
1677
1678 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1679 wpa_command(ifname, buf);
1680 return 0;
1681}
1682#endif /* __SAMSUNG__ */
1683
1684
1685static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1686 const char *ifname, struct sigma_cmd *cmd)
1687{
1688 const char *ssid = get_param(cmd, "ssid");
1689 int id;
1690 const char *val;
1691
1692 if (ssid == NULL)
1693 return -1;
1694
1695 start_sta_mode(dut);
1696
1697#ifdef __SAMSUNG__
1698 add_use_network(ifname);
1699#endif /* __SAMSUNG__ */
1700
1701 id = add_network(ifname);
1702 if (id < 0)
1703 return -2;
1704 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1705
1706 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1707 return -2;
1708
1709 dut->infra_network_id = id;
1710 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1711
1712 val = get_param(cmd, "program");
1713 if (!val)
1714 val = get_param(cmd, "prog");
1715 if (val && strcasecmp(val, "hs2") == 0) {
1716 char buf[100];
1717 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1718 wpa_command(ifname, buf);
1719
1720 val = get_param(cmd, "prefer");
1721 if (val && atoi(val) > 0)
1722 set_network(ifname, id, "priority", "1");
1723 }
1724
1725 return id;
1726}
1727
1728
Jouni Malinenf7222712019-06-13 01:50:21 +03001729static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1730 struct sigma_conn *conn,
1731 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001732{
1733 const char *intf = get_param(cmd, "Interface");
1734 const char *ssid = get_param(cmd, "ssid");
1735 const char *type = get_param(cmd, "encpType");
1736 const char *ifname;
1737 char buf[200];
1738 int id;
1739
1740 if (intf == NULL || ssid == NULL)
1741 return -1;
1742
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001743 if (strcmp(intf, get_main_ifname(dut)) == 0)
1744 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001745 else
1746 ifname = intf;
1747
1748 id = add_network_common(dut, conn, ifname, cmd);
1749 if (id < 0)
1750 return id;
1751
1752 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1753 return -2;
1754
1755 if (type && strcasecmp(type, "wep") == 0) {
1756 const char *val;
1757 int i;
1758
1759 val = get_param(cmd, "activeKey");
1760 if (val) {
1761 int keyid;
1762 keyid = atoi(val);
1763 if (keyid < 1 || keyid > 4)
1764 return -1;
1765 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1766 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1767 return -2;
1768 }
1769
1770 for (i = 0; i < 4; i++) {
1771 snprintf(buf, sizeof(buf), "key%d", i + 1);
1772 val = get_param(cmd, buf);
1773 if (val == NULL)
1774 continue;
1775 snprintf(buf, sizeof(buf), "wep_key%d", i);
1776 if (set_network(ifname, id, buf, val) < 0)
1777 return -2;
1778 }
1779 }
1780
1781 return 1;
1782}
1783
1784
Jouni Malinene4fde732019-03-25 22:29:37 +02001785static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1786 int id, const char *val)
1787{
1788 char key_mgmt[200], *end, *pos;
1789 const char *in_pos = val;
1790
Jouni Malinen8179fee2019-03-28 03:19:47 +02001791 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001792 pos = key_mgmt;
1793 end = pos + sizeof(key_mgmt);
1794 while (*in_pos) {
1795 int res, akm = atoi(in_pos);
1796 const char *str;
1797
Jouni Malinen8179fee2019-03-28 03:19:47 +02001798 if (akm >= 0 && akm < 32)
1799 dut->akm_values |= 1 << akm;
1800
Jouni Malinene4fde732019-03-25 22:29:37 +02001801 switch (akm) {
1802 case AKM_WPA_EAP:
1803 str = "WPA-EAP";
1804 break;
1805 case AKM_WPA_PSK:
1806 str = "WPA-PSK";
1807 break;
1808 case AKM_FT_EAP:
1809 str = "FT-EAP";
1810 break;
1811 case AKM_FT_PSK:
1812 str = "FT-PSK";
1813 break;
1814 case AKM_EAP_SHA256:
1815 str = "WPA-EAP-SHA256";
1816 break;
1817 case AKM_PSK_SHA256:
1818 str = "WPA-PSK-SHA256";
1819 break;
1820 case AKM_SAE:
1821 str = "SAE";
1822 break;
1823 case AKM_FT_SAE:
1824 str = "FT-SAE";
1825 break;
1826 case AKM_SUITE_B:
1827 str = "WPA-EAP-SUITE-B-192";
1828 break;
1829 case AKM_FT_SUITE_B:
1830 str = "FT-EAP-SHA384";
1831 break;
1832 case AKM_FILS_SHA256:
1833 str = "FILS-SHA256";
1834 break;
1835 case AKM_FILS_SHA384:
1836 str = "FILS-SHA384";
1837 break;
1838 case AKM_FT_FILS_SHA256:
1839 str = "FT-FILS-SHA256";
1840 break;
1841 case AKM_FT_FILS_SHA384:
1842 str = "FT-FILS-SHA384";
1843 break;
1844 default:
1845 sigma_dut_print(dut, DUT_MSG_ERROR,
1846 "Unsupported AKMSuitetype %d", akm);
1847 return -1;
1848 }
1849
1850 res = snprintf(pos, end - pos, "%s%s",
1851 pos == key_mgmt ? "" : " ", str);
1852 if (res < 0 || res >= end - pos)
1853 return -1;
1854 pos += res;
1855
1856 in_pos = strchr(in_pos, ';');
1857 if (!in_pos)
1858 break;
1859 while (*in_pos == ';')
1860 in_pos++;
1861 }
1862 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1863 val, key_mgmt);
1864 return set_network(ifname, id, "key_mgmt", key_mgmt);
1865}
1866
1867
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001868static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1869 const char *ifname, struct sigma_cmd *cmd)
1870{
1871 const char *val;
1872 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001873 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001874 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301875 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001876
1877 id = add_network_common(dut, conn, ifname, cmd);
1878 if (id < 0)
1879 return id;
1880
Jouni Malinen47dcc952017-10-09 16:43:24 +03001881 val = get_param(cmd, "Type");
1882 owe = val && strcasecmp(val, "OWE") == 0;
1883
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001884 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001885 if (!val && owe)
1886 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001887 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001888 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1889 * this missing parameter and assume proto=WPA2. */
1890 if (set_network(ifname, id, "proto", "WPA2") < 0)
1891 return ERROR_SEND_STATUS;
1892 } else if (strcasecmp(val, "wpa") == 0 ||
1893 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001894 if (set_network(ifname, id, "proto", "WPA") < 0)
1895 return -2;
1896 } else if (strcasecmp(val, "wpa2") == 0 ||
1897 strcasecmp(val, "wpa2-psk") == 0 ||
1898 strcasecmp(val, "wpa2-ft") == 0 ||
1899 strcasecmp(val, "wpa2-sha256") == 0) {
1900 if (set_network(ifname, id, "proto", "WPA2") < 0)
1901 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301902 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1903 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001904 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1905 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001906 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301907 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001908 if (set_network(ifname, id, "proto", "WPA2") < 0)
1909 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001910 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001911 } else {
1912 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1913 return 0;
1914 }
1915
1916 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001917 if (val) {
1918 cipher_set = 1;
1919 if (strcasecmp(val, "tkip") == 0) {
1920 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1921 return -2;
1922 } else if (strcasecmp(val, "aes-ccmp") == 0) {
1923 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1924 return -2;
1925 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
1926 if (set_network(ifname, id, "pairwise",
1927 "CCMP TKIP") < 0)
1928 return -2;
1929 } else if (strcasecmp(val, "aes-gcmp") == 0) {
1930 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1931 return -2;
1932 if (set_network(ifname, id, "group", "GCMP") < 0)
1933 return -2;
1934 } else {
1935 send_resp(dut, conn, SIGMA_ERROR,
1936 "errorCode,Unrecognized encpType value");
1937 return 0;
1938 }
1939 }
1940
1941 val = get_param(cmd, "PairwiseCipher");
1942 if (val) {
1943 cipher_set = 1;
1944 /* TODO: Support space separated list */
1945 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1946 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
1947 return -2;
1948 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1949 if (set_network(ifname, id, "pairwise",
1950 "CCMP-256") < 0)
1951 return -2;
1952 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1953 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
1954 return -2;
1955 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1956 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
1957 return -2;
1958 } else {
1959 send_resp(dut, conn, SIGMA_ERROR,
1960 "errorCode,Unrecognized PairwiseCipher value");
1961 return 0;
1962 }
1963 }
1964
Jouni Malinen47dcc952017-10-09 16:43:24 +03001965 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03001966 send_resp(dut, conn, SIGMA_ERROR,
1967 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001968 return 0;
1969 }
Jouni Malinenad395a22017-09-01 21:13:46 +03001970
1971 val = get_param(cmd, "GroupCipher");
1972 if (val) {
1973 if (strcasecmp(val, "AES-GCMP-256") == 0) {
1974 if (set_network(ifname, id, "group", "GCMP-256") < 0)
1975 return -2;
1976 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
1977 if (set_network(ifname, id, "group", "CCMP-256") < 0)
1978 return -2;
1979 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
1980 if (set_network(ifname, id, "group", "GCMP") < 0)
1981 return -2;
1982 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
1983 if (set_network(ifname, id, "group", "CCMP") < 0)
1984 return -2;
1985 } else {
1986 send_resp(dut, conn, SIGMA_ERROR,
1987 "errorCode,Unrecognized GroupCipher value");
1988 return 0;
1989 }
1990 }
1991
Jouni Malinen7b239522017-09-14 21:37:18 +03001992 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03001993 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03001994 const char *cipher;
1995
1996 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
1997 cipher = "BIP-GMAC-256";
1998 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
1999 cipher = "BIP-CMAC-256";
2000 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2001 cipher = "BIP-GMAC-128";
2002 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2003 cipher = "AES-128-CMAC";
2004 } else {
2005 send_resp(dut, conn, SIGMA_INVALID,
2006 "errorCode,Unsupported GroupMgntCipher");
2007 return 0;
2008 }
2009 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
2010 send_resp(dut, conn, SIGMA_INVALID,
2011 "errorCode,Failed to set GroupMgntCipher");
2012 return 0;
2013 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002014 }
2015
Jouni Malinene4fde732019-03-25 22:29:37 +02002016 val = get_param(cmd, "AKMSuiteType");
2017 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2018 return ERROR_SEND_STATUS;
2019
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002020 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302021
2022 if (dut->program == PROGRAM_OCE) {
2023 dut->sta_pmf = STA_PMF_OPTIONAL;
2024 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2025 return -2;
2026 }
2027
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002028 val = get_param(cmd, "PMF");
2029 if (val) {
2030 if (strcasecmp(val, "Required") == 0 ||
2031 strcasecmp(val, "Forced_Required") == 0) {
2032 dut->sta_pmf = STA_PMF_REQUIRED;
2033 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2034 return -2;
2035 } else if (strcasecmp(val, "Optional") == 0) {
2036 dut->sta_pmf = STA_PMF_OPTIONAL;
2037 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2038 return -2;
2039 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002040 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002041 strcasecmp(val, "Forced_Disabled") == 0) {
2042 dut->sta_pmf = STA_PMF_DISABLED;
2043 } else {
2044 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2045 return 0;
2046 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302047 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002048 dut->sta_pmf = STA_PMF_REQUIRED;
2049 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2050 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002051 }
2052
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002053 val = get_param(cmd, "BeaconProtection");
2054 if (val && atoi(val) == 1 &&
2055 set_network(ifname, id, "beacon_prot", "1") < 0)
2056 return ERROR_SEND_STATUS;
2057
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002058 return id;
2059}
2060
2061
Jouni Malinenf7222712019-06-13 01:50:21 +03002062static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2063 struct sigma_conn *conn,
2064 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002065{
2066 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002067 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002068 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002069 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002070 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002071 const char *ifname, *val, *alg;
2072 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002073 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002074 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002075
2076 if (intf == NULL)
2077 return -1;
2078
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002079 if (strcmp(intf, get_main_ifname(dut)) == 0)
2080 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002081 else
2082 ifname = intf;
2083
2084 id = set_wpa_common(dut, conn, ifname, cmd);
2085 if (id < 0)
2086 return id;
2087
2088 val = get_param(cmd, "keyMgmtType");
2089 alg = get_param(cmd, "micAlg");
2090
Jouni Malinen992a81e2017-08-22 13:57:47 +03002091 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002092 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002093 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2094 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002095 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002096 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2097 return -2;
2098 }
2099 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2100 sigma_dut_print(dut, DUT_MSG_ERROR,
2101 "Failed to clear sae_groups to default");
2102 return -2;
2103 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002104 if (!pmf) {
2105 dut->sta_pmf = STA_PMF_REQUIRED;
2106 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2107 return -2;
2108 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002109 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2110 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2111 if (set_network(ifname, id, "key_mgmt",
2112 "FT-SAE FT-PSK") < 0)
2113 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002114 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002115 if (set_network(ifname, id, "key_mgmt",
2116 "SAE WPA-PSK") < 0)
2117 return -2;
2118 }
2119 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2120 sigma_dut_print(dut, DUT_MSG_ERROR,
2121 "Failed to clear sae_groups to default");
2122 return -2;
2123 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002124 if (!pmf) {
2125 dut->sta_pmf = STA_PMF_OPTIONAL;
2126 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2127 return -2;
2128 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002129 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002130 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2131 return -2;
2132 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2133 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2134 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302135 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2136 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2137 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002138 } else if (!akm &&
2139 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2140 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002141 if (set_network(ifname, id, "key_mgmt",
2142 "WPA-PSK WPA-PSK-SHA256") < 0)
2143 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002144 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002145 if (set_network(ifname, id, "key_mgmt",
2146 "WPA-PSK WPA-PSK-SHA256") < 0)
2147 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002148 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002149 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2150 return -2;
2151 }
2152
2153 val = get_param(cmd, "passPhrase");
2154 if (val == NULL)
2155 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002156 if (type && strcasecmp(type, "SAE") == 0) {
2157 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2158 return -2;
2159 } else {
2160 if (set_network_quoted(ifname, id, "psk", val) < 0)
2161 return -2;
2162 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002163
Jouni Malinen78d10c42019-03-25 22:34:32 +02002164 val = get_param(cmd, "PasswordId");
2165 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2166 return ERROR_SEND_STATUS;
2167
Jouni Malinen992a81e2017-08-22 13:57:47 +03002168 val = get_param(cmd, "ECGroupID");
2169 if (val) {
Jouni Malinenb54f0df2019-12-12 01:57:29 +02002170 snprintf(buf, sizeof(buf), "SET sae_groups %s", val);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002171 if (wpa_command(ifname, buf) != 0) {
2172 sigma_dut_print(dut, DUT_MSG_ERROR,
2173 "Failed to clear sae_groups");
2174 return -2;
2175 }
2176 }
2177
Jouni Malinen68143132017-09-02 02:34:08 +03002178 val = get_param(cmd, "InvalidSAEElement");
2179 if (val) {
2180 free(dut->sae_commit_override);
2181 dut->sae_commit_override = strdup(val);
2182 }
2183
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002184 val = get_param(cmd, "PMKID_Include");
2185 if (val) {
2186 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2187 get_enable_disable(val));
2188 wpa_command(intf, buf);
2189 }
2190
Jouni Malineneeb43d32019-12-06 17:40:07 +02002191 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2192 if (val) {
2193 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2194 get_enable_disable(val));
2195 wpa_command(intf, buf);
2196 }
2197
Jouni Malinenf2348d22019-12-07 11:52:55 +02002198 val = get_param(cmd, "ECGroupID_RGE");
2199 if (val) {
2200 snprintf(buf, sizeof(buf), "SET extra_sae_rejected_groups %s",
2201 val);
2202 wpa_command(intf, buf);
2203 }
2204
Jouni Malinen99e55022019-12-07 13:59:41 +02002205 val = get_param(cmd, "RSNXE_Content");
2206 if (val) {
2207 const char *param;
2208
2209 if (strncasecmp(val, "AssocReq:", 9) == 0) {
2210 val += 9;
2211 param = "rsnxe_override_assoc";
2212 } else if (strncasecmp(val, "EapolM2:", 8) == 0) {
2213 val += 8;
2214 param = "rsnxe_override_eapol";
2215 } else {
2216 send_resp(dut, conn, SIGMA_ERROR,
2217 "errorCode,Unsupported RSNXE_Content value");
2218 return STATUS_SENT_ERROR;
2219 }
2220 snprintf(buf, sizeof(buf), "SET %s %s", param, val);
2221 wpa_command(intf, buf);
2222 }
2223
Jouni Malinen11e55212019-11-22 21:46:59 +02002224 val = get_param(cmd, "sae_pwe");
2225 if (val) {
2226 if (strcasecmp(val, "h2e") == 0) {
2227 dut->sae_pwe = SAE_PWE_H2E;
Jouni Malinen7244a412019-12-07 11:54:10 +02002228 } else if (strcasecmp(val, "loop") == 0 ||
2229 strcasecmp(val, "looping") == 0) {
Jouni Malinen11e55212019-11-22 21:46:59 +02002230 dut->sae_pwe = SAE_PWE_LOOP;
2231 } else {
2232 send_resp(dut, conn, SIGMA_ERROR,
2233 "errorCode,Unsupported sae_pwe value");
2234 return STATUS_SENT_ERROR;
2235 }
2236 }
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302237
2238 val = get_param(cmd, "Clear_RSNXE");
2239 if (val && strcmp(val, "1") == 0 &&
2240 (wpa_command(intf, "SET rsnxe_override_assoc ") ||
2241 wpa_command(intf, "SET rsnxe_override_eapol "))) {
2242 send_resp(dut, conn, SIGMA_ERROR,
2243 "errorCode,Failed to clear RSNXE");
2244 return ERROR_SEND_STATUS;
2245 }
2246
Jouni Malinenc0078772020-03-04 21:23:16 +02002247 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2248 sae_pwe = 3;
2249 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002250 sae_pwe = 0;
2251 else if (dut->sae_pwe == SAE_PWE_H2E)
2252 sae_pwe = 1;
2253 else if (dut->sae_h2e_default)
2254 sae_pwe = 2;
2255 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2256 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2257 return ERROR_SEND_STATUS;
2258
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002259 if (dut->program == PROGRAM_60GHZ && network_mode &&
2260 strcasecmp(network_mode, "PBSS") == 0 &&
2261 set_network(ifname, id, "pbss", "1") < 0)
2262 return -2;
2263
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002264 return 1;
2265}
2266
2267
Jouni Malinen8ac93452019-08-14 15:19:13 +03002268static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2269 struct sigma_conn *conn,
2270 const char *ifname, int id)
2271{
2272 char buf[200];
2273
2274 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2275 if (!file_exists(buf))
2276 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2277 if (!file_exists(buf))
2278 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2279 if (!file_exists(buf)) {
2280 char msg[300];
2281
2282 snprintf(msg, sizeof(msg),
2283 "ErrorCode,trustedRootCA system store (%s) not found",
2284 buf);
2285 send_resp(dut, conn, SIGMA_ERROR, msg);
2286 return STATUS_SENT_ERROR;
2287 }
2288
2289 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2290 return ERROR_SEND_STATUS;
2291
2292 return SUCCESS_SEND_STATUS;
2293}
2294
2295
2296static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2297 struct sigma_conn *conn,
2298 const char *ifname, int id,
2299 const char *val)
2300{
2301 char buf[200];
2302#ifdef ANDROID
2303 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2304 int length;
2305#endif /* ANDROID */
2306
2307 if (strcmp(val, "DEFAULT") == 0)
2308 return set_trust_root_system(dut, conn, ifname, id);
2309
2310#ifdef ANDROID
2311 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2312 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2313 if (length > 0) {
2314 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2315 buf);
2316 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2317 goto ca_cert_selected;
2318 }
2319#endif /* ANDROID */
2320
2321 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2322#ifdef __linux__
2323 if (!file_exists(buf)) {
2324 char msg[300];
2325
2326 snprintf(msg, sizeof(msg),
2327 "ErrorCode,trustedRootCA file (%s) not found", buf);
2328 send_resp(dut, conn, SIGMA_ERROR, msg);
2329 return STATUS_SENT_ERROR;
2330 }
2331#endif /* __linux__ */
2332#ifdef ANDROID
2333ca_cert_selected:
2334#endif /* ANDROID */
2335 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2336 return ERROR_SEND_STATUS;
2337
2338 return SUCCESS_SEND_STATUS;
2339}
2340
2341
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002342static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302343 const char *ifname, int username_identity,
2344 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002345{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002346 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002347 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002348 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002349 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002350 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002351
2352 id = set_wpa_common(dut, conn, ifname, cmd);
2353 if (id < 0)
2354 return id;
2355
2356 val = get_param(cmd, "keyMgmtType");
2357 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302358 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002359 trust_root = get_param(cmd, "trustedRootCA");
2360 domain = get_param(cmd, "Domain");
2361 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002362
Jouni Malinenad395a22017-09-01 21:13:46 +03002363 if (val && strcasecmp(val, "SuiteB") == 0) {
2364 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2365 0)
2366 return -2;
2367 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002368 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2369 return -2;
2370 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2371 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2372 return -2;
2373 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2374 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2375 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002376 } else if (!akm &&
2377 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2378 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002379 if (set_network(ifname, id, "key_mgmt",
2380 "WPA-EAP WPA-EAP-SHA256") < 0)
2381 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302382 } else if (akm && atoi(akm) == 14) {
2383 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2384 dut->sta_pmf == STA_PMF_REQUIRED) {
2385 if (set_network(ifname, id, "key_mgmt",
2386 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2387 return -2;
2388 } else {
2389 if (set_network(ifname, id, "key_mgmt",
2390 "WPA-EAP FILS-SHA256") < 0)
2391 return -2;
2392 }
2393
Jouni Malinen8179fee2019-03-28 03:19:47 +02002394 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302395 } else if (akm && atoi(akm) == 15) {
2396 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2397 dut->sta_pmf == STA_PMF_REQUIRED) {
2398 if (set_network(ifname, id, "key_mgmt",
2399 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2400 return -2;
2401 } else {
2402 if (set_network(ifname, id, "key_mgmt",
2403 "WPA-EAP FILS-SHA384") < 0)
2404 return -2;
2405 }
2406
Jouni Malinen8179fee2019-03-28 03:19:47 +02002407 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002408 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002409 if (set_network(ifname, id, "key_mgmt",
2410 "WPA-EAP WPA-EAP-SHA256") < 0)
2411 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002412 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002413 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2414 return -2;
2415 }
2416
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002417 if (trust_root) {
2418 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2419 !domain_suffix) {
2420 send_resp(dut, conn, SIGMA_ERROR,
2421 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2422 return STATUS_SENT_ERROR;
2423 }
2424 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002425 if (res != SUCCESS_SEND_STATUS)
2426 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002427 }
2428
Jouni Malinen53264f62019-05-03 13:04:40 +03002429 val = get_param(cmd, "ServerCert");
2430 if (val) {
2431 FILE *f;
2432 char *result = NULL, *pos;
2433
2434 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2435 val);
2436 f = fopen(buf, "r");
2437 if (f) {
2438 result = fgets(buf, sizeof(buf), f);
2439 fclose(f);
2440 }
2441 if (!result) {
2442 snprintf(buf2, sizeof(buf2),
2443 "ErrorCode,ServerCert hash could not be read from %s",
2444 buf);
2445 send_resp(dut, conn, SIGMA_ERROR, buf2);
2446 return STATUS_SENT_ERROR;
2447 }
2448 pos = strchr(buf, '\n');
2449 if (pos)
2450 *pos = '\0';
2451 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2452 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2453 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002454
2455 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2456 if (file_exists(buf)) {
2457 sigma_dut_print(dut, DUT_MSG_DEBUG,
2458 "TOD policy enabled for the configured ServerCert hash");
2459 dut->sta_tod_policy = 1;
2460 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002461 }
2462
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002463 if (domain &&
2464 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002465 return ERROR_SEND_STATUS;
2466
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002467 if (domain_suffix &&
2468 set_network_quoted(ifname, id, "domain_suffix_match",
2469 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002470 return ERROR_SEND_STATUS;
2471
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302472 if (username_identity) {
2473 val = get_param(cmd, "username");
2474 if (val) {
2475 if (set_network_quoted(ifname, id, "identity", val) < 0)
2476 return -2;
2477 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002478
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302479 val = get_param(cmd, "password");
2480 if (val) {
2481 if (set_network_quoted(ifname, id, "password", val) < 0)
2482 return -2;
2483 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002484 }
2485
Jouni Malinen8179fee2019-03-28 03:19:47 +02002486 if (dut->akm_values &
2487 ((1 << AKM_FILS_SHA256) |
2488 (1 << AKM_FILS_SHA384) |
2489 (1 << AKM_FT_FILS_SHA256) |
2490 (1 << AKM_FT_FILS_SHA384)))
2491 erp = 1;
2492 if (erp && set_network(ifname, id, "erp", "1") < 0)
2493 return ERROR_SEND_STATUS;
2494
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002495 dut->sta_associate_wait_connect = 1;
2496
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002497 return id;
2498}
2499
2500
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002501static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2502{
2503 const char *val;
2504
2505 if (!cipher)
2506 return 0;
2507
2508 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2509 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2510 else if (strcasecmp(cipher,
2511 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2512 val = "ECDHE-RSA-AES256-GCM-SHA384";
2513 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2514 val = "DHE-RSA-AES256-GCM-SHA384";
2515 else if (strcasecmp(cipher,
2516 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2517 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2518 else
2519 return -1;
2520
2521 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2522 set_network_quoted(ifname, id, "phase1", "");
2523
2524 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2525}
2526
2527
Jouni Malinenf7222712019-06-13 01:50:21 +03002528static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2529 struct sigma_conn *conn,
2530 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002531{
2532 const char *intf = get_param(cmd, "Interface");
2533 const char *ifname, *val;
2534 int id;
2535 char buf[200];
2536#ifdef ANDROID
2537 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2538 int length;
2539 int jb_or_newer = 0;
2540 char prop[PROPERTY_VALUE_MAX];
2541#endif /* ANDROID */
2542
2543 if (intf == NULL)
2544 return -1;
2545
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002546 if (strcmp(intf, get_main_ifname(dut)) == 0)
2547 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002548 else
2549 ifname = intf;
2550
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302551 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002552 if (id < 0)
2553 return id;
2554
2555 if (set_network(ifname, id, "eap", "TLS") < 0)
2556 return -2;
2557
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302558 if (!get_param(cmd, "username") &&
2559 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002560 "wifi-user@wifilabs.local") < 0)
2561 return -2;
2562
2563 val = get_param(cmd, "clientCertificate");
2564 if (val == NULL)
2565 return -1;
2566#ifdef ANDROID
2567 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2568 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2569 if (length < 0) {
2570 /*
2571 * JB started reporting keystore type mismatches, so retry with
2572 * the GET_PUBKEY command if the generic GET fails.
2573 */
2574 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2575 buf, kvalue);
2576 }
2577
2578 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2579 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2580 if (strncmp(prop, "4.0", 3) != 0)
2581 jb_or_newer = 1;
2582 } else
2583 jb_or_newer = 1; /* assume newer */
2584
2585 if (jb_or_newer && length > 0) {
2586 sigma_dut_print(dut, DUT_MSG_INFO,
2587 "Use Android keystore [%s]", buf);
2588 if (set_network(ifname, id, "engine", "1") < 0)
2589 return -2;
2590 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2591 return -2;
2592 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2593 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2594 return -2;
2595 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2596 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2597 return -2;
2598 return 1;
2599 } else if (length > 0) {
2600 sigma_dut_print(dut, DUT_MSG_INFO,
2601 "Use Android keystore [%s]", buf);
2602 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2603 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2604 return -2;
2605 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2606 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2607 return -2;
2608 return 1;
2609 }
2610#endif /* ANDROID */
2611
2612 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2613#ifdef __linux__
2614 if (!file_exists(buf)) {
2615 char msg[300];
2616 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2617 "(%s) not found", buf);
2618 send_resp(dut, conn, SIGMA_ERROR, msg);
2619 return -3;
2620 }
2621#endif /* __linux__ */
2622 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2623 return -2;
2624 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2625 return -2;
2626
2627 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2628 return -2;
2629
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002630 val = get_param(cmd, "keyMgmtType");
2631 if (val && strcasecmp(val, "SuiteB") == 0) {
2632 val = get_param(cmd, "CertType");
2633 if (val && strcasecmp(val, "RSA") == 0) {
2634 if (set_network_quoted(ifname, id, "phase1",
2635 "tls_suiteb=1") < 0)
2636 return -2;
2637 } else {
2638 if (set_network_quoted(ifname, id, "openssl_ciphers",
2639 "SUITEB192") < 0)
2640 return -2;
2641 }
2642
2643 val = get_param(cmd, "TLSCipher");
2644 if (set_tls_cipher(ifname, id, val) < 0) {
2645 send_resp(dut, conn, SIGMA_ERROR,
2646 "ErrorCode,Unsupported TLSCipher value");
2647 return -3;
2648 }
2649 }
2650
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002651 return 1;
2652}
2653
2654
Jouni Malinenf7222712019-06-13 01:50:21 +03002655static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2656 struct sigma_conn *conn,
2657 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002658{
2659 const char *intf = get_param(cmd, "Interface");
2660 const char *ifname;
2661 int id;
2662
2663 if (intf == NULL)
2664 return -1;
2665
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002666 if (strcmp(intf, get_main_ifname(dut)) == 0)
2667 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002668 else
2669 ifname = intf;
2670
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302671 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002672 if (id < 0)
2673 return id;
2674
2675 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2676 send_resp(dut, conn, SIGMA_ERROR,
2677 "errorCode,Failed to set TTLS method");
2678 return 0;
2679 }
2680
2681 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2682 send_resp(dut, conn, SIGMA_ERROR,
2683 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2684 return 0;
2685 }
2686
2687 return 1;
2688}
2689
2690
Jouni Malinenf7222712019-06-13 01:50:21 +03002691static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2692 struct sigma_conn *conn,
2693 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002694{
2695 const char *intf = get_param(cmd, "Interface");
2696 const char *ifname;
2697 int id;
2698
2699 if (intf == NULL)
2700 return -1;
2701
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002702 if (strcmp(intf, get_main_ifname(dut)) == 0)
2703 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002704 else
2705 ifname = intf;
2706
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302707 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002708 if (id < 0)
2709 return id;
2710
2711 if (set_network(ifname, id, "eap", "SIM") < 0)
2712 return -2;
2713
2714 return 1;
2715}
2716
2717
Jouni Malinenf7222712019-06-13 01:50:21 +03002718static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2719 struct sigma_conn *conn,
2720 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002721{
2722 const char *intf = get_param(cmd, "Interface");
2723 const char *ifname, *val;
2724 int id;
2725 char buf[100];
2726
2727 if (intf == NULL)
2728 return -1;
2729
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002730 if (strcmp(intf, get_main_ifname(dut)) == 0)
2731 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002732 else
2733 ifname = intf;
2734
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302735 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002736 if (id < 0)
2737 return id;
2738
2739 if (set_network(ifname, id, "eap", "PEAP") < 0)
2740 return -2;
2741
2742 val = get_param(cmd, "innerEAP");
2743 if (val) {
2744 if (strcasecmp(val, "MSCHAPv2") == 0) {
2745 if (set_network_quoted(ifname, id, "phase2",
2746 "auth=MSCHAPV2") < 0)
2747 return -2;
2748 } else if (strcasecmp(val, "GTC") == 0) {
2749 if (set_network_quoted(ifname, id, "phase2",
2750 "auth=GTC") < 0)
2751 return -2;
2752 } else
2753 return -1;
2754 }
2755
2756 val = get_param(cmd, "peapVersion");
2757 if (val) {
2758 int ver = atoi(val);
2759 if (ver < 0 || ver > 1)
2760 return -1;
2761 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2762 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2763 return -2;
2764 }
2765
2766 return 1;
2767}
2768
2769
Jouni Malinenf7222712019-06-13 01:50:21 +03002770static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2771 struct sigma_conn *conn,
2772 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002773{
2774 const char *intf = get_param(cmd, "Interface");
2775 const char *ifname, *val;
2776 int id;
2777 char buf[100];
2778
2779 if (intf == NULL)
2780 return -1;
2781
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002782 if (strcmp(intf, get_main_ifname(dut)) == 0)
2783 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002784 else
2785 ifname = intf;
2786
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302787 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002788 if (id < 0)
2789 return id;
2790
2791 if (set_network(ifname, id, "eap", "FAST") < 0)
2792 return -2;
2793
2794 val = get_param(cmd, "innerEAP");
2795 if (val) {
2796 if (strcasecmp(val, "MSCHAPV2") == 0) {
2797 if (set_network_quoted(ifname, id, "phase2",
2798 "auth=MSCHAPV2") < 0)
2799 return -2;
2800 } else if (strcasecmp(val, "GTC") == 0) {
2801 if (set_network_quoted(ifname, id, "phase2",
2802 "auth=GTC") < 0)
2803 return -2;
2804 } else
2805 return -1;
2806 }
2807
2808 val = get_param(cmd, "validateServer");
2809 if (val) {
2810 /* TODO */
2811 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2812 "validateServer=%s", val);
2813 }
2814
2815 val = get_param(cmd, "pacFile");
2816 if (val) {
2817 snprintf(buf, sizeof(buf), "blob://%s", val);
2818 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2819 return -2;
2820 }
2821
2822 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2823 0)
2824 return -2;
2825
2826 return 1;
2827}
2828
2829
Jouni Malinenf7222712019-06-13 01:50:21 +03002830static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2831 struct sigma_conn *conn,
2832 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002833{
2834 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302835 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002836 const char *ifname;
2837 int id;
2838
2839 if (intf == NULL)
2840 return -1;
2841
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002842 if (strcmp(intf, get_main_ifname(dut)) == 0)
2843 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002844 else
2845 ifname = intf;
2846
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302847 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002848 if (id < 0)
2849 return id;
2850
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302851 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2852 * hexadecimal).
2853 */
2854 if (username && username[0] == '6') {
2855 if (set_network(ifname, id, "eap", "AKA'") < 0)
2856 return -2;
2857 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002858 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302859 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002860
2861 return 1;
2862}
2863
2864
Jouni Malinenf7222712019-06-13 01:50:21 +03002865static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2866 struct sigma_conn *conn,
2867 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002868{
2869 const char *intf = get_param(cmd, "Interface");
2870 const char *ifname;
2871 int id;
2872
2873 if (intf == NULL)
2874 return -1;
2875
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002876 if (strcmp(intf, get_main_ifname(dut)) == 0)
2877 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002878 else
2879 ifname = intf;
2880
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302881 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002882 if (id < 0)
2883 return id;
2884
2885 if (set_network(ifname, id, "eap", "AKA'") < 0)
2886 return -2;
2887
2888 return 1;
2889}
2890
2891
2892static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
2893 struct sigma_cmd *cmd)
2894{
2895 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002896 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002897 const char *ifname;
2898 int id;
2899
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002900 if (strcmp(intf, get_main_ifname(dut)) == 0)
2901 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002902 else
2903 ifname = intf;
2904
2905 id = add_network_common(dut, conn, ifname, cmd);
2906 if (id < 0)
2907 return id;
2908
2909 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
2910 return -2;
2911
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002912 if (dut->program == PROGRAM_60GHZ && network_mode &&
2913 strcasecmp(network_mode, "PBSS") == 0 &&
2914 set_network(ifname, id, "pbss", "1") < 0)
2915 return -2;
2916
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002917 return 1;
2918}
2919
2920
Jouni Malinen47dcc952017-10-09 16:43:24 +03002921static int sta_set_owe(struct sigma_dut *dut, struct sigma_conn *conn,
2922 struct sigma_cmd *cmd)
2923{
2924 const char *intf = get_param(cmd, "Interface");
2925 const char *ifname, *val;
2926 int id;
2927
2928 if (intf == NULL)
2929 return -1;
2930
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002931 if (strcmp(intf, get_main_ifname(dut)) == 0)
2932 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002933 else
2934 ifname = intf;
2935
2936 id = set_wpa_common(dut, conn, ifname, cmd);
2937 if (id < 0)
2938 return id;
2939
2940 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
2941 return -2;
2942
2943 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03002944 if (val && strcmp(val, "0") == 0) {
2945 if (wpa_command(ifname,
2946 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
2947 sigma_dut_print(dut, DUT_MSG_ERROR,
2948 "Failed to set OWE DH Param element override");
2949 return -2;
2950 }
Hu Wang6010ce72020-03-05 19:33:53 +08002951 } else if (val &&
2952 (set_network(ifname, id, "owe_group", val) < 0 ||
2953 (dut->owe_ptk_workaround &&
2954 set_network(ifname, id, "owe_ptk_workaround", "1") < 0))) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03002955 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08002956 "Failed to set owe_group");
Jouni Malinen47dcc952017-10-09 16:43:24 +03002957 return -2;
2958 }
2959
2960 return 1;
2961}
2962
2963
Jouni Malinenf7222712019-06-13 01:50:21 +03002964static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
2965 struct sigma_conn *conn,
2966 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002967{
2968 const char *type = get_param(cmd, "Type");
2969
2970 if (type == NULL) {
2971 send_resp(dut, conn, SIGMA_ERROR,
2972 "ErrorCode,Missing Type argument");
2973 return 0;
2974 }
2975
2976 if (strcasecmp(type, "OPEN") == 0)
2977 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03002978 if (strcasecmp(type, "OWE") == 0)
2979 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002980 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002981 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03002982 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002983 return cmd_sta_set_psk(dut, conn, cmd);
2984 if (strcasecmp(type, "EAPTLS") == 0)
2985 return cmd_sta_set_eaptls(dut, conn, cmd);
2986 if (strcasecmp(type, "EAPTTLS") == 0)
2987 return cmd_sta_set_eapttls(dut, conn, cmd);
2988 if (strcasecmp(type, "EAPPEAP") == 0)
2989 return cmd_sta_set_peap(dut, conn, cmd);
2990 if (strcasecmp(type, "EAPSIM") == 0)
2991 return cmd_sta_set_eapsim(dut, conn, cmd);
2992 if (strcasecmp(type, "EAPFAST") == 0)
2993 return cmd_sta_set_eapfast(dut, conn, cmd);
2994 if (strcasecmp(type, "EAPAKA") == 0)
2995 return cmd_sta_set_eapaka(dut, conn, cmd);
2996 if (strcasecmp(type, "EAPAKAPRIME") == 0)
2997 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08002998 if (strcasecmp(type, "wep") == 0)
2999 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003000
3001 send_resp(dut, conn, SIGMA_ERROR,
3002 "ErrorCode,Unsupported Type value");
3003 return 0;
3004}
3005
3006
3007int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
3008{
3009#ifdef __linux__
3010 /* special handling for ath6kl */
3011 char path[128], fname[128], *pos;
3012 ssize_t res;
3013 FILE *f;
3014
Jouni Malinene39cd562019-05-29 23:39:56 +03003015 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3016 intf);
3017 if (res < 0 || res >= sizeof(fname))
3018 return 0;
3019 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003020 if (res < 0)
3021 return 0; /* not ath6kl */
3022
3023 if (res >= (int) sizeof(path))
3024 res = sizeof(path) - 1;
3025 path[res] = '\0';
3026 pos = strrchr(path, '/');
3027 if (pos == NULL)
3028 pos = path;
3029 else
3030 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003031 res = snprintf(fname, sizeof(fname),
3032 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3033 "create_qos", pos);
3034 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003035 return 0; /* not ath6kl */
3036
3037 if (uapsd) {
3038 f = fopen(fname, "w");
3039 if (f == NULL)
3040 return -1;
3041
3042 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3043 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3044 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3045 "20000 0\n");
3046 fclose(f);
3047 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003048 res = snprintf(fname, sizeof(fname),
3049 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3050 "delete_qos", pos);
3051 if (res < 0 || res >= sizeof(fname))
3052 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003053
3054 f = fopen(fname, "w");
3055 if (f == NULL)
3056 return -1;
3057
3058 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3059 fprintf(f, "2 4\n");
3060 fclose(f);
3061 }
3062#endif /* __linux__ */
3063
3064 return 0;
3065}
3066
3067
Jouni Malinenf7222712019-06-13 01:50:21 +03003068static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3069 struct sigma_conn *conn,
3070 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003071{
3072 const char *intf = get_param(cmd, "Interface");
3073 /* const char *ssid = get_param(cmd, "ssid"); */
3074 const char *val;
3075 int max_sp_len = 4;
3076 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3077 char buf[100];
3078 int ret1, ret2;
3079
3080 val = get_param(cmd, "maxSPLength");
3081 if (val) {
3082 max_sp_len = atoi(val);
3083 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3084 max_sp_len != 4)
3085 return -1;
3086 }
3087
3088 val = get_param(cmd, "acBE");
3089 if (val)
3090 ac_be = atoi(val);
3091
3092 val = get_param(cmd, "acBK");
3093 if (val)
3094 ac_bk = atoi(val);
3095
3096 val = get_param(cmd, "acVI");
3097 if (val)
3098 ac_vi = atoi(val);
3099
3100 val = get_param(cmd, "acVO");
3101 if (val)
3102 ac_vo = atoi(val);
3103
3104 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3105
3106 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3107 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3108 ret1 = wpa_command(intf, buf);
3109
3110 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3111 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3112 ret2 = wpa_command(intf, buf);
3113
3114 if (ret1 && ret2) {
3115 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3116 "UAPSD parameters.");
3117 return -2;
3118 }
3119
3120 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3121 send_resp(dut, conn, SIGMA_ERROR,
3122 "ErrorCode,Failed to set ath6kl QoS parameters");
3123 return 0;
3124 }
3125
3126 return 1;
3127}
3128
3129
Jouni Malinenf7222712019-06-13 01:50:21 +03003130static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3131 struct sigma_conn *conn,
3132 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003133{
3134 char buf[1000];
3135 const char *intf = get_param(cmd, "Interface");
3136 const char *grp = get_param(cmd, "Group");
3137 const char *act = get_param(cmd, "Action");
3138 const char *tid = get_param(cmd, "Tid");
3139 const char *dir = get_param(cmd, "Direction");
3140 const char *psb = get_param(cmd, "Psb");
3141 const char *up = get_param(cmd, "Up");
3142 const char *fixed = get_param(cmd, "Fixed");
3143 const char *size = get_param(cmd, "Size");
3144 const char *msize = get_param(cmd, "Maxsize");
3145 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3146 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3147 const char *inact = get_param(cmd, "Inactivity");
3148 const char *sus = get_param(cmd, "Suspension");
3149 const char *mindr = get_param(cmd, "Mindatarate");
3150 const char *meandr = get_param(cmd, "Meandatarate");
3151 const char *peakdr = get_param(cmd, "Peakdatarate");
3152 const char *phyrate = get_param(cmd, "Phyrate");
3153 const char *burstsize = get_param(cmd, "Burstsize");
3154 const char *sba = get_param(cmd, "Sba");
3155 int direction;
3156 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003157 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003158 int fixed_int;
3159 int psb_ts;
3160
3161 if (intf == NULL || grp == NULL || act == NULL )
3162 return -1;
3163
3164 if (strcasecmp(act, "addts") == 0) {
3165 if (tid == NULL || dir == NULL || psb == NULL ||
3166 up == NULL || fixed == NULL || size == NULL)
3167 return -1;
3168
3169 /*
3170 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3171 * possible values, but WMM-AC and V-E test scripts use "UP,
3172 * "DOWN", and "BIDI".
3173 */
3174 if (strcasecmp(dir, "uplink") == 0 ||
3175 strcasecmp(dir, "up") == 0) {
3176 direction = 0;
3177 } else if (strcasecmp(dir, "downlink") == 0 ||
3178 strcasecmp(dir, "down") == 0) {
3179 direction = 1;
3180 } else if (strcasecmp(dir, "bidi") == 0) {
3181 direction = 2;
3182 } else {
3183 sigma_dut_print(dut, DUT_MSG_ERROR,
3184 "Direction %s not supported", dir);
3185 return -1;
3186 }
3187
3188 if (strcasecmp(psb, "legacy") == 0) {
3189 psb_ts = 0;
3190 } else if (strcasecmp(psb, "uapsd") == 0) {
3191 psb_ts = 1;
3192 } else {
3193 sigma_dut_print(dut, DUT_MSG_ERROR,
3194 "PSB %s not supported", psb);
3195 return -1;
3196 }
3197
3198 if (atoi(tid) < 0 || atoi(tid) > 7) {
3199 sigma_dut_print(dut, DUT_MSG_ERROR,
3200 "TID %s not supported", tid);
3201 return -1;
3202 }
3203
3204 if (strcasecmp(fixed, "true") == 0) {
3205 fixed_int = 1;
3206 } else {
3207 fixed_int = 0;
3208 }
3209
Peng Xu93319622017-10-04 17:58:16 -07003210 if (sba)
3211 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003212
3213 dut->dialog_token++;
3214 handle = 7000 + dut->dialog_token;
3215
3216 /*
3217 * size: convert to hex
3218 * maxsi: convert to hex
3219 * mindr: convert to hex
3220 * meandr: convert to hex
3221 * peakdr: convert to hex
3222 * burstsize: convert to hex
3223 * phyrate: convert to hex
3224 * sba: convert to hex with modification
3225 * minsi: convert to integer
3226 * sus: convert to integer
3227 * inact: convert to integer
3228 * maxsi: convert to integer
3229 */
3230
3231 /*
3232 * The Nominal MSDU Size field is 2 octets long and contains an
3233 * unsigned integer that specifies the nominal size, in octets,
3234 * of MSDUs belonging to the traffic under this traffic
3235 * specification and is defined in Figure 16. If the Fixed
3236 * subfield is set to 1, then the size of the MSDU is fixed and
3237 * is indicated by the Size Subfield. If the Fixed subfield is
3238 * set to 0, then the size of the MSDU might not be fixed and
3239 * the Size indicates the nominal MSDU size.
3240 *
3241 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3242 * and specifies the excess allocation of time (and bandwidth)
3243 * over and above the stated rates required to transport an MSDU
3244 * belonging to the traffic in this TSPEC. This field is
3245 * represented as an unsigned binary number with an implicit
3246 * binary point after the leftmost 3 bits. For example, an SBA
3247 * of 1.75 is represented as 0x3800. This field is included to
3248 * account for retransmissions. As such, the value of this field
3249 * must be greater than unity.
3250 */
3251
3252 snprintf(buf, sizeof(buf),
3253 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3254 " 0x%X 0x%X 0x%X"
3255 " 0x%X 0x%X 0x%X"
3256 " 0x%X %d %d %d %d"
3257 " %d %d",
3258 intf, handle, tid, direction, psb_ts, up,
3259 (unsigned int) ((fixed_int << 15) | atoi(size)),
3260 msize ? atoi(msize) : 0,
3261 mindr ? atoi(mindr) : 0,
3262 meandr ? atoi(meandr) : 0,
3263 peakdr ? atoi(peakdr) : 0,
3264 burstsize ? atoi(burstsize) : 0,
3265 phyrate ? atoi(phyrate) : 0,
3266 sba ? ((unsigned int) (((int) sba_fv << 13) |
3267 (int)((sba_fv - (int) sba_fv) *
3268 8192))) : 0,
3269 minsi ? atoi(minsi) : 0,
3270 sus ? atoi(sus) : 0,
3271 0, 0,
3272 inact ? atoi(inact) : 0,
3273 maxsi ? atoi(maxsi) : 0);
3274
3275 if (system(buf) != 0) {
3276 sigma_dut_print(dut, DUT_MSG_ERROR,
3277 "iwpriv addtspec request failed");
3278 send_resp(dut, conn, SIGMA_ERROR,
3279 "errorCode,Failed to execute addTspec command");
3280 return 0;
3281 }
3282
3283 sigma_dut_print(dut, DUT_MSG_INFO,
3284 "iwpriv addtspec request send");
3285
3286 /* Mapping handle to a TID */
3287 dut->tid_to_handle[atoi(tid)] = handle;
3288 } else if (strcasecmp(act, "delts") == 0) {
3289 if (tid == NULL)
3290 return -1;
3291
3292 if (atoi(tid) < 0 || atoi(tid) > 7) {
3293 sigma_dut_print(dut, DUT_MSG_ERROR,
3294 "TID %s not supported", tid);
3295 send_resp(dut, conn, SIGMA_ERROR,
3296 "errorCode,Unsupported TID");
3297 return 0;
3298 }
3299
3300 handle = dut->tid_to_handle[atoi(tid)];
3301
3302 if (handle < 7000 || handle > 7255) {
3303 /* Invalid handle ie no mapping for that TID */
3304 sigma_dut_print(dut, DUT_MSG_ERROR,
3305 "handle-> %d not found", handle);
3306 }
3307
3308 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3309 intf, handle);
3310
3311 if (system(buf) != 0) {
3312 sigma_dut_print(dut, DUT_MSG_ERROR,
3313 "iwpriv deltspec request failed");
3314 send_resp(dut, conn, SIGMA_ERROR,
3315 "errorCode,Failed to execute delTspec command");
3316 return 0;
3317 }
3318
3319 sigma_dut_print(dut, DUT_MSG_INFO,
3320 "iwpriv deltspec request send");
3321
3322 dut->tid_to_handle[atoi(tid)] = 0;
3323 } else {
3324 sigma_dut_print(dut, DUT_MSG_ERROR,
3325 "Action type %s not supported", act);
3326 send_resp(dut, conn, SIGMA_ERROR,
3327 "errorCode,Unsupported Action");
3328 return 0;
3329 }
3330
3331 return 1;
3332}
3333
3334
vamsi krishna52e16f92017-08-29 12:37:34 +05303335static int find_network(struct sigma_dut *dut, const char *ssid)
3336{
3337 char list[4096];
3338 char *pos;
3339
3340 sigma_dut_print(dut, DUT_MSG_DEBUG,
3341 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003342 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303343 list, sizeof(list)) < 0)
3344 return -1;
3345 pos = strstr(list, ssid);
3346 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3347 return -1;
3348
3349 while (pos > list && pos[-1] != '\n')
3350 pos--;
3351 dut->infra_network_id = atoi(pos);
3352 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3353 return 0;
3354}
3355
3356
Sunil Dutt44595082018-02-12 19:41:45 +05303357#ifdef NL80211_SUPPORT
3358static int sta_config_rsnie(struct sigma_dut *dut, int val)
3359{
3360 struct nl_msg *msg;
3361 int ret;
3362 struct nlattr *params;
3363 int ifindex;
3364
3365 ifindex = if_nametoindex("wlan0");
3366 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3367 NL80211_CMD_VENDOR)) ||
3368 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3369 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3370 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3371 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
3372 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
3373 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, val)) {
3374 sigma_dut_print(dut, DUT_MSG_ERROR,
3375 "%s: err in adding vendor_cmd and vendor_data",
3376 __func__);
3377 nlmsg_free(msg);
3378 return -1;
3379 }
3380 nla_nest_end(msg, params);
3381
3382 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3383 if (ret) {
3384 sigma_dut_print(dut, DUT_MSG_ERROR,
3385 "%s: err in send_and_recv_msgs, ret=%d",
3386 __func__, ret);
3387 return ret;
3388 }
3389
3390 return 0;
3391}
3392#endif /* NL80211_SUPPORT */
3393
3394
Jouni Malinenf7222712019-06-13 01:50:21 +03003395static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
3396 struct sigma_conn *conn,
3397 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003398{
3399 /* const char *intf = get_param(cmd, "Interface"); */
3400 const char *ssid = get_param(cmd, "ssid");
3401 const char *wps_param = get_param(cmd, "WPS");
3402 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03003403 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003404 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003405 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03003406 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003407 int e;
3408 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
3409 struct wpa_ctrl *ctrl = NULL;
3410 int num_network_not_found = 0;
3411 int num_disconnected = 0;
3412 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003413
3414 if (ssid == NULL)
3415 return -1;
3416
Jouni Malinen37d5c692019-08-19 16:56:55 +03003417 dut->server_cert_tod = 0;
3418
Jouni Malinen3c367e82017-06-23 17:01:47 +03003419 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05303420#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003421 if (get_driver_type(dut) == DRIVER_WCN) {
Sunil Dutt44595082018-02-12 19:41:45 +05303422 sta_config_rsnie(dut, 1);
3423 dut->config_rsnie = 1;
3424 }
3425#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03003426 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
3427 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003428 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03003429 send_resp(dut, conn, SIGMA_ERROR,
3430 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
3431 return 0;
3432 }
3433 }
3434
Jouni Malinen68143132017-09-02 02:34:08 +03003435 if (dut->sae_commit_override) {
3436 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
3437 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003438 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03003439 send_resp(dut, conn, SIGMA_ERROR,
3440 "ErrorCode,Failed to set SAE commit override");
3441 return 0;
3442 }
3443 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303444#ifdef ANDROID
3445 if (dut->fils_hlp)
3446 process_fils_hlp(dut);
3447#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03003448
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003449 if (wps_param &&
3450 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
3451 wps = 1;
3452
3453 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003454 if (dut->program == PROGRAM_60GHZ && network_mode &&
3455 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003456 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003457 "pbss", "1") < 0)
3458 return -2;
3459
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003460 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
3461 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
3462 "parameters not yet set");
3463 return 0;
3464 }
3465 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003466 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003467 return -2;
3468 } else {
3469 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
3470 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003471 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003472 return -2;
3473 }
3474 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05303475 if (strcmp(ssid, dut->infra_ssid) == 0) {
3476 sigma_dut_print(dut, DUT_MSG_DEBUG,
3477 "sta_associate for the most recently added network");
3478 } else if (find_network(dut, ssid) < 0) {
3479 sigma_dut_print(dut, DUT_MSG_DEBUG,
3480 "sta_associate for a previously stored network profile");
3481 send_resp(dut, conn, SIGMA_ERROR,
3482 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003483 return 0;
3484 }
3485
3486 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003487 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003488 "bssid", bssid) < 0) {
3489 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3490 "Invalid bssid argument");
3491 return 0;
3492 }
3493
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003494 if (dut->program == PROGRAM_WPA3 &&
3495 dut->sta_associate_wait_connect) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003496 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003497 if (!ctrl)
3498 return ERROR_SEND_STATUS;
3499 }
3500
Jouni Malinen46a19b62017-06-23 14:31:27 +03003501 extra[0] = '\0';
3502 if (chan)
3503 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02003504 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03003505 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
3506 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003507 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003508 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
3509 "network id %d on %s",
3510 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003511 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003512 ret = ERROR_SEND_STATUS;
3513 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003514 }
3515 }
3516
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003517 if (!ctrl)
3518 return SUCCESS_SEND_STATUS;
3519
3520 /* Wait for connection result to be able to store server certificate
3521 * hash for trust root override testing
3522 * (dev_exec_action,ServerCertTrust). */
3523
3524 for (e = 0; e < 20; e++) {
3525 const char *events[] = {
3526 "CTRL-EVENT-EAP-PEER-CERT",
3527 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
3528 "CTRL-EVENT-DISCONNECTED",
3529 "CTRL-EVENT-CONNECTED",
3530 "CTRL-EVENT-NETWORK-NOT-FOUND",
3531 NULL
3532 };
3533 char buf[1024];
3534 int res;
3535
3536 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
3537 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02003538 send_resp(dut, conn, SIGMA_COMPLETE,
3539 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003540 ret = STATUS_SENT_ERROR;
3541 break;
3542 }
3543 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
3544 buf);
3545
3546 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
3547 strstr(buf, " depth=0")) {
3548 char *pos = strstr(buf, " hash=");
3549
3550 if (pos) {
3551 char *end;
3552
Jouni Malinen34b19cb2019-08-16 16:37:17 +03003553 if (strstr(buf, " tod=1"))
3554 tod = 1;
3555 else if (strstr(buf, " tod=2"))
3556 tod = 2;
3557 else
3558 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003559 sigma_dut_print(dut, DUT_MSG_DEBUG,
3560 "Server certificate TOD policy: %d",
3561 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03003562 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03003563
3564 pos += 6;
3565 end = strchr(pos, ' ');
3566 if (end)
3567 *end = '\0';
3568 strlcpy(dut->server_cert_hash, pos,
3569 sizeof(dut->server_cert_hash));
3570 sigma_dut_print(dut, DUT_MSG_DEBUG,
3571 "Server certificate hash: %s",
3572 dut->server_cert_hash);
3573 }
3574 }
3575
3576 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
3577 send_resp(dut, conn, SIGMA_COMPLETE,
3578 "Result,TLS server certificate validation failed");
3579 ret = STATUS_SENT_ERROR;
3580 break;
3581 }
3582
3583 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
3584 num_network_not_found++;
3585
3586 if (num_network_not_found > 2) {
3587 send_resp(dut, conn, SIGMA_COMPLETE,
3588 "Result,Network not found");
3589 ret = STATUS_SENT_ERROR;
3590 break;
3591 }
3592 }
3593
3594 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
3595 num_disconnected++;
3596
3597 if (num_disconnected > 2) {
3598 send_resp(dut, conn, SIGMA_COMPLETE,
3599 "Result,Connection failed");
3600 ret = STATUS_SENT_ERROR;
3601 break;
3602 }
3603 }
3604
3605 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
3606 if (tod >= 0) {
3607 sigma_dut_print(dut, DUT_MSG_DEBUG,
3608 "Network profile TOD policy update: %d -> %d",
3609 dut->sta_tod_policy, tod);
3610 dut->sta_tod_policy = tod;
3611 }
3612 break;
3613 }
3614 }
3615done:
3616 if (ctrl) {
3617 wpa_ctrl_detach(ctrl);
3618 wpa_ctrl_close(ctrl);
3619 }
3620 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003621}
3622
3623
3624static int run_hs20_osu(struct sigma_dut *dut, const char *params)
3625{
3626 char buf[500], cmd[200];
3627 int res;
3628
3629 /* Use hs20-osu-client file at the current dir, if found; otherwise use
3630 * default path */
3631 res = snprintf(cmd, sizeof(cmd),
3632 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
3633 file_exists("./hs20-osu-client") ?
3634 "./hs20-osu-client" : "hs20-osu-client",
3635 sigma_wpas_ctrl,
3636 dut->summary_log ? "-s " : "",
3637 dut->summary_log ? dut->summary_log : "");
3638 if (res < 0 || res >= (int) sizeof(cmd))
3639 return -1;
3640
3641 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
3642 if (res < 0 || res >= (int) sizeof(buf))
3643 return -1;
3644 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
3645
3646 if (system(buf) != 0) {
3647 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
3648 return -1;
3649 }
3650 sigma_dut_print(dut, DUT_MSG_DEBUG,
3651 "Completed hs20-osu-client operation");
3652
3653 return 0;
3654}
3655
3656
3657static int download_ppsmo(struct sigma_dut *dut,
3658 struct sigma_conn *conn,
3659 const char *intf,
3660 struct sigma_cmd *cmd)
3661{
3662 const char *name, *path, *val;
3663 char url[500], buf[600], fbuf[100];
3664 char *fqdn = NULL;
3665
3666 name = get_param(cmd, "FileName");
3667 path = get_param(cmd, "FilePath");
3668 if (name == NULL || path == NULL)
3669 return -1;
3670
3671 if (strcasecmp(path, "VendorSpecific") == 0) {
3672 snprintf(url, sizeof(url), "PPS/%s", name);
3673 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
3674 "from the device (%s)", url);
3675 if (!file_exists(url)) {
3676 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3677 "PPS MO file does not exist");
3678 return 0;
3679 }
3680 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
3681 if (system(buf) != 0) {
3682 send_resp(dut, conn, SIGMA_ERROR,
3683 "errorCode,Failed to copy PPS MO");
3684 return 0;
3685 }
3686 } else if (strncasecmp(path, "http:", 5) != 0 &&
3687 strncasecmp(path, "https:", 6) != 0) {
3688 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3689 "Unsupported FilePath value");
3690 return 0;
3691 } else {
3692 snprintf(url, sizeof(url), "%s/%s", path, name);
3693 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
3694 url);
3695 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
3696 remove("pps-tnds.xml");
3697 if (system(buf) != 0) {
3698 send_resp(dut, conn, SIGMA_ERROR,
3699 "errorCode,Failed to download PPS MO");
3700 return 0;
3701 }
3702 }
3703
3704 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
3705 send_resp(dut, conn, SIGMA_ERROR,
3706 "errorCode,Failed to parse downloaded PPSMO");
3707 return 0;
3708 }
3709 unlink("pps-tnds.xml");
3710
3711 val = get_param(cmd, "managementTreeURI");
3712 if (val) {
3713 const char *pos, *end;
3714 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
3715 val);
3716 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
3717 send_resp(dut, conn, SIGMA_ERROR,
3718 "errorCode,Invalid managementTreeURI prefix");
3719 return 0;
3720 }
3721 pos = val + 8;
3722 end = strchr(pos, '/');
3723 if (end == NULL ||
3724 strcmp(end, "/PerProviderSubscription") != 0) {
3725 send_resp(dut, conn, SIGMA_ERROR,
3726 "errorCode,Invalid managementTreeURI postfix");
3727 return 0;
3728 }
3729 if (end - pos >= (int) sizeof(fbuf)) {
3730 send_resp(dut, conn, SIGMA_ERROR,
3731 "errorCode,Too long FQDN in managementTreeURI");
3732 return 0;
3733 }
3734 memcpy(fbuf, pos, end - pos);
3735 fbuf[end - pos] = '\0';
3736 fqdn = fbuf;
3737 sigma_dut_print(dut, DUT_MSG_INFO,
3738 "FQDN from managementTreeURI: %s", fqdn);
3739 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
3740 FILE *f = fopen("pps-fqdn", "r");
3741 if (f) {
3742 if (fgets(fbuf, sizeof(fbuf), f)) {
3743 fbuf[sizeof(fbuf) - 1] = '\0';
3744 fqdn = fbuf;
3745 sigma_dut_print(dut, DUT_MSG_DEBUG,
3746 "Use FQDN %s", fqdn);
3747 }
3748 fclose(f);
3749 }
3750 }
3751
3752 if (fqdn == NULL) {
3753 send_resp(dut, conn, SIGMA_ERROR,
3754 "errorCode,No FQDN specified");
3755 return 0;
3756 }
3757
3758 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3759 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
3760 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
3761
3762 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
3763 if (rename("pps.xml", buf) < 0) {
3764 send_resp(dut, conn, SIGMA_ERROR,
3765 "errorCode,Could not move PPS MO");
3766 return 0;
3767 }
3768
3769 if (strcasecmp(path, "VendorSpecific") == 0) {
3770 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
3771 fqdn);
3772 if (system(buf)) {
3773 send_resp(dut, conn, SIGMA_ERROR,
3774 "errorCode,Failed to copy OSU CA cert");
3775 return 0;
3776 }
3777
3778 snprintf(buf, sizeof(buf),
3779 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
3780 fqdn);
3781 if (system(buf)) {
3782 send_resp(dut, conn, SIGMA_ERROR,
3783 "errorCode,Failed to copy AAA CA cert");
3784 return 0;
3785 }
3786 } else {
3787 snprintf(buf, sizeof(buf),
3788 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
3789 fqdn, fqdn);
3790 if (run_hs20_osu(dut, buf) < 0) {
3791 send_resp(dut, conn, SIGMA_ERROR,
3792 "errorCode,Failed to download OSU CA cert");
3793 return 0;
3794 }
3795
3796 snprintf(buf, sizeof(buf),
3797 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
3798 fqdn, fqdn);
3799 if (run_hs20_osu(dut, buf) < 0) {
3800 sigma_dut_print(dut, DUT_MSG_INFO,
3801 "Failed to download AAA CA cert");
3802 }
3803 }
3804
3805 if (file_exists("next-client-cert.pem")) {
3806 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
3807 if (rename("next-client-cert.pem", buf) < 0) {
3808 send_resp(dut, conn, SIGMA_ERROR,
3809 "errorCode,Could not move client certificate");
3810 return 0;
3811 }
3812 }
3813
3814 if (file_exists("next-client-key.pem")) {
3815 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
3816 if (rename("next-client-key.pem", buf) < 0) {
3817 send_resp(dut, conn, SIGMA_ERROR,
3818 "errorCode,Could not move client key");
3819 return 0;
3820 }
3821 }
3822
3823 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
3824 if (run_hs20_osu(dut, buf) < 0) {
3825 send_resp(dut, conn, SIGMA_ERROR,
3826 "errorCode,Failed to configure credential from "
3827 "PPSMO");
3828 return 0;
3829 }
3830
3831 return 1;
3832}
3833
3834
3835static int download_cert(struct sigma_dut *dut,
3836 struct sigma_conn *conn,
3837 const char *intf,
3838 struct sigma_cmd *cmd)
3839{
3840 const char *name, *path;
3841 char url[500], buf[600];
3842
3843 name = get_param(cmd, "FileName");
3844 path = get_param(cmd, "FilePath");
3845 if (name == NULL || path == NULL)
3846 return -1;
3847
3848 if (strcasecmp(path, "VendorSpecific") == 0) {
3849 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
3850 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3851 "certificate from the device (%s)", url);
3852 if (!file_exists(url)) {
3853 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3854 "certificate file does not exist");
3855 return 0;
3856 }
3857 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
3858 if (system(buf) != 0) {
3859 send_resp(dut, conn, SIGMA_ERROR,
3860 "errorCode,Failed to copy client "
3861 "certificate");
3862 return 0;
3863 }
3864
3865 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
3866 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
3867 "private key from the device (%s)", url);
3868 if (!file_exists(url)) {
3869 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
3870 "private key file does not exist");
3871 return 0;
3872 }
3873 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
3874 if (system(buf) != 0) {
3875 send_resp(dut, conn, SIGMA_ERROR,
3876 "errorCode,Failed to copy client key");
3877 return 0;
3878 }
3879 } else if (strncasecmp(path, "http:", 5) != 0 &&
3880 strncasecmp(path, "https:", 6) != 0) {
3881 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
3882 "Unsupported FilePath value");
3883 return 0;
3884 } else {
3885 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
3886 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
3887 "certificate/key from %s", url);
3888 snprintf(buf, sizeof(buf),
3889 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
3890 if (system(buf) != 0) {
3891 send_resp(dut, conn, SIGMA_ERROR,
3892 "errorCode,Failed to download client "
3893 "certificate");
3894 return 0;
3895 }
3896
3897 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
3898 {
3899 send_resp(dut, conn, SIGMA_ERROR,
3900 "errorCode,Failed to copy client key");
3901 return 0;
3902 }
3903 }
3904
3905 return 1;
3906}
3907
3908
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003909static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
3910 struct sigma_conn *conn,
3911 struct sigma_cmd *cmd)
3912{
3913 const char *val;
3914 const char *intf = get_param(cmd, "interface");
3915
3916 if (!intf)
3917 return -1;
3918
3919 val = get_param(cmd, "WscIEFragment");
3920 if (val && strcasecmp(val, "enable") == 0) {
3921 sigma_dut_print(dut, DUT_MSG_DEBUG,
3922 "Enable WSC IE fragmentation");
3923
3924 dut->wsc_fragment = 1;
3925 /* set long attributes to force fragmentation */
3926 if (wpa_command(intf, "SET device_name "
3927 WPS_LONG_DEVICE_NAME) < 0)
3928 return -2;
3929 if (wpa_command(intf, "SET manufacturer "
3930 WPS_LONG_MANUFACTURER) < 0)
3931 return -2;
3932 if (wpa_command(intf, "SET model_name "
3933 WPS_LONG_MODEL_NAME) < 0)
3934 return -2;
3935 if (wpa_command(intf, "SET model_number "
3936 WPS_LONG_MODEL_NUMBER) < 0)
3937 return -2;
3938 if (wpa_command(intf, "SET serial_number "
3939 WPS_LONG_SERIAL_NUMBER) < 0)
3940 return -2;
3941 }
3942
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02003943 val = get_param(cmd, "RSN_IE");
3944 if (val) {
3945 if (strcasecmp(val, "disable") == 0)
3946 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
3947 else if (strcasecmp(val, "enable") == 0)
3948 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
3949 }
3950
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02003951 val = get_param(cmd, "WpsVersion");
3952 if (val)
3953 dut->wps_forced_version = get_wps_forced_version(dut, val);
3954
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02003955 val = get_param(cmd, "WscEAPFragment");
3956 if (val && strcasecmp(val, "enable") == 0)
3957 dut->eap_fragment = 1;
3958
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02003959 return 1;
3960}
3961
3962
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003963static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
3964 struct sigma_conn *conn,
3965 const char *intf,
3966 struct sigma_cmd *cmd)
3967{
3968 const char *val;
3969
3970 val = get_param(cmd, "FileType");
3971 if (val && strcasecmp(val, "PPSMO") == 0)
3972 return download_ppsmo(dut, conn, intf, cmd);
3973 if (val && strcasecmp(val, "CERT") == 0)
3974 return download_cert(dut, conn, intf, cmd);
3975 if (val) {
3976 send_resp(dut, conn, SIGMA_ERROR,
3977 "ErrorCode,Unsupported FileType");
3978 return 0;
3979 }
3980
3981 return 1;
3982}
3983
3984
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303985static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
3986 struct sigma_conn *conn,
3987 const char *intf,
3988 struct sigma_cmd *cmd)
3989{
3990 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05303991 char buf[1000];
3992 char text[20];
3993 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05303994
3995 val = get_param(cmd, "OCESupport");
3996 if (val && strcasecmp(val, "Disable") == 0) {
3997 if (wpa_command(intf, "SET oce 0") < 0) {
3998 send_resp(dut, conn, SIGMA_ERROR,
3999 "ErrorCode,Failed to disable OCE");
4000 return 0;
4001 }
4002 } else if (val && strcasecmp(val, "Enable") == 0) {
4003 if (wpa_command(intf, "SET oce 1") < 0) {
4004 send_resp(dut, conn, SIGMA_ERROR,
4005 "ErrorCode,Failed to enable OCE");
4006 return 0;
4007 }
4008 }
4009
vamsi krishnaa2799492017-12-05 14:28:01 +05304010 val = get_param(cmd, "FILScap");
4011 if (val && (atoi(val) == 1)) {
4012 if (wpa_command(intf, "SET disable_fils 0") < 0) {
4013 send_resp(dut, conn, SIGMA_ERROR,
4014 "ErrorCode,Failed to enable FILS");
4015 return 0;
4016 }
4017 } else if (val && (atoi(val) == 0)) {
4018 if (wpa_command(intf, "SET disable_fils 1") < 0) {
4019 send_resp(dut, conn, SIGMA_ERROR,
4020 "ErrorCode,Failed to disable FILS");
4021 return 0;
4022 }
4023 }
4024
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304025 val = get_param(cmd, "FILSHLP");
4026 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004027 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304028 sizeof(text)) < 0)
4029 return -2;
4030 hwaddr_aton(text, addr);
4031 snprintf(buf, sizeof(buf),
4032 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
4033 "080045100140000040004011399e00000000ffffffff00440043"
4034 "012cb30001010600fd4f46410000000000000000000000000000"
4035 "000000000000"
4036 "%02x%02x%02x%02x%02x%02x"
4037 "0000000000000000000000000000000000000000000000000000"
4038 "0000000000000000000000000000000000000000000000000000"
4039 "0000000000000000000000000000000000000000000000000000"
4040 "0000000000000000000000000000000000000000000000000000"
4041 "0000000000000000000000000000000000000000000000000000"
4042 "0000000000000000000000000000000000000000000000000000"
4043 "0000000000000000000000000000000000000000000000000000"
4044 "0000000000000000000000000000000000000000638253633501"
4045 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
4046 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
4047 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
4048 if (wpa_command(intf, buf)) {
4049 send_resp(dut, conn, SIGMA_ERROR,
4050 "ErrorCode,Failed to add HLP");
4051 return 0;
4052 }
4053 dut->fils_hlp = 1;
4054 }
4055
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304056 return 1;
4057}
4058
4059
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004060static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
4061 const char *val)
4062{
4063 int counter = 0;
4064 char token[50];
4065 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304066 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004067
Peng Xub8fc5cc2017-05-10 17:27:28 -07004068 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004069 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304070 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004071 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004072 if (strcmp(result, "disable") == 0)
4073 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
4074 else
4075 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05304076 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004077 counter++;
4078 }
4079}
4080
4081
4082static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
4083 const char *val)
4084{
4085 char buf[100];
4086
4087 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
4088 if (system(buf) != 0) {
4089 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
4090 }
4091}
4092
4093
4094static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4095 const char *val)
4096{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004097 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004098 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004099 }
4100}
4101
4102
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004103static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
4104 const char *val)
4105{
4106#ifdef NL80211_SUPPORT
4107 struct nl_msg *msg;
4108 int ret = 0;
4109 struct nlattr *params;
4110 int ifindex;
4111 int wmmenable = 1;
4112
4113 if (val &&
4114 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
4115 wmmenable = 0;
4116
4117 ifindex = if_nametoindex(intf);
4118 if (ifindex == 0) {
4119 sigma_dut_print(dut, DUT_MSG_ERROR,
4120 "%s: Index for interface %s failed",
4121 __func__, intf);
4122 return -1;
4123 }
4124
4125 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4126 NL80211_CMD_VENDOR)) ||
4127 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4128 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4129 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4130 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4131 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4132 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
4133 wmmenable)) {
4134 sigma_dut_print(dut, DUT_MSG_ERROR,
4135 "%s: err in adding vendor_cmd and vendor_data",
4136 __func__);
4137 nlmsg_free(msg);
4138 return -1;
4139 }
4140 nla_nest_end(msg, params);
4141
4142 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4143 if (ret) {
4144 sigma_dut_print(dut, DUT_MSG_ERROR,
4145 "%s: err in send_and_recv_msgs, ret=%d",
4146 __func__, ret);
4147 }
4148 return ret;
4149#else /* NL80211_SUPPORT */
4150 sigma_dut_print(dut, DUT_MSG_ERROR,
4151 "WMM cannot be changed without NL80211_SUPPORT defined");
4152 return -1;
4153#endif /* NL80211_SUPPORT */
4154}
4155
4156
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004157static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
4158 const char *val)
4159{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004160 int sgi20;
4161
4162 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
4163
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004164 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004165}
4166
4167
4168static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
4169 const char *val)
4170{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304171 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004172
4173 /* Disable Tx Beam forming when using a fixed rate */
4174 ath_disable_txbf(dut, intf);
4175
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05304176 v = atoi(val);
4177 if (v < 0 || v > 32) {
4178 sigma_dut_print(dut, DUT_MSG_ERROR,
4179 "Invalid Fixed MCS rate: %d", v);
4180 return;
4181 }
4182 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004183
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004184 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004185
4186 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004187 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004188}
4189
4190
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08004191static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
4192 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004193{
4194 char buf[60];
4195
4196 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
4197 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
4198 else
4199 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
4200
4201 if (system(buf) != 0)
4202 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
4203}
4204
4205
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004206static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
4207 int ampdu)
4208{
4209 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004210 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004211
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08004212 if (ampdu)
4213 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07004214 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
4215 if (system(buf) != 0) {
4216 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
4217 return -1;
4218 }
4219
4220 return 0;
4221}
4222
4223
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004224static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4225 const char *val)
4226{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004227 run_iwpriv(dut, intf, "tx_stbc %s", val);
4228 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004229}
4230
4231
4232static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
4233 const char *val)
4234{
4235 char buf[60];
4236
Peng Xucc317ed2017-05-18 16:44:37 -07004237 if (strcmp(val, "160") == 0) {
4238 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
4239 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004240 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
4241 } else if (strcmp(val, "40") == 0) {
4242 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
4243 } else if (strcmp(val, "20") == 0) {
4244 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
4245 } else if (strcasecmp(val, "Auto") == 0) {
4246 buf[0] = '\0';
4247 } else {
4248 sigma_dut_print(dut, DUT_MSG_ERROR,
4249 "WIDTH/CTS_WIDTH value not supported");
4250 return -1;
4251 }
4252
4253 if (buf[0] != '\0' && system(buf) != 0) {
4254 sigma_dut_print(dut, DUT_MSG_ERROR,
4255 "Failed to set WIDTH/CTS_WIDTH");
4256 return -1;
4257 }
4258
4259 return 0;
4260}
4261
4262
4263int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
4264 const char *intf, const char *val)
4265{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004266 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004267 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004268 dut->chwidth = 0;
4269 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004270 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004271 dut->chwidth = 0;
4272 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004273 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004274 dut->chwidth = 1;
4275 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004276 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004277 dut->chwidth = 2;
4278 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07004279 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004280 dut->chwidth = 3;
4281 } else {
4282 send_resp(dut, conn, SIGMA_ERROR,
4283 "ErrorCode,WIDTH not supported");
4284 return -1;
4285 }
4286
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004287 return 0;
4288}
4289
4290
4291static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
4292 const char *val)
4293{
4294 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07004295 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004296
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004297 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004298 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004299 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08004300 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004301 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07004302 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004303 } else {
4304 sigma_dut_print(dut, DUT_MSG_ERROR,
4305 "SP_STREAM value not supported");
4306 return -1;
4307 }
4308
4309 if (system(buf) != 0) {
4310 sigma_dut_print(dut, DUT_MSG_ERROR,
4311 "Failed to set SP_STREAM");
4312 return -1;
4313 }
4314
Arif Hussainac6c5112018-05-25 17:34:00 -07004315 dut->sta_nss = sta_nss;
4316
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004317 return 0;
4318}
4319
4320
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05304321static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
4322 const char *val)
4323{
4324 char buf[60];
4325
4326 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
4327 if (system(buf) != 0)
4328 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
4329
4330 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
4331 if (system(buf) != 0)
4332 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
4333}
4334
4335
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304336static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
4337 struct sigma_conn *conn,
4338 const char *intf, int capa)
4339{
4340 char buf[32];
4341
4342 if (capa > 0 && capa < 4) {
4343 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
4344 if (wpa_command(intf, buf) < 0) {
4345 send_resp(dut, conn, SIGMA_ERROR,
4346 "ErrorCode, Failed to set cellular data capability");
4347 return 0;
4348 }
4349 return 1;
4350 }
4351
4352 sigma_dut_print(dut, DUT_MSG_ERROR,
4353 "Invalid Cellular data capability: %d", capa);
4354 send_resp(dut, conn, SIGMA_INVALID,
4355 "ErrorCode,Invalid cellular data capability");
4356 return 0;
4357}
4358
4359
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304360static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
4361 const char *intf, const char *val)
4362{
4363 if (strcasecmp(val, "Disable") == 0) {
4364 if (wpa_command(intf, "SET roaming 0") < 0) {
4365 send_resp(dut, conn, SIGMA_ERROR,
4366 "ErrorCode,Failed to disable roaming");
4367 return 0;
4368 }
4369 return 1;
4370 }
4371
4372 if (strcasecmp(val, "Enable") == 0) {
4373 if (wpa_command(intf, "SET roaming 1") < 0) {
4374 send_resp(dut, conn, SIGMA_ERROR,
4375 "ErrorCode,Failed to enable roaming");
4376 return 0;
4377 }
4378 return 1;
4379 }
4380
4381 sigma_dut_print(dut, DUT_MSG_ERROR,
4382 "Invalid value provided for roaming: %s", val);
4383 send_resp(dut, conn, SIGMA_INVALID,
4384 "ErrorCode,Unknown value provided for Roaming");
4385 return 0;
4386}
4387
4388
Ashwini Patila75de5a2017-04-13 16:35:05 +05304389static int mbo_set_assoc_disallow(struct sigma_dut *dut,
4390 struct sigma_conn *conn,
4391 const char *intf, const char *val)
4392{
4393 if (strcasecmp(val, "Disable") == 0) {
4394 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
4395 send_resp(dut, conn, SIGMA_ERROR,
4396 "ErrorCode,Failed to disable Assoc_disallow");
4397 return 0;
4398 }
4399 return 1;
4400 }
4401
4402 if (strcasecmp(val, "Enable") == 0) {
4403 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
4404 send_resp(dut, conn, SIGMA_ERROR,
4405 "ErrorCode,Failed to enable Assoc_disallow");
4406 return 0;
4407 }
4408 return 1;
4409 }
4410
4411 sigma_dut_print(dut, DUT_MSG_ERROR,
4412 "Invalid value provided for Assoc_disallow: %s", val);
4413 send_resp(dut, conn, SIGMA_INVALID,
4414 "ErrorCode,Unknown value provided for Assoc_disallow");
4415 return 0;
4416}
4417
4418
Ashwini Patilc63161e2017-04-13 16:30:23 +05304419static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
4420 const char *intf, const char *val)
4421{
4422 if (strcasecmp(val, "Reject") == 0) {
4423 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
4424 send_resp(dut, conn, SIGMA_ERROR,
4425 "ErrorCode,Failed to Reject BTM Request");
4426 return 0;
4427 }
4428 return 1;
4429 }
4430
4431 if (strcasecmp(val, "Accept") == 0) {
4432 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
4433 send_resp(dut, conn, SIGMA_ERROR,
4434 "ErrorCode,Failed to Accept BTM Request");
4435 return 0;
4436 }
4437 return 1;
4438 }
4439
4440 sigma_dut_print(dut, DUT_MSG_ERROR,
4441 "Invalid value provided for BSS_Transition: %s", val);
4442 send_resp(dut, conn, SIGMA_INVALID,
4443 "ErrorCode,Unknown value provided for BSS_Transition");
4444 return 0;
4445}
4446
4447
Ashwini Patil00402582017-04-13 12:29:39 +05304448static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
4449 struct sigma_conn *conn,
4450 const char *intf,
4451 struct sigma_cmd *cmd)
4452{
4453 const char *ch, *pref, *op_class, *reason;
4454 char buf[120];
4455 int len, ret;
4456
4457 pref = get_param(cmd, "Ch_Pref");
4458 if (!pref)
4459 return 1;
4460
4461 if (strcasecmp(pref, "clear") == 0) {
4462 free(dut->non_pref_ch_list);
4463 dut->non_pref_ch_list = NULL;
4464 } else {
4465 op_class = get_param(cmd, "Ch_Op_Class");
4466 if (!op_class) {
4467 send_resp(dut, conn, SIGMA_INVALID,
4468 "ErrorCode,Ch_Op_Class not provided");
4469 return 0;
4470 }
4471
4472 ch = get_param(cmd, "Ch_Pref_Num");
4473 if (!ch) {
4474 send_resp(dut, conn, SIGMA_INVALID,
4475 "ErrorCode,Ch_Pref_Num not provided");
4476 return 0;
4477 }
4478
4479 reason = get_param(cmd, "Ch_Reason_Code");
4480 if (!reason) {
4481 send_resp(dut, conn, SIGMA_INVALID,
4482 "ErrorCode,Ch_Reason_Code not provided");
4483 return 0;
4484 }
4485
4486 if (!dut->non_pref_ch_list) {
4487 dut->non_pref_ch_list =
4488 calloc(1, NON_PREF_CH_LIST_SIZE);
4489 if (!dut->non_pref_ch_list) {
4490 send_resp(dut, conn, SIGMA_ERROR,
4491 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
4492 return 0;
4493 }
4494 }
4495 len = strlen(dut->non_pref_ch_list);
4496 ret = snprintf(dut->non_pref_ch_list + len,
4497 NON_PREF_CH_LIST_SIZE - len,
4498 " %s:%s:%s:%s", op_class, ch, pref, reason);
4499 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
4500 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
4501 dut->non_pref_ch_list);
4502 } else {
4503 sigma_dut_print(dut, DUT_MSG_ERROR,
4504 "snprintf failed for non_pref_list, ret = %d",
4505 ret);
4506 send_resp(dut, conn, SIGMA_ERROR,
4507 "ErrorCode,snprintf failed");
4508 free(dut->non_pref_ch_list);
4509 dut->non_pref_ch_list = NULL;
4510 return 0;
4511 }
4512 }
4513
4514 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
4515 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
4516 if (ret < 0 || ret >= (int) sizeof(buf)) {
4517 sigma_dut_print(dut, DUT_MSG_DEBUG,
4518 "snprintf failed for set non_pref_chan, ret: %d",
4519 ret);
4520 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
4521 return 0;
4522 }
4523
4524 if (wpa_command(intf, buf) < 0) {
4525 send_resp(dut, conn, SIGMA_ERROR,
4526 "ErrorCode,Failed to set non-preferred channel list");
4527 return 0;
4528 }
4529
4530 return 1;
4531}
4532
4533
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004534#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004535
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08004536static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
4537 uint8_t cfg)
4538{
4539 struct nl_msg *msg;
4540 int ret = 0;
4541 struct nlattr *params;
4542 int ifindex;
4543
4544 ifindex = if_nametoindex(intf);
4545 if (ifindex == 0) {
4546 sigma_dut_print(dut, DUT_MSG_ERROR,
4547 "%s: Index for interface %s failed",
4548 __func__, intf);
4549 return -1;
4550 }
4551
4552 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4553 NL80211_CMD_VENDOR)) ||
4554 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4555 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4556 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4557 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4558 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4559 nla_put_u8(msg,
4560 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
4561 cfg)) {
4562 sigma_dut_print(dut, DUT_MSG_ERROR,
4563 "%s: err in adding vendor_cmd and vendor_data",
4564 __func__);
4565 nlmsg_free(msg);
4566 return -1;
4567 }
4568 nla_nest_end(msg, params);
4569
4570 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4571 if (ret) {
4572 sigma_dut_print(dut, DUT_MSG_ERROR,
4573 "%s: err in send_and_recv_msgs, ret=%d",
4574 __func__, ret);
4575 }
4576 return ret;
4577}
4578
4579
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004580static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
4581 enum he_fragmentation_val frag)
4582{
4583 struct nl_msg *msg;
4584 int ret = 0;
4585 struct nlattr *params;
4586 int ifindex;
4587
4588 ifindex = if_nametoindex(intf);
4589 if (ifindex == 0) {
4590 sigma_dut_print(dut, DUT_MSG_ERROR,
4591 "%s: Index for interface %s failed",
4592 __func__, intf);
4593 return -1;
4594 }
4595
4596 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4597 NL80211_CMD_VENDOR)) ||
4598 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4599 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4600 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4601 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4602 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4603 nla_put_u8(msg,
4604 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION,
4605 frag)) {
4606 sigma_dut_print(dut, DUT_MSG_ERROR,
4607 "%s: err in adding vendor_cmd and vendor_data",
4608 __func__);
4609 nlmsg_free(msg);
4610 return -1;
4611 }
4612 nla_nest_end(msg, params);
4613
4614 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4615 if (ret) {
4616 sigma_dut_print(dut, DUT_MSG_ERROR,
4617 "%s: err in send_and_recv_msgs, ret=%d",
4618 __func__, ret);
4619 }
4620 return ret;
4621}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004622
4623
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08004624int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
4625 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07004626{
4627 struct nl_msg *msg;
4628 int ret = 0;
4629 struct nlattr *params;
4630 int ifindex;
4631
4632 ifindex = if_nametoindex(intf);
4633 if (ifindex == 0) {
4634 sigma_dut_print(dut, DUT_MSG_ERROR,
4635 "%s: Index for interface %s failed",
4636 __func__, intf);
4637 return -1;
4638 }
4639
4640 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4641 NL80211_CMD_VENDOR)) ||
4642 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4643 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4644 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4645 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4646 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4647 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF,
4648 ltf)) {
4649 sigma_dut_print(dut, DUT_MSG_ERROR,
4650 "%s: err in adding vendor_cmd and vendor_data",
4651 __func__);
4652 nlmsg_free(msg);
4653 return -1;
4654 }
4655 nla_nest_end(msg, params);
4656
4657 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4658 if (ret) {
4659 sigma_dut_print(dut, DUT_MSG_ERROR,
4660 "%s: err in send_and_recv_msgs, ret=%d",
4661 __func__, ret);
4662 }
4663 return ret;
4664}
4665
4666
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08004667static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
4668 int noack, enum qca_wlan_ac_type ac)
4669{
4670 struct nl_msg *msg;
4671 int ret = 0;
4672 struct nlattr *params;
4673 int ifindex;
4674
4675 ifindex = if_nametoindex(intf);
4676 if (ifindex == 0) {
4677 sigma_dut_print(dut, DUT_MSG_ERROR,
4678 "%s: Index for interface %s failed",
4679 __func__, intf);
4680 return -1;
4681 }
4682
4683 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
4684 NL80211_CMD_VENDOR)) ||
4685 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
4686 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
4687 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
4688 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
4689 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
4690 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
4691 noack) ||
4692 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
4693 ac)) {
4694 sigma_dut_print(dut, DUT_MSG_ERROR,
4695 "%s: err in adding vendor_cmd and vendor_data",
4696 __func__);
4697 nlmsg_free(msg);
4698 return -1;
4699 }
4700 nla_nest_end(msg, params);
4701
4702 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
4703 if (ret) {
4704 sigma_dut_print(dut, DUT_MSG_ERROR,
4705 "%s: err in send_and_recv_msgs, ret=%d",
4706 __func__, ret);
4707 }
4708 return ret;
4709}
4710
4711
4712static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
4713 const char *val)
4714{
4715 int noack, ret;
4716 char token[100];
4717 char *result;
4718 char *saveptr;
4719 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
4720
4721 strlcpy(token, val, sizeof(token));
4722 token[sizeof(token) - 1] = '\0';
4723 result = strtok_r(token, ":", &saveptr);
4724 while (result) {
4725 noack = strcasecmp(result, "Disable") != 0;
4726 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
4727 if (ret) {
4728 sigma_dut_print(dut, DUT_MSG_ERROR,
4729 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
4730 ac, ret);
4731 }
4732 result = strtok_r(NULL, ":", &saveptr);
4733 ac++;
4734 }
4735}
4736
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08004737#endif /* NL80211_SUPPORT */
4738
4739
Jouni Malinenf7222712019-06-13 01:50:21 +03004740static enum sigma_cmd_result
4741cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
4742 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004743{
4744 const char *intf = get_param(cmd, "Interface");
4745 const char *val;
4746
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03004747 val = get_param(cmd, "FT_DS");
4748 if (val) {
4749 if (strcasecmp(val, "Enable") == 0) {
4750 dut->sta_ft_ds = 1;
4751 } else if (strcasecmp(val, "Disable") == 0) {
4752 dut->sta_ft_ds = 0;
4753 } else {
4754 send_resp(dut, conn, SIGMA_ERROR,
4755 "errorCode,Unsupported value for FT_DS");
4756 return STATUS_SENT_ERROR;
4757 }
4758 }
4759
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004760 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03004761 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
4762 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004763 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
4764 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004765
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004766 if (val && strcasecmp(val, "LOC") == 0)
4767 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02004768 if (val && strcasecmp(val, "60GHZ") == 0) {
4769 val = get_param(cmd, "WPS");
4770 if (val && strcasecmp(val, "disable") == 0) {
4771 dut->wps_disable = 1;
4772 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
4773 } else {
4774 /* wps_disable can have other value from the previous
4775 * test, so make sure it has the correct value.
4776 */
4777 dut->wps_disable = 0;
4778 }
4779
4780 val = get_param(cmd, "P2P");
4781 if (val && strcasecmp(val, "disable") == 0)
4782 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
4783 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07004784
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02004785 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
4786 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
4787
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004788#ifdef ANDROID_NAN
4789 if (val && strcasecmp(val, "NAN") == 0)
4790 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
4791#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07004792#ifdef MIRACAST
4793 if (val && (strcasecmp(val, "WFD") == 0 ||
4794 strcasecmp(val, "DisplayR2") == 0))
4795 return miracast_preset_testparameters(dut, conn, cmd);
4796#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004797
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304798 if (val && strcasecmp(val, "MBO") == 0) {
4799 val = get_param(cmd, "Cellular_Data_Cap");
4800 if (val &&
4801 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
4802 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05304803
4804 val = get_param(cmd, "Ch_Pref");
4805 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
4806 return 0;
4807
Ashwini Patilc63161e2017-04-13 16:30:23 +05304808 val = get_param(cmd, "BSS_Transition");
4809 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
4810 return 0;
4811
Ashwini Patila75de5a2017-04-13 16:35:05 +05304812 val = get_param(cmd, "Assoc_Disallow");
4813 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
4814 return 0;
4815
Ashwini Patil9183fdb2017-04-13 16:58:25 +05304816 val = get_param(cmd, "Roaming");
4817 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
4818 return 0;
4819
Ashwini Patil68d02cd2017-01-10 15:39:16 +05304820 return 1;
4821 }
4822
Ankita Bajaja2cb5672017-10-25 16:08:28 +05304823 if (val && strcasecmp(val, "OCE") == 0)
4824 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
4825
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004826#if 0
4827 val = get_param(cmd, "Supplicant");
4828 if (val && strcasecmp(val, "Default") != 0) {
4829 send_resp(dut, conn, SIGMA_ERROR,
4830 "ErrorCode,Only default(Vendor) supplicant "
4831 "supported");
4832 return 0;
4833 }
4834#endif
4835
4836 val = get_param(cmd, "RTS");
4837 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004838 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004839 case DRIVER_ATHEROS:
4840 ath_sta_set_rts(dut, intf, val);
4841 break;
4842 default:
4843#if 0
4844 send_resp(dut, conn, SIGMA_ERROR,
4845 "ErrorCode,Setting RTS not supported");
4846 return 0;
4847#else
4848 sigma_dut_print(dut, DUT_MSG_DEBUG,
4849 "Setting RTS not supported");
4850 break;
4851#endif
4852 }
4853 }
4854
4855#if 0
4856 val = get_param(cmd, "FRGMNT");
4857 if (val) {
4858 /* TODO */
4859 send_resp(dut, conn, SIGMA_ERROR,
4860 "ErrorCode,Setting FRGMNT not supported");
4861 return 0;
4862 }
4863#endif
4864
4865#if 0
4866 val = get_param(cmd, "Preamble");
4867 if (val) {
4868 /* TODO: Long/Short */
4869 send_resp(dut, conn, SIGMA_ERROR,
4870 "ErrorCode,Setting Preamble not supported");
4871 return 0;
4872 }
4873#endif
4874
4875 val = get_param(cmd, "Mode");
4876 if (val) {
4877 if (strcmp(val, "11b") == 0 ||
4878 strcmp(val, "11g") == 0 ||
4879 strcmp(val, "11a") == 0 ||
4880 strcmp(val, "11n") == 0 ||
4881 strcmp(val, "11ng") == 0 ||
4882 strcmp(val, "11nl") == 0 ||
4883 strcmp(val, "11nl(nabg)") == 0 ||
4884 strcmp(val, "AC") == 0 ||
4885 strcmp(val, "11AC") == 0 ||
4886 strcmp(val, "11ac") == 0 ||
4887 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08004888 strcmp(val, "11an") == 0 ||
4889 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004890 /* STA supports all modes by default */
4891 } else {
4892 send_resp(dut, conn, SIGMA_ERROR,
4893 "ErrorCode,Setting Mode not supported");
4894 return 0;
4895 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004896
4897 /* Change the mode only in case of testbed for HE program
4898 * and for 11a and 11g modes only. */
4899 if (dut->program == PROGRAM_HE &&
4900 dut->device_type == STA_testbed) {
4901 int phymode;
4902 char buf[60];
4903
4904 if (strcmp(val, "11a") == 0) {
Amarnath Hullur Subramanyam94dfaf02018-03-02 19:26:57 -08004905 phymode = 1; /* IEEE80211_MODE_11A */
4906 } else if (strcmp(val, "11g") == 0) {
4907 phymode = 3; /* IEEE80211_MODE_11G */
4908 } else if (strcmp(val, "11b") == 0) {
4909 phymode = 2; /* IEEE80211_MODE_11B */
4910 } else if (strcmp(val, "11n") == 0 ||
4911 strcmp(val, "11nl") == 0 ||
4912 strcmp(val, "11nl(nabg)") == 0) {
4913 phymode = 22; /* IEEE80211_MODE_11AGN */
4914 } else if (strcmp(val, "11ng") == 0) {
4915 phymode = 13; /* IEEE80211_MODE_11NG_HT40 */
4916 } else if (strcmp(val, "AC") == 0 ||
4917 strcasecmp(val, "11AC") == 0) {
4918 phymode = 19; /* IEEE80211_MODE_11AC_VHT80 */
4919 } else if (strcmp(val, "11na") == 0 ||
4920 strcasecmp(val, "11an") == 0) {
4921 phymode = 14; /* IEEE80211_MODE_11NA_HT40 */
4922 } else if (strcmp(val, "11ax") == 0) {
4923 phymode = 0; /* IEEE80211_MODE_AUTO */
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08004924 } else {
4925 sigma_dut_print(dut, DUT_MSG_DEBUG,
4926 "Ignoring mode change for mode: %s",
4927 val);
4928 phymode = -1;
4929 }
4930 if (phymode != -1) {
4931 snprintf(buf, sizeof(buf),
4932 "iwpriv %s setphymode %d",
4933 intf, phymode);
4934 if (system(buf) != 0) {
4935 sigma_dut_print(dut, DUT_MSG_ERROR,
4936 "iwpriv setting of phymode failed");
4937 }
4938 }
4939 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004940 }
4941
4942 val = get_param(cmd, "wmm");
4943 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004944 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004945 case DRIVER_ATHEROS:
4946 ath_sta_set_wmm(dut, intf, val);
4947 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08004948 case DRIVER_WCN:
4949 wcn_sta_set_wmm(dut, intf, val);
4950 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004951 default:
4952 sigma_dut_print(dut, DUT_MSG_DEBUG,
4953 "Setting wmm not supported");
4954 break;
4955 }
4956 }
4957
4958 val = get_param(cmd, "Powersave");
4959 if (val) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004960 char buf[60];
4961
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004962 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004963 if (get_driver_type(dut) == DRIVER_WCN) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004964 snprintf(buf, sizeof(buf),
4965 "iwpriv %s setPower 2", intf);
4966 if (system(buf) != 0) {
4967 sigma_dut_print(dut, DUT_MSG_ERROR,
4968 "iwpriv setPower 2 failed");
4969 return 0;
4970 }
4971 }
4972
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004973 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004974 "P2P_SET ps 0") < 0)
4975 return -2;
4976 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004977 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
4978 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004979 } else if (strcmp(val, "1") == 0 ||
4980 strcasecmp(val, "PSPoll") == 0 ||
4981 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004982 if (get_driver_type(dut) == DRIVER_WCN) {
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08004983 snprintf(buf, sizeof(buf),
4984 "iwpriv %s setPower 1", intf);
4985 if (system(buf) != 0) {
4986 sigma_dut_print(dut, DUT_MSG_ERROR,
4987 "iwpriv setPower 1 failed");
4988 return 0;
4989 }
4990 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004991 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004992 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004993 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004994 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004995 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004996 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004997 "P2P_SET ps 99") < 0)
4998 return -2;
4999 } else if (strcmp(val, "2") == 0 ||
5000 strcasecmp(val, "Fast") == 0) {
5001 /* TODO */
5002 send_resp(dut, conn, SIGMA_ERROR,
5003 "ErrorCode,Powersave=Fast not supported");
5004 return 0;
5005 } else if (strcmp(val, "3") == 0 ||
5006 strcasecmp(val, "PSNonPoll") == 0) {
5007 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005008 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
5009 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005010
5011 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005012 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005013 "P2P_SET ps 1") < 0)
5014 return -2;
5015 } else
5016 return -1;
5017 }
5018
5019 val = get_param(cmd, "NoAck");
5020 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005021 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005022 case DRIVER_ATHEROS:
5023 ath_sta_set_noack(dut, intf, val);
5024 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005025#ifdef NL80211_SUPPORT
5026 case DRIVER_WCN:
5027 wcn_sta_set_noack(dut, intf, val);
5028 break;
5029#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005030 default:
5031 send_resp(dut, conn, SIGMA_ERROR,
5032 "ErrorCode,Setting NoAck not supported");
5033 return 0;
5034 }
5035 }
5036
5037 val = get_param(cmd, "IgnoreChswitchProhibit");
5038 if (val) {
5039 /* TODO: Enabled/disabled */
5040 if (strcasecmp(val, "Enabled") == 0) {
5041 send_resp(dut, conn, SIGMA_ERROR,
5042 "ErrorCode,Enabling IgnoreChswitchProhibit "
5043 "not supported");
5044 return 0;
5045 }
5046 }
5047
5048 val = get_param(cmd, "TDLS");
5049 if (val) {
5050 if (strcasecmp(val, "Disabled") == 0) {
5051 if (wpa_command(intf, "SET tdls_disabled 1")) {
5052 send_resp(dut, conn, SIGMA_ERROR,
5053 "ErrorCode,Failed to disable TDLS");
5054 return 0;
5055 }
5056 } else if (strcasecmp(val, "Enabled") == 0) {
5057 if (wpa_command(intf, "SET tdls_disabled 0")) {
5058 send_resp(dut, conn, SIGMA_ERROR,
5059 "ErrorCode,Failed to enable TDLS");
5060 return 0;
5061 }
5062 } else {
5063 send_resp(dut, conn, SIGMA_ERROR,
5064 "ErrorCode,Unsupported TDLS value");
5065 return 0;
5066 }
5067 }
5068
5069 val = get_param(cmd, "TDLSmode");
5070 if (val) {
5071 if (strcasecmp(val, "Default") == 0) {
5072 wpa_command(intf, "SET tdls_testing 0");
5073 } else if (strcasecmp(val, "APProhibit") == 0) {
5074 if (wpa_command(intf, "SET tdls_testing 0x400")) {
5075 send_resp(dut, conn, SIGMA_ERROR,
5076 "ErrorCode,Failed to enable ignore "
5077 "APProhibit TDLS mode");
5078 return 0;
5079 }
5080 } else if (strcasecmp(val, "HiLoMac") == 0) {
5081 /* STA should respond with TDLS setup req for a TDLS
5082 * setup req */
5083 if (wpa_command(intf, "SET tdls_testing 0x80")) {
5084 send_resp(dut, conn, SIGMA_ERROR,
5085 "ErrorCode,Failed to enable HiLoMac "
5086 "TDLS mode");
5087 return 0;
5088 }
5089 } else if (strcasecmp(val, "WeakSecurity") == 0) {
5090 /*
5091 * Since all security modes are enabled by default when
5092 * Sigma control is used, there is no need to do
5093 * anything here.
5094 */
5095 } else if (strcasecmp(val, "ExistLink") == 0) {
5096 /*
5097 * Since we allow new TDLS Setup Request even if there
5098 * is an existing link, nothing needs to be done for
5099 * this.
5100 */
5101 } else {
5102 /* TODO:
5103 * ExistLink: STA should send TDLS setup req even if
5104 * direct link already exists
5105 */
5106 send_resp(dut, conn, SIGMA_ERROR,
5107 "ErrorCode,Unsupported TDLSmode value");
5108 return 0;
5109 }
5110 }
5111
5112 val = get_param(cmd, "FakePubKey");
5113 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
5114 send_resp(dut, conn, SIGMA_ERROR,
5115 "ErrorCode,Failed to enable FakePubKey");
5116 return 0;
5117 }
5118
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08005119#ifdef NL80211_SUPPORT
5120 val = get_param(cmd, "FrgmntSupport");
5121 if (val) {
5122 if (strcasecmp(val, "Enable") == 0) {
5123 if (sta_set_he_fragmentation(dut, intf,
5124 HE_FRAG_LEVEL1)) {
5125 send_resp(dut, conn, SIGMA_ERROR,
5126 "ErrorCode,Failed to enable HE Fragmentation");
5127 return 0;
5128 }
5129 } else if (strcasecmp(val, "Disable") == 0) {
5130 if (sta_set_he_fragmentation(dut, intf,
5131 HE_FRAG_DISABLE)) {
5132 send_resp(dut, conn, SIGMA_ERROR,
5133 "ErrorCode,Failed to disable HE Fragmentation");
5134 return 0;
5135 }
5136 }
5137 }
5138#endif /* NL80211_SUPPORT */
5139
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005140 return 1;
5141}
5142
5143
5144static const char * ath_get_radio_name(const char *radio_name)
5145{
5146 if (radio_name == NULL)
5147 return "wifi0";
5148 if (strcmp(radio_name, "wifi1") == 0)
5149 return "wifi1";
5150 if (strcmp(radio_name, "wifi2") == 0)
5151 return "wifi2";
5152 return "wifi0";
5153}
5154
5155
5156static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
5157 const char *val)
5158{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005159 unsigned int vht_mcsmap = 0;
5160 int txchainmask = 0;
5161 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5162
5163 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5164 if (dut->testbed_flag_txsp == 1) {
5165 vht_mcsmap = 0xfffc;
5166 dut->testbed_flag_txsp = 0;
5167 } else {
5168 vht_mcsmap = 0xfffe;
5169 }
5170 txchainmask = 1;
5171 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5172 if (dut->testbed_flag_txsp == 1) {
5173 vht_mcsmap = 0xfff0;
5174 dut->testbed_flag_txsp = 0;
5175 } else {
5176 vht_mcsmap = 0xfffa;
5177 }
5178 txchainmask = 3;
5179 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5180 if (dut->testbed_flag_txsp == 1) {
5181 vht_mcsmap = 0xffc0;
5182 dut->testbed_flag_txsp = 0;
5183 } else {
5184 vht_mcsmap = 0xffea;
5185 }
5186 txchainmask = 7;
5187 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5188 if (dut->testbed_flag_txsp == 1) {
5189 vht_mcsmap = 0xff00;
5190 dut->testbed_flag_txsp = 0;
5191 } else {
5192 vht_mcsmap = 0xffaa;
5193 }
5194 txchainmask = 15;
5195 } else {
5196 if (dut->testbed_flag_txsp == 1) {
5197 vht_mcsmap = 0xffc0;
5198 dut->testbed_flag_txsp = 0;
5199 } else {
5200 vht_mcsmap = 0xffea;
5201 }
5202 }
5203
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005204 if (txchainmask)
5205 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005206
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005207 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005208}
5209
5210
5211static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
5212 const char *val)
5213{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005214 unsigned int vht_mcsmap = 0;
5215 int rxchainmask = 0;
5216 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
5217
5218 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
5219 if (dut->testbed_flag_rxsp == 1) {
5220 vht_mcsmap = 0xfffc;
5221 dut->testbed_flag_rxsp = 0;
5222 } else {
5223 vht_mcsmap = 0xfffe;
5224 }
5225 rxchainmask = 1;
5226 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
5227 if (dut->testbed_flag_rxsp == 1) {
5228 vht_mcsmap = 0xfff0;
5229 dut->testbed_flag_rxsp = 0;
5230 } else {
5231 vht_mcsmap = 0xfffa;
5232 }
5233 rxchainmask = 3;
5234 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
5235 if (dut->testbed_flag_rxsp == 1) {
5236 vht_mcsmap = 0xffc0;
5237 dut->testbed_flag_rxsp = 0;
5238 } else {
5239 vht_mcsmap = 0xffea;
5240 }
5241 rxchainmask = 7;
5242 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
5243 if (dut->testbed_flag_rxsp == 1) {
5244 vht_mcsmap = 0xff00;
5245 dut->testbed_flag_rxsp = 0;
5246 } else {
5247 vht_mcsmap = 0xffaa;
5248 }
5249 rxchainmask = 15;
5250 } else {
5251 if (dut->testbed_flag_rxsp == 1) {
5252 vht_mcsmap = 0xffc0;
5253 dut->testbed_flag_rxsp = 0;
5254 } else {
5255 vht_mcsmap = 0xffea;
5256 }
5257 }
5258
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005259 if (rxchainmask)
5260 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005261
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005262 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005263}
5264
5265
5266void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
5267{
5268 if (strcasecmp(val, "enable") == 0) {
5269 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
5270 != 0) {
5271 sigma_dut_print(dut, DUT_MSG_ERROR,
5272 "Disable BB_VHTSIGB_CRC_CALC failed");
5273 }
5274
5275 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
5276 != 0) {
5277 sigma_dut_print(dut, DUT_MSG_ERROR,
5278 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5279 }
5280 } else {
5281 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
5282 != 0) {
5283 sigma_dut_print(dut, DUT_MSG_ERROR,
5284 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
5285 }
5286
5287 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
5288 != 0) {
5289 sigma_dut_print(dut, DUT_MSG_ERROR,
5290 "Enable BB_VHTSIGB_CRC_CALC failed");
5291 }
5292 }
5293}
5294
5295
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005296static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
5297 const char *val)
5298{
5299 char buf[60];
5300
5301 if (strcmp(val, "20") == 0) {
5302 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
5303 dut->chwidth = 0;
5304 } else if (strcmp(val, "40") == 0) {
5305 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
5306 dut->chwidth = 1;
5307 } else if (strcmp(val, "80") == 0) {
5308 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
5309 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05305310 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005311 buf[0] = '\0';
5312 } else {
5313 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
5314 val);
5315 return -1;
5316 }
5317
5318 if (buf[0] != '\0' && system(buf) != 0) {
5319 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
5320 return -1;
5321 }
5322
5323 return 0;
5324}
5325
5326
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005327static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
5328 const char *intf, int addbareject)
5329{
5330#ifdef NL80211_SUPPORT
5331 struct nl_msg *msg;
5332 int ret = 0;
5333 struct nlattr *params;
5334 int ifindex;
5335
5336 ifindex = if_nametoindex(intf);
5337 if (ifindex == 0) {
5338 sigma_dut_print(dut, DUT_MSG_ERROR,
5339 "%s: Index for interface %s failed",
5340 __func__, intf);
5341 return -1;
5342 }
5343
5344 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5345 NL80211_CMD_VENDOR)) ||
5346 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5347 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5348 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5349 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5350 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5351 nla_put_u8(msg,
5352 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
5353 !addbareject)) {
5354 sigma_dut_print(dut, DUT_MSG_ERROR,
5355 "%s: err in adding vendor_cmd and vendor_data",
5356 __func__);
5357 nlmsg_free(msg);
5358 return -1;
5359 }
5360 nla_nest_end(msg, params);
5361
5362 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5363 if (ret) {
5364 sigma_dut_print(dut, DUT_MSG_ERROR,
5365 "%s: err in send_and_recv_msgs, ret=%d",
5366 __func__, ret);
5367 }
5368 return ret;
5369#else /* NL80211_SUPPORT */
5370 sigma_dut_print(dut, DUT_MSG_ERROR,
5371 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
5372 return -1;
5373#endif /* NL80211_SUPPORT */
5374}
5375
5376
5377static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
5378 int addbareject)
5379{
5380 int ret;
5381
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005382 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005383 case DRIVER_WCN:
5384 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
5385 if (ret) {
5386 sigma_dut_print(dut, DUT_MSG_ERROR,
5387 "nlvendor_sta_set_addba_reject failed, ret:%d",
5388 ret);
5389 return ret;
5390 }
5391 break;
5392 default:
5393 sigma_dut_print(dut, DUT_MSG_ERROR,
5394 "errorCode,Unsupported ADDBA_REJECT with the current driver");
5395 ret = -1;
5396 break;
5397 }
5398
5399 return ret;
5400}
5401
5402
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005403static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
5404 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005405{
5406#ifdef NL80211_SUPPORT
5407 struct nl_msg *msg;
5408 int ret = 0;
5409 struct nlattr *params;
5410 int ifindex;
5411
5412 ifindex = if_nametoindex(intf);
5413 if (ifindex == 0) {
5414 sigma_dut_print(dut, DUT_MSG_ERROR,
5415 "%s: Index for interface %s failed",
5416 __func__, intf);
5417 return -1;
5418 }
5419
5420 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5421 NL80211_CMD_VENDOR)) ||
5422 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5423 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5424 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5425 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5426 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5427 nla_put_u8(msg,
5428 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005429 enable)) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005430 sigma_dut_print(dut, DUT_MSG_ERROR,
5431 "%s: err in adding vendor_cmd and vendor_data",
5432 __func__);
5433 nlmsg_free(msg);
5434 return -1;
5435 }
5436 nla_nest_end(msg, params);
5437
5438 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5439 if (ret) {
5440 sigma_dut_print(dut, DUT_MSG_ERROR,
5441 "%s: err in send_and_recv_msgs, ret=%d",
5442 __func__, ret);
5443 }
5444 return ret;
5445#else /* NL80211_SUPPORT */
5446 sigma_dut_print(dut, DUT_MSG_ERROR,
5447 "Disable addba not possible without NL80211_SUPPORT defined");
5448 return -1;
5449#endif /* NL80211_SUPPORT */
5450}
5451
5452
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305453#ifdef NL80211_SUPPORT
5454static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5455{
5456 struct nl_msg *msg;
5457 int ret = 0;
5458 int ifindex;
5459
5460 ifindex = if_nametoindex(intf);
5461 if (ifindex == 0) {
5462 sigma_dut_print(dut, DUT_MSG_ERROR,
5463 "%s: Index for interface %s failed",
5464 __func__, intf);
5465 return -1;
5466 }
5467
5468 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5469 NL80211_CMD_SET_WIPHY)) ||
5470 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
5471 sigma_dut_print(dut, DUT_MSG_ERROR,
5472 "%s: err in adding RTS threshold",
5473 __func__);
5474 nlmsg_free(msg);
5475 return -1;
5476 }
5477
5478 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5479 if (ret) {
5480 sigma_dut_print(dut, DUT_MSG_ERROR,
5481 "%s: err in send_and_recv_msgs, ret=%d",
5482 __func__, ret);
5483 }
5484 return ret;
5485}
5486#endif /* NL80211_SUPPORT */
5487
5488
5489static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
5490{
5491 char buf[100];
5492
5493#ifdef NL80211_SUPPORT
5494 if (nl80211_sta_set_rts(dut, intf, val) == 0)
5495 return 0;
5496 sigma_dut_print(dut, DUT_MSG_DEBUG,
5497 "Fall back to using iwconfig for setting RTS threshold");
5498#endif /* NL80211_SUPPORT */
5499
5500 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
5501 if (system(buf) != 0) {
5502 sigma_dut_print(dut, DUT_MSG_ERROR,
5503 "Failed to set RTS threshold %d", val);
5504 return -1;
5505 }
5506 return 0;
5507}
5508
5509
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005510static int cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
5511 struct sigma_conn *conn,
5512 struct sigma_cmd *cmd)
5513{
5514 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005515 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03005516 char buf[128];
5517 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005518
5519 val = get_param(cmd, "40_INTOLERANT");
5520 if (val) {
5521 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5522 /* TODO: iwpriv ht40intol through wpa_supplicant */
5523 send_resp(dut, conn, SIGMA_ERROR,
5524 "ErrorCode,40_INTOLERANT not supported");
5525 return 0;
5526 }
5527 }
5528
5529 val = get_param(cmd, "ADDBA_REJECT");
5530 if (val) {
5531 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5532 /* reject any ADDBA with status "decline" */
5533 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005534 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005535 } else {
5536 /* accept ADDBA */
5537 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005538 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005539 }
5540 }
5541
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08005542 if (addbareject >= 0 &&
5543 sta_set_addba_reject(dut, intf, addbareject) < 0) {
5544 send_resp(dut, conn, SIGMA_ERROR,
5545 "ErrorCode,set addba_reject failed");
5546 return 0;
5547 }
5548
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005549 val = get_param(cmd, "AMPDU");
5550 if (val) {
5551 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
5552 /* enable AMPDU Aggregation */
5553 if (ampdu == 0) {
5554 send_resp(dut, conn, SIGMA_ERROR,
5555 "ErrorCode,Mismatch in "
5556 "addba_reject/ampdu - "
5557 "not supported");
5558 return 0;
5559 }
5560 ampdu = 1;
5561 } else {
5562 /* disable AMPDU Aggregation */
5563 if (ampdu == 1) {
5564 send_resp(dut, conn, SIGMA_ERROR,
5565 "ErrorCode,Mismatch in "
5566 "addba_reject/ampdu - "
5567 "not supported");
5568 return 0;
5569 }
5570 ampdu = 0;
5571 }
5572 }
5573
5574 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005575 int ret;
5576
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005577 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
5578 ampdu ? "Enabling" : "Disabling");
5579 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005580 if (wpa_command(intf, buf) < 0 &&
5581 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005582 send_resp(dut, conn, SIGMA_ERROR,
5583 "ErrorCode,set aggr failed");
5584 return 0;
5585 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005586
5587 if (ampdu == 0) {
5588 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08005589 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08005590 if (ret) {
5591 sigma_dut_print(dut, DUT_MSG_ERROR,
5592 "Failed to disable addba, ret:%d",
5593 ret);
5594 }
5595 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005596 }
5597
5598 val = get_param(cmd, "AMSDU");
5599 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005600 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005601 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005602 case DRIVER_WCN:
5603 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005604 break;
5605 default:
5606 if (strcmp(val, "1") == 0 ||
5607 strcasecmp(val, "Enable") == 0) {
5608 /* Enable AMSDU Aggregation */
5609 send_resp(dut, conn, SIGMA_ERROR,
5610 "ErrorCode,AMSDU aggregation not supported");
5611 return 0;
5612 }
5613 break;
5614 }
5615 }
5616
5617 val = get_param(cmd, "STBC_RX");
5618 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005619 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005620 case DRIVER_ATHEROS:
5621 ath_sta_set_stbc(dut, intf, val);
5622 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305623 case DRIVER_WCN:
5624 wcn_sta_set_stbc(dut, intf, val);
5625 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005626 default:
5627 send_resp(dut, conn, SIGMA_ERROR,
5628 "ErrorCode,STBC_RX not supported");
5629 return 0;
5630 }
5631 }
5632
5633 val = get_param(cmd, "WIDTH");
5634 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005635 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005636 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08005637 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005638 send_resp(dut, conn, SIGMA_ERROR,
5639 "ErrorCode,Failed to set WIDTH");
5640 return 0;
5641 }
5642 break;
5643 case DRIVER_ATHEROS:
5644 if (ath_set_width(dut, conn, intf, val) < 0)
5645 return 0;
5646 break;
5647 default:
5648 sigma_dut_print(dut, DUT_MSG_ERROR,
5649 "Setting WIDTH not supported");
5650 break;
5651 }
5652 }
5653
5654 val = get_param(cmd, "SMPS");
5655 if (val) {
5656 /* TODO: Dynamic/0, Static/1, No Limit/2 */
5657 send_resp(dut, conn, SIGMA_ERROR,
5658 "ErrorCode,SMPS not supported");
5659 return 0;
5660 }
5661
5662 val = get_param(cmd, "TXSP_STREAM");
5663 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005664 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005665 case DRIVER_WCN:
5666 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5667 send_resp(dut, conn, SIGMA_ERROR,
5668 "ErrorCode,Failed to set TXSP_STREAM");
5669 return 0;
5670 }
5671 break;
5672 case DRIVER_ATHEROS:
5673 ath_sta_set_txsp_stream(dut, intf, val);
5674 break;
5675 default:
5676 sigma_dut_print(dut, DUT_MSG_ERROR,
5677 "Setting TXSP_STREAM not supported");
5678 break;
5679 }
5680 }
5681
5682 val = get_param(cmd, "RXSP_STREAM");
5683 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005684 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005685 case DRIVER_WCN:
5686 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
5687 send_resp(dut, conn, SIGMA_ERROR,
5688 "ErrorCode,Failed to set RXSP_STREAM");
5689 return 0;
5690 }
5691 break;
5692 case DRIVER_ATHEROS:
5693 ath_sta_set_rxsp_stream(dut, intf, val);
5694 break;
5695 default:
5696 sigma_dut_print(dut, DUT_MSG_ERROR,
5697 "Setting RXSP_STREAM not supported");
5698 break;
5699 }
5700 }
5701
5702 val = get_param(cmd, "DYN_BW_SGNL");
5703 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005704 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005705 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08005706 if (strcasecmp(val, "enable") == 0) {
5707 snprintf(buf, sizeof(buf),
5708 "iwpriv %s cwmenable 1", intf);
5709 if (system(buf) != 0) {
5710 sigma_dut_print(dut, DUT_MSG_ERROR,
5711 "iwpriv cwmenable 1 failed");
5712 return 0;
5713 }
5714 } else if (strcasecmp(val, "disable") == 0) {
5715 snprintf(buf, sizeof(buf),
5716 "iwpriv %s cwmenable 0", intf);
5717 if (system(buf) != 0) {
5718 sigma_dut_print(dut, DUT_MSG_ERROR,
5719 "iwpriv cwmenable 0 failed");
5720 return 0;
5721 }
5722 } else {
5723 sigma_dut_print(dut, DUT_MSG_ERROR,
5724 "Unsupported DYN_BW_SGL");
5725 }
5726
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005727 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5728 if (system(buf) != 0) {
5729 sigma_dut_print(dut, DUT_MSG_ERROR,
5730 "Failed to set cts_cbw in DYN_BW_SGNL");
5731 return 0;
5732 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005733 break;
5734 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005735 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08005736 ath_config_dyn_bw_sig(dut, intf, val);
5737 break;
5738 default:
5739 sigma_dut_print(dut, DUT_MSG_ERROR,
5740 "Failed to set DYN_BW_SGNL");
5741 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005742 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005743 }
5744
5745 val = get_param(cmd, "RTS_FORCE");
5746 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07005747 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005748 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305749 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005750 sigma_dut_print(dut, DUT_MSG_ERROR,
5751 "Failed to set RTS_FORCE 64");
5752 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03005753 res = snprintf(buf, sizeof(buf),
5754 "wifitool %s beeliner_fw_test 100 1",
5755 intf);
5756 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08005757 sigma_dut_print(dut, DUT_MSG_ERROR,
5758 "wifitool beeliner_fw_test 100 1 failed");
5759 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005760 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05305761 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02005762 sigma_dut_print(dut, DUT_MSG_ERROR,
5763 "Failed to set RTS_FORCE 2347");
5764 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005765 } else {
5766 send_resp(dut, conn, SIGMA_ERROR,
5767 "ErrorCode,RTS_FORCE value not supported");
5768 return 0;
5769 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005770 }
5771
5772 val = get_param(cmd, "CTS_WIDTH");
5773 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005774 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005775 case DRIVER_WCN:
5776 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
5777 send_resp(dut, conn, SIGMA_ERROR,
5778 "ErrorCode,Failed to set CTS_WIDTH");
5779 return 0;
5780 }
5781 break;
5782 case DRIVER_ATHEROS:
5783 ath_set_cts_width(dut, intf, val);
5784 break;
5785 default:
5786 sigma_dut_print(dut, DUT_MSG_ERROR,
5787 "Setting CTS_WIDTH not supported");
5788 break;
5789 }
5790 }
5791
5792 val = get_param(cmd, "BW_SGNL");
5793 if (val) {
5794 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005795 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005796 } else if (strcasecmp(val, "Disable") == 0) {
5797 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005798 } else {
5799 send_resp(dut, conn, SIGMA_ERROR,
5800 "ErrorCode,BW_SGNL value not supported");
5801 return 0;
5802 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005803 }
5804
5805 val = get_param(cmd, "Band");
5806 if (val) {
5807 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
5808 /* STA supports all bands by default */
5809 } else {
5810 send_resp(dut, conn, SIGMA_ERROR,
5811 "ErrorCode,Unsupported Band");
5812 return 0;
5813 }
5814 }
5815
5816 val = get_param(cmd, "zero_crc");
5817 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005818 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005819 case DRIVER_ATHEROS:
5820 ath_set_zero_crc(dut, val);
5821 break;
5822 default:
5823 break;
5824 }
5825 }
5826
5827 return 1;
5828}
5829
5830
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005831static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
5832{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005833 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005834#ifdef __linux__
5835 case DRIVER_WIL6210:
5836 return wil6210_set_force_mcs(dut, force, mcs);
5837#endif /* __linux__ */
5838 default:
5839 sigma_dut_print(dut, DUT_MSG_ERROR,
5840 "Unsupported sta_set_force_mcs with the current driver");
5841 return -1;
5842 }
5843}
5844
5845
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005846static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
5847{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005848 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005849#ifdef __linux__
5850 case DRIVER_WIL6210:
5851 return wil6210_force_rsn_ie(dut, state);
5852#endif /* __linux__ */
5853 default:
5854 sigma_dut_print(dut, DUT_MSG_ERROR,
5855 "Unsupported sta_60g_force_rsn_ie with the current driver");
5856 return -1;
5857 }
5858}
5859
5860
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005861static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
5862 struct sigma_cmd *cmd)
5863{
5864 const char *val;
5865 char buf[100];
5866
5867 val = get_param(cmd, "MSDUSize");
5868 if (val) {
5869 int mtu;
5870
5871 dut->amsdu_size = atoi(val);
5872 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
5873 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
5874 sigma_dut_print(dut, DUT_MSG_ERROR,
5875 "MSDUSize %d is above max %d or below min %d",
5876 dut->amsdu_size,
5877 IEEE80211_MAX_DATA_LEN_DMG,
5878 IEEE80211_SNAP_LEN_DMG);
5879 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005880 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005881 }
5882
5883 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
5884 sigma_dut_print(dut, DUT_MSG_DEBUG,
5885 "Setting amsdu_size to %d", mtu);
5886 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005887 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005888
5889 if (system(buf) != 0) {
5890 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
5891 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005892 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005893 }
5894 }
5895
5896 val = get_param(cmd, "BAckRcvBuf");
5897 if (val) {
5898 dut->back_rcv_buf = atoi(val);
5899 if (dut->back_rcv_buf == 0) {
5900 sigma_dut_print(dut, DUT_MSG_ERROR,
5901 "Failed to convert %s or value is 0",
5902 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005903 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005904 }
5905
5906 sigma_dut_print(dut, DUT_MSG_DEBUG,
5907 "Setting BAckRcvBuf to %s", val);
5908 }
5909
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005910 val = get_param(cmd, "MCS_FixedRate");
5911 if (val) {
5912 if (sta_set_force_mcs(dut, 1, atoi(val))) {
5913 sigma_dut_print(dut, DUT_MSG_ERROR,
5914 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005915 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02005916 }
5917 }
5918
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005919 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005920}
5921
5922
5923static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
5924 struct sigma_cmd *cmd)
5925{
5926 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005927 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005928 const char *val;
5929 char buf[100];
5930
5931 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005932 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005933 if (wpa_command(ifname, "PING") != 0) {
5934 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005935 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005936 }
5937
5938 wpa_command(ifname, "FLUSH");
5939 net_id = add_network_common(dut, conn, ifname, cmd);
5940 if (net_id < 0) {
5941 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
5942 return net_id;
5943 }
5944
5945 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
5946 if (set_network(ifname, net_id, "mode", "2") < 0) {
5947 sigma_dut_print(dut, DUT_MSG_ERROR,
5948 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005949 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005950 }
5951
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02005952 if (set_network(ifname, net_id, "pbss", "1") < 0)
5953 return -2;
5954
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005955 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005956 "Supplicant set network with mode 2. network_id %d",
5957 net_id);
5958
5959 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
5960 sigma_dut_print(dut, DUT_MSG_INFO,
5961 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005962 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02005963 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005964
5965 val = get_param(cmd, "Security");
5966 if (val && strcasecmp(val, "OPEN") == 0) {
5967 dut->ap_key_mgmt = AP_OPEN;
5968 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
5969 sigma_dut_print(dut, DUT_MSG_ERROR,
5970 "Failed to set supplicant to %s security",
5971 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005972 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005973 }
5974 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
5975 dut->ap_key_mgmt = AP_WPA2_PSK;
5976 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
5977 sigma_dut_print(dut, DUT_MSG_ERROR,
5978 "Failed to set supplicant to %s security",
5979 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005980 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005981 }
5982
5983 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
5984 sigma_dut_print(dut, DUT_MSG_ERROR,
5985 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005986 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005987 }
5988 } else if (val) {
5989 sigma_dut_print(dut, DUT_MSG_ERROR,
5990 "Requested Security %s is not supported on 60GHz",
5991 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02005992 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005993 }
5994
5995 val = get_param(cmd, "Encrypt");
5996 if (val && strcasecmp(val, "AES-GCMP") == 0) {
5997 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
5998 sigma_dut_print(dut, DUT_MSG_ERROR,
5999 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006000 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006001 }
6002 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
6003 sigma_dut_print(dut, DUT_MSG_ERROR,
6004 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006005 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006006 }
6007 } else if (val) {
6008 sigma_dut_print(dut, DUT_MSG_ERROR,
6009 "Requested Encrypt %s is not supported on 60 GHz",
6010 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006011 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006012 }
6013
6014 val = get_param(cmd, "PSK");
6015 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
6016 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
6017 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006018 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006019 }
6020
6021 /* Convert 60G channel to freq */
6022 switch (dut->ap_channel) {
6023 case 1:
6024 val = "58320";
6025 break;
6026 case 2:
6027 val = "60480";
6028 break;
6029 case 3:
6030 val = "62640";
6031 break;
6032 default:
6033 sigma_dut_print(dut, DUT_MSG_ERROR,
6034 "Failed to configure channel %d. Not supported",
6035 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006036 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006037 }
6038
6039 if (set_network(ifname, net_id, "frequency", val) < 0) {
6040 sigma_dut_print(dut, DUT_MSG_ERROR,
6041 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006042 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006043 }
6044
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02006045 if (dut->eap_fragment) {
6046 sigma_dut_print(dut, DUT_MSG_DEBUG,
6047 "Set EAP fragment size to 128 bytes.");
6048 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
6049 return ERROR_SEND_STATUS;
6050 }
6051
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006052 sigma_dut_print(dut, DUT_MSG_DEBUG,
6053 "Supplicant set network with frequency");
6054
6055 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
6056 if (wpa_command(ifname, buf) < 0) {
6057 sigma_dut_print(dut, DUT_MSG_INFO,
6058 "Failed to select network id %d on %s",
6059 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006060 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006061 }
6062
6063 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
6064
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006065 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006066}
6067
6068
Lior David67543f52017-01-03 19:04:22 +02006069static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
6070{
6071 char buf[128], fname[128];
6072 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006073 int res;
Lior David67543f52017-01-03 19:04:22 +02006074
6075 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
6076 sigma_dut_print(dut, DUT_MSG_ERROR,
6077 "failed to get wil6210 debugfs dir");
6078 return -1;
6079 }
6080
Jouni Malinen3aa72862019-05-29 23:14:51 +03006081 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
6082 if (res < 0 || res >= sizeof(fname))
6083 return -1;
Lior David67543f52017-01-03 19:04:22 +02006084 f = fopen(fname, "w");
6085 if (!f) {
6086 sigma_dut_print(dut, DUT_MSG_ERROR,
6087 "failed to open: %s", fname);
6088 return -1;
6089 }
6090
6091 fprintf(f, "%d\n", abft_len);
6092 fclose(f);
6093
6094 return 0;
6095}
6096
6097
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02006098int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
6099 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02006100{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006101 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02006102 case DRIVER_WIL6210:
6103 return wil6210_set_abft_len(dut, abft_len);
6104 default:
6105 sigma_dut_print(dut, DUT_MSG_ERROR,
6106 "set abft_len not supported");
6107 return -1;
6108 }
6109}
6110
6111
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006112static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
6113 struct sigma_cmd *cmd)
6114{
6115 const char *val;
Lior David67543f52017-01-03 19:04:22 +02006116 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006117
6118 if (dut->dev_role != DEVROLE_PCP) {
6119 send_resp(dut, conn, SIGMA_INVALID,
6120 "ErrorCode,Invalid DevRole");
6121 return 0;
6122 }
6123
6124 val = get_param(cmd, "SSID");
6125 if (val) {
6126 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
6127 send_resp(dut, conn, SIGMA_INVALID,
6128 "ErrorCode,Invalid SSID");
6129 return -1;
6130 }
6131
Peng Xub8fc5cc2017-05-10 17:27:28 -07006132 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006133 }
6134
6135 val = get_param(cmd, "CHANNEL");
6136 if (val) {
6137 const char *pos;
6138
6139 dut->ap_channel = atoi(val);
6140 pos = strchr(val, ';');
6141 if (pos) {
6142 pos++;
6143 dut->ap_channel_1 = atoi(pos);
6144 }
6145 }
6146
6147 switch (dut->ap_channel) {
6148 case 1:
6149 case 2:
6150 case 3:
6151 break;
6152 default:
6153 sigma_dut_print(dut, DUT_MSG_ERROR,
6154 "Channel %d is not supported", dut->ap_channel);
6155 send_resp(dut, conn, SIGMA_ERROR,
6156 "Requested channel is not supported");
6157 return -1;
6158 }
6159
6160 val = get_param(cmd, "BCNINT");
6161 if (val)
6162 dut->ap_bcnint = atoi(val);
6163
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006164 val = get_param(cmd, "AllocType");
6165 if (val) {
6166 send_resp(dut, conn, SIGMA_ERROR,
6167 "ErrorCode,AllocType is not supported yet");
6168 return -1;
6169 }
6170
6171 val = get_param(cmd, "PercentBI");
6172 if (val) {
6173 send_resp(dut, conn, SIGMA_ERROR,
6174 "ErrorCode,PercentBI is not supported yet");
6175 return -1;
6176 }
6177
6178 val = get_param(cmd, "CBAPOnly");
6179 if (val) {
6180 send_resp(dut, conn, SIGMA_ERROR,
6181 "ErrorCode,CBAPOnly is not supported yet");
6182 return -1;
6183 }
6184
6185 val = get_param(cmd, "AMPDU");
6186 if (val) {
6187 if (strcasecmp(val, "Enable") == 0)
6188 dut->ap_ampdu = 1;
6189 else if (strcasecmp(val, "Disable") == 0)
6190 dut->ap_ampdu = 2;
6191 else {
6192 send_resp(dut, conn, SIGMA_ERROR,
6193 "ErrorCode,AMPDU value is not Enable nor Disabled");
6194 return -1;
6195 }
6196 }
6197
6198 val = get_param(cmd, "AMSDU");
6199 if (val) {
6200 if (strcasecmp(val, "Enable") == 0)
6201 dut->ap_amsdu = 1;
6202 else if (strcasecmp(val, "Disable") == 0)
6203 dut->ap_amsdu = 2;
6204 }
6205
6206 val = get_param(cmd, "NumMSDU");
6207 if (val) {
6208 send_resp(dut, conn, SIGMA_ERROR,
6209 "ErrorCode, NumMSDU is not supported yet");
6210 return -1;
6211 }
6212
6213 val = get_param(cmd, "ABFTLRang");
6214 if (val) {
6215 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02006216 "ABFTLRang parameter %s", val);
6217 if (strcmp(val, "Gt1") == 0)
6218 abft_len = 2; /* 2 slots in this case */
6219 }
6220
6221 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
6222 send_resp(dut, conn, SIGMA_ERROR,
6223 "ErrorCode, Can't set ABFT length");
6224 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006225 }
6226
6227 if (sta_pcp_start(dut, conn, cmd) < 0) {
6228 send_resp(dut, conn, SIGMA_ERROR,
6229 "ErrorCode, Can't start PCP role");
6230 return -1;
6231 }
6232
6233 return sta_set_60g_common(dut, conn, cmd);
6234}
6235
6236
6237static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
6238 struct sigma_cmd *cmd)
6239{
6240 const char *val = get_param(cmd, "DiscoveryMode");
6241
6242 if (dut->dev_role != DEVROLE_STA) {
6243 send_resp(dut, conn, SIGMA_INVALID,
6244 "ErrorCode,Invalid DevRole");
6245 return 0;
6246 }
6247
6248 if (val) {
6249 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
6250 /* Ignore Discovery mode till Driver expose API. */
6251#if 0
6252 if (strcasecmp(val, "1") == 0) {
6253 send_resp(dut, conn, SIGMA_INVALID,
6254 "ErrorCode,DiscoveryMode 1 not supported");
6255 return 0;
6256 }
6257
6258 if (strcasecmp(val, "0") == 0) {
6259 /* OK */
6260 } else {
6261 send_resp(dut, conn, SIGMA_INVALID,
6262 "ErrorCode,DiscoveryMode not supported");
6263 return 0;
6264 }
6265#endif
6266 }
6267
6268 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02006269 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006270 return sta_set_60g_common(dut, conn, cmd);
6271}
6272
6273
Jouni Malinenf7222712019-06-13 01:50:21 +03006274static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
6275 struct sigma_conn *conn,
6276 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006277{
6278 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02006279 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05306280
Jouni Malinened77e672018-01-10 16:45:13 +02006281 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08006282 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02006283 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05306284 wpa_command(intf, "DISCONNECT");
6285 return 1;
6286 }
6287
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006288 disconnect_station(dut);
6289 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
6290 * due to cached results. */
6291 wpa_command(intf, "SET ignore_old_scan_res 1");
6292 wpa_command(intf, "BSS_FLUSH");
6293 return 1;
6294}
6295
6296
Jouni Malinenf7222712019-06-13 01:50:21 +03006297static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
6298 struct sigma_conn *conn,
6299 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006300{
6301 const char *intf = get_param(cmd, "Interface");
6302 const char *bssid = get_param(cmd, "bssid");
6303 const char *val = get_param(cmd, "CHANNEL");
6304 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306305 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05306306 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006307 int res;
6308 int chan = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006309 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05306310 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006311 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006312
6313 if (bssid == NULL) {
6314 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
6315 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006316 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006317 }
6318
6319 if (val)
6320 chan = atoi(val);
6321
6322 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
6323 /* The current network may be from sta_associate or
6324 * sta_hs2_associate
6325 */
6326 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
6327 0 ||
6328 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006329 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006330 }
6331
6332 ctrl = open_wpa_mon(intf);
6333 if (ctrl == NULL) {
6334 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
6335 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006336 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006337 }
6338
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006339 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05306340 sizeof(result)) < 0 ||
6341 strncmp(result, "COMPLETED", 9) != 0) {
6342 sigma_dut_print(dut, DUT_MSG_DEBUG,
6343 "sta_reassoc: Not connected");
6344 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006345 } else if (dut->sta_ft_ds) {
6346 sigma_dut_print(dut, DUT_MSG_DEBUG,
6347 "sta_reassoc: Use FT-over-DS");
6348 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05306349 }
6350
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306351 if (dut->rsne_override) {
6352#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006353 if (get_driver_type(dut) == DRIVER_WCN &&
6354 dut->config_rsnie == 0) {
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05306355 sta_config_rsnie(dut, 1);
6356 dut->config_rsnie = 1;
6357 }
6358#endif /* NL80211_SUPPORT */
6359 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
6360 dut->rsne_override);
6361 if (wpa_command(intf, buf) < 0) {
6362 send_resp(dut, conn, SIGMA_ERROR,
6363 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
6364 return 0;
6365 }
6366 }
6367
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006368 if (ft_ds) {
6369 if (chan) {
6370 unsigned int freq;
6371
6372 freq = channel_to_freq(dut, chan);
6373 if (!freq) {
6374 sigma_dut_print(dut, DUT_MSG_ERROR,
6375 "Invalid channel number provided: %d",
6376 chan);
6377 send_resp(dut, conn, SIGMA_INVALID,
6378 "ErrorCode,Invalid channel number");
6379 goto close_mon_conn;
6380 }
6381 res = snprintf(buf, sizeof(buf),
6382 "SCAN TYPE=ONLY freq=%d", freq);
6383 } else {
6384 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6385 }
6386 if (res < 0 || res >= (int) sizeof(buf)) {
6387 send_resp(dut, conn, SIGMA_ERROR,
6388 "ErrorCode,snprintf failed");
6389 goto close_mon_conn;
6390 }
6391 if (wpa_command(intf, buf) < 0) {
6392 sigma_dut_print(dut, DUT_MSG_INFO,
6393 "Failed to start scan");
6394 send_resp(dut, conn, SIGMA_ERROR,
6395 "ErrorCode,scan failed");
6396 goto close_mon_conn;
6397 }
6398
6399 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6400 buf, sizeof(buf));
6401 if (res < 0) {
6402 sigma_dut_print(dut, DUT_MSG_INFO,
6403 "Scan did not complete");
6404 send_resp(dut, conn, SIGMA_ERROR,
6405 "ErrorCode,scan did not complete");
6406 goto close_mon_conn;
6407 }
6408
6409 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
6410 if (res > 0 && res < (int) sizeof(buf))
6411 res = wpa_command(intf, buf);
6412
6413 if (res < 0 || res >= (int) sizeof(buf)) {
6414 send_resp(dut, conn, SIGMA_ERROR,
6415 "errorCode,FT_DS command failed");
6416 status = STATUS_SENT_ERROR;
6417 goto close_mon_conn;
6418 }
6419 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306420 if (chan) {
6421 unsigned int freq;
6422
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02006423 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05306424 if (!freq) {
6425 sigma_dut_print(dut, DUT_MSG_ERROR,
6426 "Invalid channel number provided: %d",
6427 chan);
6428 send_resp(dut, conn, SIGMA_INVALID,
6429 "ErrorCode,Invalid channel number");
6430 goto close_mon_conn;
6431 }
6432 res = snprintf(buf, sizeof(buf),
6433 "SCAN TYPE=ONLY freq=%d", freq);
6434 } else {
6435 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
6436 }
6437 if (res < 0 || res >= (int) sizeof(buf)) {
6438 send_resp(dut, conn, SIGMA_ERROR,
6439 "ErrorCode,snprintf failed");
6440 goto close_mon_conn;
6441 }
6442 if (wpa_command(intf, buf) < 0) {
6443 sigma_dut_print(dut, DUT_MSG_INFO,
6444 "Failed to start scan");
6445 send_resp(dut, conn, SIGMA_ERROR,
6446 "ErrorCode,scan failed");
6447 goto close_mon_conn;
6448 }
6449
6450 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
6451 buf, sizeof(buf));
6452 if (res < 0) {
6453 sigma_dut_print(dut, DUT_MSG_INFO,
6454 "Scan did not complete");
6455 send_resp(dut, conn, SIGMA_ERROR,
6456 "ErrorCode,scan did not complete");
6457 goto close_mon_conn;
6458 }
6459
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006460 if (set_network(intf, dut->infra_network_id, "bssid", "any")
6461 < 0) {
6462 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
6463 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006464 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05306465 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006466 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306467 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006468 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306469 if (res < 0 || res >= (int) sizeof(buf) ||
6470 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006471 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05306472 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05306473 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006474 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006475 sigma_dut_print(dut, DUT_MSG_INFO,
6476 "sta_reassoc: Run %s successful", buf);
6477 } else if (wpa_command(intf, "REASSOCIATE")) {
6478 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
6479 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05306480 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006481 }
6482
6483 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
6484 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05306485 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006486 send_resp(dut, conn, SIGMA_ERROR,
6487 "errorCode,Connection did not complete");
6488 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05306489 goto close_mon_conn;
6490 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03006491 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006492
Ashwini Patil467efef2017-05-25 12:18:27 +05306493close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006494 wpa_ctrl_detach(ctrl);
6495 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05306496 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006497}
6498
6499
6500static void hs2_clear_credentials(const char *intf)
6501{
6502 wpa_command(intf, "REMOVE_CRED all");
6503}
6504
6505
Lior Davidcc88b562017-01-03 18:52:09 +02006506#ifdef __linux__
6507static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
6508 unsigned int *aid)
6509{
Lior David0fe101e2017-03-09 16:09:50 +02006510 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02006511
Lior David0fe101e2017-03-09 16:09:50 +02006512 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02006513}
6514#endif /* __linux__ */
6515
6516
6517static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
6518 unsigned int *aid)
6519{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006520 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02006521#ifdef __linux__
6522 case DRIVER_WIL6210:
6523 return wil6210_get_aid(dut, bssid, aid);
6524#endif /* __linux__ */
6525 default:
6526 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
6527 return -1;
6528 }
6529}
6530
6531
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006532static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
6533 struct sigma_cmd *cmd)
6534{
6535 char buf[MAX_CMD_LEN];
6536 char bss_list[MAX_CMD_LEN];
6537 const char *parameter = get_param(cmd, "Parameter");
6538
6539 if (parameter == NULL)
6540 return -1;
6541
Lior Davidcc88b562017-01-03 18:52:09 +02006542 if (strcasecmp(parameter, "AID") == 0) {
6543 unsigned int aid = 0;
6544 char bssid[20];
6545
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006546 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02006547 bssid, sizeof(bssid)) < 0) {
6548 sigma_dut_print(dut, DUT_MSG_ERROR,
6549 "could not get bssid");
6550 return -2;
6551 }
6552
6553 if (sta_get_aid_60g(dut, bssid, &aid))
6554 return -2;
6555
6556 snprintf(buf, sizeof(buf), "aid,%d", aid);
6557 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
6558 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6559 return 0;
6560 }
6561
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006562 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
6563 char *bss_line;
6564 char *bss_id = NULL;
6565 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306566 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006567
6568 if (ifname == NULL) {
6569 sigma_dut_print(dut, DUT_MSG_INFO,
6570 "For get DiscoveredDevList need Interface name.");
6571 return -1;
6572 }
6573
6574 /*
6575 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
6576 * of BSSIDs in "bssid=<BSSID>\n"
6577 */
6578 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
6579 bss_list,
6580 sizeof(bss_list)) < 0) {
6581 sigma_dut_print(dut, DUT_MSG_ERROR,
6582 "Failed to get bss list");
6583 return -1;
6584 }
6585
6586 sigma_dut_print(dut, DUT_MSG_DEBUG,
6587 "bss list for ifname:%s is:%s",
6588 ifname, bss_list);
6589
6590 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306591 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006592 while (bss_line) {
6593 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
6594 bss_id) {
6595 int len;
6596
6597 len = snprintf(buf + strlen(buf),
6598 sizeof(buf) - strlen(buf),
6599 ",%s", bss_id);
6600 free(bss_id);
6601 bss_id = NULL;
6602 if (len < 0) {
6603 sigma_dut_print(dut,
6604 DUT_MSG_ERROR,
6605 "Failed to read BSSID");
6606 send_resp(dut, conn, SIGMA_ERROR,
6607 "ErrorCode,Failed to read BSS ID");
6608 return 0;
6609 }
6610
6611 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
6612 sigma_dut_print(dut,
6613 DUT_MSG_ERROR,
6614 "Response buf too small for list");
6615 send_resp(dut, conn,
6616 SIGMA_ERROR,
6617 "ErrorCode,Response buf too small for list");
6618 return 0;
6619 }
6620 }
6621
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05306622 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006623 }
6624
6625 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
6626 buf);
6627 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6628 return 0;
6629 }
6630
6631 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6632 return 0;
6633}
6634
6635
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006636static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
6637 struct sigma_cmd *cmd)
6638{
6639 char buf[MAX_CMD_LEN];
6640 const char *parameter = get_param(cmd, "Parameter");
6641
6642 if (!parameter)
6643 return -1;
6644
6645 if (strcasecmp(parameter, "RSSI") == 0) {
6646 char rssi[10];
6647
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006648 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006649 rssi, sizeof(rssi)) < 0) {
6650 sigma_dut_print(dut, DUT_MSG_ERROR,
6651 "Could not get RSSI");
6652 return -2;
6653 }
6654
6655 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
6656 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
6657 send_resp(dut, conn, SIGMA_COMPLETE, buf);
6658 return 0;
6659 }
6660
6661 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6662 return 0;
6663}
6664
6665
Jouni Malinenca0abd32020-02-09 20:18:10 +02006666static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
6667 struct sigma_conn *conn,
6668 struct sigma_cmd *cmd)
6669{
6670 const char *intf = get_param(cmd, "Interface");
6671 char buf[4096], bssid[20], resp[200], *pos, *tmp;
6672
6673 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
6674 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
6675 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
6676 send_resp(dut, conn, SIGMA_ERROR,
6677 "ErrorCode,PMKSA_GET not supported");
6678 return STATUS_SENT_ERROR;
6679 }
6680
6681 if (strncmp(buf, "FAIL", 4) == 0 ||
6682 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
6683 send_resp(dut, conn, SIGMA_ERROR,
6684 "ErrorCode,Could not find current network");
6685 return STATUS_SENT_ERROR;
6686 }
6687
6688 pos = buf;
6689 while (pos) {
6690 if (strncmp(pos, bssid, 17) == 0) {
6691 pos = strchr(pos, ' ');
6692 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05306693 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02006694 pos++;
6695 pos = strchr(pos, ' ');
6696 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05306697 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02006698 pos++;
6699 tmp = strchr(pos, ' ');
6700 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05306701 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02006702 *tmp = '\0';
6703 break;
6704 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02006705 pos = strchr(pos, '\n');
6706 if (pos)
6707 pos++;
6708 }
6709
6710 if (!pos) {
6711 send_resp(dut, conn, SIGMA_ERROR,
6712 "ErrorCode,PMK not available");
6713 return STATUS_SENT_ERROR;
6714 }
6715
6716 snprintf(resp, sizeof(resp), "PMK,%s", pos);
6717 send_resp(dut, conn, SIGMA_COMPLETE, resp);
6718 return STATUS_SENT;
6719}
6720
6721
Jouni Malinenf7222712019-06-13 01:50:21 +03006722static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
6723 struct sigma_conn *conn,
6724 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006725{
6726 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02006727 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006728
Jouni Malinenca0abd32020-02-09 20:18:10 +02006729 if (!parameter)
6730 return INVALID_SEND_STATUS;
6731
6732 if (strcasecmp(parameter, "PMK") == 0)
6733 return sta_get_pmk(dut, conn, cmd);
6734
6735 if (!program)
6736 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006737
6738 if (strcasecmp(program, "P2PNFC") == 0)
6739 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
6740
6741 if (strcasecmp(program, "60ghz") == 0)
6742 return sta_get_parameter_60g(dut, conn, cmd);
6743
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07006744 if (strcasecmp(program, "he") == 0)
6745 return sta_get_parameter_he(dut, conn, cmd);
6746
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006747#ifdef ANDROID_NAN
6748 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07006749 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006750#endif /* ANDROID_NAN */
6751
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006752#ifdef MIRACAST
6753 if (strcasecmp(program, "WFD") == 0 ||
6754 strcasecmp(program, "DisplayR2") == 0)
6755 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
6756#endif /* MIRACAST */
6757
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006758 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
6759 return 0;
6760}
6761
6762
6763static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
6764 const char *type)
6765{
6766 char buf[100];
6767
6768 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006769 run_iwpriv(dut, intf, "chwidth 2");
6770 run_iwpriv(dut, intf, "mode 11ACVHT80");
6771 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006772 }
6773
6774 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006775 run_iwpriv(dut, intf, "chwidth 0");
6776 run_iwpriv(dut, intf, "mode 11naht40");
6777 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006778 }
6779
6780 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006781 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006782
6783 /* Reset CTS width */
6784 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
6785 intf);
6786 if (system(buf) != 0) {
6787 sigma_dut_print(dut, DUT_MSG_ERROR,
6788 "wifitool %s beeliner_fw_test 54 0 failed",
6789 intf);
6790 }
6791
6792 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006793 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006794
6795 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
6796 if (system(buf) != 0) {
6797 sigma_dut_print(dut, DUT_MSG_ERROR,
6798 "iwpriv rts failed");
6799 }
6800 }
6801
6802 if (type && strcasecmp(type, "Testbed") == 0) {
6803 dut->testbed_flag_txsp = 1;
6804 dut->testbed_flag_rxsp = 1;
6805 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006806 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006807
6808 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006809 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006810
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006811 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006812
6813 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006814 run_iwpriv(dut, intf, "tx_stbc 0");
6815 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006816
6817 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006818 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006819 }
6820
6821 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006822 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07006823 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006824
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006825 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006826 }
6827}
6828
6829
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08006830#ifdef NL80211_SUPPORT
6831static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
6832 enum he_mcs_config mcs)
6833{
6834 struct nl_msg *msg;
6835 int ret = 0;
6836 struct nlattr *params;
6837 int ifindex;
6838
6839 ifindex = if_nametoindex(intf);
6840 if (ifindex == 0) {
6841 sigma_dut_print(dut, DUT_MSG_ERROR,
6842 "%s: Index for interface %s failed",
6843 __func__, intf);
6844 return -1;
6845 }
6846
6847 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6848 NL80211_CMD_VENDOR)) ||
6849 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6850 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6851 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6852 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6853 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6854 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS,
6855 mcs)) {
6856 sigma_dut_print(dut, DUT_MSG_ERROR,
6857 "%s: err in adding vendor_cmd and vendor_data",
6858 __func__);
6859 nlmsg_free(msg);
6860 return -1;
6861 }
6862 nla_nest_end(msg, params);
6863
6864 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6865 if (ret) {
6866 sigma_dut_print(dut, DUT_MSG_ERROR,
6867 "%s: err in send_and_recv_msgs, ret=%d",
6868 __func__, ret);
6869 }
6870 return ret;
6871}
6872#endif /* NL80211_SUPPORT */
6873
6874
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07006875static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
6876 const char *intf, int enable)
6877{
6878#ifdef NL80211_SUPPORT
6879 struct nl_msg *msg;
6880 int ret = 0;
6881 struct nlattr *params;
6882 int ifindex;
6883
6884 ifindex = if_nametoindex(intf);
6885 if (ifindex == 0) {
6886 sigma_dut_print(dut, DUT_MSG_ERROR,
6887 "%s: Index for interface %s failed",
6888 __func__, intf);
6889 return -1;
6890 }
6891
6892 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6893 NL80211_CMD_VENDOR)) ||
6894 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6895 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6896 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6897 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6898 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6899 nla_put_u8(msg,
6900 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
6901 enable)) {
6902 sigma_dut_print(dut, DUT_MSG_ERROR,
6903 "%s: err in adding vendor_cmd and vendor_data",
6904 __func__);
6905 nlmsg_free(msg);
6906 return -1;
6907 }
6908 nla_nest_end(msg, params);
6909
6910 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6911 if (ret) {
6912 sigma_dut_print(dut, DUT_MSG_ERROR,
6913 "%s: err in send_and_recv_msgs, ret=%d",
6914 __func__, ret);
6915 }
6916 return ret;
6917#else /* NL80211_SUPPORT */
6918 sigma_dut_print(dut, DUT_MSG_ERROR,
6919 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
6920 return -1;
6921#endif /* NL80211_SUPPORT */
6922}
6923
6924
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08006925static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
6926 const char *intf, int enable)
6927{
6928#ifdef NL80211_SUPPORT
6929 struct nl_msg *msg;
6930 int ret = 0;
6931 struct nlattr *params;
6932 int ifindex;
6933
6934 ifindex = if_nametoindex(intf);
6935 if (ifindex == 0) {
6936 sigma_dut_print(dut, DUT_MSG_ERROR,
6937 "%s: Index for interface %s failed",
6938 __func__, intf);
6939 return -1;
6940 }
6941
6942 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6943 NL80211_CMD_VENDOR)) ||
6944 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6945 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6946 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6947 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6948 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
6949 nla_put_u8(msg,
6950 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
6951 enable)) {
6952 sigma_dut_print(dut, DUT_MSG_ERROR,
6953 "%s: err in adding vendor_cmd and vendor_data",
6954 __func__);
6955 nlmsg_free(msg);
6956 return -1;
6957 }
6958 nla_nest_end(msg, params);
6959
6960 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6961 if (ret) {
6962 sigma_dut_print(dut, DUT_MSG_ERROR,
6963 "%s: err in send_and_recv_msgs, ret=%d",
6964 __func__, ret);
6965 }
6966 return ret;
6967#else /* NL80211_SUPPORT */
6968 sigma_dut_print(dut, DUT_MSG_ERROR,
6969 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
6970 return -1;
6971#endif /* NL80211_SUPPORT */
6972}
6973
6974
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006975#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08006976
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08006977static int sta_set_he_testbed_def(struct sigma_dut *dut,
6978 const char *intf, int cfg)
6979{
6980 struct nl_msg *msg;
6981 int ret = 0;
6982 struct nlattr *params;
6983 int ifindex;
6984
6985 ifindex = if_nametoindex(intf);
6986 if (ifindex == 0) {
6987 sigma_dut_print(dut, DUT_MSG_ERROR,
6988 "%s: Index for interface %s failed",
6989 __func__, intf);
6990 return -1;
6991 }
6992
6993 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6994 NL80211_CMD_VENDOR)) ||
6995 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
6996 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
6997 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
6998 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
6999 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7000 nla_put_u8(msg,
7001 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
7002 cfg)) {
7003 sigma_dut_print(dut, DUT_MSG_ERROR,
7004 "%s: err in adding vendor_cmd and vendor_data",
7005 __func__);
7006 nlmsg_free(msg);
7007 return -1;
7008 }
7009 nla_nest_end(msg, params);
7010
7011 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7012 if (ret) {
7013 sigma_dut_print(dut, DUT_MSG_ERROR,
7014 "%s: err in send_and_recv_msgs, ret=%d",
7015 __func__, ret);
7016 }
7017 return ret;
7018}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007019
7020
7021static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
7022{
7023 struct nl_msg *msg;
7024 int ret = 0;
7025 struct nlattr *params;
7026 int ifindex;
7027
7028 ifindex = if_nametoindex(intf);
7029 if (ifindex == 0) {
7030 sigma_dut_print(dut, DUT_MSG_ERROR,
7031 "%s: Index for interface %s failed",
7032 __func__, intf);
7033 return -1;
7034 }
7035
7036 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7037 NL80211_CMD_VENDOR)) ||
7038 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7039 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7040 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7041 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7042 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7043 nla_put_u8(msg,
7044 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
7045 cfg)) {
7046 sigma_dut_print(dut, DUT_MSG_ERROR,
7047 "%s: err in adding vendor_cmd and vendor_data",
7048 __func__);
7049 nlmsg_free(msg);
7050 return -1;
7051 }
7052 nla_nest_end(msg, params);
7053
7054 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7055 if (ret) {
7056 sigma_dut_print(dut, DUT_MSG_ERROR,
7057 "%s: err in send_and_recv_msgs, ret=%d",
7058 __func__, ret);
7059 }
7060 return ret;
7061}
7062
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007063#endif /* NL80211_SUPPORT */
7064
7065
Qiwei Caib6806972020-01-15 13:52:11 +08007066int sta_set_addba_buf_size(struct sigma_dut *dut,
7067 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007068{
7069#ifdef NL80211_SUPPORT
7070 struct nl_msg *msg;
7071 int ret = 0;
7072 struct nlattr *params;
7073 int ifindex;
7074
7075 ifindex = if_nametoindex(intf);
7076 if (ifindex == 0) {
7077 sigma_dut_print(dut, DUT_MSG_ERROR,
7078 "%s: Index for interface %s failed",
7079 __func__, intf);
7080 return -1;
7081 }
7082
7083 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7084 NL80211_CMD_VENDOR)) ||
7085 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7086 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7087 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7088 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7089 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07007090 nla_put_u16(msg,
7091 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
7092 bufsize)) {
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007093 sigma_dut_print(dut, DUT_MSG_ERROR,
7094 "%s: err in adding vendor_cmd and vendor_data",
7095 __func__);
7096 nlmsg_free(msg);
7097 return -1;
7098 }
7099 nla_nest_end(msg, params);
7100
7101 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7102 if (ret) {
7103 sigma_dut_print(dut, DUT_MSG_ERROR,
7104 "%s: err in send_and_recv_msgs, ret=%d",
7105 __func__, ret);
7106 }
7107 return ret;
7108#else /* NL80211_SUPPORT */
7109 sigma_dut_print(dut, DUT_MSG_ERROR,
7110 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
7111 return -1;
7112#endif /* NL80211_SUPPORT */
7113}
7114
7115
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007116static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
7117 int enable)
7118{
7119#ifdef NL80211_SUPPORT
7120 struct nl_msg *msg;
7121 int ret = 0;
7122 struct nlattr *params;
7123 int ifindex;
7124
7125 ifindex = if_nametoindex(intf);
7126 if (ifindex == 0) {
7127 sigma_dut_print(dut, DUT_MSG_ERROR,
7128 "%s: Index for interface %s failed",
7129 __func__, intf);
7130 return -1;
7131 }
7132
7133 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7134 NL80211_CMD_VENDOR)) ||
7135 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7136 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7137 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7138 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7139 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7140 nla_put_u8(msg,
7141 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
7142 enable)) {
7143 sigma_dut_print(dut, DUT_MSG_ERROR,
7144 "%s: err in adding vendor_cmd and vendor_data",
7145 __func__);
7146 nlmsg_free(msg);
7147 return -1;
7148 }
7149 nla_nest_end(msg, params);
7150
7151 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7152 if (ret) {
7153 sigma_dut_print(dut, DUT_MSG_ERROR,
7154 "%s: err in send_and_recv_msgs, ret=%d",
7155 __func__, ret);
7156 }
7157 return ret;
7158#else /* NL80211_SUPPORT */
7159 sigma_dut_print(dut, DUT_MSG_ERROR,
7160 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
7161 return -1;
7162#endif /* NL80211_SUPPORT */
7163}
7164
7165
Arif Hussain9765f7d2018-07-03 08:28:26 -07007166static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
7167 int val)
7168{
7169#ifdef NL80211_SUPPORT
7170 struct nl_msg *msg;
7171 int ret = 0;
7172 struct nlattr *params;
7173 int ifindex;
7174
7175 ifindex = if_nametoindex(intf);
7176 if (ifindex == 0) {
7177 sigma_dut_print(dut, DUT_MSG_ERROR,
7178 "%s: Index for interface %s failed, val:%d",
7179 __func__, intf, val);
7180 return -1;
7181 }
7182
7183 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7184 NL80211_CMD_VENDOR)) ||
7185 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7186 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7187 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7188 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7189 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7190 nla_put_u8(msg,
7191 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
7192 val)) {
7193 sigma_dut_print(dut, DUT_MSG_ERROR,
7194 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7195 __func__, val);
7196 nlmsg_free(msg);
7197 return -1;
7198 }
7199 nla_nest_end(msg, params);
7200
7201 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7202 if (ret) {
7203 sigma_dut_print(dut, DUT_MSG_ERROR,
7204 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7205 __func__, ret, val);
7206 }
7207 return ret;
7208#else /* NL80211_SUPPORT */
7209 sigma_dut_print(dut, DUT_MSG_ERROR,
7210 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
7211 return -1;
7212#endif /* NL80211_SUPPORT */
7213}
7214
7215
Arif Hussain68d23f52018-07-11 13:39:08 -07007216#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007217static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
7218 enum qca_wlan_he_mac_padding_dur val)
7219{
Arif Hussain68d23f52018-07-11 13:39:08 -07007220 struct nl_msg *msg;
7221 int ret = 0;
7222 struct nlattr *params;
7223 int ifindex;
7224
7225 ifindex = if_nametoindex(intf);
7226 if (ifindex == 0) {
7227 sigma_dut_print(dut, DUT_MSG_ERROR,
7228 "%s: Index for interface %s failed, val:%d",
7229 __func__, intf, val);
7230 return -1;
7231 }
7232
7233 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7234 NL80211_CMD_VENDOR)) ||
7235 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7236 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7237 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7238 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7239 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7240 nla_put_u8(msg,
7241 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR,
7242 val)) {
7243 sigma_dut_print(dut, DUT_MSG_ERROR,
7244 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7245 __func__, val);
7246 nlmsg_free(msg);
7247 return -1;
7248 }
7249 nla_nest_end(msg, params);
7250
7251 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7252 if (ret) {
7253 sigma_dut_print(dut, DUT_MSG_ERROR,
7254 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7255 __func__, ret, val);
7256 }
7257 return ret;
Arif Hussain68d23f52018-07-11 13:39:08 -07007258}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007259#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07007260
7261
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007262static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
7263 int val)
7264{
7265#ifdef NL80211_SUPPORT
7266 struct nl_msg *msg;
7267 int ret = 0;
7268 struct nlattr *params;
7269 int ifindex;
7270
7271 ifindex = if_nametoindex(intf);
7272 if (ifindex == 0) {
7273 sigma_dut_print(dut, DUT_MSG_ERROR,
7274 "%s: Index for interface %s failed, val:%d",
7275 __func__, intf, val);
7276 return -1;
7277 }
7278
7279 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7280 NL80211_CMD_VENDOR)) ||
7281 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7282 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7283 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7284 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7285 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7286 nla_put_u8(msg,
7287 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
7288 val)) {
7289 sigma_dut_print(dut, DUT_MSG_ERROR,
7290 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7291 __func__, val);
7292 nlmsg_free(msg);
7293 return -1;
7294 }
7295 nla_nest_end(msg, params);
7296
7297 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7298 if (ret) {
7299 sigma_dut_print(dut, DUT_MSG_ERROR,
7300 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7301 __func__, ret, val);
7302 }
7303 return ret;
7304#else /* NL80211_SUPPORT */
7305 sigma_dut_print(dut, DUT_MSG_ERROR,
7306 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
7307 return -1;
7308#endif /* NL80211_SUPPORT */
7309}
7310
7311
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007312#ifdef NL80211_SUPPORT
7313static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
7314{
7315 struct nl_msg *msg;
7316 int ret = 0;
7317 struct nlattr *params;
7318 int ifindex;
7319
7320 ifindex = if_nametoindex(intf);
7321 if (ifindex == 0) {
7322 sigma_dut_print(dut, DUT_MSG_ERROR,
7323 "%s: Index for interface %s failed",
7324 __func__, intf);
7325 return -1;
7326 }
7327
7328 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7329 NL80211_CMD_VENDOR)) ||
7330 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7331 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7332 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7333 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7334 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7335 nla_put_flag(msg,
7336 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG)) {
7337 sigma_dut_print(dut, DUT_MSG_ERROR,
7338 "%s: err in adding vendor_cmd and vendor_data",
7339 __func__);
7340 nlmsg_free(msg);
7341 return -1;
7342 }
7343 nla_nest_end(msg, params);
7344
7345 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7346 if (ret) {
7347 sigma_dut_print(dut, DUT_MSG_ERROR,
7348 "%s: err in send_and_recv_msgs, ret=%d",
7349 __func__, ret);
7350 }
7351 return ret;
7352}
7353#endif /* NL80211_SUPPORT */
7354
7355
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007356static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
7357 int val)
7358{
7359#ifdef NL80211_SUPPORT
7360 struct nl_msg *msg;
7361 int ret = 0;
7362 struct nlattr *params;
7363 int ifindex;
7364
7365 ifindex = if_nametoindex(intf);
7366 if (ifindex == 0) {
7367 sigma_dut_print(dut, DUT_MSG_ERROR,
7368 "%s: Index for interface %s failed, val:%d",
7369 __func__, intf, val);
7370 return -1;
7371 }
7372
7373 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7374 NL80211_CMD_VENDOR)) ||
7375 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7376 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7377 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7378 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7379 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7380 nla_put_u8(msg,
7381 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA,
7382 val)) {
7383 sigma_dut_print(dut, DUT_MSG_ERROR,
7384 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7385 __func__, val);
7386 nlmsg_free(msg);
7387 return -1;
7388 }
7389 nla_nest_end(msg, params);
7390
7391 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7392 if (ret) {
7393 sigma_dut_print(dut, DUT_MSG_ERROR,
7394 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7395 __func__, ret, val);
7396 }
7397 return ret;
7398#else /* NL80211_SUPPORT */
7399 sigma_dut_print(dut, DUT_MSG_ERROR,
7400 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
7401 return -1;
7402#endif /* NL80211_SUPPORT */
7403}
7404
7405
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007406static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
7407 int val)
7408{
7409#ifdef NL80211_SUPPORT
7410 struct nl_msg *msg;
7411 int ret = 0;
7412 struct nlattr *params;
7413 int ifindex;
7414
7415 ifindex = if_nametoindex(intf);
7416 if (ifindex == 0) {
7417 sigma_dut_print(dut, DUT_MSG_ERROR,
7418 "%s: Index for interface %s failed, val:%d",
7419 __func__, intf, val);
7420 return -1;
7421 }
7422
7423 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7424 NL80211_CMD_VENDOR)) ||
7425 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7426 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7427 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7428 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7429 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7430 nla_put_u8(msg,
7431 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP,
7432 val)) {
7433 sigma_dut_print(dut, DUT_MSG_ERROR,
7434 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7435 __func__, val);
7436 nlmsg_free(msg);
7437 return -1;
7438 }
7439 nla_nest_end(msg, params);
7440
7441 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7442 if (ret) {
7443 sigma_dut_print(dut, DUT_MSG_ERROR,
7444 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7445 __func__, ret, val);
7446 }
7447 return ret;
7448#else /* NL80211_SUPPORT */
7449 sigma_dut_print(dut, DUT_MSG_ERROR,
7450 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
7451 return -1;
7452#endif /* NL80211_SUPPORT */
7453}
7454
7455
Arif Hussain480d5f42019-03-12 14:40:42 -07007456static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
7457 int val)
7458{
7459#ifdef NL80211_SUPPORT
7460 struct nl_msg *msg;
7461 int ret;
7462 struct nlattr *params;
7463 int ifindex;
7464
7465 ifindex = if_nametoindex(intf);
7466 if (ifindex == 0) {
7467 sigma_dut_print(dut, DUT_MSG_ERROR,
7468 "%s: Index for interface %s failed, val:%d",
7469 __func__, intf, val);
7470 return -1;
7471 }
7472
7473 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7474 NL80211_CMD_VENDOR)) ||
7475 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7476 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7477 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7478 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
7479 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
7480 nla_put_u8(msg,
7481 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT,
7482 val)) {
7483 sigma_dut_print(dut, DUT_MSG_ERROR,
7484 "%s: err in adding vendor_cmd and vendor_data, val: %d",
7485 __func__, val);
7486 nlmsg_free(msg);
7487 return -1;
7488 }
7489 nla_nest_end(msg, params);
7490
7491 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
7492 if (ret) {
7493 sigma_dut_print(dut, DUT_MSG_ERROR,
7494 "%s: err in send_and_recv_msgs, ret=%d, val=%d",
7495 __func__, ret, val);
7496 }
7497 return ret;
7498#else /* NL80211_SUPPORT */
7499 sigma_dut_print(dut, DUT_MSG_ERROR,
7500 "TWT Request cannot be changed without NL80211_SUPPORT defined");
7501 return -1;
7502#endif /* NL80211_SUPPORT */
7503}
7504
7505
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007506static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
7507 const char *type)
7508{
7509 char buf[60];
7510
7511 if (dut->program == PROGRAM_HE) {
7512 /* resetting phymode to auto in case of HE program */
7513 snprintf(buf, sizeof(buf), "iwpriv %s setphymode 0", intf);
7514 if (system(buf) != 0) {
7515 sigma_dut_print(dut, DUT_MSG_ERROR,
7516 "iwpriv %s setphymode failed", intf);
7517 }
7518
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07007519 /* reset the rate to Auto rate */
7520 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
7521 intf);
7522 if (system(buf) != 0) {
7523 sigma_dut_print(dut, DUT_MSG_ERROR,
7524 "iwpriv %s set_11ax_rate 0xff failed",
7525 intf);
7526 }
7527
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07007528 /* reset the LDPC setting */
7529 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
7530 if (system(buf) != 0) {
7531 sigma_dut_print(dut, DUT_MSG_ERROR,
7532 "iwpriv %s ldpc 1 failed", intf);
7533 }
7534
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08007535 /* reset the power save setting */
7536 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2", intf);
7537 if (system(buf) != 0) {
7538 sigma_dut_print(dut, DUT_MSG_ERROR,
7539 "iwpriv %s setPower 2 failed", intf);
7540 }
7541
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007542 /* remove all network profiles */
7543 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007544
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08007545 /* Configure ADDBA Req/Rsp buffer size to be 64 */
7546 sta_set_addba_buf_size(dut, intf, 64);
7547
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007548#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007549 /* Reset the device HE capabilities to its default supported
7550 * configuration. */
7551 sta_set_he_testbed_def(dut, intf, 0);
7552
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08007553 /* Disable noackpolicy for all AC */
7554 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
7555 sigma_dut_print(dut, DUT_MSG_ERROR,
7556 "Disable of noackpolicy for all AC failed");
7557 }
7558#endif /* NL80211_SUPPORT */
7559
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08007560 /* Enable WMM by default */
7561 if (wcn_sta_set_wmm(dut, intf, "on")) {
7562 sigma_dut_print(dut, DUT_MSG_ERROR,
7563 "Enable of WMM in sta_reset_default_wcn failed");
7564 }
7565
7566 /* Disable ADDBA_REJECT by default */
7567 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
7568 sigma_dut_print(dut, DUT_MSG_ERROR,
7569 "Disable of addba_reject in sta_reset_default_wcn failed");
7570 }
7571
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08007572 /* Enable sending of ADDBA by default */
7573 if (nlvendor_config_send_addba(dut, intf, 1)) {
7574 sigma_dut_print(dut, DUT_MSG_ERROR,
7575 "Enable sending of ADDBA in sta_reset_default_wcn failed");
7576 }
7577
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08007578 /* Enable AMPDU by default */
7579 iwpriv_sta_set_ampdu(dut, intf, 1);
7580
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007581#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08007582 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007583 sigma_dut_print(dut, DUT_MSG_ERROR,
7584 "Set LTF config to default in sta_reset_default_wcn failed");
7585 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07007586
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007587 /* set the beamformee NSTS(maximum number of
7588 * space-time streams) to default DUT config
7589 */
7590 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07007591 sigma_dut_print(dut, DUT_MSG_ERROR,
7592 "Failed to set BeamformeeSTS");
7593 }
Arif Hussain68d23f52018-07-11 13:39:08 -07007594
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07007595 if (sta_set_mac_padding_duration(
7596 dut, intf,
7597 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07007598 sigma_dut_print(dut, DUT_MSG_ERROR,
7599 "Failed to set MAC padding duration");
7600 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07007601
7602 if (sta_set_mu_edca_override(dut, intf, 0)) {
7603 sigma_dut_print(dut, DUT_MSG_ERROR,
7604 "ErrorCode,Failed to set MU EDCA override disable");
7605 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07007606
7607 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
7608 sigma_dut_print(dut, DUT_MSG_ERROR,
7609 "Failed to set OM ctrl supp");
7610 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07007611
7612 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
7613 sigma_dut_print(dut, DUT_MSG_ERROR,
7614 "Failed to set Tx SU PPDU enable");
7615 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007616
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07007617 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
7618 sigma_dut_print(dut, DUT_MSG_ERROR,
7619 "failed to send TB PPDU Tx cfg");
7620 }
7621
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07007622 if (sta_set_he_om_ctrl_reset(dut, intf)) {
7623 sigma_dut_print(dut, DUT_MSG_ERROR,
7624 "Failed to set OM ctrl reset");
7625 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007626
7627 /* +HTC-HE support default on */
7628 if (sta_set_he_htc_supp(dut, intf, 1)) {
7629 sigma_dut_print(dut, DUT_MSG_ERROR,
7630 "Setting of +HTC-HE support failed");
7631 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07007632#endif /* NL80211_SUPPORT */
7633
Arif Hussain8d5b27b2018-05-14 14:31:03 -07007634 if (sta_set_tx_beamformee(dut, intf, 1)) {
7635 sigma_dut_print(dut, DUT_MSG_ERROR,
7636 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
7637 }
7638
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007639 /* Set nss to 1 and MCS 0-7 in case of testbed */
7640 if (type && strcasecmp(type, "Testbed") == 0) {
7641#ifdef NL80211_SUPPORT
7642 int ret;
7643#endif /* NL80211_SUPPORT */
7644
7645 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
7646 if (system(buf) != 0) {
7647 sigma_dut_print(dut, DUT_MSG_ERROR,
7648 "iwpriv %s nss failed", intf);
7649 }
7650
7651#ifdef NL80211_SUPPORT
7652 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
7653 if (ret) {
7654 sigma_dut_print(dut, DUT_MSG_ERROR,
7655 "Setting of MCS failed, ret:%d",
7656 ret);
7657 }
7658#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08007659
7660 /* Disable STBC as default */
7661 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08007662
7663 /* Disable AMSDU as default */
7664 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007665
7666#ifdef NL80211_SUPPORT
7667 /* HE fragmentation default off */
7668 if (sta_set_he_fragmentation(dut, intf,
7669 HE_FRAG_DISABLE)) {
7670 sigma_dut_print(dut, DUT_MSG_ERROR,
7671 "Setting of HE fragmentation failed");
7672 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08007673
7674 /* set the beamformee NSTS(maximum number of
7675 * space-time streams) to default testbed config
7676 */
7677 if (sta_set_beamformee_sts(dut, intf, 3)) {
7678 sigma_dut_print(dut, DUT_MSG_ERROR,
7679 "Failed to set BeamformeeSTS");
7680 }
7681
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08007682 /* +HTC-HE support default off */
7683 if (sta_set_he_htc_supp(dut, intf, 0)) {
7684 sigma_dut_print(dut, DUT_MSG_ERROR,
7685 "Setting of +HTC-HE support failed");
7686 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08007687
7688 /* Set device HE capabilities to testbed default
7689 * configuration. */
7690 if (sta_set_he_testbed_def(dut, intf, 1)) {
7691 sigma_dut_print(dut, DUT_MSG_DEBUG,
7692 "Failed to set HE defaults");
7693 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08007694
7695 /* Disable VHT support in 2.4 GHz for testbed */
7696 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08007697#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08007698
7699 /* Enable WEP/TKIP with HE capability in testbed */
7700 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
7701 sigma_dut_print(dut, DUT_MSG_ERROR,
7702 "Enabling HE config with WEP/TKIP failed");
7703 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08007704 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007705
7706 /* Defaults in case of DUT */
7707 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07007708 /* Enable STBC by default */
7709 wcn_sta_set_stbc(dut, intf, "1");
7710
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007711 /* set nss to 2 */
7712 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
7713 if (system(buf) != 0) {
7714 sigma_dut_print(dut, DUT_MSG_ERROR,
7715 "iwpriv %s nss 2 failed", intf);
7716 }
Arif Hussainac6c5112018-05-25 17:34:00 -07007717 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007718
7719#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07007720 /* Set HE_MCS to 0-11 */
7721 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08007722 sigma_dut_print(dut, DUT_MSG_ERROR,
7723 "Setting of MCS failed");
7724 }
7725#endif /* NL80211_SUPPORT */
7726
7727 /* Disable WEP/TKIP with HE capability in DUT */
7728 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
7729 sigma_dut_print(dut, DUT_MSG_ERROR,
7730 "Enabling HE config with WEP/TKIP failed");
7731 }
7732 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007733 }
7734}
7735
7736
Jouni Malinenf7222712019-06-13 01:50:21 +03007737static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
7738 struct sigma_conn *conn,
7739 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007740{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007741 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007742 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007743 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007744 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05307745 const char *dev_role = get_param(cmd, "DevRole");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007746
Jouni Malinenb21f0542019-11-04 17:53:38 +02007747 if (dut->station_ifname_2g &&
7748 strcmp(dut->station_ifname_2g, intf) == 0)
7749 dut->use_5g = 0;
7750 else if (dut->station_ifname_5g &&
7751 strcmp(dut->station_ifname_5g, intf) == 0)
7752 dut->use_5g = 1;
7753
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007754 if (!program)
7755 program = get_param(cmd, "prog");
7756 dut->program = sigma_program_to_enum(program);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007757 dut->device_type = STA_unknown;
7758 type = get_param(cmd, "type");
7759 if (type && strcasecmp(type, "Testbed") == 0)
7760 dut->device_type = STA_testbed;
7761 if (type && strcasecmp(type, "DUT") == 0)
7762 dut->device_type = STA_dut;
7763
7764 if (dut->program == PROGRAM_TDLS) {
7765 /* Clear TDLS testing mode */
7766 wpa_command(intf, "SET tdls_disabled 0");
7767 wpa_command(intf, "SET tdls_testing 0");
7768 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007769 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05307770 /* Enable the WCN driver in TDLS Explicit trigger mode
7771 */
7772 wpa_command(intf, "SET tdls_external_control 0");
7773 wpa_command(intf, "SET tdls_trigger_control 0");
7774 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007775 }
7776
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07007777#ifdef MIRACAST
7778 if (dut->program == PROGRAM_WFD ||
7779 dut->program == PROGRAM_DISPLAYR2)
7780 miracast_sta_reset_default(dut, conn, cmd);
7781#endif /* MIRACAST */
7782
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007783 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007784 case DRIVER_ATHEROS:
7785 sta_reset_default_ath(dut, intf, type);
7786 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08007787 case DRIVER_WCN:
7788 sta_reset_default_wcn(dut, intf, type);
7789 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007790 default:
7791 break;
7792 }
7793
7794#ifdef ANDROID_NAN
7795 if (dut->program == PROGRAM_NAN)
7796 nan_cmd_sta_reset_default(dut, conn, cmd);
7797#endif /* ANDROID_NAN */
7798
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05307799 if (dut->program == PROGRAM_LOC &&
7800 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
7801 return ERROR_SEND_STATUS;
7802
Jouni Malinenba630452018-06-22 11:49:59 +03007803 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007804 unlink("SP/wi-fi.org/pps.xml");
7805 if (system("rm -r SP/*") != 0) {
7806 }
7807 unlink("next-client-cert.pem");
7808 unlink("next-client-key.pem");
7809 }
7810
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007811 /* For WPS program of the 60 GHz band the band type needs to be saved */
7812 if (dut->program == PROGRAM_WPS) {
7813 if (band && strcasecmp(band, "60GHz") == 0) {
7814 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007815 /* For 60 GHz enable WPS for WPS TCs */
7816 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007817 } else {
7818 dut->band = WPS_BAND_NON_60G;
7819 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007820 } else if (dut->program == PROGRAM_60GHZ) {
7821 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
7822 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007823 }
7824
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02007825 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007826 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007827 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007828
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02007829 sigma_dut_print(dut, DUT_MSG_INFO,
7830 "WPS 60 GHz program, wps_disable = %d",
7831 dut->wps_disable);
7832
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007833 if (!dev_role) {
7834 send_resp(dut, conn, SIGMA_ERROR,
7835 "errorCode,Missing DevRole argument");
7836 return 0;
7837 }
7838
7839 if (strcasecmp(dev_role, "STA") == 0)
7840 dut->dev_role = DEVROLE_STA;
7841 else if (strcasecmp(dev_role, "PCP") == 0)
7842 dut->dev_role = DEVROLE_PCP;
7843 else {
7844 send_resp(dut, conn, SIGMA_ERROR,
7845 "errorCode,Unknown DevRole");
7846 return 0;
7847 }
7848
7849 if (dut->device_type == STA_unknown) {
7850 sigma_dut_print(dut, DUT_MSG_ERROR,
7851 "Device type is not STA testbed or DUT");
7852 send_resp(dut, conn, SIGMA_ERROR,
7853 "errorCode,Unknown device type");
7854 return 0;
7855 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007856
7857 sigma_dut_print(dut, DUT_MSG_DEBUG,
7858 "Setting msdu_size to MAX: 7912");
7859 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007860 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007861
7862 if (system(buf) != 0) {
7863 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7864 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007865 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02007866 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007867
7868 if (sta_set_force_mcs(dut, 0, 1)) {
7869 sigma_dut_print(dut, DUT_MSG_ERROR,
7870 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007871 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007872 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007873 }
7874
7875 wpa_command(intf, "WPS_ER_STOP");
7876 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05307877 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007878 wpa_command(intf, "SET radio_disabled 0");
7879
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02007880 dut->wps_forced_version = 0;
7881
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007882 if (dut->wsc_fragment) {
7883 dut->wsc_fragment = 0;
7884 wpa_command(intf, "SET device_name Test client");
7885 wpa_command(intf, "SET manufacturer ");
7886 wpa_command(intf, "SET model_name ");
7887 wpa_command(intf, "SET model_number ");
7888 wpa_command(intf, "SET serial_number ");
7889 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007890 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
7891 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
7892 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
7893 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02007894
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007895 if (dut->tmp_mac_addr && dut->set_macaddr) {
7896 dut->tmp_mac_addr = 0;
7897 if (system(dut->set_macaddr) != 0) {
7898 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
7899 "temporary MAC address");
7900 }
7901 }
7902
7903 set_ps(intf, dut, 0);
7904
Jouni Malinenba630452018-06-22 11:49:59 +03007905 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
7906 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007907 wpa_command(intf, "SET interworking 1");
7908 wpa_command(intf, "SET hs20 1");
7909 }
7910
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007911 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03007912 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08007913 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007914 wpa_command(intf, "SET pmf 1");
7915 } else {
7916 wpa_command(intf, "SET pmf 0");
7917 }
7918
7919 hs2_clear_credentials(intf);
7920 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
7921 wpa_command(intf, "SET access_network_type 15");
7922
7923 static_ip_file(0, NULL, NULL, NULL);
7924 kill_dhcp_client(dut, intf);
7925 clear_ip_addr(dut, intf);
7926
7927 dut->er_oper_performed = 0;
7928 dut->er_oper_bssid[0] = '\0';
7929
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007930 if (dut->program == PROGRAM_LOC) {
7931 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007932 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07007933 }
7934
Ashwini Patil00402582017-04-13 12:29:39 +05307935 if (dut->program == PROGRAM_MBO) {
7936 free(dut->non_pref_ch_list);
7937 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05307938 free(dut->btm_query_cand_list);
7939 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05307940 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05307941 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05307942 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05307943 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05307944 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05307945 }
7946
Jouni Malinen3c367e82017-06-23 17:01:47 +03007947 free(dut->rsne_override);
7948 dut->rsne_override = NULL;
7949
Jouni Malinen68143132017-09-02 02:34:08 +03007950 free(dut->sae_commit_override);
7951 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03007952 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02007953 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03007954
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007955 dut->sta_associate_wait_connect = 0;
7956 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03007957 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03007958 dut->sta_tod_policy = 0;
7959
Jouni Malinend86e5822017-08-29 03:55:32 +03007960 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02007961 free(dut->dpp_peer_uri);
7962 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02007963 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02007964 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinend86e5822017-08-29 03:55:32 +03007965
Jouni Malinenfac9cad2017-10-10 18:35:55 +03007966 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
7967
vamsi krishnaa2799492017-12-05 14:28:01 +05307968 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307969 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05307970 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05307971 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
7972 dut->fils_hlp = 0;
7973#ifdef ANDROID
7974 hlp_thread_cleanup(dut);
7975#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05307976 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05307977
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05307978 if (dut->program == PROGRAM_QM)
7979 wpa_command(intf, "SET interworking 1");
7980
Jouni Malinen8179fee2019-03-28 03:19:47 +02007981 dut->akm_values = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007982 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02007983
Sunil Dutt076081f2018-02-05 19:45:50 +05307984#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007985 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05307986 dut->config_rsnie == 1) {
7987 dut->config_rsnie = 0;
7988 sta_config_rsnie(dut, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05307989 }
7990#endif /* NL80211_SUPPORT */
7991
Sunil Duttfebf8a82018-02-09 18:50:13 +05307992 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
7993 dut->dev_role = DEVROLE_STA_CFON;
7994 return sta_cfon_reset_default(dut, conn, cmd);
7995 }
7996
Jouni Malinen439352d2018-09-13 03:42:23 +03007997 wpa_command(intf, "SET setband AUTO");
7998
Sunil Duttfebf8a82018-02-09 18:50:13 +05307999 if (dut->program != PROGRAM_VHT)
8000 return cmd_sta_p2p_reset(dut, conn, cmd);
8001
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08008002 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008003}
8004
8005
Jouni Malinenf7222712019-06-13 01:50:21 +03008006static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
8007 struct sigma_conn *conn,
8008 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008009{
8010 const char *program = get_param(cmd, "Program");
8011
8012 if (program == NULL)
8013 return -1;
8014#ifdef ANDROID_NAN
8015 if (strcasecmp(program, "NAN") == 0)
8016 return nan_cmd_sta_get_events(dut, conn, cmd);
8017#endif /* ANDROID_NAN */
8018 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8019 return 0;
8020}
8021
8022
Jouni Malinen82905202018-04-29 17:20:10 +03008023static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
8024 struct sigma_cmd *cmd)
8025{
8026 const char *url = get_param(cmd, "url");
8027 const char *method = get_param(cmd, "method");
8028 pid_t pid;
8029 int status;
8030
8031 if (!url || !method)
8032 return -1;
8033
8034 /* TODO: Add support for method,post */
8035 if (strcasecmp(method, "get") != 0) {
8036 send_resp(dut, conn, SIGMA_ERROR,
8037 "ErrorCode,Unsupported method");
8038 return 0;
8039 }
8040
8041 pid = fork();
8042 if (pid < 0) {
8043 perror("fork");
8044 return -1;
8045 }
8046
8047 if (pid == 0) {
8048 char * argv[5] = { "wget", "-O", "/dev/null",
8049 (char *) url, NULL };
8050
8051 execv("/usr/bin/wget", argv);
8052 perror("execv");
8053 exit(0);
8054 return -1;
8055 }
8056
8057 if (waitpid(pid, &status, 0) < 0) {
8058 perror("waitpid");
8059 return -1;
8060 }
8061
8062 if (WIFEXITED(status)) {
8063 const char *errmsg;
8064
8065 if (WEXITSTATUS(status) == 0)
8066 return 1;
8067 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
8068 WEXITSTATUS(status));
8069 switch (WEXITSTATUS(status)) {
8070 case 4:
8071 errmsg = "errmsg,Network failure";
8072 break;
8073 case 8:
8074 errmsg = "errmsg,Server issued an error response";
8075 break;
8076 default:
8077 errmsg = "errmsg,Unknown failure from wget";
8078 break;
8079 }
8080 send_resp(dut, conn, SIGMA_ERROR, errmsg);
8081 return 0;
8082 }
8083
8084 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
8085 return 0;
8086}
8087
8088
Jouni Malinenf7222712019-06-13 01:50:21 +03008089static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
8090 struct sigma_conn *conn,
8091 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008092{
8093 const char *program = get_param(cmd, "Prog");
8094
Jouni Malinen82905202018-04-29 17:20:10 +03008095 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008096 return -1;
8097#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03008098 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008099 return nan_cmd_sta_exec_action(dut, conn, cmd);
8100#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03008101
8102 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07008103 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03008104
8105 if (get_param(cmd, "url"))
8106 return sta_exec_action_url(dut, conn, cmd);
8107
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008108 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8109 return 0;
8110}
8111
8112
Jouni Malinenf7222712019-06-13 01:50:21 +03008113static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
8114 struct sigma_conn *conn,
8115 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008116{
8117 const char *intf = get_param(cmd, "Interface");
8118 const char *val, *mcs32, *rate;
8119
8120 val = get_param(cmd, "GREENFIELD");
8121 if (val) {
8122 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
8123 /* Enable GD */
8124 send_resp(dut, conn, SIGMA_ERROR,
8125 "ErrorCode,GF not supported");
8126 return 0;
8127 }
8128 }
8129
8130 val = get_param(cmd, "SGI20");
8131 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008132 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008133 case DRIVER_ATHEROS:
8134 ath_sta_set_sgi(dut, intf, val);
8135 break;
8136 default:
8137 send_resp(dut, conn, SIGMA_ERROR,
8138 "ErrorCode,SGI20 not supported");
8139 return 0;
8140 }
8141 }
8142
8143 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
8144 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
8145 if (mcs32 && rate) {
8146 /* TODO */
8147 send_resp(dut, conn, SIGMA_ERROR,
8148 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
8149 return 0;
8150 } else if (mcs32 && !rate) {
8151 /* TODO */
8152 send_resp(dut, conn, SIGMA_ERROR,
8153 "ErrorCode,MCS32 not supported");
8154 return 0;
8155 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008156 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008157 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07008158 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008159 ath_sta_set_11nrates(dut, intf, rate);
8160 break;
8161 default:
8162 send_resp(dut, conn, SIGMA_ERROR,
8163 "ErrorCode,MCS32_FIXEDRATE not supported");
8164 return 0;
8165 }
8166 }
8167
8168 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8169}
8170
8171
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008172static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
8173 int mcs_config)
8174{
8175#ifdef NL80211_SUPPORT
8176 int ret;
8177
8178 switch (mcs_config) {
8179 case HE_80_MCS0_7:
8180 case HE_80_MCS0_9:
8181 case HE_80_MCS0_11:
8182 ret = sta_set_he_mcs(dut, intf, mcs_config);
8183 if (ret) {
8184 sigma_dut_print(dut, DUT_MSG_ERROR,
8185 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
8186 mcs_config, ret);
8187 }
8188 break;
8189 default:
8190 sigma_dut_print(dut, DUT_MSG_ERROR,
8191 "cmd_set_max_he_mcs: Invalid mcs %d",
8192 mcs_config);
8193 break;
8194 }
8195#else /* NL80211_SUPPORT */
8196 sigma_dut_print(dut, DUT_MSG_ERROR,
8197 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
8198#endif /* NL80211_SUPPORT */
8199}
8200
8201
Arif Hussain480d5f42019-03-12 14:40:42 -07008202static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
8203 struct sigma_cmd *cmd)
8204{
8205#ifdef NL80211_SUPPORT
8206 struct nlattr *params;
8207 struct nlattr *attr;
8208 struct nlattr *attr1;
8209 struct nl_msg *msg;
8210 int ifindex, ret;
8211 const char *val;
8212 const char *intf = get_param(cmd, "Interface");
8213 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
8214 wake_interval_mantissa = 512;
8215 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
8216 protection = 0;
8217
8218 ifindex = if_nametoindex(intf);
8219 if (ifindex == 0) {
8220 sigma_dut_print(dut, DUT_MSG_ERROR,
8221 "%s: Index for interface %s failed",
8222 __func__, intf);
8223 return -1;
8224 }
8225
8226 val = get_param(cmd, "FlowType");
8227 if (val) {
8228 flow_type = atoi(val);
8229 if (flow_type != 0 && flow_type != 1) {
8230 sigma_dut_print(dut, DUT_MSG_ERROR,
8231 "TWT: Invalid FlowType %d", flow_type);
8232 return -1;
8233 }
8234 }
8235
8236 val = get_param(cmd, "TWT_Trigger");
8237 if (val) {
8238 twt_trigger = atoi(val);
8239 if (twt_trigger != 0 && twt_trigger != 1) {
8240 sigma_dut_print(dut, DUT_MSG_ERROR,
8241 "TWT: Invalid TWT_Trigger %d",
8242 twt_trigger);
8243 return -1;
8244 }
8245 }
8246
8247 val = get_param(cmd, "Protection");
8248 if (val) {
8249 protection = atoi(val);
8250 if (protection != 0 && protection != 1) {
8251 sigma_dut_print(dut, DUT_MSG_ERROR,
8252 "TWT: Invalid Protection %d",
8253 protection);
8254 return -1;
8255 }
8256 }
8257
8258 val = get_param(cmd, "TargetWakeTime");
8259 if (val)
8260 target_wake_time = atoi(val);
8261
8262 val = get_param(cmd, "WakeIntervalMantissa");
8263 if (val)
8264 wake_interval_mantissa = atoi(val);
8265
8266 val = get_param(cmd, "WakeIntervalExp");
8267 if (val)
8268 wake_interval_exp = atoi(val);
8269
8270 val = get_param(cmd, "NominalMinWakeDur");
8271 if (val)
8272 nominal_min_wake_dur = atoi(val);
8273
8274 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8275 NL80211_CMD_VENDOR)) ||
8276 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8277 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8278 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8279 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8280 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8281 !(params = nla_nest_start(
8282 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP)) ||
8283 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8284 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
8285 wake_interval_exp) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008286 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, 1) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008287 (twt_trigger &&
8288 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008289 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
8290 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -07008291 (protection &&
8292 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -07008293 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
8294 target_wake_time) ||
8295 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
8296 nominal_min_wake_dur) ||
8297 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
8298 wake_interval_mantissa)) {
8299 sigma_dut_print(dut, DUT_MSG_ERROR,
8300 "%s: err in adding vendor_cmd and vendor_data",
8301 __func__);
8302 nlmsg_free(msg);
8303 return -1;
8304 }
8305 nla_nest_end(msg, attr1);
8306 nla_nest_end(msg, params);
8307 nla_nest_end(msg, attr);
8308
8309 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8310 if (ret) {
8311 sigma_dut_print(dut, DUT_MSG_ERROR,
8312 "%s: err in send_and_recv_msgs, ret=%d",
8313 __func__, ret);
8314 }
8315
8316 return ret;
8317#else /* NL80211_SUPPORT */
8318 sigma_dut_print(dut, DUT_MSG_ERROR,
8319 "TWT request cannot be done without NL80211_SUPPORT defined");
8320 return -1;
8321#endif /* NL80211_SUPPORT */
8322}
8323
8324
8325static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
8326 struct sigma_cmd *cmd)
8327{
8328 #ifdef NL80211_SUPPORT
8329 struct nlattr *params;
8330 struct nlattr *attr;
8331 struct nlattr *attr1;
8332 int ifindex, ret;
8333 struct nl_msg *msg;
8334 const char *intf = get_param(cmd, "Interface");
8335
8336 ifindex = if_nametoindex(intf);
8337 if (ifindex == 0) {
8338 sigma_dut_print(dut, DUT_MSG_ERROR,
8339 "%s: Index for interface %s failed",
8340 __func__, intf);
8341 return -1;
8342 }
8343
8344 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8345 NL80211_CMD_VENDOR)) ||
8346 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8347 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8348 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8349 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8350 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8351 !(params = nla_nest_start(
8352 msg,
8353 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE)) ||
8354 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8355 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0)) {
8356 sigma_dut_print(dut, DUT_MSG_ERROR,
8357 "%s: err in adding vendor_cmd and vendor_data",
8358 __func__);
8359 nlmsg_free(msg);
8360 return -1;
8361 }
8362 nla_nest_end(msg, attr1);
8363 nla_nest_end(msg, params);
8364 nla_nest_end(msg, attr);
8365
8366 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8367 if (ret) {
8368 sigma_dut_print(dut, DUT_MSG_ERROR,
8369 "%s: err in send_and_recv_msgs, ret=%d",
8370 __func__, ret);
8371 }
8372
8373 return ret;
8374#else /* NL80211_SUPPORT */
8375 sigma_dut_print(dut, DUT_MSG_ERROR,
8376 "TWT teardown cannot be done without NL80211_SUPPORT defined");
8377 return -1;
8378#endif /* NL80211_SUPPORT */
8379}
8380
8381
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -08008382static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
8383 struct sigma_cmd *cmd)
8384{
8385#ifdef NL80211_SUPPORT
8386 struct nlattr *params;
8387 struct nlattr *attr;
8388 struct nlattr *attr1;
8389 struct nl_msg *msg;
8390 int ifindex, ret;
8391 const char *val;
8392 const char *intf = get_param(cmd, "Interface");
8393 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
8394 ulmu_data_dis = 0;
8395
8396 ifindex = if_nametoindex(intf);
8397 if (ifindex == 0) {
8398 sigma_dut_print(dut, DUT_MSG_ERROR,
8399 "%s: Index for interface %s failed",
8400 __func__, intf);
8401 return -1;
8402 }
8403 val = get_param(cmd, "OMCtrl_RxNSS");
8404 if (val)
8405 rx_nss = atoi(val);
8406
8407 val = get_param(cmd, "OMCtrl_ChnlWidth");
8408 if (val)
8409 ch_bw = atoi(val);
8410
8411 val = get_param(cmd, "OMCtrl_ULMUDisable");
8412 if (val)
8413 ulmu_dis = atoi(val);
8414
8415 val = get_param(cmd, "OMCtrl_TxNSTS");
8416 if (val)
8417 tx_nsts = atoi(val);
8418
8419 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
8420 if (val)
8421 ulmu_data_dis = atoi(val);
8422
8423 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8424 NL80211_CMD_VENDOR)) ||
8425 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8426 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8427 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8428 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
8429 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8430 !(params = nla_nest_start(
8431 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
8432 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
8433 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
8434 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
8435 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
8436 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
8437 ulmu_data_dis) ||
8438 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
8439 ulmu_dis)) {
8440 sigma_dut_print(dut, DUT_MSG_ERROR,
8441 "%s: err in adding vendor_cmd and vendor_data",
8442 __func__);
8443 nlmsg_free(msg);
8444 return -1;
8445 }
8446 nla_nest_end(msg, attr1);
8447 nla_nest_end(msg, params);
8448 nla_nest_end(msg, attr);
8449
8450 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8451 if (ret) {
8452 sigma_dut_print(dut, DUT_MSG_ERROR,
8453 "%s: err in send_and_recv_msgs, ret=%d",
8454 __func__, ret);
8455 }
8456
8457 return ret;
8458#else /* NL80211_SUPPORT */
8459 sigma_dut_print(dut, DUT_MSG_ERROR,
8460 "OMI TX cannot be processed without NL80211_SUPPORT defined");
8461 return -1;
8462#endif /* NL80211_SUPPORT */
8463}
8464
8465
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008466static int cmd_sta_set_wireless_vht(struct sigma_dut *dut,
8467 struct sigma_conn *conn,
8468 struct sigma_cmd *cmd)
8469{
8470 const char *intf = get_param(cmd, "Interface");
8471 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -07008472 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008473 int tkip = -1;
8474 int wep = -1;
8475
Arif Hussaina37e9552018-06-20 17:05:59 -07008476 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008477 val = get_param(cmd, "SGI80");
8478 if (val) {
8479 int sgi80;
8480
8481 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008482 run_iwpriv(dut, intf, "shortgi %d", sgi80);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008483 }
8484
8485 val = get_param(cmd, "TxBF");
8486 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008487 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008488 case DRIVER_WCN:
8489 if (sta_set_tx_beamformee(dut, intf, 1)) {
8490 send_resp(dut, conn, SIGMA_ERROR,
8491 "ErrorCode,Failed to set TX beamformee enable");
8492 return 0;
8493 }
8494 break;
8495 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008496 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008497 send_resp(dut, conn, SIGMA_ERROR,
8498 "ErrorCode,Setting vhtsubfee failed");
8499 return 0;
8500 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008501 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008502 send_resp(dut, conn, SIGMA_ERROR,
8503 "ErrorCode,Setting vhtsubfer failed");
8504 return 0;
8505 }
8506 break;
8507 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008508 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -07008509 "Unsupported driver type");
8510 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008511 }
8512 }
8513
8514 val = get_param(cmd, "MU_TxBF");
8515 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008516 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008517 case DRIVER_ATHEROS:
8518 ath_sta_set_txsp_stream(dut, intf, "1SS");
8519 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008520 run_iwpriv(dut, intf, "vhtmubfee 1");
8521 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +05308522 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008523 case DRIVER_WCN:
8524 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
8525 send_resp(dut, conn, SIGMA_ERROR,
8526 "ErrorCode,Failed to set RX/TXSP_STREAM");
8527 return 0;
8528 }
Sunil Duttae9e5d12018-06-29 11:50:47 +05308529 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008530 default:
8531 sigma_dut_print(dut, DUT_MSG_ERROR,
8532 "Setting SP_STREAM not supported");
8533 break;
8534 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008535 }
8536
8537 val = get_param(cmd, "LDPC");
8538 if (val) {
8539 int ldpc;
8540
8541 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008542 run_iwpriv(dut, intf, "ldpc %d", ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008543 }
8544
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008545 val = get_param(cmd, "BCC");
8546 if (val) {
8547 int bcc;
8548
8549 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8550 /* use LDPC iwpriv itself to set bcc coding, bcc coding
8551 * is mutually exclusive to bcc */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008552 run_iwpriv(dut, intf, "ldpc %d", !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -08008553 }
8554
Arif Hussain7b47d2d2018-05-09 10:44:02 -07008555 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
8556 if (val && dut->sta_nss == 1)
8557 cmd_set_max_he_mcs(dut, intf, atoi(val));
8558
8559 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
8560 if (val && dut->sta_nss == 2)
8561 cmd_set_max_he_mcs(dut, intf, atoi(val));
8562
Arif Hussainac6c5112018-05-25 17:34:00 -07008563 val = get_param(cmd, "MCS_FixedRate");
8564 if (val) {
8565#ifdef NL80211_SUPPORT
8566 int mcs, ratecode = 0;
8567 enum he_mcs_config mcs_config;
8568 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +03008569 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07008570
8571 ratecode = (0x07 & dut->sta_nss) << 5;
8572 mcs = atoi(val);
8573 /* Add the MCS to the ratecode */
8574 if (mcs >= 0 && mcs <= 11) {
8575 ratecode += mcs;
8576 if (dut->device_type == STA_testbed &&
8577 mcs > 7 && mcs <= 11) {
8578 if (mcs <= 9)
8579 mcs_config = HE_80_MCS0_9;
8580 else
8581 mcs_config = HE_80_MCS0_11;
8582 ret = sta_set_he_mcs(dut, intf, mcs_config);
8583 if (ret) {
8584 sigma_dut_print(dut, DUT_MSG_ERROR,
8585 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
8586 mcs, mcs_config, ret);
8587 }
8588 }
8589 snprintf(buf, sizeof(buf),
8590 "iwpriv %s set_11ax_rate 0x%03x",
8591 intf, ratecode);
8592 if (system(buf) != 0) {
8593 sigma_dut_print(dut, DUT_MSG_ERROR,
8594 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
8595 ratecode);
8596 }
8597 } else {
8598 sigma_dut_print(dut, DUT_MSG_ERROR,
8599 "MCS_FixedRate: HE MCS %d not supported",
8600 mcs);
8601 }
8602#else /* NL80211_SUPPORT */
8603 sigma_dut_print(dut, DUT_MSG_ERROR,
8604 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
8605#endif /* NL80211_SUPPORT */
8606 }
8607
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008608 val = get_param(cmd, "opt_md_notif_ie");
8609 if (val) {
8610 char *result = NULL;
8611 char delim[] = ";";
8612 char token[30];
8613 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308614 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008615
Peng Xub8fc5cc2017-05-10 17:27:28 -07008616 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308617 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008618
8619 /* Extract the NSS information */
8620 if (result) {
8621 value = atoi(result);
8622 switch (value) {
8623 case 1:
8624 config_val = 1;
8625 break;
8626 case 2:
8627 config_val = 3;
8628 break;
8629 case 3:
8630 config_val = 7;
8631 break;
8632 case 4:
8633 config_val = 15;
8634 break;
8635 default:
8636 config_val = 3;
8637 break;
8638 }
8639
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008640 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
8641 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008642
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008643 }
8644
8645 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308646 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008647 if (result) {
8648 value = atoi(result);
8649 switch (value) {
8650 case 20:
8651 config_val = 0;
8652 break;
8653 case 40:
8654 config_val = 1;
8655 break;
8656 case 80:
8657 config_val = 2;
8658 break;
8659 case 160:
8660 config_val = 3;
8661 break;
8662 default:
8663 config_val = 2;
8664 break;
8665 }
8666
8667 dut->chwidth = config_val;
8668
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008669 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008670 }
8671
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008672 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008673 }
8674
8675 val = get_param(cmd, "nss_mcs_cap");
8676 if (val) {
8677 int nss, mcs;
8678 char token[20];
8679 char *result = NULL;
8680 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308681 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008682
Peng Xub8fc5cc2017-05-10 17:27:28 -07008683 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308684 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308685 if (!result) {
8686 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008687 "NSS not specified");
8688 send_resp(dut, conn, SIGMA_ERROR,
8689 "errorCode,NSS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308690 return 0;
8691 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008692 nss = atoi(result);
8693
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008694 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -07008695 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008696
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308697 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008698 if (result == NULL) {
8699 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008700 "MCS not specified");
8701 send_resp(dut, conn, SIGMA_ERROR,
8702 "errorCode,MCS not specified");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008703 return 0;
8704 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05308705 result = strtok_r(result, "-", &saveptr);
8706 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308707 if (!result) {
8708 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008709 "MCS not specified");
8710 send_resp(dut, conn, SIGMA_ERROR,
8711 "errorCode,MCS not specified");
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +05308712 return 0;
8713 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008714 mcs = atoi(result);
8715
Arif Hussaina37e9552018-06-20 17:05:59 -07008716 if (program && strcasecmp(program, "HE") == 0) {
8717#ifdef NL80211_SUPPORT
8718 enum he_mcs_config mcs_config;
8719 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008720
Arif Hussaina37e9552018-06-20 17:05:59 -07008721 if (mcs >= 0 && mcs <= 7) {
8722 mcs_config = HE_80_MCS0_7;
8723 } else if (mcs > 7 && mcs <= 9) {
8724 mcs_config = HE_80_MCS0_9;
8725 } else if (mcs > 9 && mcs <= 11) {
8726 mcs_config = HE_80_MCS0_11;
8727 } else {
8728 sigma_dut_print(dut, DUT_MSG_ERROR,
8729 "nss_mcs_cap: HE: Invalid mcs: %d",
8730 mcs);
8731 send_resp(dut, conn, SIGMA_ERROR,
8732 "errorCode,Invalid MCS");
8733 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008734 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008735
8736 ret = sta_set_he_mcs(dut, intf, mcs_config);
8737 if (ret) {
8738 sigma_dut_print(dut, DUT_MSG_ERROR,
8739 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
8740 mcs_config, ret);
8741 send_resp(dut, conn, SIGMA_ERROR,
8742 "errorCode,Failed to set MCS");
8743 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008744 }
Arif Hussaina37e9552018-06-20 17:05:59 -07008745#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008746 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -07008747 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
8748#endif /* NL80211_SUPPORT */
8749 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008750 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -07008751
8752 switch (nss) {
8753 case 1:
8754 switch (mcs) {
8755 case 7:
8756 vht_mcsmap = 0xfffc;
8757 break;
8758 case 8:
8759 vht_mcsmap = 0xfffd;
8760 break;
8761 case 9:
8762 vht_mcsmap = 0xfffe;
8763 break;
8764 default:
8765 vht_mcsmap = 0xfffe;
8766 break;
8767 }
8768 break;
8769 case 2:
8770 switch (mcs) {
8771 case 7:
8772 vht_mcsmap = 0xfff0;
8773 break;
8774 case 8:
8775 vht_mcsmap = 0xfff5;
8776 break;
8777 case 9:
8778 vht_mcsmap = 0xfffa;
8779 break;
8780 default:
8781 vht_mcsmap = 0xfffa;
8782 break;
8783 }
8784 break;
8785 case 3:
8786 switch (mcs) {
8787 case 7:
8788 vht_mcsmap = 0xffc0;
8789 break;
8790 case 8:
8791 vht_mcsmap = 0xffd5;
8792 break;
8793 case 9:
8794 vht_mcsmap = 0xffea;
8795 break;
8796 default:
8797 vht_mcsmap = 0xffea;
8798 break;
8799 }
8800 break;
8801 default:
8802 vht_mcsmap = 0xffea;
8803 break;
8804 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008805 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008806 }
8807 }
8808
8809 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
8810
8811 val = get_param(cmd, "Vht_tkip");
8812 if (val)
8813 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8814
8815 val = get_param(cmd, "Vht_wep");
8816 if (val)
8817 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
8818
8819 if (tkip != -1 || wep != -1) {
8820 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008821 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008822 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008823 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008824 } else {
8825 sigma_dut_print(dut, DUT_MSG_ERROR,
8826 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
8827 return 0;
8828 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008829 }
8830
Arif Hussain55f00da2018-07-03 08:28:26 -07008831 val = get_param(cmd, "txBandwidth");
8832 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008833 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -07008834 case DRIVER_WCN:
8835 if (wcn_sta_set_width(dut, intf, val) < 0) {
8836 send_resp(dut, conn, SIGMA_ERROR,
8837 "ErrorCode,Failed to set txBandwidth");
8838 return 0;
8839 }
8840 break;
8841 case DRIVER_ATHEROS:
8842 if (ath_set_width(dut, conn, intf, val) < 0) {
8843 send_resp(dut, conn, SIGMA_ERROR,
8844 "ErrorCode,Failed to set txBandwidth");
8845 return 0;
8846 }
8847 break;
8848 default:
8849 sigma_dut_print(dut, DUT_MSG_ERROR,
8850 "Setting txBandwidth not supported");
8851 break;
8852 }
8853 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008854
Arif Hussain9765f7d2018-07-03 08:28:26 -07008855 val = get_param(cmd, "BeamformeeSTS");
8856 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -07008857 if (sta_set_tx_beamformee(dut, intf, 1)) {
8858 send_resp(dut, conn, SIGMA_ERROR,
8859 "ErrorCode,Failed to set TX beamformee enable");
8860 return 0;
8861 }
8862
Arif Hussain9765f7d2018-07-03 08:28:26 -07008863 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
8864 send_resp(dut, conn, SIGMA_ERROR,
8865 "ErrorCode,Failed to set BeamformeeSTS");
8866 return 0;
8867 }
8868 }
8869
Arif Hussain68d23f52018-07-11 13:39:08 -07008870 val = get_param(cmd, "Trig_MAC_Padding_Dur");
8871 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008872#ifdef NL80211_SUPPORT
8873 enum qca_wlan_he_mac_padding_dur set_val;
8874
8875 switch (atoi(val)) {
8876 case 16:
8877 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
8878 break;
8879 case 8:
8880 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
8881 break;
8882 default:
8883 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
8884 break;
8885 }
8886 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008887 send_resp(dut, conn, SIGMA_ERROR,
8888 "ErrorCode,Failed to set MAC padding duration");
8889 return 0;
8890 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008891#else /* NL80211_SUPPORT */
8892 sigma_dut_print(dut, DUT_MSG_ERROR,
8893 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
8894#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008895 }
8896
Arif Hussain480d5f42019-03-12 14:40:42 -07008897 val = get_param(cmd, "TWT_ReqSupport");
8898 if (val) {
8899 int set_val;
8900
8901 if (strcasecmp(val, "Enable") == 0) {
8902 set_val = 1;
8903 } else if (strcasecmp(val, "Disable") == 0) {
8904 set_val = 0;
8905 } else {
8906 send_resp(dut, conn, SIGMA_ERROR,
8907 "ErrorCode,Invalid TWT_ReqSupport");
8908 return STATUS_SENT;
8909 }
8910
8911 if (sta_set_twt_req_support(dut, intf, set_val)) {
8912 sigma_dut_print(dut, DUT_MSG_ERROR,
8913 "Failed to set TWT req support %d",
8914 set_val);
8915 send_resp(dut, conn, SIGMA_ERROR,
8916 "ErrorCode,Failed to set TWT_ReqSupport");
8917 return STATUS_SENT;
8918 }
8919 }
8920
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008921 val = get_param(cmd, "MU_EDCA");
8922 if (val && (strcasecmp(val, "Override") == 0)) {
8923 if (sta_set_mu_edca_override(dut, intf, 1)) {
8924 send_resp(dut, conn, SIGMA_ERROR,
8925 "ErrorCode,Failed to set MU EDCA override");
8926 return 0;
8927 }
8928 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008929
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008930 val = get_param(cmd, "OMControl");
8931 if (val) {
8932 int set_val = 1;
8933
8934 if (strcasecmp(val, "Enable") == 0)
8935 set_val = 1;
8936 else if (strcasecmp(val, "Disable") == 0)
8937 set_val = 0;
8938
8939 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
8940 send_resp(dut, conn, SIGMA_ERROR,
8941 "ErrorCode,Failed to set OM ctrl supp");
8942 return 0;
8943 }
8944 }
8945
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008946 val = get_param(cmd, "ADDBAResp_BufSize");
8947 if (val) {
8948 int buf_size;
8949
8950 if (strcasecmp(val, "gt64") == 0)
8951 buf_size = 256;
8952 else
8953 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008954 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008955 sta_set_addba_buf_size(dut, intf, buf_size)) {
8956 send_resp(dut, conn, SIGMA_ERROR,
8957 "ErrorCode,set addbaresp_buff_size failed");
8958 return 0;
8959 }
8960 }
8961
8962 val = get_param(cmd, "ADDBAReq_BufSize");
8963 if (val) {
8964 int buf_size;
8965
8966 if (strcasecmp(val, "gt64") == 0)
8967 buf_size = 256;
8968 else
8969 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02008970 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -07008971 sta_set_addba_buf_size(dut, intf, buf_size)) {
8972 send_resp(dut, conn, SIGMA_ERROR,
8973 "ErrorCode,set addbareq_buff_size failed");
8974 return 0;
8975 }
8976 }
8977
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008978 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
8979}
8980
8981
8982static int sta_set_wireless_60g(struct sigma_dut *dut,
8983 struct sigma_conn *conn,
8984 struct sigma_cmd *cmd)
8985{
8986 const char *dev_role = get_param(cmd, "DevRole");
8987
8988 if (!dev_role) {
8989 send_resp(dut, conn, SIGMA_INVALID,
8990 "ErrorCode,DevRole not specified");
8991 return 0;
8992 }
8993
8994 if (strcasecmp(dev_role, "PCP") == 0)
8995 return sta_set_60g_pcp(dut, conn, cmd);
8996 if (strcasecmp(dev_role, "STA") == 0)
8997 return sta_set_60g_sta(dut, conn, cmd);
8998 send_resp(dut, conn, SIGMA_INVALID,
8999 "ErrorCode,DevRole not supported");
9000 return 0;
9001}
9002
9003
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309004static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
9005 struct sigma_cmd *cmd)
9006{
9007 int status;
9008 const char *intf = get_param(cmd, "Interface");
9009 const char *val = get_param(cmd, "DevRole");
9010
9011 if (val && strcasecmp(val, "STA-CFON") == 0) {
9012 status = sta_cfon_set_wireless(dut, conn, cmd);
9013 if (status)
9014 return status;
9015 }
9016 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9017}
9018
9019
Jouni Malinenf7222712019-06-13 01:50:21 +03009020static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
9021 struct sigma_conn *conn,
9022 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009023{
9024 const char *val;
9025
9026 val = get_param(cmd, "Program");
9027 if (val) {
9028 if (strcasecmp(val, "11n") == 0)
9029 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -08009030 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009031 return cmd_sta_set_wireless_vht(dut, conn, cmd);
9032 if (strcasecmp(val, "60ghz") == 0)
9033 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309034 if (strcasecmp(val, "OCE") == 0)
9035 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +02009036 /* sta_set_wireless in WPS program is only used for 60G */
9037 if (is_60g_sigma_dut(dut))
9038 return sta_set_wireless_60g(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009039 send_resp(dut, conn, SIGMA_ERROR,
9040 "ErrorCode,Program value not supported");
9041 } else {
9042 send_resp(dut, conn, SIGMA_ERROR,
9043 "ErrorCode,Program argument not available");
9044 }
9045
9046 return 0;
9047}
9048
9049
9050static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
9051 int tid)
9052{
9053 char buf[100];
9054 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
9055
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +05309056 if (tid < 0 ||
9057 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
9058 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
9059 return;
9060 }
9061
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009062 /*
9063 * Two ways to ensure that addba request with a
9064 * non zero TID could be sent out. EV 117296
9065 */
9066 snprintf(buf, sizeof(buf),
9067 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
9068 tid);
9069 if (system(buf) != 0) {
9070 sigma_dut_print(dut, DUT_MSG_ERROR,
9071 "Ping did not send out");
9072 }
9073
9074 snprintf(buf, sizeof(buf),
9075 "iwconfig %s | grep Access | awk '{print $6}' > %s",
9076 intf, VI_QOS_TMP_FILE);
9077 if (system(buf) != 0)
9078 return;
9079
9080 snprintf(buf, sizeof(buf),
9081 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
9082 intf, VI_QOS_TMP_FILE);
9083 if (system(buf) != 0)
9084 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
9085
9086 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
9087 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
9088 if (system(buf) != 0) {
9089 sigma_dut_print(dut, DUT_MSG_ERROR,
9090 "VI_QOS_TEMP_FILE generation error failed");
9091 }
9092 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
9093 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
9094 if (system(buf) != 0) {
9095 sigma_dut_print(dut, DUT_MSG_ERROR,
9096 "VI_QOS_FILE generation failed");
9097 }
9098
9099 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
9100 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
9101 if (system(buf) != 0) {
9102 sigma_dut_print(dut, DUT_MSG_ERROR,
9103 "VI_QOS_FILE generation failed");
9104 }
9105
9106 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
9107 if (system(buf) != 0) {
9108 }
9109}
9110
9111
9112static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9113 struct sigma_cmd *cmd)
9114{
9115 const char *intf = get_param(cmd, "Interface");
9116 const char *val;
9117 int tid = 0;
9118 char buf[100];
9119
9120 val = get_param(cmd, "TID");
9121 if (val) {
9122 tid = atoi(val);
9123 if (tid)
9124 ath_sta_inject_frame(dut, intf, tid);
9125 }
9126
9127 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07009128 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009129
9130 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
9131 if (system(buf) != 0) {
9132 sigma_dut_print(dut, DUT_MSG_ERROR,
9133 "wifitool senddelba failed");
9134 }
9135
9136 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
9137 if (system(buf) != 0) {
9138 sigma_dut_print(dut, DUT_MSG_ERROR,
9139 "wifitool sendaddba failed");
9140 }
9141
9142 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9143
9144 return 1;
9145}
9146
9147
Lior David9981b512017-01-20 13:16:40 +02009148#ifdef __linux__
9149
9150static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
9151 int agg_size)
9152{
9153 char dir[128], buf[128];
9154 FILE *f;
9155 regex_t re;
9156 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +03009157 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +02009158
9159 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
9160 sigma_dut_print(dut, DUT_MSG_ERROR,
9161 "failed to get wil6210 debugfs dir");
9162 return -1;
9163 }
9164
Jouni Malinen3aa72862019-05-29 23:14:51 +03009165 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
9166 if (res < 0 || res >= sizeof(buf))
9167 return -1;
Lior David9981b512017-01-20 13:16:40 +02009168 f = fopen(buf, "r");
9169 if (!f) {
9170 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009171 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +03009172 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
9173 if (res < 0 || res >= sizeof(buf))
9174 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009175 f = fopen(buf, "r");
9176 if (!f) {
9177 sigma_dut_print(dut, DUT_MSG_ERROR,
9178 "failed to open: %s", buf);
9179 return -1;
9180 }
Lior David9981b512017-01-20 13:16:40 +02009181 }
9182
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +02009183 /* can be either VRING tx... or RING... */
9184 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +02009185 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
9186 goto out;
9187 }
9188
9189 /* find TX VRING for the mac address */
9190 found = 0;
9191 while (fgets(buf, sizeof(buf), f)) {
9192 if (strcasestr(buf, dest_mac)) {
9193 found = 1;
9194 break;
9195 }
9196 }
9197
9198 if (!found) {
9199 sigma_dut_print(dut, DUT_MSG_ERROR,
9200 "no TX VRING for %s", dest_mac);
9201 goto out;
9202 }
9203
9204 /* extract VRING ID, "VRING tx_<id> = {" */
9205 if (!fgets(buf, sizeof(buf), f)) {
9206 sigma_dut_print(dut, DUT_MSG_ERROR,
9207 "no VRING start line for %s", dest_mac);
9208 goto out;
9209 }
9210
9211 rc = regexec(&re, buf, 2, m, 0);
9212 regfree(&re);
9213 if (rc || m[1].rm_so < 0) {
9214 sigma_dut_print(dut, DUT_MSG_ERROR,
9215 "no VRING TX ID for %s", dest_mac);
9216 goto out;
9217 }
9218 buf[m[1].rm_eo] = 0;
9219 vring_id = atoi(&buf[m[1].rm_so]);
9220
9221 /* send the addba command */
9222 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +03009223 res = snprintf(buf, sizeof(buf), "%s/back", dir);
9224 if (res < 0 || res >= sizeof(buf))
9225 return -1;
Lior David9981b512017-01-20 13:16:40 +02009226 f = fopen(buf, "w");
9227 if (!f) {
9228 sigma_dut_print(dut, DUT_MSG_ERROR,
9229 "failed to open: %s", buf);
9230 return -1;
9231 }
9232
9233 fprintf(f, "add %d %d\n", vring_id, agg_size);
9234
9235 ret = 0;
9236
9237out:
9238 fclose(f);
9239
9240 return ret;
9241}
9242
9243
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009244int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
9245 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009246{
9247 const char *val;
9248 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009249
9250 val = get_param(cmd, "TID");
9251 if (val) {
9252 tid = atoi(val);
9253 if (tid != 0) {
9254 sigma_dut_print(dut, DUT_MSG_ERROR,
9255 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
9256 tid);
9257 }
9258 }
9259
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009260 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009261 if (!val) {
9262 sigma_dut_print(dut, DUT_MSG_ERROR,
9263 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009264 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009265 }
9266
Lior David9981b512017-01-20 13:16:40 +02009267 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009268 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009269
9270 return 1;
9271}
9272
Lior David9981b512017-01-20 13:16:40 +02009273#endif /* __linux__ */
9274
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009275
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009276static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
9277 struct sigma_cmd *cmd)
9278{
9279#ifdef NL80211_SUPPORT
9280 const char *intf = get_param(cmd, "Interface");
9281 const char *val;
9282 int tid = -1;
9283 int bufsize = 64;
9284 struct nl_msg *msg;
9285 int ret = 0;
9286 struct nlattr *params;
9287 int ifindex;
9288
9289 val = get_param(cmd, "TID");
9290 if (val)
9291 tid = atoi(val);
9292
9293 if (tid == -1) {
9294 send_resp(dut, conn, SIGMA_ERROR,
9295 "ErrorCode,sta_send_addba tid invalid");
9296 return 0;
9297 }
9298
9299 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
9300
9301 ifindex = if_nametoindex(intf);
9302 if (ifindex == 0) {
9303 sigma_dut_print(dut, DUT_MSG_ERROR,
9304 "%s: Index for interface %s failed",
9305 __func__, intf);
9306 send_resp(dut, conn, SIGMA_ERROR,
9307 "ErrorCode,sta_send_addba interface invalid");
9308 return 0;
9309 }
9310
9311 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9312 NL80211_CMD_VENDOR)) ||
9313 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9314 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9315 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9316 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
9317 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9318 nla_put_u8(msg,
9319 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
9320 QCA_WLAN_ADD_BA) ||
9321 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
9322 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -07009323 nla_put_u16(msg,
9324 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
9325 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009326 sigma_dut_print(dut, DUT_MSG_ERROR,
9327 "%s: err in adding vendor_cmd and vendor_data",
9328 __func__);
9329 nlmsg_free(msg);
9330 send_resp(dut, conn, SIGMA_ERROR,
9331 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
9332 return 0;
9333 }
9334 nla_nest_end(msg, params);
9335
9336 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9337 if (ret) {
9338 sigma_dut_print(dut, DUT_MSG_ERROR,
9339 "%s: err in send_and_recv_msgs, ret=%d",
9340 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +05309341 if (ret == -EOPNOTSUPP)
9342 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009343 send_resp(dut, conn, SIGMA_ERROR,
9344 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
9345 return 0;
9346 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009347#else /* NL80211_SUPPORT */
9348 sigma_dut_print(dut, DUT_MSG_ERROR,
9349 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009350#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +05309351
9352 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009353}
9354
9355
Jouni Malinenf7222712019-06-13 01:50:21 +03009356static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
9357 struct sigma_conn *conn,
9358 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009359{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009360 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009361 case DRIVER_ATHEROS:
9362 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -08009363 case DRIVER_WCN:
9364 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +02009365#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009366 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +02009367 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +02009368#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009369 default:
9370 /*
9371 * There is no driver specific implementation for other drivers.
9372 * Ignore the command and report COMPLETE since the following
9373 * throughput test operation will end up sending ADDBA anyway.
9374 */
9375 return 1;
9376 }
9377}
9378
9379
9380int inject_eth_frame(int s, const void *data, size_t len,
9381 unsigned short ethtype, char *dst, char *src)
9382{
9383 struct iovec iov[4] = {
9384 {
9385 .iov_base = dst,
9386 .iov_len = ETH_ALEN,
9387 },
9388 {
9389 .iov_base = src,
9390 .iov_len = ETH_ALEN,
9391 },
9392 {
9393 .iov_base = &ethtype,
9394 .iov_len = sizeof(unsigned short),
9395 },
9396 {
9397 .iov_base = (void *) data,
9398 .iov_len = len,
9399 }
9400 };
9401 struct msghdr msg = {
9402 .msg_name = NULL,
9403 .msg_namelen = 0,
9404 .msg_iov = iov,
9405 .msg_iovlen = 4,
9406 .msg_control = NULL,
9407 .msg_controllen = 0,
9408 .msg_flags = 0,
9409 };
9410
9411 return sendmsg(s, &msg, 0);
9412}
9413
9414#if defined(__linux__) || defined(__QNXNTO__)
9415
9416int inject_frame(int s, const void *data, size_t len, int encrypt)
9417{
9418#define IEEE80211_RADIOTAP_F_WEP 0x04
9419#define IEEE80211_RADIOTAP_F_FRAG 0x08
9420 unsigned char rtap_hdr[] = {
9421 0x00, 0x00, /* radiotap version */
9422 0x0e, 0x00, /* radiotap length */
9423 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
9424 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
9425 0x00, /* padding */
9426 0x00, 0x00, /* RX and TX flags to indicate that */
9427 0x00, 0x00, /* this is the injected frame directly */
9428 };
9429 struct iovec iov[2] = {
9430 {
9431 .iov_base = &rtap_hdr,
9432 .iov_len = sizeof(rtap_hdr),
9433 },
9434 {
9435 .iov_base = (void *) data,
9436 .iov_len = len,
9437 }
9438 };
9439 struct msghdr msg = {
9440 .msg_name = NULL,
9441 .msg_namelen = 0,
9442 .msg_iov = iov,
9443 .msg_iovlen = 2,
9444 .msg_control = NULL,
9445 .msg_controllen = 0,
9446 .msg_flags = 0,
9447 };
9448
9449 if (encrypt)
9450 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
9451
9452 return sendmsg(s, &msg, 0);
9453}
9454
9455
9456int open_monitor(const char *ifname)
9457{
9458#ifdef __QNXNTO__
9459 struct sockaddr_dl ll;
9460 int s;
9461
9462 memset(&ll, 0, sizeof(ll));
9463 ll.sdl_family = AF_LINK;
9464 ll.sdl_index = if_nametoindex(ifname);
9465 if (ll.sdl_index == 0) {
9466 perror("if_nametoindex");
9467 return -1;
9468 }
9469 s = socket(PF_INET, SOCK_RAW, 0);
9470#else /* __QNXNTO__ */
9471 struct sockaddr_ll ll;
9472 int s;
9473
9474 memset(&ll, 0, sizeof(ll));
9475 ll.sll_family = AF_PACKET;
9476 ll.sll_ifindex = if_nametoindex(ifname);
9477 if (ll.sll_ifindex == 0) {
9478 perror("if_nametoindex");
9479 return -1;
9480 }
9481 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
9482#endif /* __QNXNTO__ */
9483 if (s < 0) {
9484 perror("socket[PF_PACKET,SOCK_RAW]");
9485 return -1;
9486 }
9487
9488 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
9489 perror("monitor socket bind");
9490 close(s);
9491 return -1;
9492 }
9493
9494 return s;
9495}
9496
9497
9498static int hex2num(char c)
9499{
9500 if (c >= '0' && c <= '9')
9501 return c - '0';
9502 if (c >= 'a' && c <= 'f')
9503 return c - 'a' + 10;
9504 if (c >= 'A' && c <= 'F')
9505 return c - 'A' + 10;
9506 return -1;
9507}
9508
9509
9510int hwaddr_aton(const char *txt, unsigned char *addr)
9511{
9512 int i;
9513
9514 for (i = 0; i < 6; i++) {
9515 int a, b;
9516
9517 a = hex2num(*txt++);
9518 if (a < 0)
9519 return -1;
9520 b = hex2num(*txt++);
9521 if (b < 0)
9522 return -1;
9523 *addr++ = (a << 4) | b;
9524 if (i < 5 && *txt++ != ':')
9525 return -1;
9526 }
9527
9528 return 0;
9529}
9530
9531#endif /* defined(__linux__) || defined(__QNXNTO__) */
9532
9533enum send_frame_type {
9534 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
9535};
9536enum send_frame_protection {
9537 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
9538};
9539
9540
9541static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
9542 enum send_frame_type frame,
9543 enum send_frame_protection protected,
9544 const char *dest)
9545{
9546#ifdef __linux__
9547 unsigned char buf[1000], *pos;
9548 int s, res;
9549 char bssid[20], addr[20];
9550 char result[32], ssid[100];
9551 size_t ssid_len;
9552
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009553 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009554 sizeof(result)) < 0 ||
9555 strncmp(result, "COMPLETED", 9) != 0) {
9556 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
9557 return 0;
9558 }
9559
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009560 if (get_wpa_status(get_station_ifname(dut), "bssid",
9561 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009562 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9563 "current BSSID");
9564 return 0;
9565 }
9566
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009567 if (get_wpa_status(get_station_ifname(dut), "address",
9568 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009569 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9570 "own MAC address");
9571 return 0;
9572 }
9573
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009574 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009575 < 0) {
9576 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
9577 "current SSID");
9578 return 0;
9579 }
9580 ssid_len = strlen(ssid);
9581
9582 pos = buf;
9583
9584 /* Frame Control */
9585 switch (frame) {
9586 case DISASSOC:
9587 *pos++ = 0xa0;
9588 break;
9589 case DEAUTH:
9590 *pos++ = 0xc0;
9591 break;
9592 case SAQUERY:
9593 *pos++ = 0xd0;
9594 break;
9595 case AUTH:
9596 *pos++ = 0xb0;
9597 break;
9598 case ASSOCREQ:
9599 *pos++ = 0x00;
9600 break;
9601 case REASSOCREQ:
9602 *pos++ = 0x20;
9603 break;
9604 case DLS_REQ:
9605 *pos++ = 0xd0;
9606 break;
9607 }
9608
9609 if (protected == INCORRECT_KEY)
9610 *pos++ = 0x40; /* Set Protected field to 1 */
9611 else
9612 *pos++ = 0x00;
9613
9614 /* Duration */
9615 *pos++ = 0x00;
9616 *pos++ = 0x00;
9617
9618 /* addr1 = DA (current AP) */
9619 hwaddr_aton(bssid, pos);
9620 pos += 6;
9621 /* addr2 = SA (own address) */
9622 hwaddr_aton(addr, pos);
9623 pos += 6;
9624 /* addr3 = BSSID (current AP) */
9625 hwaddr_aton(bssid, pos);
9626 pos += 6;
9627
9628 /* Seq# (to be filled by driver/mac80211) */
9629 *pos++ = 0x00;
9630 *pos++ = 0x00;
9631
9632 if (protected == INCORRECT_KEY) {
9633 /* CCMP parameters */
9634 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
9635 pos += 8;
9636 }
9637
9638 if (protected == INCORRECT_KEY) {
9639 switch (frame) {
9640 case DEAUTH:
9641 /* Reason code (encrypted) */
9642 memcpy(pos, "\xa7\x39", 2);
9643 pos += 2;
9644 break;
9645 case DISASSOC:
9646 /* Reason code (encrypted) */
9647 memcpy(pos, "\xa7\x39", 2);
9648 pos += 2;
9649 break;
9650 case SAQUERY:
9651 /* Category|Action|TransID (encrypted) */
9652 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
9653 pos += 4;
9654 break;
9655 default:
9656 return -1;
9657 }
9658
9659 /* CCMP MIC */
9660 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
9661 pos += 8;
9662 } else {
9663 switch (frame) {
9664 case DEAUTH:
9665 /* reason code = 8 */
9666 *pos++ = 0x08;
9667 *pos++ = 0x00;
9668 break;
9669 case DISASSOC:
9670 /* reason code = 8 */
9671 *pos++ = 0x08;
9672 *pos++ = 0x00;
9673 break;
9674 case SAQUERY:
9675 /* Category - SA Query */
9676 *pos++ = 0x08;
9677 /* SA query Action - Request */
9678 *pos++ = 0x00;
9679 /* Transaction ID */
9680 *pos++ = 0x12;
9681 *pos++ = 0x34;
9682 break;
9683 case AUTH:
9684 /* Auth Alg (Open) */
9685 *pos++ = 0x00;
9686 *pos++ = 0x00;
9687 /* Seq# */
9688 *pos++ = 0x01;
9689 *pos++ = 0x00;
9690 /* Status code */
9691 *pos++ = 0x00;
9692 *pos++ = 0x00;
9693 break;
9694 case ASSOCREQ:
9695 /* Capability Information */
9696 *pos++ = 0x31;
9697 *pos++ = 0x04;
9698 /* Listen Interval */
9699 *pos++ = 0x0a;
9700 *pos++ = 0x00;
9701 /* SSID */
9702 *pos++ = 0x00;
9703 *pos++ = ssid_len;
9704 memcpy(pos, ssid, ssid_len);
9705 pos += ssid_len;
9706 /* Supported Rates */
9707 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9708 10);
9709 pos += 10;
9710 /* Extended Supported Rates */
9711 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9712 pos += 6;
9713 /* RSN */
9714 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9715 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9716 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9717 pos += 28;
9718 break;
9719 case REASSOCREQ:
9720 /* Capability Information */
9721 *pos++ = 0x31;
9722 *pos++ = 0x04;
9723 /* Listen Interval */
9724 *pos++ = 0x0a;
9725 *pos++ = 0x00;
9726 /* Current AP */
9727 hwaddr_aton(bssid, pos);
9728 pos += 6;
9729 /* SSID */
9730 *pos++ = 0x00;
9731 *pos++ = ssid_len;
9732 memcpy(pos, ssid, ssid_len);
9733 pos += ssid_len;
9734 /* Supported Rates */
9735 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
9736 10);
9737 pos += 10;
9738 /* Extended Supported Rates */
9739 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
9740 pos += 6;
9741 /* RSN */
9742 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
9743 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
9744 "\x00\x00\x00\x00\x0f\xac\x06", 28);
9745 pos += 28;
9746 break;
9747 case DLS_REQ:
9748 /* Category - DLS */
9749 *pos++ = 0x02;
9750 /* DLS Action - Request */
9751 *pos++ = 0x00;
9752 /* Destination MACAddress */
9753 if (dest)
9754 hwaddr_aton(dest, pos);
9755 else
9756 memset(pos, 0, 6);
9757 pos += 6;
9758 /* Source MACAddress */
9759 hwaddr_aton(addr, pos);
9760 pos += 6;
9761 /* Capability Information */
9762 *pos++ = 0x10; /* Privacy */
9763 *pos++ = 0x06; /* QoS */
9764 /* DLS Timeout Value */
9765 *pos++ = 0x00;
9766 *pos++ = 0x01;
9767 /* Supported rates */
9768 *pos++ = 0x01;
9769 *pos++ = 0x08;
9770 *pos++ = 0x0c; /* 6 Mbps */
9771 *pos++ = 0x12; /* 9 Mbps */
9772 *pos++ = 0x18; /* 12 Mbps */
9773 *pos++ = 0x24; /* 18 Mbps */
9774 *pos++ = 0x30; /* 24 Mbps */
9775 *pos++ = 0x48; /* 36 Mbps */
9776 *pos++ = 0x60; /* 48 Mbps */
9777 *pos++ = 0x6c; /* 54 Mbps */
9778 /* TODO: Extended Supported Rates */
9779 /* TODO: HT Capabilities */
9780 break;
9781 }
9782 }
9783
9784 s = open_monitor("sigmadut");
9785 if (s < 0) {
9786 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
9787 "monitor socket");
9788 return 0;
9789 }
9790
9791 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
9792 if (res < 0) {
9793 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
9794 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309795 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009796 return 0;
9797 }
9798 if (res < pos - buf) {
9799 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Only partial "
9800 "frame sent");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05309801 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009802 return 0;
9803 }
9804
9805 close(s);
9806
9807 return 1;
9808#else /* __linux__ */
9809 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
9810 "yet supported");
9811 return 0;
9812#endif /* __linux__ */
9813}
9814
9815
9816static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
9817 struct sigma_conn *conn,
9818 struct sigma_cmd *cmd)
9819{
9820 const char *intf = get_param(cmd, "Interface");
9821 const char *sta, *val;
9822 unsigned char addr[ETH_ALEN];
9823 char buf[100];
9824
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +03009825 if (!intf)
9826 return -1;
9827
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009828 sta = get_param(cmd, "peer");
9829 if (sta == NULL)
9830 sta = get_param(cmd, "station");
9831 if (sta == NULL) {
9832 send_resp(dut, conn, SIGMA_ERROR,
9833 "ErrorCode,Missing peer address");
9834 return 0;
9835 }
9836 if (hwaddr_aton(sta, addr) < 0) {
9837 send_resp(dut, conn, SIGMA_ERROR,
9838 "ErrorCode,Invalid peer address");
9839 return 0;
9840 }
9841
9842 val = get_param(cmd, "type");
9843 if (val == NULL)
9844 return -1;
9845
9846 if (strcasecmp(val, "DISCOVERY") == 0) {
9847 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
9848 if (wpa_command(intf, buf) < 0) {
9849 send_resp(dut, conn, SIGMA_ERROR,
9850 "ErrorCode,Failed to send TDLS discovery");
9851 return 0;
9852 }
9853 return 1;
9854 }
9855
9856 if (strcasecmp(val, "SETUP") == 0) {
9857 int status = 0, timeout = 0;
9858
9859 val = get_param(cmd, "Status");
9860 if (val)
9861 status = atoi(val);
9862
9863 val = get_param(cmd, "Timeout");
9864 if (val)
9865 timeout = atoi(val);
9866
9867 if (status != 0 && status != 37) {
9868 send_resp(dut, conn, SIGMA_ERROR,
9869 "ErrorCode,Unsupported status value");
9870 return 0;
9871 }
9872
9873 if (timeout != 0 && timeout != 301) {
9874 send_resp(dut, conn, SIGMA_ERROR,
9875 "ErrorCode,Unsupported timeout value");
9876 return 0;
9877 }
9878
9879 if (status && timeout) {
9880 send_resp(dut, conn, SIGMA_ERROR,
9881 "ErrorCode,Unsupported timeout+status "
9882 "combination");
9883 return 0;
9884 }
9885
9886 if (status == 37 &&
9887 wpa_command(intf, "SET tdls_testing 0x200")) {
9888 send_resp(dut, conn, SIGMA_ERROR,
9889 "ErrorCode,Failed to enable "
9890 "decline setup response test mode");
9891 return 0;
9892 }
9893
9894 if (timeout == 301) {
9895 int res;
9896 if (dut->no_tpk_expiration)
9897 res = wpa_command(intf,
9898 "SET tdls_testing 0x108");
9899 else
9900 res = wpa_command(intf,
9901 "SET tdls_testing 0x8");
9902 if (res) {
9903 send_resp(dut, conn, SIGMA_ERROR,
9904 "ErrorCode,Failed to set short TPK "
9905 "lifetime");
9906 return 0;
9907 }
9908 }
9909
9910 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
9911 if (wpa_command(intf, buf) < 0) {
9912 send_resp(dut, conn, SIGMA_ERROR,
9913 "ErrorCode,Failed to send TDLS setup");
9914 return 0;
9915 }
9916 return 1;
9917 }
9918
9919 if (strcasecmp(val, "TEARDOWN") == 0) {
9920 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
9921 if (wpa_command(intf, buf) < 0) {
9922 send_resp(dut, conn, SIGMA_ERROR,
9923 "ErrorCode,Failed to send TDLS teardown");
9924 return 0;
9925 }
9926 return 1;
9927 }
9928
9929 send_resp(dut, conn, SIGMA_ERROR,
9930 "ErrorCode,Unsupported TDLS frame");
9931 return 0;
9932}
9933
9934
9935static int sta_ap_known(const char *ifname, const char *bssid)
9936{
9937 char buf[4096];
9938
Jouni Malinendd32f192018-09-15 02:55:19 +03009939 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009940 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
9941 return 0;
9942 if (strncmp(buf, "id=", 3) != 0)
9943 return 0;
9944 return 1;
9945}
9946
9947
9948static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
9949 const char *bssid)
9950{
9951 int res;
9952 struct wpa_ctrl *ctrl;
9953 char buf[256];
9954
9955 if (sta_ap_known(ifname, bssid))
9956 return 0;
9957 sigma_dut_print(dut, DUT_MSG_DEBUG,
9958 "AP not in BSS table - start scan");
9959
9960 ctrl = open_wpa_mon(ifname);
9961 if (ctrl == NULL) {
9962 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
9963 "wpa_supplicant monitor connection");
9964 return -1;
9965 }
9966
9967 if (wpa_command(ifname, "SCAN") < 0) {
9968 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
9969 wpa_ctrl_detach(ctrl);
9970 wpa_ctrl_close(ctrl);
9971 return -1;
9972 }
9973
9974 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
9975 buf, sizeof(buf));
9976
9977 wpa_ctrl_detach(ctrl);
9978 wpa_ctrl_close(ctrl);
9979
9980 if (res < 0) {
9981 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
9982 return -1;
9983 }
9984
9985 if (sta_ap_known(ifname, bssid))
9986 return 0;
9987 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
9988 return -1;
9989}
9990
9991
9992static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
9993 struct sigma_conn *conn,
9994 struct sigma_cmd *cmd,
9995 const char *intf)
9996{
9997 char buf[200];
9998
9999 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
10000 if (system(buf) != 0) {
10001 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
10002 "ndsend");
10003 return 0;
10004 }
10005
10006 return 1;
10007}
10008
10009
10010static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
10011 struct sigma_conn *conn,
10012 struct sigma_cmd *cmd,
10013 const char *intf)
10014{
10015 char buf[200];
10016 const char *ip = get_param(cmd, "SenderIP");
10017
Peng Xu26b356d2017-10-04 17:58:16 -070010018 if (!ip)
10019 return 0;
10020
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010021 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
10022 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10023 if (system(buf) == 0) {
10024 sigma_dut_print(dut, DUT_MSG_INFO,
10025 "Neighbor Solicitation got a response "
10026 "for %s@%s", ip, intf);
10027 }
10028
10029 return 1;
10030}
10031
10032
10033static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
10034 struct sigma_conn *conn,
10035 struct sigma_cmd *cmd,
10036 const char *ifname)
10037{
10038 char buf[200];
10039 const char *ip = get_param(cmd, "SenderIP");
10040
10041 if (ip == NULL) {
10042 send_resp(dut, conn, SIGMA_ERROR,
10043 "ErrorCode,Missing SenderIP parameter");
10044 return 0;
10045 }
10046 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
10047 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10048 if (system(buf) != 0) {
10049 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
10050 "for %s@%s", ip, ifname);
10051 }
10052
10053 return 1;
10054}
10055
10056
10057static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
10058 struct sigma_conn *conn,
10059 struct sigma_cmd *cmd,
10060 const char *ifname)
10061{
10062 char buf[200];
10063 char ip[16];
10064 int s;
Peng Xub3756882017-10-04 14:39:09 -070010065 struct ifreq ifr;
10066 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010067
10068 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070010069 if (s < 0) {
10070 perror("socket");
10071 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010072 }
10073
Peng Xub3756882017-10-04 14:39:09 -070010074 memset(&ifr, 0, sizeof(ifr));
10075 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
10076 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
10077 sigma_dut_print(dut, DUT_MSG_INFO,
10078 "Failed to get %s IP address: %s",
10079 ifname, strerror(errno));
10080 close(s);
10081 return -1;
10082 }
10083 close(s);
10084
10085 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
10086 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
10087
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010088 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
10089 ip);
10090 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
10091 if (system(buf) != 0) {
10092 }
10093
10094 return 1;
10095}
10096
10097
10098static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
10099 struct sigma_conn *conn,
10100 struct sigma_cmd *cmd,
10101 const char *ifname)
10102{
10103 char buf[200], addr[20];
10104 char dst[ETH_ALEN], src[ETH_ALEN];
10105 short ethtype = htons(ETH_P_ARP);
10106 char *pos;
10107 int s, res;
10108 const char *val;
10109 struct sockaddr_in taddr;
10110
10111 val = get_param(cmd, "dest");
10112 if (val)
10113 hwaddr_aton(val, (unsigned char *) dst);
10114
10115 val = get_param(cmd, "DestIP");
10116 if (val)
10117 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070010118 else
10119 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010120
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010121 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010122 sizeof(addr)) < 0)
10123 return -2;
10124 hwaddr_aton(addr, (unsigned char *) src);
10125
10126 pos = buf;
10127 *pos++ = 0x00;
10128 *pos++ = 0x01;
10129 *pos++ = 0x08;
10130 *pos++ = 0x00;
10131 *pos++ = 0x06;
10132 *pos++ = 0x04;
10133 *pos++ = 0x00;
10134 *pos++ = 0x02;
10135 memcpy(pos, src, ETH_ALEN);
10136 pos += ETH_ALEN;
10137 memcpy(pos, &taddr.sin_addr, 4);
10138 pos += 4;
10139 memcpy(pos, dst, ETH_ALEN);
10140 pos += ETH_ALEN;
10141 memcpy(pos, &taddr.sin_addr, 4);
10142 pos += 4;
10143
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010144 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010145 if (s < 0) {
10146 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
10147 "monitor socket");
10148 return 0;
10149 }
10150
10151 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
10152 if (res < 0) {
10153 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
10154 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053010155 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010156 return 0;
10157 }
10158
10159 close(s);
10160
10161 return 1;
10162}
10163
10164
10165static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
10166 struct sigma_conn *conn,
10167 struct sigma_cmd *cmd,
10168 const char *intf, const char *dest)
10169{
10170 char buf[100];
10171
10172 if (if_nametoindex("sigmadut") == 0) {
10173 snprintf(buf, sizeof(buf),
10174 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010175 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010176 if (system(buf) != 0 ||
10177 if_nametoindex("sigmadut") == 0) {
10178 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
10179 "monitor interface with '%s'", buf);
10180 return -2;
10181 }
10182 }
10183
10184 if (system("ifconfig sigmadut up") != 0) {
10185 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
10186 "monitor interface up");
10187 return -2;
10188 }
10189
10190 return sta_inject_frame(dut, conn, DLS_REQ, UNPROTECTED, dest);
10191}
10192
10193
10194static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
10195 struct sigma_conn *conn,
10196 struct sigma_cmd *cmd)
10197{
10198 const char *intf = get_param(cmd, "Interface");
10199 const char *dest = get_param(cmd, "Dest");
10200 const char *type = get_param(cmd, "FrameName");
10201 const char *val;
10202 char buf[200], *pos, *end;
10203 int count, count2;
10204
10205 if (type == NULL)
10206 type = get_param(cmd, "Type");
10207
10208 if (intf == NULL || dest == NULL || type == NULL)
10209 return -1;
10210
10211 if (strcasecmp(type, "NeighAdv") == 0)
10212 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
10213
10214 if (strcasecmp(type, "NeighSolicitReq") == 0)
10215 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
10216
10217 if (strcasecmp(type, "ARPProbe") == 0)
10218 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
10219
10220 if (strcasecmp(type, "ARPAnnounce") == 0)
10221 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
10222
10223 if (strcasecmp(type, "ARPReply") == 0)
10224 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
10225
10226 if (strcasecmp(type, "DLS-request") == 0 ||
10227 strcasecmp(type, "DLSrequest") == 0)
10228 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
10229 dest);
10230
10231 if (strcasecmp(type, "ANQPQuery") != 0 &&
10232 strcasecmp(type, "Query") != 0) {
10233 send_resp(dut, conn, SIGMA_ERROR,
10234 "ErrorCode,Unsupported HS 2.0 send frame type");
10235 return 0;
10236 }
10237
10238 if (sta_scan_ap(dut, intf, dest) < 0) {
10239 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
10240 "the requested AP");
10241 return 0;
10242 }
10243
10244 pos = buf;
10245 end = buf + sizeof(buf);
10246 count = 0;
10247 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
10248
10249 val = get_param(cmd, "ANQP_CAP_LIST");
10250 if (val && atoi(val)) {
10251 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
10252 count++;
10253 }
10254
10255 val = get_param(cmd, "VENUE_NAME");
10256 if (val && atoi(val)) {
10257 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
10258 count++;
10259 }
10260
10261 val = get_param(cmd, "NETWORK_AUTH_TYPE");
10262 if (val && atoi(val)) {
10263 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
10264 count++;
10265 }
10266
10267 val = get_param(cmd, "ROAMING_CONS");
10268 if (val && atoi(val)) {
10269 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
10270 count++;
10271 }
10272
10273 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
10274 if (val && atoi(val)) {
10275 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
10276 count++;
10277 }
10278
10279 val = get_param(cmd, "NAI_REALM_LIST");
10280 if (val && atoi(val)) {
10281 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
10282 count++;
10283 }
10284
10285 val = get_param(cmd, "3GPP_INFO");
10286 if (val && atoi(val)) {
10287 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
10288 count++;
10289 }
10290
10291 val = get_param(cmd, "DOMAIN_LIST");
10292 if (val && atoi(val)) {
10293 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
10294 count++;
10295 }
10296
Jouni Malinen34cf9532018-04-29 19:26:33 +030010297 val = get_param(cmd, "Venue_URL");
10298 if (val && atoi(val)) {
10299 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
10300 count++;
10301 }
10302
Jouni Malinend3bca5d2018-04-29 17:25:23 +030010303 val = get_param(cmd, "Advice_Of_Charge");
10304 if (val && atoi(val)) {
10305 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
10306 count++;
10307 }
10308
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010309 if (count && wpa_command(intf, buf)) {
10310 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
10311 return 0;
10312 }
10313
10314 pos = buf;
10315 end = buf + sizeof(buf);
10316 count2 = 0;
10317 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
10318
10319 val = get_param(cmd, "HS_CAP_LIST");
10320 if (val && atoi(val)) {
10321 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
10322 count2++;
10323 }
10324
10325 val = get_param(cmd, "OPER_NAME");
10326 if (val && atoi(val)) {
10327 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
10328 count2++;
10329 }
10330
10331 val = get_param(cmd, "WAN_METRICS");
10332 if (!val)
10333 val = get_param(cmd, "WAN_MAT");
10334 if (!val)
10335 val = get_param(cmd, "WAN_MET");
10336 if (val && atoi(val)) {
10337 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
10338 count2++;
10339 }
10340
10341 val = get_param(cmd, "CONNECTION_CAPABILITY");
10342 if (val && atoi(val)) {
10343 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
10344 count2++;
10345 }
10346
10347 val = get_param(cmd, "OP_CLASS");
10348 if (val && atoi(val)) {
10349 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
10350 count2++;
10351 }
10352
10353 val = get_param(cmd, "OSU_PROVIDER_LIST");
10354 if (val && atoi(val)) {
10355 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
10356 count2++;
10357 }
10358
Jouni Malinenf67afec2018-04-29 19:24:58 +030010359 val = get_param(cmd, "OPER_ICON_METADATA");
10360 if (!val)
10361 val = get_param(cmd, "OPERATOR_ICON_METADATA");
10362 if (val && atoi(val)) {
10363 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
10364 count2++;
10365 }
10366
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010367 if (count && count2) {
10368 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
10369 "second query");
10370 sleep(1);
10371 }
10372
10373 if (count2 && wpa_command(intf, buf)) {
10374 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
10375 "failed");
10376 return 0;
10377 }
10378
10379 val = get_param(cmd, "NAI_HOME_REALM_LIST");
10380 if (val) {
10381 if (count || count2) {
10382 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10383 "sending out second query");
10384 sleep(1);
10385 }
10386
10387 if (strcmp(val, "1") == 0)
10388 val = "mail.example.com";
10389 snprintf(buf, end - pos,
10390 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
10391 dest, val);
10392 if (wpa_command(intf, buf)) {
10393 send_resp(dut, conn, SIGMA_ERROR,
10394 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
10395 "failed");
10396 return 0;
10397 }
10398 }
10399
10400 val = get_param(cmd, "ICON_REQUEST");
10401 if (val) {
10402 if (count || count2) {
10403 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
10404 "sending out second query");
10405 sleep(1);
10406 }
10407
10408 snprintf(buf, end - pos,
10409 "HS20_ICON_REQUEST %s %s", dest, val);
10410 if (wpa_command(intf, buf)) {
10411 send_resp(dut, conn, SIGMA_ERROR,
10412 "ErrorCode,HS20_ICON_REQUEST failed");
10413 return 0;
10414 }
10415 }
10416
10417 return 1;
10418}
10419
10420
10421static int ath_sta_send_frame_vht(struct sigma_dut *dut,
10422 struct sigma_conn *conn,
10423 struct sigma_cmd *cmd)
10424{
10425 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010426 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010427 int chwidth, nss;
10428
10429 val = get_param(cmd, "framename");
10430 if (!val)
10431 return -1;
10432 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10433
10434 /* Command sequence to generate Op mode notification */
10435 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010436 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010437
10438 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010439 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010440
10441 /* Extract Channel width */
10442 val = get_param(cmd, "Channel_width");
10443 if (val) {
10444 switch (atoi(val)) {
10445 case 20:
10446 chwidth = 0;
10447 break;
10448 case 40:
10449 chwidth = 1;
10450 break;
10451 case 80:
10452 chwidth = 2;
10453 break;
10454 case 160:
10455 chwidth = 3;
10456 break;
10457 default:
10458 chwidth = 2;
10459 break;
10460 }
10461
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010462 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010463 }
10464
10465 /* Extract NSS */
10466 val = get_param(cmd, "NSS");
10467 if (val) {
10468 switch (atoi(val)) {
10469 case 1:
10470 nss = 1;
10471 break;
10472 case 2:
10473 nss = 3;
10474 break;
10475 case 3:
10476 nss = 7;
10477 break;
10478 default:
10479 /* We do not support NSS > 3 */
10480 nss = 3;
10481 break;
10482 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010483 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010484 }
10485
10486 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010487 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010488 }
10489
10490 return 1;
10491}
10492
10493
10494static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
10495 struct sigma_conn *conn,
10496 struct sigma_cmd *cmd)
10497{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010498 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010499 case DRIVER_ATHEROS:
10500 return ath_sta_send_frame_vht(dut, conn, cmd);
10501 default:
10502 send_resp(dut, conn, SIGMA_ERROR,
10503 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
10504 return 0;
10505 }
10506}
10507
10508
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010509static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
10510 struct sigma_cmd *cmd)
10511{
10512 const char *val;
10513 const char *intf = get_param(cmd, "Interface");
10514
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010515 if (!intf)
10516 return -1;
10517
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010518 val = get_param(cmd, "framename");
10519 if (!val)
10520 return -1;
10521 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
10522
10523 /* Command sequence to generate Op mode notification */
10524 if (val && strcasecmp(val, "action") == 0) {
10525 val = get_param(cmd, "PPDUTxType");
10526 if (val && strcasecmp(val, "TB") == 0) {
10527 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
10528 sigma_dut_print(dut, DUT_MSG_ERROR,
10529 "failed to send TB PPDU Tx cfg");
10530 send_resp(dut, conn, SIGMA_ERROR,
10531 "ErrorCode,set TB PPDU Tx cfg failed");
10532 return 0;
10533 }
10534 return 1;
10535 }
10536
10537 sigma_dut_print(dut, DUT_MSG_ERROR,
10538 "Action Tx type is not defined");
10539 }
10540
10541 return 1;
10542}
10543
10544
10545static int cmd_sta_send_frame_he(struct sigma_dut *dut,
10546 struct sigma_conn *conn,
10547 struct sigma_cmd *cmd)
10548{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010549 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010550 case DRIVER_WCN:
10551 return wcn_sta_send_frame_he(dut, conn, cmd);
10552 default:
10553 send_resp(dut, conn, SIGMA_ERROR,
10554 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
10555 return 0;
10556 }
10557}
10558
10559
Lior David0fe101e2017-03-09 16:09:50 +020010560#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010561
10562static int
10563wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
10564 const char *frame_name, const char *dest_mac)
10565{
10566 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
10567 const char *ssid = get_param(cmd, "ssid");
10568 const char *countstr = get_param(cmd, "count");
10569 const char *channelstr = get_param(cmd, "channel");
10570 const char *group_id = get_param(cmd, "groupid");
10571 const char *client_id = get_param(cmd, "clientmac");
10572 int count, channel, freq, i;
10573 const char *fname;
10574 char frame[1024], src_mac[20], group_id_attr[25],
10575 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
10576 const char *group_ssid;
10577 const int group_ssid_prefix_len = 9;
10578 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
10579 size_t framelen = sizeof(frame);
10580 struct template_frame_tag tags[2];
10581 size_t tags_total = ARRAY_SIZE(tags);
10582 int tag_index, len, dst_len;
10583
10584 if (!countstr || !channelstr) {
10585 sigma_dut_print(dut, DUT_MSG_ERROR,
10586 "Missing argument: count, channel");
10587 return -1;
10588 }
10589 if (isprobereq && !ssid) {
10590 sigma_dut_print(dut, DUT_MSG_ERROR,
10591 "Missing argument: ssid");
10592 return -1;
10593 }
10594 if (!isprobereq && (!group_id || !client_id)) {
10595 sigma_dut_print(dut, DUT_MSG_ERROR,
10596 "Missing argument: group_id, client_id");
10597 return -1;
10598 }
10599
10600 count = atoi(countstr);
10601 channel = atoi(channelstr);
10602 freq = channel_to_freq(dut, channel);
10603
10604 if (!freq) {
10605 sigma_dut_print(dut, DUT_MSG_ERROR,
10606 "invalid channel: %s", channelstr);
10607 return -1;
10608 }
10609
10610 if (isprobereq) {
10611 if (strcasecmp(ssid, "wildcard") == 0) {
10612 fname = "probe_req_wildcard.txt";
10613 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
10614 fname = "probe_req_P2P_Wildcard.txt";
10615 } else {
10616 sigma_dut_print(dut, DUT_MSG_ERROR,
10617 "invalid probe request type");
10618 return -1;
10619 }
10620 } else {
10621 fname = "P2P_device_discovery_req.txt";
10622 }
10623
10624 if (parse_template_frame_file(dut, fname, frame, &framelen,
10625 tags, &tags_total)) {
10626 sigma_dut_print(dut, DUT_MSG_ERROR,
10627 "invalid frame template: %s", fname);
10628 return -1;
10629 }
10630
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010631 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010632 src_mac, sizeof(src_mac)) < 0 ||
10633 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
10634 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
10635 return -1;
10636 /* Use wildcard BSSID, since we are in PBSS */
10637 memset(&hdr->addr3, 0xFF, ETH_ALEN);
10638
10639 if (!isprobereq) {
10640 tag_index = find_template_frame_tag(tags, tags_total, 1);
10641 if (tag_index < 0) {
10642 sigma_dut_print(dut, DUT_MSG_ERROR,
10643 "can't find device id attribute");
10644 return -1;
10645 }
10646 if (parse_mac_address(dut, client_id,
10647 (unsigned char *) client_mac)) {
10648 sigma_dut_print(dut, DUT_MSG_ERROR,
10649 "invalid client_id: %s", client_id);
10650 return -1;
10651 }
10652 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10653 framelen - tags[tag_index].offset,
10654 IEEE80211_P2P_ATTR_DEVICE_ID,
10655 client_mac, ETH_ALEN)) {
10656 sigma_dut_print(dut, DUT_MSG_ERROR,
10657 "fail to replace device id attribute");
10658 return -1;
10659 }
10660
10661 /*
10662 * group_id arg contains device MAC address followed by
10663 * space and SSID (DIRECT-somessid).
10664 * group id attribute contains device address (6 bytes)
10665 * followed by SSID prefix DIRECT-XX (9 bytes)
10666 */
10667 if (strlen(group_id) < sizeof(device_macstr)) {
10668 sigma_dut_print(dut, DUT_MSG_ERROR,
10669 "group_id arg too short");
10670 return -1;
10671 }
10672 memcpy(device_macstr, group_id, sizeof(device_macstr));
10673 device_macstr[sizeof(device_macstr) - 1] = '\0';
10674 if (parse_mac_address(dut, device_macstr,
10675 (unsigned char *) group_id_attr)) {
10676 sigma_dut_print(dut, DUT_MSG_ERROR,
10677 "fail to parse device address from group_id");
10678 return -1;
10679 }
10680 group_ssid = strchr(group_id, ' ');
10681 if (!group_ssid) {
10682 sigma_dut_print(dut, DUT_MSG_ERROR,
10683 "invalid group_id arg, no ssid");
10684 return -1;
10685 }
10686 group_ssid++;
10687 len = strlen(group_ssid);
10688 if (len < group_ssid_prefix_len) {
10689 sigma_dut_print(dut, DUT_MSG_ERROR,
10690 "group_id SSID too short");
10691 return -1;
10692 }
10693 dst_len = sizeof(group_id_attr) - ETH_ALEN;
10694 if (len > dst_len) {
10695 sigma_dut_print(dut, DUT_MSG_ERROR,
10696 "group_id SSID (%s) too long",
10697 group_ssid);
10698 return -1;
10699 }
10700
10701 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
10702 tag_index = find_template_frame_tag(tags, tags_total, 2);
10703 if (tag_index < 0) {
10704 sigma_dut_print(dut, DUT_MSG_ERROR,
10705 "can't find group id attribute");
10706 return -1;
10707 }
10708 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
10709 framelen - tags[tag_index].offset,
10710 IEEE80211_P2P_ATTR_GROUP_ID,
10711 group_id_attr,
10712 sizeof(group_id_attr))) {
10713 sigma_dut_print(dut, DUT_MSG_ERROR,
10714 "fail to replace group id attribute");
10715 return -1;
10716 }
10717 }
10718
10719 for (i = 0; i < count; i++) {
10720 if (wil6210_transmit_frame(dut, freq,
10721 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
10722 frame, framelen)) {
10723 sigma_dut_print(dut, DUT_MSG_ERROR,
10724 "fail to transmit probe request frame");
10725 return -1;
10726 }
10727 }
10728
10729 return 0;
10730}
10731
10732
Lior David0fe101e2017-03-09 16:09:50 +020010733int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
10734 struct sigma_cmd *cmd)
10735{
10736 const char *frame_name = get_param(cmd, "framename");
10737 const char *mac = get_param(cmd, "dest_mac");
10738
10739 if (!frame_name || !mac) {
10740 sigma_dut_print(dut, DUT_MSG_ERROR,
10741 "framename and dest_mac must be provided");
10742 return -1;
10743 }
10744
10745 if (strcasecmp(frame_name, "brp") == 0) {
10746 const char *l_rx = get_param(cmd, "L-RX");
10747 int l_rx_i;
10748
10749 if (!l_rx) {
10750 sigma_dut_print(dut, DUT_MSG_ERROR,
10751 "L-RX must be provided");
10752 return -1;
10753 }
10754 l_rx_i = atoi(l_rx);
10755
10756 sigma_dut_print(dut, DUT_MSG_INFO,
10757 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
10758 mac, l_rx);
10759 if (l_rx_i != 16) {
10760 sigma_dut_print(dut, DUT_MSG_ERROR,
10761 "unsupported L-RX: %s", l_rx);
10762 return -1;
10763 }
10764
10765 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
10766 return -1;
10767 } else if (strcasecmp(frame_name, "ssw") == 0) {
10768 sigma_dut_print(dut, DUT_MSG_INFO,
10769 "dev_send_frame: SLS, dest_mac %s", mac);
10770 if (wil6210_send_sls(dut, mac))
10771 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010772 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
10773 (strcasecmp(frame_name, "devdiscreq") == 0)) {
10774 sigma_dut_print(dut, DUT_MSG_INFO,
10775 "dev_send_frame: %s, dest_mac %s", frame_name,
10776 mac);
10777 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
10778 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020010779 } else {
10780 sigma_dut_print(dut, DUT_MSG_ERROR,
10781 "unsupported frame type: %s", frame_name);
10782 return -1;
10783 }
10784
10785 return 1;
10786}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030010787
Lior David0fe101e2017-03-09 16:09:50 +020010788#endif /* __linux__ */
10789
10790
10791static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
10792 struct sigma_conn *conn,
10793 struct sigma_cmd *cmd)
10794{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010795 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020010796#ifdef __linux__
10797 case DRIVER_WIL6210:
10798 return wil6210_send_frame_60g(dut, conn, cmd);
10799#endif /* __linux__ */
10800 default:
10801 send_resp(dut, conn, SIGMA_ERROR,
10802 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
10803 return 0;
10804 }
10805}
10806
10807
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010808static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
10809 const char *intf, struct sigma_cmd *cmd)
10810{
10811 const char *val, *addr;
10812 char buf[100];
10813
10814 addr = get_param(cmd, "DestMac");
10815 if (!addr) {
10816 send_resp(dut, conn, SIGMA_INVALID,
10817 "ErrorCode,AP MAC address is missing");
10818 return 0;
10819 }
10820
10821 val = get_param(cmd, "ANQPQuery_ID");
10822 if (!val) {
10823 send_resp(dut, conn, SIGMA_INVALID,
10824 "ErrorCode,Missing ANQPQuery_ID");
10825 return 0;
10826 }
10827
10828 if (strcasecmp(val, "NeighborReportReq") == 0) {
10829 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
10830 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
10831 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
10832 } else {
10833 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
10834 val);
10835 send_resp(dut, conn, SIGMA_INVALID,
10836 "ErrorCode,Invalid ANQPQuery_ID");
10837 return 0;
10838 }
10839
Ashwini Patild174f2c2017-04-13 16:49:46 +053010840 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
10841 * (Address3 = Wildcard BSSID when sent to not-associated AP;
10842 * if associated, AP BSSID).
10843 */
10844 if (wpa_command(intf, "SET gas_address3 1") < 0) {
10845 send_resp(dut, conn, SIGMA_ERROR,
10846 "ErrorCode,Failed to set gas_address3");
10847 return 0;
10848 }
10849
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010850 if (wpa_command(intf, buf) < 0) {
10851 send_resp(dut, conn, SIGMA_ERROR,
10852 "ErrorCode,Failed to send ANQP query");
10853 return 0;
10854 }
10855
10856 return 1;
10857}
10858
10859
10860static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
10861 struct sigma_conn *conn,
10862 const char *intf,
10863 struct sigma_cmd *cmd)
10864{
10865 const char *val = get_param(cmd, "FrameName");
10866
10867 if (val && strcasecmp(val, "ANQPQuery") == 0)
10868 return mbo_send_anqp_query(dut, conn, intf, cmd);
10869
10870 return 2;
10871}
10872
10873
Jouni Malinenf7222712019-06-13 01:50:21 +030010874enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
10875 struct sigma_conn *conn,
10876 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010877{
10878 const char *intf = get_param(cmd, "Interface");
10879 const char *val;
10880 enum send_frame_type frame;
10881 enum send_frame_protection protected;
10882 char buf[100];
10883 unsigned char addr[ETH_ALEN];
10884 int res;
10885
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030010886 if (!intf)
10887 return -1;
10888
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010889 val = get_param(cmd, "program");
10890 if (val == NULL)
10891 val = get_param(cmd, "frame");
10892 if (val && strcasecmp(val, "TDLS") == 0)
10893 return cmd_sta_send_frame_tdls(dut, conn, cmd);
10894 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030010895 strcasecmp(val, "HS2-R2") == 0 ||
10896 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010897 return cmd_sta_send_frame_hs2(dut, conn, cmd);
10898 if (val && strcasecmp(val, "VHT") == 0)
10899 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070010900 if (val && strcasecmp(val, "HE") == 0)
10901 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070010902 if (val && strcasecmp(val, "LOC") == 0)
10903 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020010904 if (val && strcasecmp(val, "60GHz") == 0)
10905 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053010906 if (val && strcasecmp(val, "MBO") == 0) {
10907 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
10908 if (res != 2)
10909 return res;
10910 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010911
10912 val = get_param(cmd, "TD_DISC");
10913 if (val) {
10914 if (hwaddr_aton(val, addr) < 0)
10915 return -1;
10916 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
10917 if (wpa_command(intf, buf) < 0) {
10918 send_resp(dut, conn, SIGMA_ERROR,
10919 "ErrorCode,Failed to send TDLS discovery");
10920 return 0;
10921 }
10922 return 1;
10923 }
10924
10925 val = get_param(cmd, "TD_Setup");
10926 if (val) {
10927 if (hwaddr_aton(val, addr) < 0)
10928 return -1;
10929 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
10930 if (wpa_command(intf, buf) < 0) {
10931 send_resp(dut, conn, SIGMA_ERROR,
10932 "ErrorCode,Failed to start TDLS setup");
10933 return 0;
10934 }
10935 return 1;
10936 }
10937
10938 val = get_param(cmd, "TD_TearDown");
10939 if (val) {
10940 if (hwaddr_aton(val, addr) < 0)
10941 return -1;
10942 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
10943 if (wpa_command(intf, buf) < 0) {
10944 send_resp(dut, conn, SIGMA_ERROR,
10945 "ErrorCode,Failed to tear down TDLS link");
10946 return 0;
10947 }
10948 return 1;
10949 }
10950
10951 val = get_param(cmd, "TD_ChannelSwitch");
10952 if (val) {
10953 /* TODO */
10954 send_resp(dut, conn, SIGMA_ERROR,
10955 "ErrorCode,TD_ChannelSwitch not yet supported");
10956 return 0;
10957 }
10958
10959 val = get_param(cmd, "TD_NF");
10960 if (val) {
10961 /* TODO */
10962 send_resp(dut, conn, SIGMA_ERROR,
10963 "ErrorCode,TD_NF not yet supported");
10964 return 0;
10965 }
10966
10967 val = get_param(cmd, "PMFFrameType");
10968 if (val == NULL)
10969 val = get_param(cmd, "FrameName");
10970 if (val == NULL)
10971 val = get_param(cmd, "Type");
10972 if (val == NULL)
10973 return -1;
10974 if (strcasecmp(val, "disassoc") == 0)
10975 frame = DISASSOC;
10976 else if (strcasecmp(val, "deauth") == 0)
10977 frame = DEAUTH;
10978 else if (strcasecmp(val, "saquery") == 0)
10979 frame = SAQUERY;
10980 else if (strcasecmp(val, "auth") == 0)
10981 frame = AUTH;
10982 else if (strcasecmp(val, "assocreq") == 0)
10983 frame = ASSOCREQ;
10984 else if (strcasecmp(val, "reassocreq") == 0)
10985 frame = REASSOCREQ;
10986 else if (strcasecmp(val, "neigreq") == 0) {
10987 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
10988
10989 val = get_param(cmd, "ssid");
10990 if (val == NULL)
10991 return -1;
10992
10993 res = send_neighbor_request(dut, intf, val);
10994 if (res) {
10995 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
10996 "Failed to send neighbor report request");
10997 return 0;
10998 }
10999
11000 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053011001 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
11002 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011003 sigma_dut_print(dut, DUT_MSG_DEBUG,
11004 "Got Transition Management Query");
11005
Ashwini Patil5acd7382017-04-13 15:55:04 +053011006 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011007 if (res) {
11008 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11009 "Failed to send Transition Management Query");
11010 return 0;
11011 }
11012
11013 return 1;
11014 } else {
11015 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11016 "PMFFrameType");
11017 return 0;
11018 }
11019
11020 val = get_param(cmd, "PMFProtected");
11021 if (val == NULL)
11022 val = get_param(cmd, "Protected");
11023 if (val == NULL)
11024 return -1;
11025 if (strcasecmp(val, "Correct-key") == 0 ||
11026 strcasecmp(val, "CorrectKey") == 0)
11027 protected = CORRECT_KEY;
11028 else if (strcasecmp(val, "IncorrectKey") == 0)
11029 protected = INCORRECT_KEY;
11030 else if (strcasecmp(val, "Unprotected") == 0)
11031 protected = UNPROTECTED;
11032 else {
11033 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11034 "PMFProtected");
11035 return 0;
11036 }
11037
11038 if (protected != UNPROTECTED &&
11039 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
11040 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
11041 "PMFProtected for auth/assocreq/reassocreq");
11042 return 0;
11043 }
11044
11045 if (if_nametoindex("sigmadut") == 0) {
11046 snprintf(buf, sizeof(buf),
11047 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011048 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011049 if (system(buf) != 0 ||
11050 if_nametoindex("sigmadut") == 0) {
11051 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
11052 "monitor interface with '%s'", buf);
11053 return -2;
11054 }
11055 }
11056
11057 if (system("ifconfig sigmadut up") != 0) {
11058 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
11059 "monitor interface up");
11060 return -2;
11061 }
11062
11063 return sta_inject_frame(dut, conn, frame, protected, NULL);
11064}
11065
11066
11067static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
11068 struct sigma_conn *conn,
11069 struct sigma_cmd *cmd,
11070 const char *ifname)
11071{
11072 char buf[200];
11073 const char *val;
11074
11075 val = get_param(cmd, "ClearARP");
11076 if (val && atoi(val) == 1) {
11077 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
11078 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11079 if (system(buf) != 0) {
11080 send_resp(dut, conn, SIGMA_ERROR,
11081 "errorCode,Failed to clear ARP cache");
11082 return 0;
11083 }
11084 }
11085
11086 return 1;
11087}
11088
11089
11090int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
11091 struct sigma_cmd *cmd)
11092{
11093 const char *intf = get_param(cmd, "Interface");
11094 const char *val;
11095
11096 if (intf == NULL)
11097 return -1;
11098
11099 val = get_param(cmd, "program");
11100 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030011101 strcasecmp(val, "HS2-R2") == 0 ||
11102 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011103 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
11104
11105 return -1;
11106}
11107
11108
Jouni Malinenf7222712019-06-13 01:50:21 +030011109static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
11110 struct sigma_conn *conn,
11111 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011112{
11113 const char *intf = get_param(cmd, "Interface");
11114 const char *mac = get_param(cmd, "MAC");
11115
11116 if (intf == NULL || mac == NULL)
11117 return -1;
11118
11119 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
11120 "interface %s to %s", intf, mac);
11121
11122 if (dut->set_macaddr) {
11123 char buf[128];
11124 int res;
11125 if (strcasecmp(mac, "default") == 0) {
11126 res = snprintf(buf, sizeof(buf), "%s",
11127 dut->set_macaddr);
11128 dut->tmp_mac_addr = 0;
11129 } else {
11130 res = snprintf(buf, sizeof(buf), "%s %s",
11131 dut->set_macaddr, mac);
11132 dut->tmp_mac_addr = 1;
11133 }
11134 if (res < 0 || res >= (int) sizeof(buf))
11135 return -1;
11136 if (system(buf) != 0) {
11137 send_resp(dut, conn, SIGMA_ERROR,
11138 "errorCode,Failed to set MAC "
11139 "address");
11140 return 0;
11141 }
11142 return 1;
11143 }
11144
11145 if (strcasecmp(mac, "default") == 0)
11146 return 1;
11147
11148 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
11149 "command");
11150 return 0;
11151}
11152
11153
11154static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
11155 struct sigma_conn *conn, const char *intf,
11156 int val)
11157{
11158 char buf[200];
11159 int res;
11160
11161 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
11162 intf, val);
11163 if (res < 0 || res >= (int) sizeof(buf))
11164 return -1;
11165 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11166 if (system(buf) != 0) {
11167 send_resp(dut, conn, SIGMA_ERROR,
11168 "errorCode,Failed to configure offchannel mode");
11169 return 0;
11170 }
11171
11172 return 1;
11173}
11174
11175
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011176static int off_chan_val(enum sec_ch_offset off)
11177{
11178 switch (off) {
11179 case SEC_CH_NO:
11180 return 0;
11181 case SEC_CH_40ABOVE:
11182 return 40;
11183 case SEC_CH_40BELOW:
11184 return -40;
11185 }
11186
11187 return 0;
11188}
11189
11190
11191static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
11192 const char *intf, int off_ch_num,
11193 enum sec_ch_offset sec)
11194{
11195 char buf[200];
11196 int res;
11197
11198 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
11199 intf, off_ch_num);
11200 if (res < 0 || res >= (int) sizeof(buf))
11201 return -1;
11202 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11203 if (system(buf) != 0) {
11204 send_resp(dut, conn, SIGMA_ERROR,
11205 "errorCode,Failed to set offchan");
11206 return 0;
11207 }
11208
11209 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
11210 intf, off_chan_val(sec));
11211 if (res < 0 || res >= (int) sizeof(buf))
11212 return -1;
11213 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11214 if (system(buf) != 0) {
11215 send_resp(dut, conn, SIGMA_ERROR,
11216 "errorCode,Failed to set sec chan offset");
11217 return 0;
11218 }
11219
11220 return 1;
11221}
11222
11223
11224static int tdls_set_offchannel_offset(struct sigma_dut *dut,
11225 struct sigma_conn *conn,
11226 const char *intf, int off_ch_num,
11227 enum sec_ch_offset sec)
11228{
11229 char buf[200];
11230 int res;
11231
11232 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
11233 off_ch_num);
11234 if (res < 0 || res >= (int) sizeof(buf))
11235 return -1;
11236 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11237
11238 if (wpa_command(intf, buf) < 0) {
11239 send_resp(dut, conn, SIGMA_ERROR,
11240 "ErrorCode,Failed to set offchan");
11241 return 0;
11242 }
11243 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
11244 off_chan_val(sec));
11245 if (res < 0 || res >= (int) sizeof(buf))
11246 return -1;
11247
11248 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11249
11250 if (wpa_command(intf, buf) < 0) {
11251 send_resp(dut, conn, SIGMA_ERROR,
11252 "ErrorCode,Failed to set sec chan offset");
11253 return 0;
11254 }
11255
11256 return 1;
11257}
11258
11259
11260static int tdls_set_offchannel_mode(struct sigma_dut *dut,
11261 struct sigma_conn *conn,
11262 const char *intf, int val)
11263{
11264 char buf[200];
11265 int res;
11266
11267 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
11268 val);
11269 if (res < 0 || res >= (int) sizeof(buf))
11270 return -1;
11271 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
11272
11273 if (wpa_command(intf, buf) < 0) {
11274 send_resp(dut, conn, SIGMA_ERROR,
11275 "ErrorCode,Failed to configure offchannel mode");
11276 return 0;
11277 }
11278
11279 return 1;
11280}
11281
11282
11283static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
11284 struct sigma_conn *conn,
11285 struct sigma_cmd *cmd)
11286{
11287 const char *val;
11288 enum {
11289 CHSM_NOT_SET,
11290 CHSM_ENABLE,
11291 CHSM_DISABLE,
11292 CHSM_REJREQ,
11293 CHSM_UNSOLRESP
11294 } chsm = CHSM_NOT_SET;
11295 int off_ch_num = -1;
11296 enum sec_ch_offset sec_ch = SEC_CH_NO;
11297 int res;
11298
11299 val = get_param(cmd, "Uapsd");
11300 if (val) {
11301 char buf[100];
11302 if (strcasecmp(val, "Enable") == 0)
11303 snprintf(buf, sizeof(buf), "SET ps 99");
11304 else if (strcasecmp(val, "Disable") == 0)
11305 snprintf(buf, sizeof(buf), "SET ps 98");
11306 else {
11307 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
11308 "Unsupported uapsd parameter value");
11309 return 0;
11310 }
11311 if (wpa_command(intf, buf)) {
11312 send_resp(dut, conn, SIGMA_ERROR,
11313 "ErrorCode,Failed to change U-APSD "
11314 "powersave mode");
11315 return 0;
11316 }
11317 }
11318
11319 val = get_param(cmd, "TPKTIMER");
11320 if (val && strcasecmp(val, "DISABLE") == 0) {
11321 if (wpa_command(intf, "SET tdls_testing 0x100")) {
11322 send_resp(dut, conn, SIGMA_ERROR,
11323 "ErrorCode,Failed to enable no TPK "
11324 "expiration test mode");
11325 return 0;
11326 }
11327 dut->no_tpk_expiration = 1;
11328 }
11329
11330 val = get_param(cmd, "ChSwitchMode");
11331 if (val) {
11332 if (strcasecmp(val, "Enable") == 0 ||
11333 strcasecmp(val, "Initiate") == 0)
11334 chsm = CHSM_ENABLE;
11335 else if (strcasecmp(val, "Disable") == 0 ||
11336 strcasecmp(val, "passive") == 0)
11337 chsm = CHSM_DISABLE;
11338 else if (strcasecmp(val, "RejReq") == 0)
11339 chsm = CHSM_REJREQ;
11340 else if (strcasecmp(val, "UnSolResp") == 0)
11341 chsm = CHSM_UNSOLRESP;
11342 else {
11343 send_resp(dut, conn, SIGMA_ERROR,
11344 "ErrorCode,Unknown ChSwitchMode value");
11345 return 0;
11346 }
11347 }
11348
11349 val = get_param(cmd, "OffChNum");
11350 if (val) {
11351 off_ch_num = atoi(val);
11352 if (off_ch_num == 0) {
11353 send_resp(dut, conn, SIGMA_ERROR,
11354 "ErrorCode,Invalid OffChNum");
11355 return 0;
11356 }
11357 }
11358
11359 val = get_param(cmd, "SecChOffset");
11360 if (val) {
11361 if (strcmp(val, "20") == 0)
11362 sec_ch = SEC_CH_NO;
11363 else if (strcasecmp(val, "40above") == 0)
11364 sec_ch = SEC_CH_40ABOVE;
11365 else if (strcasecmp(val, "40below") == 0)
11366 sec_ch = SEC_CH_40BELOW;
11367 else {
11368 send_resp(dut, conn, SIGMA_ERROR,
11369 "ErrorCode,Unknown SecChOffset value");
11370 return 0;
11371 }
11372 }
11373
11374 if (chsm == CHSM_NOT_SET) {
11375 /* no offchannel changes requested */
11376 return 1;
11377 }
11378
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011379 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
11380 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011381 send_resp(dut, conn, SIGMA_ERROR,
11382 "ErrorCode,Unknown interface");
11383 return 0;
11384 }
11385
11386 switch (chsm) {
11387 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030011388 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011389 break;
11390 case CHSM_ENABLE:
11391 if (off_ch_num < 0) {
11392 send_resp(dut, conn, SIGMA_ERROR,
11393 "ErrorCode,Missing OffChNum argument");
11394 return 0;
11395 }
11396 if (wifi_chip_type == DRIVER_WCN) {
11397 res = tdls_set_offchannel_offset(dut, conn, intf,
11398 off_ch_num, sec_ch);
11399 } else {
11400 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11401 sec_ch);
11402 }
11403 if (res != 1)
11404 return res;
11405 if (wifi_chip_type == DRIVER_WCN)
11406 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
11407 else
11408 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
11409 break;
11410 case CHSM_DISABLE:
11411 if (wifi_chip_type == DRIVER_WCN)
11412 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
11413 else
11414 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
11415 break;
11416 case CHSM_REJREQ:
11417 if (wifi_chip_type == DRIVER_WCN)
11418 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
11419 else
11420 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
11421 break;
11422 case CHSM_UNSOLRESP:
11423 if (off_ch_num < 0) {
11424 send_resp(dut, conn, SIGMA_ERROR,
11425 "ErrorCode,Missing OffChNum argument");
11426 return 0;
11427 }
11428 if (wifi_chip_type == DRIVER_WCN) {
11429 res = tdls_set_offchannel_offset(dut, conn, intf,
11430 off_ch_num, sec_ch);
11431 } else {
11432 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
11433 sec_ch);
11434 }
11435 if (res != 1)
11436 return res;
11437 if (wifi_chip_type == DRIVER_WCN)
11438 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
11439 else
11440 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
11441 break;
11442 }
11443
11444 return res;
11445}
11446
11447
11448static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11449 struct sigma_conn *conn,
11450 struct sigma_cmd *cmd)
11451{
11452 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011453 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011454
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070011455 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080011456
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011457 val = get_param(cmd, "nss_mcs_opt");
11458 if (val) {
11459 /* String (nss_operating_mode; mcs_operating_mode) */
11460 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011461 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011462
11463 token = strdup(val);
11464 if (!token)
11465 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011466 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011467 if (!result) {
11468 sigma_dut_print(dut, DUT_MSG_ERROR,
11469 "VHT NSS not specified");
11470 goto failed;
11471 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011472 if (strcasecmp(result, "def") != 0) {
11473 nss = atoi(result);
11474 if (nss == 4)
11475 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011476 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011477 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011478
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011479 }
11480
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053011481 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053011482 if (!result) {
11483 sigma_dut_print(dut, DUT_MSG_ERROR,
11484 "VHT MCS not specified");
11485 goto failed;
11486 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011487 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011488 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011489 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011490 } else {
11491 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011492 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011493 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011494 }
11495 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011496 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011497 }
11498
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053011499 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011500 return 1;
11501failed:
11502 free(token);
11503 return 0;
11504}
11505
11506
11507static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
11508 struct sigma_conn *conn,
11509 struct sigma_cmd *cmd)
11510{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011511 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011512 case DRIVER_ATHEROS:
11513 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
11514 default:
11515 send_resp(dut, conn, SIGMA_ERROR,
11516 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
11517 return 0;
11518 }
11519}
11520
11521
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011522static int wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11523 struct sigma_conn *conn,
11524 struct sigma_cmd *cmd)
11525{
11526 const char *val;
11527 char *token = NULL, *result;
11528 char buf[60];
11529
11530 val = get_param(cmd, "nss_mcs_opt");
11531 if (val) {
11532 /* String (nss_operating_mode; mcs_operating_mode) */
11533 int nss, mcs, ratecode;
11534 char *saveptr;
11535
11536 token = strdup(val);
11537 if (!token)
11538 return -2;
11539
11540 result = strtok_r(token, ";", &saveptr);
11541 if (!result) {
11542 sigma_dut_print(dut, DUT_MSG_ERROR,
11543 "HE NSS not specified");
11544 goto failed;
11545 }
11546 nss = 1;
11547 if (strcasecmp(result, "def") != 0)
11548 nss = atoi(result);
11549
11550 result = strtok_r(NULL, ";", &saveptr);
11551 if (!result) {
11552 sigma_dut_print(dut, DUT_MSG_ERROR,
11553 "HE MCS not specified");
11554 goto failed;
11555 }
11556 mcs = 7;
11557 if (strcasecmp(result, "def") != 0)
11558 mcs = atoi(result);
11559
Arif Hussain557bf412018-05-25 17:29:36 -070011560 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011561 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070011562 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011563 } else if (nss > 2) {
11564 sigma_dut_print(dut, DUT_MSG_ERROR,
11565 "HE NSS %d not supported", nss);
11566 goto failed;
11567 }
11568
Arif Hussain557bf412018-05-25 17:29:36 -070011569 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
11570 if (system(buf) != 0) {
11571 sigma_dut_print(dut, DUT_MSG_ERROR,
11572 "nss_mcs_opt: iwpriv %s nss %d failed",
11573 intf, nss);
11574 goto failed;
11575 }
Arif Hussainac6c5112018-05-25 17:34:00 -070011576 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070011577
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011578 /* Add the MCS to the ratecode */
11579 if (mcs >= 0 && mcs <= 11) {
11580 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070011581#ifdef NL80211_SUPPORT
11582 if (dut->device_type == STA_testbed) {
11583 enum he_mcs_config mcs_config;
11584 int ret;
11585
11586 if (mcs <= 7)
11587 mcs_config = HE_80_MCS0_7;
11588 else if (mcs <= 9)
11589 mcs_config = HE_80_MCS0_9;
11590 else
11591 mcs_config = HE_80_MCS0_11;
11592 ret = sta_set_he_mcs(dut, intf, mcs_config);
11593 if (ret) {
11594 sigma_dut_print(dut, DUT_MSG_ERROR,
11595 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
11596 mcs, mcs_config, ret);
11597 goto failed;
11598 }
11599 }
11600#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011601 } else {
11602 sigma_dut_print(dut, DUT_MSG_ERROR,
11603 "HE MCS %d not supported", mcs);
11604 goto failed;
11605 }
11606 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
11607 intf, ratecode);
11608 if (system(buf) != 0) {
11609 sigma_dut_print(dut, DUT_MSG_ERROR,
11610 "iwpriv setting of 11ax rates failed");
11611 goto failed;
11612 }
11613 free(token);
11614 }
11615
11616 val = get_param(cmd, "GI");
11617 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011618 int fix_rate_sgi;
11619
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011620 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011621 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011622 fix_rate_sgi = 1;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011623 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011624 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
11625 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011626 fix_rate_sgi = 2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011627 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070011628 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
11629 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011630 fix_rate_sgi = 3;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011631 } else {
11632 send_resp(dut, conn, SIGMA_ERROR,
11633 "errorCode,GI value not supported");
11634 return 0;
11635 }
11636 if (system(buf) != 0) {
11637 send_resp(dut, conn, SIGMA_ERROR,
11638 "errorCode,Failed to set shortgi");
11639 return 0;
11640 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080011641 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
11642 intf, fix_rate_sgi);
11643 if (system(buf) != 0) {
11644 send_resp(dut, conn, SIGMA_ERROR,
11645 "errorCode,Failed to set fix rate shortgi");
11646 return STATUS_SENT;
11647 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011648 }
11649
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011650 val = get_param(cmd, "LTF");
11651 if (val) {
11652#ifdef NL80211_SUPPORT
11653 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011654 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011655 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011656 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011657 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080011658 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070011659 } else {
11660 send_resp(dut, conn, SIGMA_ERROR,
11661 "errorCode, LTF value not supported");
11662 return 0;
11663 }
11664#else /* NL80211_SUPPORT */
11665 sigma_dut_print(dut, DUT_MSG_ERROR,
11666 "LTF cannot be set without NL80211_SUPPORT defined");
11667 return -2;
11668#endif /* NL80211_SUPPORT */
11669 }
11670
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070011671 val = get_param(cmd, "TxSUPPDU");
11672 if (val) {
11673 int set_val = 1;
11674
11675 if (strcasecmp(val, "Enable") == 0)
11676 set_val = 1;
11677 else if (strcasecmp(val, "Disable") == 0)
11678 set_val = 0;
11679
11680 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
11681 send_resp(dut, conn, SIGMA_ERROR,
11682 "ErrorCode,Failed to set Tx SU PPDU config");
11683 return 0;
11684 }
11685 }
11686
Arif Hussain480d5f42019-03-12 14:40:42 -070011687 val = get_param(cmd, "TWT_Setup");
11688 if (val) {
11689 if (strcasecmp(val, "Request") == 0) {
11690 if (sta_twt_request(dut, conn, cmd)) {
11691 send_resp(dut, conn, SIGMA_ERROR,
11692 "ErrorCode,sta_twt_request failed");
11693 return STATUS_SENT;
11694 }
11695 } else if (strcasecmp(val, "Teardown") == 0) {
11696 if (sta_twt_teardown(dut, conn, cmd)) {
11697 send_resp(dut, conn, SIGMA_ERROR,
11698 "ErrorCode,sta_twt_teardown failed");
11699 return STATUS_SENT;
11700 }
11701 }
11702 }
11703
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080011704 val = get_param(cmd, "transmitOMI");
11705 if (val && sta_transmit_omi(dut, conn, cmd)) {
11706 send_resp(dut, conn, SIGMA_ERROR,
11707 "ErrorCode,sta_transmit_omi failed");
11708 return STATUS_SENT;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070011709 }
11710
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080011711 val = get_param(cmd, "Powersave");
11712 if (val) {
11713 char buf[60];
11714
11715 if (strcasecmp(val, "off") == 0) {
11716 snprintf(buf, sizeof(buf),
11717 "iwpriv %s setPower 2", intf);
11718 if (system(buf) != 0) {
11719 sigma_dut_print(dut, DUT_MSG_ERROR,
11720 "iwpriv setPower 2 failed");
11721 return 0;
11722 }
11723 } else if (strcasecmp(val, "on") == 0) {
11724 snprintf(buf, sizeof(buf),
11725 "iwpriv %s setPower 1", intf);
11726 if (system(buf) != 0) {
11727 sigma_dut_print(dut, DUT_MSG_ERROR,
11728 "iwpriv setPower 1 failed");
11729 return 0;
11730 }
11731 } else {
11732 sigma_dut_print(dut, DUT_MSG_ERROR,
11733 "Unsupported Powersave value '%s'",
11734 val);
11735 return -1;
11736 }
11737 }
11738
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080011739 val = get_param(cmd, "MU_EDCA");
11740 if (val) {
11741 if (strcasecmp(val, "Override") == 0) {
11742 if (sta_set_mu_edca_override(dut, intf, 1)) {
11743 send_resp(dut, conn, SIGMA_ERROR,
11744 "errorCode,MU EDCA override set failed");
11745 return STATUS_SENT;
11746 }
11747 } else if (strcasecmp(val, "Disable") == 0) {
11748 if (sta_set_mu_edca_override(dut, intf, 0)) {
11749 send_resp(dut, conn, SIGMA_ERROR,
11750 "errorCode,MU EDCA override disable failed");
11751 return STATUS_SENT;
11752 }
11753 }
11754 }
11755
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011756 return 1;
11757
11758failed:
11759 free(token);
11760 return -2;
11761}
11762
11763
11764static int cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
11765 struct sigma_conn *conn,
11766 struct sigma_cmd *cmd)
11767{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011768 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080011769 case DRIVER_WCN:
11770 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
11771 default:
11772 send_resp(dut, conn, SIGMA_ERROR,
11773 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
11774 return 0;
11775 }
11776}
11777
11778
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080011779static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
11780 struct sigma_conn *conn,
11781 struct sigma_cmd *cmd)
11782{
11783 const char *val;
11784
11785 val = get_param(cmd, "powersave");
11786 if (val) {
11787 char buf[60];
11788
11789 if (strcasecmp(val, "off") == 0) {
11790 snprintf(buf, sizeof(buf), "iwpriv %s setPower 2",
11791 intf);
11792 if (system(buf) != 0) {
11793 sigma_dut_print(dut, DUT_MSG_ERROR,
11794 "iwpriv setPower 2 failed");
11795 return 0;
11796 }
11797 } else if (strcasecmp(val, "on") == 0) {
11798 snprintf(buf, sizeof(buf), "iwpriv %s setPower 1",
11799 intf);
11800 if (system(buf) != 0) {
11801 sigma_dut_print(dut, DUT_MSG_ERROR,
11802 "iwpriv setPower 1 failed");
11803 return 0;
11804 }
11805 } else {
11806 sigma_dut_print(dut, DUT_MSG_ERROR,
11807 "Unsupported power save config");
11808 return -1;
11809 }
11810 return 1;
11811 }
11812
11813 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
11814
11815 return 0;
11816}
11817
11818
Ashwini Patil5acd7382017-04-13 15:55:04 +053011819static int btm_query_candidate_list(struct sigma_dut *dut,
11820 struct sigma_conn *conn,
11821 struct sigma_cmd *cmd)
11822{
11823 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
11824 int len, ret;
11825 char buf[10];
11826
11827 /*
11828 * Neighbor Report elements format:
11829 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
11830 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
11831 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
11832 */
11833
11834 bssid = get_param(cmd, "Nebor_BSSID");
11835 if (!bssid) {
11836 send_resp(dut, conn, SIGMA_INVALID,
11837 "errorCode,Nebor_BSSID is missing");
11838 return 0;
11839 }
11840
11841 info = get_param(cmd, "Nebor_Bssid_Info");
11842 if (!info) {
11843 sigma_dut_print(dut, DUT_MSG_INFO,
11844 "Using default value for Nebor_Bssid_Info: %s",
11845 DEFAULT_NEIGHBOR_BSSID_INFO);
11846 info = DEFAULT_NEIGHBOR_BSSID_INFO;
11847 }
11848
11849 op_class = get_param(cmd, "Nebor_Op_Class");
11850 if (!op_class) {
11851 send_resp(dut, conn, SIGMA_INVALID,
11852 "errorCode,Nebor_Op_Class is missing");
11853 return 0;
11854 }
11855
11856 ch = get_param(cmd, "Nebor_Op_Ch");
11857 if (!ch) {
11858 send_resp(dut, conn, SIGMA_INVALID,
11859 "errorCode,Nebor_Op_Ch is missing");
11860 return 0;
11861 }
11862
11863 phy_type = get_param(cmd, "Nebor_Phy_Type");
11864 if (!phy_type) {
11865 sigma_dut_print(dut, DUT_MSG_INFO,
11866 "Using default value for Nebor_Phy_Type: %s",
11867 DEFAULT_NEIGHBOR_PHY_TYPE);
11868 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
11869 }
11870
11871 /* Parse optional subelements */
11872 buf[0] = '\0';
11873 pref = get_param(cmd, "Nebor_Pref");
11874 if (pref) {
11875 /* hexdump for preferrence subelement */
11876 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
11877 if (ret < 0 || ret >= (int) sizeof(buf)) {
11878 sigma_dut_print(dut, DUT_MSG_ERROR,
11879 "snprintf failed for optional subelement ret: %d",
11880 ret);
11881 send_resp(dut, conn, SIGMA_ERROR,
11882 "errorCode,snprintf failed for subelement");
11883 return 0;
11884 }
11885 }
11886
11887 if (!dut->btm_query_cand_list) {
11888 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
11889 if (!dut->btm_query_cand_list) {
11890 send_resp(dut, conn, SIGMA_ERROR,
11891 "errorCode,Failed to allocate memory for btm_query_cand_list");
11892 return 0;
11893 }
11894 }
11895
11896 len = strlen(dut->btm_query_cand_list);
11897 ret = snprintf(dut->btm_query_cand_list + len,
11898 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
11899 bssid, info, op_class, ch, phy_type, buf);
11900 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
11901 sigma_dut_print(dut, DUT_MSG_ERROR,
11902 "snprintf failed for neighbor report list ret: %d",
11903 ret);
11904 send_resp(dut, conn, SIGMA_ERROR,
11905 "errorCode,snprintf failed for neighbor report");
11906 free(dut->btm_query_cand_list);
11907 dut->btm_query_cand_list = NULL;
11908 return 0;
11909 }
11910
11911 return 1;
11912}
11913
11914
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011915int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
11916 struct sigma_ese_alloc *allocs, int *allocs_size)
11917{
11918 int max_count = *allocs_size;
11919 int count = 0, i;
11920 const char *val;
11921
11922 do {
11923 val = get_param_indexed(cmd, "AllocID", count);
11924 if (val)
11925 count++;
11926 } while (val);
11927
11928 if (count == 0 || count > max_count) {
11929 sigma_dut_print(dut, DUT_MSG_ERROR,
11930 "Invalid number of allocations(%d)", count);
11931 return -1;
11932 }
11933
11934 for (i = 0; i < count; i++) {
11935 val = get_param_indexed(cmd, "PercentBI", i);
11936 if (!val) {
11937 sigma_dut_print(dut, DUT_MSG_ERROR,
11938 "Missing PercentBI parameter at index %d",
11939 i);
11940 return -1;
11941 }
11942 allocs[i].percent_bi = atoi(val);
11943
11944 val = get_param_indexed(cmd, "SrcAID", i);
11945 if (val)
11946 allocs[i].src_aid = strtol(val, NULL, 0);
11947 else
11948 allocs[i].src_aid = ESE_BCAST_AID;
11949
11950 val = get_param_indexed(cmd, "DestAID", i);
11951 if (val)
11952 allocs[i].dst_aid = strtol(val, NULL, 0);
11953 else
11954 allocs[i].dst_aid = ESE_BCAST_AID;
11955
11956 allocs[i].type = ESE_CBAP;
11957 sigma_dut_print(dut, DUT_MSG_INFO,
11958 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
11959 i, allocs[i].percent_bi, allocs[i].src_aid,
11960 allocs[i].dst_aid);
11961 }
11962
11963 *allocs_size = count;
11964 return 0;
11965}
11966
11967
11968static int sta_set_60g_ese(struct sigma_dut *dut, int count,
11969 struct sigma_ese_alloc *allocs)
11970{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011971 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020011972#ifdef __linux__
11973 case DRIVER_WIL6210:
11974 if (wil6210_set_ese(dut, count, allocs))
11975 return -1;
11976 return 1;
11977#endif /* __linux__ */
11978 default:
11979 sigma_dut_print(dut, DUT_MSG_ERROR,
11980 "Unsupported sta_set_60g_ese with the current driver");
11981 return -1;
11982 }
11983}
11984
11985
11986static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
11987 struct sigma_conn *conn,
11988 struct sigma_cmd *cmd)
11989{
11990 const char *val;
11991
11992 val = get_param(cmd, "ExtSchIE");
11993 if (val && !strcasecmp(val, "Enable")) {
11994 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
11995 int count = MAX_ESE_ALLOCS;
11996
11997 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
11998 return -1;
11999 return sta_set_60g_ese(dut, count, allocs);
12000 }
12001
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020012002 val = get_param(cmd, "MCS_FixedRate");
12003 if (val) {
12004 int sta_mcs = atoi(val);
12005
12006 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
12007 sta_mcs);
12008 wil6210_set_force_mcs(dut, 1, sta_mcs);
12009
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012010 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020012011 }
12012
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012013 send_resp(dut, conn, SIGMA_ERROR,
12014 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020012015 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012016}
12017
12018
Jouni Malinen6250cb02020-04-15 13:54:45 +030012019static enum sigma_cmd_result
12020cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
12021 struct sigma_conn *conn,
12022 struct sigma_cmd *cmd)
12023{
12024 const char *val;
12025
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053012026 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030012027 if (val && atoi(val) == 1) {
12028 if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
12029 send_resp(dut, conn, SIGMA_ERROR,
12030 "errorCode,Failed to set ft_rsnxe_used");
12031 return STATUS_SENT_ERROR;
12032 }
12033 return SUCCESS_SEND_STATUS;
12034 }
12035 send_resp(dut, conn, SIGMA_ERROR,
12036 "errorCode,Unsupported WPA3 rfeature");
12037 return STATUS_SENT_ERROR;
12038}
12039
12040
Jouni Malinenf7222712019-06-13 01:50:21 +030012041static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
12042 struct sigma_conn *conn,
12043 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012044{
12045 const char *intf = get_param(cmd, "Interface");
12046 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012047 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012048
12049 if (intf == NULL || prog == NULL)
12050 return -1;
12051
Ashwini Patil5acd7382017-04-13 15:55:04 +053012052 /* BSS Transition candidate list for BTM query */
12053 val = get_param(cmd, "Nebor_BSSID");
12054 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
12055 return 0;
12056
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012057 if (strcasecmp(prog, "TDLS") == 0)
12058 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
12059
12060 if (strcasecmp(prog, "VHT") == 0)
12061 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
12062
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080012063 if (strcasecmp(prog, "HE") == 0)
12064 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
12065
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012066 if (strcasecmp(prog, "MBO") == 0) {
12067 val = get_param(cmd, "Cellular_Data_Cap");
12068 if (val &&
12069 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
12070 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053012071
12072 val = get_param(cmd, "Ch_Pref");
12073 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
12074 return 0;
12075
Ashwini Patil68d02cd2017-01-10 15:39:16 +053012076 return 1;
12077 }
12078
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020012079 if (strcasecmp(prog, "60GHz") == 0)
12080 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
12081
Jouni Malinen6250cb02020-04-15 13:54:45 +030012082 if (strcasecmp(prog, "WPA3") == 0)
12083 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
12084
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012085 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
12086 return 0;
12087}
12088
12089
Jouni Malinenf7222712019-06-13 01:50:21 +030012090static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
12091 struct sigma_conn *conn,
12092 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012093{
12094 const char *intf = get_param(cmd, "Interface");
12095 const char *mode = get_param(cmd, "Mode");
12096 int res;
12097
12098 if (intf == NULL || mode == NULL)
12099 return -1;
12100
12101 if (strcasecmp(mode, "On") == 0)
12102 res = wpa_command(intf, "SET radio_disabled 0");
12103 else if (strcasecmp(mode, "Off") == 0)
12104 res = wpa_command(intf, "SET radio_disabled 1");
12105 else
12106 return -1;
12107
12108 if (res) {
12109 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12110 "radio mode");
12111 return 0;
12112 }
12113
12114 return 1;
12115}
12116
12117
Jouni Malinenf7222712019-06-13 01:50:21 +030012118static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
12119 struct sigma_conn *conn,
12120 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012121{
12122 const char *intf = get_param(cmd, "Interface");
12123 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012124 const char *prog = get_param(cmd, "program");
12125 const char *powersave = get_param(cmd, "powersave");
12126 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012127
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012128 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012129 return -1;
12130
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012131 if (prog && strcasecmp(prog, "60GHz") == 0) {
12132 /*
12133 * The CAPI mode parameter does not exist in 60G
12134 * unscheduled PS.
12135 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080012136 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012137 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012138 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020012139 strcasecmp(prog, "HE") == 0) {
12140 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020012141 } else {
12142 if (mode == NULL)
12143 return -1;
12144
12145 if (strcasecmp(mode, "On") == 0)
12146 res = set_ps(intf, dut, 1);
12147 else if (strcasecmp(mode, "Off") == 0)
12148 res = set_ps(intf, dut, 0);
12149 else
12150 return -1;
12151 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012152
12153 if (res) {
12154 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
12155 "power save mode");
12156 return 0;
12157 }
12158
12159 return 1;
12160}
12161
12162
Jouni Malinenf7222712019-06-13 01:50:21 +030012163static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
12164 struct sigma_conn *conn,
12165 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012166{
12167 const char *intf = get_param(cmd, "Interface");
12168 const char *val, *bssid;
12169 int res;
12170 char *buf;
12171 size_t buf_len;
12172
12173 val = get_param(cmd, "BSSID_FILTER");
12174 if (val == NULL)
12175 return -1;
12176
12177 bssid = get_param(cmd, "BSSID_List");
12178 if (atoi(val) == 0 || bssid == NULL) {
12179 /* Disable BSSID filter */
12180 if (wpa_command(intf, "SET bssid_filter ")) {
12181 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
12182 "to disable BSSID filter");
12183 return 0;
12184 }
12185
12186 return 1;
12187 }
12188
12189 buf_len = 100 + strlen(bssid);
12190 buf = malloc(buf_len);
12191 if (buf == NULL)
12192 return -1;
12193
12194 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
12195 res = wpa_command(intf, buf);
12196 free(buf);
12197 if (res) {
12198 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
12199 "BSSID filter");
12200 return 0;
12201 }
12202
12203 return 1;
12204}
12205
12206
Jouni Malinenf7222712019-06-13 01:50:21 +030012207static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
12208 struct sigma_conn *conn,
12209 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012210{
12211 const char *intf = get_param(cmd, "Interface");
12212 const char *val;
12213
12214 /* TODO: ARP */
12215
12216 val = get_param(cmd, "HS2_CACHE_PROFILE");
12217 if (val && strcasecmp(val, "All") == 0)
12218 hs2_clear_credentials(intf);
12219
12220 return 1;
12221}
12222
12223
Jouni Malinenf7222712019-06-13 01:50:21 +030012224static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
12225 struct sigma_conn *conn,
12226 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012227{
12228 const char *intf = get_param(cmd, "Interface");
12229 const char *key_type = get_param(cmd, "KeyType");
12230 char buf[100], resp[200];
12231
12232 if (key_type == NULL)
12233 return -1;
12234
12235 if (strcasecmp(key_type, "GTK") == 0) {
12236 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
12237 strncmp(buf, "FAIL", 4) == 0) {
12238 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12239 "not fetch current GTK");
12240 return 0;
12241 }
12242 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
12243 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12244 return 0;
12245 } else {
12246 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
12247 "KeyType");
12248 return 0;
12249 }
12250
12251 return 1;
12252}
12253
12254
12255static int hs2_set_policy(struct sigma_dut *dut)
12256{
12257#ifdef ANDROID
12258 system("ip rule del prio 23000");
12259 if (system("ip rule add from all lookup main prio 23000") != 0) {
12260 sigma_dut_print(dut, DUT_MSG_ERROR,
12261 "Failed to run:ip rule add from all lookup main prio");
12262 return -1;
12263 }
12264 if (system("ip route flush cache") != 0) {
12265 sigma_dut_print(dut, DUT_MSG_ERROR,
12266 "Failed to run ip route flush cache");
12267 return -1;
12268 }
12269 return 1;
12270#else /* ANDROID */
12271 return 0;
12272#endif /* ANDROID */
12273}
12274
12275
Jouni Malinenf7222712019-06-13 01:50:21 +030012276static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
12277 struct sigma_conn *conn,
12278 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012279{
12280 const char *intf = get_param(cmd, "Interface");
12281 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030012282 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012283 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030012284 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012285 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
12286 int tries = 0;
12287 int ignore_blacklist = 0;
12288 const char *events[] = {
12289 "CTRL-EVENT-CONNECTED",
12290 "INTERWORKING-BLACKLISTED",
12291 "INTERWORKING-NO-MATCH",
12292 NULL
12293 };
12294
12295 start_sta_mode(dut);
12296
Jouni Malinen439352d2018-09-13 03:42:23 +030012297 if (band) {
12298 if (strcmp(band, "2.4") == 0) {
12299 wpa_command(intf, "SET setband 2G");
12300 } else if (strcmp(band, "5") == 0) {
12301 wpa_command(intf, "SET setband 5G");
12302 } else {
12303 send_resp(dut, conn, SIGMA_ERROR,
12304 "errorCode,Unsupported band");
12305 return 0;
12306 }
12307 }
12308
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012309 blacklisted[0] = '\0';
12310 if (val && atoi(val))
12311 ignore_blacklist = 1;
12312
12313try_again:
12314 ctrl = open_wpa_mon(intf);
12315 if (ctrl == NULL) {
12316 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12317 "wpa_supplicant monitor connection");
12318 return -2;
12319 }
12320
12321 tries++;
12322 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
12323 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
12324 "Interworking connection");
12325 wpa_ctrl_detach(ctrl);
12326 wpa_ctrl_close(ctrl);
12327 return 0;
12328 }
12329
12330 buf[0] = '\0';
12331 while (1) {
12332 char *pos;
12333 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
12334 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
12335 if (!pos)
12336 break;
12337 pos += 25;
12338 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
12339 pos);
12340 if (!blacklisted[0])
12341 memcpy(blacklisted, pos, strlen(pos) + 1);
12342 }
12343
12344 if (ignore_blacklist && blacklisted[0]) {
12345 char *end;
12346 end = strchr(blacklisted, ' ');
12347 if (end)
12348 *end = '\0';
12349 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
12350 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030012351 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
12352 blacklisted);
12353 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012354 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
12355 wpa_ctrl_detach(ctrl);
12356 wpa_ctrl_close(ctrl);
12357 return 0;
12358 }
12359 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
12360 buf, sizeof(buf));
12361 }
12362
12363 wpa_ctrl_detach(ctrl);
12364 wpa_ctrl_close(ctrl);
12365
12366 if (res < 0) {
12367 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12368 "connect");
12369 return 0;
12370 }
12371
12372 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
12373 strstr(buf, "INTERWORKING-BLACKLISTED")) {
12374 if (tries < 2) {
12375 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
12376 goto try_again;
12377 }
12378 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
12379 "matching credentials found");
12380 return 0;
12381 }
12382
12383 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
12384 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
12385 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
12386 "get current BSSID/SSID");
12387 return 0;
12388 }
12389
12390 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
12391 send_resp(dut, conn, SIGMA_COMPLETE, resp);
12392 hs2_set_policy(dut);
12393 return 0;
12394}
12395
12396
Jouni Malinenf7222712019-06-13 01:50:21 +030012397static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
12398 struct sigma_conn *conn,
12399 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030012400{
12401 const char *intf = get_param(cmd, "Interface");
12402 const char *display = get_param(cmd, "Display");
12403 struct wpa_ctrl *ctrl;
12404 char buf[300], params[400], *pos;
12405 char bssid[20];
12406 int info_avail = 0;
12407 unsigned int old_timeout;
12408 int res;
12409
12410 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
12411 send_resp(dut, conn, SIGMA_ERROR,
12412 "ErrorCode,Could not get current BSSID");
12413 return 0;
12414 }
12415 ctrl = open_wpa_mon(intf);
12416 if (!ctrl) {
12417 sigma_dut_print(dut, DUT_MSG_ERROR,
12418 "Failed to open wpa_supplicant monitor connection");
12419 return -2;
12420 }
12421
12422 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
12423 wpa_command(intf, buf);
12424
12425 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
12426 if (res < 0) {
12427 send_resp(dut, conn, SIGMA_ERROR,
12428 "ErrorCode,Could not complete GAS query");
12429 goto fail;
12430 }
12431
12432 old_timeout = dut->default_timeout;
12433 dut->default_timeout = 2;
12434 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
12435 dut->default_timeout = old_timeout;
12436 if (res < 0)
12437 goto done;
12438 pos = strchr(buf, ' ');
12439 if (!pos)
12440 goto done;
12441 pos++;
12442 pos = strchr(pos, ' ');
12443 if (!pos)
12444 goto done;
12445 pos++;
12446 info_avail = 1;
12447 snprintf(params, sizeof(params), "browser %s", pos);
12448
12449 if (display && strcasecmp(display, "Yes") == 0) {
12450 pid_t pid;
12451
12452 pid = fork();
12453 if (pid < 0) {
12454 perror("fork");
12455 return -1;
12456 }
12457
12458 if (pid == 0) {
12459 run_hs20_osu(dut, params);
12460 exit(0);
12461 }
12462 }
12463
12464done:
12465 snprintf(buf, sizeof(buf), "Info_available,%s",
12466 info_avail ? "Yes" : "No");
12467 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12468fail:
12469 wpa_ctrl_detach(ctrl);
12470 wpa_ctrl_close(ctrl);
12471 return 0;
12472}
12473
12474
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012475static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
12476 struct sigma_conn *conn,
12477 const char *ifname,
12478 struct sigma_cmd *cmd)
12479{
12480 const char *val;
12481 int id;
12482
12483 id = add_cred(ifname);
12484 if (id < 0)
12485 return -2;
12486 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12487
12488 val = get_param(cmd, "prefer");
12489 if (val && atoi(val) > 0)
12490 set_cred(ifname, id, "priority", "1");
12491
12492 val = get_param(cmd, "REALM");
12493 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12494 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12495 "realm");
12496 return 0;
12497 }
12498
12499 val = get_param(cmd, "HOME_FQDN");
12500 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12501 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12502 "home_fqdn");
12503 return 0;
12504 }
12505
12506 val = get_param(cmd, "Username");
12507 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12508 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12509 "username");
12510 return 0;
12511 }
12512
12513 val = get_param(cmd, "Password");
12514 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
12515 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12516 "password");
12517 return 0;
12518 }
12519
12520 val = get_param(cmd, "ROOT_CA");
12521 if (val) {
12522 char fname[200];
12523 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12524#ifdef __linux__
12525 if (!file_exists(fname)) {
12526 char msg[300];
12527 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12528 "file (%s) not found", fname);
12529 send_resp(dut, conn, SIGMA_ERROR, msg);
12530 return 0;
12531 }
12532#endif /* __linux__ */
12533 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12534 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12535 "not set root CA");
12536 return 0;
12537 }
12538 }
12539
12540 return 1;
12541}
12542
12543
12544static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
12545{
12546 FILE *in, *out;
12547 char buf[500];
12548 int found = 0;
12549
12550 in = fopen("devdetail.xml", "r");
12551 if (in == NULL)
12552 return -1;
12553 out = fopen("devdetail.xml.tmp", "w");
12554 if (out == NULL) {
12555 fclose(in);
12556 return -1;
12557 }
12558
12559 while (fgets(buf, sizeof(buf), in)) {
12560 char *pos = strstr(buf, "<IMSI>");
12561 if (pos) {
12562 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
12563 imsi);
12564 pos += 6;
12565 *pos = '\0';
12566 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
12567 found++;
12568 } else {
12569 fprintf(out, "%s", buf);
12570 }
12571 }
12572
12573 fclose(out);
12574 fclose(in);
12575 if (found)
12576 rename("devdetail.xml.tmp", "devdetail.xml");
12577 else
12578 unlink("devdetail.xml.tmp");
12579
12580 return 0;
12581}
12582
12583
12584static int sta_add_credential_sim(struct sigma_dut *dut,
12585 struct sigma_conn *conn,
12586 const char *ifname, struct sigma_cmd *cmd)
12587{
12588 const char *val, *imsi = NULL;
12589 int id;
12590 char buf[200];
12591 int res;
12592 const char *pos;
12593 size_t mnc_len;
12594 char plmn_mcc[4];
12595 char plmn_mnc[4];
12596
12597 id = add_cred(ifname);
12598 if (id < 0)
12599 return -2;
12600 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12601
12602 val = get_param(cmd, "prefer");
12603 if (val && atoi(val) > 0)
12604 set_cred(ifname, id, "priority", "1");
12605
12606 val = get_param(cmd, "PLMN_MCC");
12607 if (val == NULL) {
12608 send_resp(dut, conn, SIGMA_ERROR,
12609 "errorCode,Missing PLMN_MCC");
12610 return 0;
12611 }
12612 if (strlen(val) != 3) {
12613 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
12614 return 0;
12615 }
12616 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
12617
12618 val = get_param(cmd, "PLMN_MNC");
12619 if (val == NULL) {
12620 send_resp(dut, conn, SIGMA_ERROR,
12621 "errorCode,Missing PLMN_MNC");
12622 return 0;
12623 }
12624 if (strlen(val) != 2 && strlen(val) != 3) {
12625 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
12626 return 0;
12627 }
12628 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
12629
12630 val = get_param(cmd, "IMSI");
12631 if (val == NULL) {
12632 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
12633 "IMSI");
12634 return 0;
12635 }
12636
12637 imsi = pos = val;
12638
12639 if (strncmp(plmn_mcc, pos, 3) != 0) {
12640 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
12641 return 0;
12642 }
12643 pos += 3;
12644
12645 mnc_len = strlen(plmn_mnc);
12646 if (mnc_len < 2) {
12647 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
12648 return 0;
12649 }
12650
12651 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
12652 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
12653 return 0;
12654 }
12655 pos += mnc_len;
12656
12657 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
12658 if (res < 0 || res >= (int) sizeof(buf))
12659 return -1;
12660 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
12661 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12662 "not set IMSI");
12663 return 0;
12664 }
12665
12666 val = get_param(cmd, "Password");
12667 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
12668 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12669 "not set password");
12670 return 0;
12671 }
12672
Jouni Malinenba630452018-06-22 11:49:59 +030012673 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012674 /*
12675 * Set provisioning_sp for the test cases where SIM/USIM
12676 * provisioning is used.
12677 */
12678 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
12679 "wi-fi.org") < 0) {
12680 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12681 "not set provisioning_sp");
12682 return 0;
12683 }
12684
12685 update_devdetail_imsi(dut, imsi);
12686 }
12687
12688 return 1;
12689}
12690
12691
12692static int sta_add_credential_cert(struct sigma_dut *dut,
12693 struct sigma_conn *conn,
12694 const char *ifname,
12695 struct sigma_cmd *cmd)
12696{
12697 const char *val;
12698 int id;
12699
12700 id = add_cred(ifname);
12701 if (id < 0)
12702 return -2;
12703 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
12704
12705 val = get_param(cmd, "prefer");
12706 if (val && atoi(val) > 0)
12707 set_cred(ifname, id, "priority", "1");
12708
12709 val = get_param(cmd, "REALM");
12710 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
12711 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12712 "realm");
12713 return 0;
12714 }
12715
12716 val = get_param(cmd, "HOME_FQDN");
12717 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
12718 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12719 "home_fqdn");
12720 return 0;
12721 }
12722
12723 val = get_param(cmd, "Username");
12724 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
12725 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
12726 "username");
12727 return 0;
12728 }
12729
12730 val = get_param(cmd, "clientCertificate");
12731 if (val) {
12732 char fname[200];
12733 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12734#ifdef __linux__
12735 if (!file_exists(fname)) {
12736 char msg[300];
12737 snprintf(msg, sizeof(msg),
12738 "ErrorCode,clientCertificate "
12739 "file (%s) not found", fname);
12740 send_resp(dut, conn, SIGMA_ERROR, msg);
12741 return 0;
12742 }
12743#endif /* __linux__ */
12744 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
12745 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12746 "not set client_cert");
12747 return 0;
12748 }
12749 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
12750 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12751 "not set private_key");
12752 return 0;
12753 }
12754 }
12755
12756 val = get_param(cmd, "ROOT_CA");
12757 if (val) {
12758 char fname[200];
12759 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
12760#ifdef __linux__
12761 if (!file_exists(fname)) {
12762 char msg[300];
12763 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
12764 "file (%s) not found", fname);
12765 send_resp(dut, conn, SIGMA_ERROR, msg);
12766 return 0;
12767 }
12768#endif /* __linux__ */
12769 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
12770 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
12771 "not set root CA");
12772 return 0;
12773 }
12774 }
12775
12776 return 1;
12777}
12778
12779
Jouni Malinenf7222712019-06-13 01:50:21 +030012780static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
12781 struct sigma_conn *conn,
12782 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012783{
12784 const char *intf = get_param(cmd, "Interface");
12785 const char *type;
12786
12787 start_sta_mode(dut);
12788
12789 type = get_param(cmd, "Type");
12790 if (!type)
12791 return -1;
12792
12793 if (strcasecmp(type, "uname_pwd") == 0)
12794 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
12795
12796 if (strcasecmp(type, "sim") == 0)
12797 return sta_add_credential_sim(dut, conn, intf, cmd);
12798
12799 if (strcasecmp(type, "cert") == 0)
12800 return sta_add_credential_cert(dut, conn, intf, cmd);
12801
12802 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
12803 "type");
12804 return 0;
12805}
12806
12807
Jouni Malinenf7222712019-06-13 01:50:21 +030012808static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
12809 struct sigma_conn *conn,
12810 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012811{
12812 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012813 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Arif Hussain66a4af02019-02-07 15:04:51 -080012814 char buf[4096];
vamsi krishna89ad8c62017-09-19 12:51:18 +053012815 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012816 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012817 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012818 enum sigma_cmd_result status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012819
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020012820 start_sta_mode(dut);
12821
Arif Hussain66a4af02019-02-07 15:04:51 -080012822 val = get_param(cmd, "GetParameter");
12823 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012824 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080012825 buf, sizeof(buf)) < 0) {
12826 sigma_dut_print(dut, DUT_MSG_ERROR,
12827 "Could not get ssid bssid");
12828 return ERROR_SEND_STATUS;
12829 }
12830
12831 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
12832 send_resp(dut, conn, SIGMA_COMPLETE, buf);
12833 return STATUS_SENT;
12834 }
12835
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012836 val = get_param(cmd, "HESSID");
12837 if (val) {
12838 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
12839 if (res < 0 || res >= (int) sizeof(buf))
12840 return -1;
12841 wpa_command(intf, buf);
12842 }
12843
12844 val = get_param(cmd, "ACCS_NET_TYPE");
12845 if (val) {
12846 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
12847 val);
12848 if (res < 0 || res >= (int) sizeof(buf))
12849 return -1;
12850 wpa_command(intf, buf);
12851 }
12852
vamsi krishna89ad8c62017-09-19 12:51:18 +053012853 bssid = get_param(cmd, "Bssid");
12854 ssid = get_param(cmd, "Ssid");
12855
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012856 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
12857 dut->device_type == STA_testbed) {
12858 ssid = NULL;
12859 wildcard_ssid = 1;
12860 }
12861
vamsi krishna89ad8c62017-09-19 12:51:18 +053012862 if (ssid) {
12863 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
12864 send_resp(dut, conn, SIGMA_ERROR,
12865 "ErrorCode,Too long SSID");
12866 return 0;
12867 }
12868 ascii2hexstr(ssid, ssid_hex);
12869 }
12870
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012871 short_ssid = get_param(cmd, "ShortSSID");
12872 if (short_ssid) {
12873 uint32_t short_ssid_hex;
12874
12875 short_ssid_hex = strtoul(short_ssid, NULL, 16);
12876 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
12877 (((short_ssid_hex >> 8) & 0xFF) << 16) |
12878 (((short_ssid_hex >> 16) & 0xFF) << 8) |
12879 ((short_ssid_hex >> 24) & 0xFF);
12880
12881 res = snprintf(buf, sizeof(buf),
12882 "VENDOR_ELEM_ADD 14 ff053a%08x",
12883 short_ssid_hex);
12884 if (res < 0 || res >= (int) sizeof(buf) ||
12885 wpa_command(intf, buf)) {
12886 send_resp(dut, conn, SIGMA_ERROR,
12887 "errorCode,Failed to add short SSID");
12888 return STATUS_SENT_ERROR;
12889 }
12890 }
12891
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080012892 scan_freq = get_param(cmd, "ChnlFreq");
12893
12894 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053012895 bssid ? " bssid=": "",
12896 bssid ? bssid : "",
12897 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080012898 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080012899 wildcard_ssid ? " wildcard_ssid=1" : "",
12900 scan_freq ? " freq=" : "",
12901 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012902 if (res < 0 || res >= (int) sizeof(buf)) {
12903 send_resp(dut, conn, SIGMA_ERROR,
12904 "errorCode,Could not build scan command");
12905 status = STATUS_SENT_ERROR;
12906 goto remove_s_ssid;
12907 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053012908
12909 if (wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012910 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
12911 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012912 status = STATUS_SENT_ERROR;
12913 } else {
12914 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012915 }
12916
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080012917remove_s_ssid:
12918 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
12919 sigma_dut_print(dut, DUT_MSG_ERROR,
12920 "Failed to delete vendor element");
12921
12922 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012923}
12924
12925
Jouni Malinenf7222712019-06-13 01:50:21 +030012926static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
12927 struct sigma_conn *conn,
12928 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020012929{
12930 const char *intf = get_param(cmd, "Interface");
12931 const char *bssid;
12932 char buf[4096], *pos;
12933 int freq, chan;
12934 char *ssid;
12935 char resp[100];
12936 int res;
12937 struct wpa_ctrl *ctrl;
12938
12939 bssid = get_param(cmd, "BSSID");
12940 if (!bssid) {
12941 send_resp(dut, conn, SIGMA_INVALID,
12942 "errorCode,BSSID argument is missing");
12943 return 0;
12944 }
12945
12946 ctrl = open_wpa_mon(intf);
12947 if (!ctrl) {
12948 sigma_dut_print(dut, DUT_MSG_ERROR,
12949 "Failed to open wpa_supplicant monitor connection");
12950 return -1;
12951 }
12952
12953 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
12954 send_resp(dut, conn, SIGMA_ERROR,
12955 "errorCode,Could not start scan");
12956 wpa_ctrl_detach(ctrl);
12957 wpa_ctrl_close(ctrl);
12958 return 0;
12959 }
12960
12961 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12962 buf, sizeof(buf));
12963
12964 wpa_ctrl_detach(ctrl);
12965 wpa_ctrl_close(ctrl);
12966
12967 if (res < 0) {
12968 send_resp(dut, conn, SIGMA_ERROR,
12969 "errorCode,Scan did not complete");
12970 return 0;
12971 }
12972
12973 snprintf(buf, sizeof(buf), "BSS %s", bssid);
12974 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
12975 strncmp(buf, "id=", 3) != 0) {
12976 send_resp(dut, conn, SIGMA_ERROR,
12977 "errorCode,Specified BSSID not found");
12978 return 0;
12979 }
12980
12981 pos = strstr(buf, "\nfreq=");
12982 if (!pos) {
12983 send_resp(dut, conn, SIGMA_ERROR,
12984 "errorCode,Channel not found");
12985 return 0;
12986 }
12987 freq = atoi(pos + 6);
12988 chan = freq_to_channel(freq);
12989
12990 pos = strstr(buf, "\nssid=");
12991 if (!pos) {
12992 send_resp(dut, conn, SIGMA_ERROR,
12993 "errorCode,SSID not found");
12994 return 0;
12995 }
12996 ssid = pos + 6;
12997 pos = strchr(ssid, '\n');
12998 if (pos)
12999 *pos = '\0';
13000 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
13001 send_resp(dut, conn, SIGMA_COMPLETE, resp);
13002 return 0;
13003}
13004
13005
Jouni Malinenf7222712019-06-13 01:50:21 +030013006static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
13007 struct sigma_conn *conn,
13008 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013009{
13010#ifdef __linux__
13011 struct timeval tv;
13012 struct tm tm;
13013 time_t t;
13014 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053013015 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013016
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013017 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013018
13019 memset(&tm, 0, sizeof(tm));
13020 val = get_param(cmd, "seconds");
13021 if (val)
13022 tm.tm_sec = atoi(val);
13023 val = get_param(cmd, "minutes");
13024 if (val)
13025 tm.tm_min = atoi(val);
13026 val = get_param(cmd, "hours");
13027 if (val)
13028 tm.tm_hour = atoi(val);
13029 val = get_param(cmd, "date");
13030 if (val)
13031 tm.tm_mday = atoi(val);
13032 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053013033 if (val) {
13034 v = atoi(val);
13035 if (v < 1 || v > 12) {
13036 send_resp(dut, conn, SIGMA_INVALID,
13037 "errorCode,Invalid month");
13038 return 0;
13039 }
13040 tm.tm_mon = v - 1;
13041 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013042 val = get_param(cmd, "year");
13043 if (val) {
13044 int year = atoi(val);
13045#ifdef ANDROID
13046 if (year > 2035)
13047 year = 2035; /* years beyond 2035 not supported */
13048#endif /* ANDROID */
13049 tm.tm_year = year - 1900;
13050 }
13051 t = mktime(&tm);
13052 if (t == (time_t) -1) {
13053 send_resp(dut, conn, SIGMA_ERROR,
13054 "errorCode,Invalid date or time");
13055 return 0;
13056 }
13057
13058 memset(&tv, 0, sizeof(tv));
13059 tv.tv_sec = t;
13060
13061 if (settimeofday(&tv, NULL) < 0) {
13062 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
13063 strerror(errno));
13064 send_resp(dut, conn, SIGMA_ERROR,
13065 "errorCode,Failed to set time");
13066 return 0;
13067 }
13068
13069 return 1;
13070#endif /* __linux__ */
13071
13072 return -1;
13073}
13074
13075
Jouni Malinenf7222712019-06-13 01:50:21 +030013076static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
13077 struct sigma_conn *conn,
13078 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013079{
13080 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013081 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013082 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013083 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013084 int res;
13085 struct wpa_ctrl *ctrl;
13086
13087 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013088 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013089
13090 val = get_param(cmd, "ProdESSAssoc");
13091 if (val)
13092 prod_ess_assoc = atoi(val);
13093
13094 kill_dhcp_client(dut, intf);
13095 if (start_dhcp_client(dut, intf) < 0)
13096 return -2;
13097
13098 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
13099 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13100 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013101 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013102 prod_ess_assoc ? "" : "-N",
13103 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030013104 name ? "'" : "",
13105 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
13106 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013107
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053013108 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013109 if (run_hs20_osu(dut, buf) < 0) {
13110 FILE *f;
13111
13112 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
13113
13114 f = fopen("hs20-osu-client.res", "r");
13115 if (f) {
13116 char resp[400], res[300], *pos;
13117 if (!fgets(res, sizeof(res), f))
13118 res[0] = '\0';
13119 pos = strchr(res, '\n');
13120 if (pos)
13121 *pos = '\0';
13122 fclose(f);
13123 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
13124 res);
13125 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
13126 if (system(resp) != 0) {
13127 }
13128 snprintf(resp, sizeof(resp),
13129 "SSID,,BSSID,,failureReason,%s", res);
13130 send_resp(dut, conn, SIGMA_COMPLETE, resp);
13131 return 0;
13132 }
13133
13134 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13135 return 0;
13136 }
13137
13138 if (!prod_ess_assoc)
13139 goto report;
13140
13141 ctrl = open_wpa_mon(intf);
13142 if (ctrl == NULL) {
13143 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13144 "wpa_supplicant monitor connection");
13145 return -1;
13146 }
13147
13148 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
13149 buf, sizeof(buf));
13150
13151 wpa_ctrl_detach(ctrl);
13152 wpa_ctrl_close(ctrl);
13153
13154 if (res < 0) {
13155 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
13156 "network after OSU");
13157 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13158 return 0;
13159 }
13160
13161report:
13162 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
13163 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
13164 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
13165 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
13166 return 0;
13167 }
13168
13169 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
13170 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013171 return 0;
13172}
13173
13174
Jouni Malinenf7222712019-06-13 01:50:21 +030013175static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
13176 struct sigma_conn *conn,
13177 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013178{
13179 const char *val;
13180 int timeout = 120;
13181
13182 val = get_param(cmd, "PolicyUpdate");
13183 if (val == NULL || atoi(val) == 0)
13184 return 1; /* No operation requested */
13185
13186 val = get_param(cmd, "Timeout");
13187 if (val)
13188 timeout = atoi(val);
13189
13190 if (timeout) {
13191 /* TODO: time out the command and return
13192 * PolicyUpdateStatus,TIMEOUT if needed. */
13193 }
13194
13195 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
13196 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
13197 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
13198 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
13199 return 0;
13200 }
13201
13202 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
13203 return 0;
13204}
13205
13206
Jouni Malinenf7222712019-06-13 01:50:21 +030013207static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
13208 struct sigma_conn *conn,
13209 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013210{
13211 struct wpa_ctrl *ctrl;
13212 const char *intf = get_param(cmd, "Interface");
13213 const char *bssid = get_param(cmd, "Bssid");
13214 const char *ssid = get_param(cmd, "SSID");
13215 const char *security = get_param(cmd, "Security");
13216 const char *passphrase = get_param(cmd, "Passphrase");
13217 const char *pin = get_param(cmd, "PIN");
13218 char buf[1000];
13219 char ssid_hex[200], passphrase_hex[200];
13220 const char *keymgmt, *cipher;
13221
13222 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013223 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013224
13225 if (!bssid) {
13226 send_resp(dut, conn, SIGMA_ERROR,
13227 "ErrorCode,Missing Bssid argument");
13228 return 0;
13229 }
13230
13231 if (!ssid) {
13232 send_resp(dut, conn, SIGMA_ERROR,
13233 "ErrorCode,Missing SSID argument");
13234 return 0;
13235 }
13236
13237 if (!security) {
13238 send_resp(dut, conn, SIGMA_ERROR,
13239 "ErrorCode,Missing Security argument");
13240 return 0;
13241 }
13242
13243 if (!passphrase) {
13244 send_resp(dut, conn, SIGMA_ERROR,
13245 "ErrorCode,Missing Passphrase argument");
13246 return 0;
13247 }
13248
13249 if (!pin) {
13250 send_resp(dut, conn, SIGMA_ERROR,
13251 "ErrorCode,Missing PIN argument");
13252 return 0;
13253 }
13254
vamsi krishna8c9c1562017-05-12 15:51:46 +053013255 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
13256 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013257 send_resp(dut, conn, SIGMA_ERROR,
13258 "ErrorCode,Too long SSID/passphrase");
13259 return 0;
13260 }
13261
13262 ctrl = open_wpa_mon(intf);
13263 if (ctrl == NULL) {
13264 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13265 "wpa_supplicant monitor connection");
13266 return -2;
13267 }
13268
13269 if (strcasecmp(security, "wpa2-psk") == 0) {
13270 keymgmt = "WPA2PSK";
13271 cipher = "CCMP";
13272 } else {
13273 wpa_ctrl_detach(ctrl);
13274 wpa_ctrl_close(ctrl);
13275 send_resp(dut, conn, SIGMA_ERROR,
13276 "ErrorCode,Unsupported Security value");
13277 return 0;
13278 }
13279
13280 ascii2hexstr(ssid, ssid_hex);
13281 ascii2hexstr(passphrase, passphrase_hex);
13282 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
13283 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
13284
13285 if (wpa_command(intf, buf) < 0) {
13286 wpa_ctrl_detach(ctrl);
13287 wpa_ctrl_close(ctrl);
13288 send_resp(dut, conn, SIGMA_ERROR,
13289 "ErrorCode,Failed to start registrar");
13290 return 0;
13291 }
13292
13293 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
13294 dut->er_oper_performed = 1;
13295
13296 return wps_connection_event(dut, conn, ctrl, intf, 0);
13297}
13298
13299
Jouni Malinenf7222712019-06-13 01:50:21 +030013300static enum sigma_cmd_result
13301cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
13302 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013303{
13304 struct wpa_ctrl *ctrl;
13305 const char *intf = get_param(cmd, "Interface");
13306 const char *bssid = get_param(cmd, "Bssid");
13307 char buf[100];
13308
13309 if (!bssid) {
13310 send_resp(dut, conn, SIGMA_ERROR,
13311 "ErrorCode,Missing Bssid argument");
13312 return 0;
13313 }
13314
13315 ctrl = open_wpa_mon(intf);
13316 if (ctrl == NULL) {
13317 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
13318 "wpa_supplicant monitor connection");
13319 return -2;
13320 }
13321
13322 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
13323
13324 if (wpa_command(intf, buf) < 0) {
13325 wpa_ctrl_detach(ctrl);
13326 wpa_ctrl_close(ctrl);
13327 send_resp(dut, conn, SIGMA_ERROR,
13328 "ErrorCode,Failed to start registrar");
13329 return 0;
13330 }
13331
13332 return wps_connection_event(dut, conn, ctrl, intf, 0);
13333}
13334
13335
Jouni Malinenf7222712019-06-13 01:50:21 +030013336static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
13337 struct sigma_conn *conn,
13338 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053013339{
13340 struct wpa_ctrl *ctrl;
13341 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013342 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013343 const char *config_method = get_param(cmd, "WPSConfigMethod");
13344 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053013345 int res;
13346 char buf[256];
13347 const char *events[] = {
13348 "CTRL-EVENT-CONNECTED",
13349 "WPS-OVERLAP-DETECTED",
13350 "WPS-TIMEOUT",
13351 "WPS-FAIL",
13352 NULL
13353 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013354 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053013355
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013356 /* 60G WPS tests do not pass Interface parameter */
13357 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013358 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013359
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013360 if (dut->mode == SIGMA_MODE_AP)
13361 return ap_wps_registration(dut, conn, cmd);
13362
13363 if (config_method) {
13364 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
13365 * sta_wps_enter_pin before calling start_wps_registration. */
13366 if (strcasecmp(config_method, "PBC") == 0)
13367 dut->wps_method = WFA_CS_WPS_PBC;
13368 }
13369 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
13370 send_resp(dut, conn, SIGMA_ERROR,
13371 "ErrorCode,WPS parameters not yet set");
13372 return STATUS_SENT;
13373 }
13374
13375 /* Make sure WPS is enabled (also for STA mode) */
13376 dut->wps_disable = 0;
13377
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013378 if (dut->band == WPS_BAND_60G && network_mode &&
13379 strcasecmp(network_mode, "PBSS") == 0) {
13380 sigma_dut_print(dut, DUT_MSG_DEBUG,
13381 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013382 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020013383 return -2;
13384 }
13385
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013386 if (dut->force_rsn_ie) {
13387 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
13388 dut->force_rsn_ie);
13389 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
13390 sigma_dut_print(dut, DUT_MSG_INFO,
13391 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020013392 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020013393 }
13394 }
13395
vamsi krishna9b144002017-09-20 13:28:13 +053013396 ctrl = open_wpa_mon(intf);
13397 if (!ctrl) {
13398 sigma_dut_print(dut, DUT_MSG_ERROR,
13399 "Failed to open wpa_supplicant monitor connection");
13400 return -2;
13401 }
13402
13403 role = get_param(cmd, "WpsRole");
13404 if (!role) {
13405 send_resp(dut, conn, SIGMA_INVALID,
13406 "ErrorCode,WpsRole not provided");
13407 goto fail;
13408 }
13409
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013410 if (strcasecmp(role, "Enrollee") != 0) {
13411 /* Registrar role for STA not supported */
13412 send_resp(dut, conn, SIGMA_ERROR,
13413 "ErrorCode,Unsupported WpsRole value");
13414 goto fail;
13415 }
13416
13417 if (is_60g_sigma_dut(dut)) {
13418 if (dut->wps_method == WFA_CS_WPS_PBC)
13419 snprintf(buf, sizeof(buf), "WPS_PBC");
13420 else /* WFA_CS_WPS_PIN_KEYPAD */
13421 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
13422 dut->wps_pin);
13423 if (wpa_command(intf, buf) < 0) {
13424 send_resp(dut, conn, SIGMA_ERROR,
13425 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053013426 goto fail;
13427 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020013428 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13429 if (res < 0) {
13430 send_resp(dut, conn, SIGMA_ERROR,
13431 "ErrorCode,WPS connection did not complete");
13432 goto fail;
13433 }
13434 if (strstr(buf, "WPS-TIMEOUT")) {
13435 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
13436 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13437 send_resp(dut, conn, SIGMA_COMPLETE,
13438 "WpsState,OverlapSession");
13439 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13440 send_resp(dut, conn, SIGMA_COMPLETE,
13441 "WpsState,Successful");
13442 } else {
13443 send_resp(dut, conn, SIGMA_COMPLETE,
13444 "WpsState,Failure");
13445 }
13446 } else {
13447 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053013448 if (wpa_command(intf, "WPS_PBC") < 0) {
13449 send_resp(dut, conn, SIGMA_ERROR,
13450 "ErrorCode,Failed to enable PBC");
13451 goto fail;
13452 }
13453 } else {
13454 /* TODO: PIN method */
13455 send_resp(dut, conn, SIGMA_ERROR,
13456 "ErrorCode,Unsupported WpsConfigMethod value");
13457 goto fail;
13458 }
13459 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
13460 if (res < 0) {
13461 send_resp(dut, conn, SIGMA_ERROR,
13462 "ErrorCode,WPS connection did not complete");
13463 goto fail;
13464 }
13465 if (strstr(buf, "WPS-TIMEOUT")) {
13466 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
13467 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
13468 send_resp(dut, conn, SIGMA_ERROR,
13469 "ErrorCode,OverlapSession");
13470 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
13471 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
13472 } else {
13473 send_resp(dut, conn, SIGMA_ERROR,
13474 "ErrorCode,WPS operation failed");
13475 }
vamsi krishna9b144002017-09-20 13:28:13 +053013476 }
13477
13478fail:
13479 wpa_ctrl_detach(ctrl);
13480 wpa_ctrl_close(ctrl);
13481 return 0;
13482}
13483
13484
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013485static int req_intf(struct sigma_cmd *cmd)
13486{
13487 return get_param(cmd, "interface") == NULL ? -1 : 0;
13488}
13489
13490
13491void sta_register_cmds(void)
13492{
13493 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
13494 cmd_sta_get_ip_config);
13495 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
13496 cmd_sta_set_ip_config);
13497 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
13498 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
13499 cmd_sta_get_mac_address);
13500 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
13501 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
13502 cmd_sta_verify_ip_connection);
13503 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
13504 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
13505 cmd_sta_set_encryption);
13506 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
13507 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
13508 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
13509 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
13510 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
13511 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
13512 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
13513 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
13514 cmd_sta_set_eapakaprime);
13515 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
13516 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
13517 /* TODO: sta_set_ibss */
13518 /* TODO: sta_set_mode */
13519 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
13520 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
13521 /* TODO: sta_up_load */
13522 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
13523 cmd_sta_preset_testparameters);
13524 /* TODO: sta_set_system */
13525 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
13526 /* TODO: sta_set_rifs_test */
13527 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
13528 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
13529 /* TODO: sta_send_coexist_mgmt */
13530 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
13531 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
13532 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
13533 sigma_dut_reg_cmd("sta_reset_default", req_intf,
13534 cmd_sta_reset_default);
13535 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
13536 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
13537 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
13538 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
13539 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020013540 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013541 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
13542 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
13543 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
13544 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
13545 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030013546 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
13547 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013548 sigma_dut_reg_cmd("sta_add_credential", req_intf,
13549 cmd_sta_add_credential);
13550 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020013551 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013552 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
13553 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
13554 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
13555 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
13556 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
13557 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030013558 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013559 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
13560 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020013561 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053013562 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013563}