blob: 6c20b85ce2bd5a6bc0c22752d9f76b77e42c86cf [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 Malinen2feb9132021-11-16 00:53:06 +02005 * Copyright (c) 2018-2021, 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"
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080037#include "nl80211_copy.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020038
39/* Temporary files for sta_send_addba */
40#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
41#define VI_QOS_FILE "/tmp/vi-qos.txt"
42#define VI_QOS_REFFILE "/etc/vi-qos.txt"
43
44/*
45 * MTU for Ethernet need to take into account 8-byte SNAP header
46 * to be added when encapsulating Ethernet frame into 802.11
47 */
48#ifndef IEEE80211_MAX_DATA_LEN_DMG
49#define IEEE80211_MAX_DATA_LEN_DMG 7920
50#endif
51#ifndef IEEE80211_SNAP_LEN_DMG
52#define IEEE80211_SNAP_LEN_DMG 8
53#endif
54
Ashwini Patil00402582017-04-13 12:29:39 +053055#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053056#define NEIGHBOR_REPORT_SIZE 1000
57#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
58#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053059
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030060#define WIL_DEFAULT_BI 100
61
62/* default remain on channel time for transmitting frames (milliseconds) */
63#define WIL_TRANSMIT_FRAME_DEFAULT_ROC 500
64#define IEEE80211_P2P_ATTR_DEVICE_ID 3
65#define IEEE80211_P2P_ATTR_GROUP_ID 15
66
67/* describes tagged bytes in template frame file */
68struct template_frame_tag {
69 int num;
70 int offset;
71 size_t len;
72};
73
Jouni Malinencd4e3c32015-10-29 12:39:56 +020074extern char *sigma_wpas_ctrl;
75extern char *sigma_cert_path;
76extern enum driver_type wifi_chip_type;
77extern char *sigma_radio_ifname[];
78
Lior David0fe101e2017-03-09 16:09:50 +020079#ifdef __linux__
80#define WIL_WMI_MAX_PAYLOAD 248
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020081#define WIL_WMI_ESE_CFG_CMDID 0xa01
Lior David0fe101e2017-03-09 16:09:50 +020082#define WIL_WMI_BF_TRIG_CMDID 0x83a
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020083#define WIL_WMI_UNIT_TEST_CMDID 0x900
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030084#define WIL_WMI_P2P_CFG_CMDID 0x910
85#define WIL_WMI_START_LISTEN_CMDID 0x914
86#define WIL_WMI_DISCOVERY_STOP_CMDID 0x917
Lior David0fe101e2017-03-09 16:09:50 +020087
88struct wil_wmi_header {
89 uint8_t mid;
90 uint8_t reserved;
91 uint16_t cmd;
92 uint32_t ts;
93} __attribute__((packed));
94
95enum wil_wmi_bf_trig_type {
96 WIL_WMI_SLS,
97 WIL_WMI_BRP_RX,
98 WIL_WMI_BRP_TX,
99};
100
101struct wil_wmi_bf_trig_cmd {
102 /* enum wil_wmi_bf_trig_type */
103 uint32_t bf_type;
104 /* cid when type == WMI_BRP_RX */
105 uint32_t sta_id;
106 uint32_t reserved;
107 /* mac address when type = WIL_WMI_SLS */
108 uint8_t dest_mac[6];
109} __attribute__((packed));
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200110
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200111enum wil_wmi_sched_scheme_advertisment {
112 WIL_WMI_ADVERTISE_ESE_DISABLED,
113 WIL_WMI_ADVERTISE_ESE_IN_BEACON,
114 WIL_WMI_ADVERTISE_ESE_IN_ANNOUNCE_FRAME,
115};
116
117enum wil_wmi_ese_slot_type {
118 WIL_WMI_ESE_SP,
119 WIL_WMI_ESE_CBAP,
120 WIL_WMI_ESE_ANNOUNCE_NO_ACK,
121};
122
123struct wil_wmi_ese_slot {
124 /* offset from start of BI in microseconds */
125 uint32_t tbtt_offset;
126 uint8_t flags;
127 /* enum wil_wmi_ese_slot_type */
128 uint8_t slot_type;
129 /* duration in microseconds */
130 uint16_t duration;
131 /* frame exchange sequence duration, microseconds */
132 uint16_t tx_op;
133 /* time between 2 blocks for periodic allocation(microseconds) */
134 uint16_t period;
135 /* number of blocks in periodic allocation */
136 uint8_t num_blocks;
137 /* for semi-active allocations */
138 uint8_t idle_period;
139 uint8_t src_aid;
140 uint8_t dst_aid;
141 uint32_t reserved;
142} __attribute__((packed));
143
144#define WIL_WMI_MAX_ESE_SLOTS 4
145struct wil_wmi_ese_cfg {
146 uint8_t serial_num;
147 /* wil_wmi_sched_scheme_advertisment */
148 uint8_t ese_advertisment;
149 uint16_t flags;
150 uint8_t num_allocs;
151 uint8_t reserved[3];
152 uint64_t start_tbtt;
153 /* allocations list */
154 struct wil_wmi_ese_slot slots[WIL_WMI_MAX_ESE_SLOTS];
155} __attribute__((packed));
156
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200157#define WIL_WMI_UT_FORCE_MCS 6
158struct wil_wmi_force_mcs {
159 /* WIL_WMI_UT_HW_SYSAPI */
160 uint16_t module_id;
161 /* WIL_WMI_UT_FORCE_MCS */
162 uint16_t subtype_id;
163 /* cid (ignored in oob_mode, affects all stations) */
164 uint32_t cid;
165 /* 1 to force MCS, 0 to restore default behavior */
166 uint32_t force_enable;
167 /* MCS index, 0-12 */
168 uint32_t mcs;
169} __attribute__((packed));
170
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200171#define WIL_WMI_UT_HW_SYSAPI 10
172#define WIL_WMI_UT_FORCE_RSN_IE 0x29
173struct wil_wmi_force_rsn_ie {
174 /* WIL_WMI_UT_HW_SYSAPI */
175 uint16_t module_id;
176 /* WIL_WMI_UT_FORCE_RSN_IE */
177 uint16_t subtype_id;
178 /* 0 = no change, 1 = remove if exists, 2 = add if does not exist */
179 uint32_t state;
180} __attribute__((packed));
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300181
182enum wil_wmi_discovery_mode {
183 WMI_DISCOVERY_MODE_NON_OFFLOAD,
184 WMI_DISCOVERY_MODE_OFFLOAD,
185 WMI_DISCOVERY_MODE_PEER2PEER,
186};
187
188struct wil_wmi_p2p_cfg_cmd {
189 /* enum wil_wmi_discovery_mode */
190 uint8_t discovery_mode;
191 /* 0-based (wireless channel - 1) */
192 uint8_t channel;
193 /* set to WIL_DEFAULT_BI */
194 uint16_t bcon_interval;
195} __attribute__((packed));
Lior David0fe101e2017-03-09 16:09:50 +0200196#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200197
198#ifdef ANDROID
199
200static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
201
202#define ANDROID_KEYSTORE_GET 'g'
203#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
204
205static int android_keystore_get(char cmd, const char *key, unsigned char *val)
206{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200207 /* Android 4.3 changed keystore design, so need to use keystore_get() */
208#ifndef KEYSTORE_MESSAGE_SIZE
209#define KEYSTORE_MESSAGE_SIZE 65535
210#endif /* KEYSTORE_MESSAGE_SIZE */
211
212 ssize_t len;
213 uint8_t *value = NULL;
214
215 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
216 "keystore command '%c' key '%s' --> keystore_get",
217 cmd, key);
218
219 len = keystore_get(key, strlen(key), &value);
220 if (len < 0) {
221 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
222 "keystore_get() failed");
223 return -1;
224 }
225
226 if (len > KEYSTORE_MESSAGE_SIZE)
227 len = KEYSTORE_MESSAGE_SIZE;
228 memcpy(val, value, len);
229 free(value);
230 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200231}
232#endif /* ANDROID */
233
234
Vinita S. Maloo0fcb57d2020-04-24 14:03:56 +0530235#ifdef NL80211_SUPPORT
236static int nl80211_sta_set_power_save(struct sigma_dut *dut,
237 const char *intf,
238 enum nl80211_ps_state ps_state)
239{
240 struct nl_msg *msg;
241 int ifindex, ret;
242
243 ifindex = if_nametoindex(intf);
244 if (ifindex == 0) {
245 sigma_dut_print(dut, DUT_MSG_ERROR,
246 "%s: Index for interface %s not found",
247 __func__, intf);
248 return -1;
249 }
250
251 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
252 NL80211_CMD_SET_POWER_SAVE);
253 if (!msg) {
254 sigma_dut_print(dut, DUT_MSG_ERROR,
255 "%s: err in creating nl80211 msg", __func__);
256 return -1;
257 }
258
259 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state)) {
260 sigma_dut_print(dut, DUT_MSG_ERROR,
261 "%s: err in populating nl80211 msg", __func__);
262 nlmsg_free(msg);
263 return -1;
264 }
265
266 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
267 if (ret) {
268 sigma_dut_print(dut, DUT_MSG_ERROR,
269 "%s: err in send_and_recv_msgs, ret=%d (%s)",
270 __func__, ret, strerror(-ret));
271 return -1;
272 }
273
274 return 0;
275}
276#endif /* NL80211_SUPPORT */
277
278
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530279static int set_power_save_wcn(struct sigma_dut *dut, const char *intf, int ps)
280{
281 char buf[100];
Vinita S. Maloo0fcb57d2020-04-24 14:03:56 +0530282#ifdef NL80211_SUPPORT
283 enum nl80211_ps_state ps_state;
284
285 ps_state = ps == 1 ? NL80211_PS_ENABLED : NL80211_PS_DISABLED;
286 if (nl80211_sta_set_power_save(dut, intf, ps_state) == 0)
287 return 0;
288#endif /* NL80211_SUPPORT */
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530289
290 snprintf(buf, sizeof(buf), "iwpriv %s setPower %d", intf, ps);
291 if (system(buf) != 0) {
292 sigma_dut_print(dut, DUT_MSG_ERROR,
293 "iwpriv setPower %d failed", ps);
294 return -1;
295 }
296 return 0;
297}
298
299
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200300int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
301{
302#ifdef __linux__
303 char buf[100];
304
305 if (wifi_chip_type == DRIVER_WCN) {
306 if (enabled) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530307 if (set_power_save_wcn(dut, intf, 1) < 0) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530308 snprintf(buf, sizeof(buf),
309 "iwpriv wlan0 dump 906");
310 if (system(buf) != 0)
311 goto set_power_save;
312 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200313 } else {
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530314 if (set_power_save_wcn(dut, intf, 2) < 0) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530315 snprintf(buf, sizeof(buf),
316 "iwpriv wlan0 dump 905");
317 if (system(buf) != 0)
318 goto set_power_save;
319 snprintf(buf, sizeof(buf),
320 "iwpriv wlan0 dump 912");
321 if (system(buf) != 0)
322 goto set_power_save;
323 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200324 }
325
326 return 0;
327 }
328
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530329set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200330 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
331 intf, enabled ? "on" : "off");
332 if (system(buf) != 0) {
333 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
334 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530335 if (system(buf) != 0) {
336 sigma_dut_print(dut, DUT_MSG_ERROR,
337 "Failed to set power save %s",
338 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200339 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530340 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200341 }
342
343 return 0;
344#else /* __linux__ */
345 return -1;
346#endif /* __linux__ */
347}
348
349
Lior Davidcc88b562017-01-03 18:52:09 +0200350#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200351
Lior Davidcc88b562017-01-03 18:52:09 +0200352static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
353 size_t len)
354{
355 DIR *dir, *wil_dir;
356 struct dirent *entry;
357 int ret = -1;
358 const char *root_path = "/sys/kernel/debug/ieee80211";
359
360 dir = opendir(root_path);
361 if (!dir)
362 return -2;
363
364 while ((entry = readdir(dir))) {
365 if (strcmp(entry->d_name, ".") == 0 ||
366 strcmp(entry->d_name, "..") == 0)
367 continue;
368
369 if (snprintf(path, len, "%s/%s/wil6210",
370 root_path, entry->d_name) >= (int) len) {
371 ret = -3;
372 break;
373 }
374
375 wil_dir = opendir(path);
376 if (wil_dir) {
377 closedir(wil_dir);
378 ret = 0;
379 break;
380 }
381 }
382
383 closedir(dir);
384 return ret;
385}
Lior David0fe101e2017-03-09 16:09:50 +0200386
387
388static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
389 void *payload, uint16_t length)
390{
391 struct {
392 struct wil_wmi_header hdr;
393 char payload[WIL_WMI_MAX_PAYLOAD];
394 } __attribute__((packed)) cmd;
395 char buf[128], fname[128];
396 size_t towrite, written;
397 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300398 int res;
Lior David0fe101e2017-03-09 16:09:50 +0200399
400 if (length > WIL_WMI_MAX_PAYLOAD) {
401 sigma_dut_print(dut, DUT_MSG_ERROR,
402 "payload too large(%u, max %u)",
403 length, WIL_WMI_MAX_PAYLOAD);
404 return -1;
405 }
406
407 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
408 cmd.hdr.cmd = command;
409 memcpy(cmd.payload, payload, length);
410
411 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
412 sigma_dut_print(dut, DUT_MSG_ERROR,
413 "failed to get wil6210 debugfs dir");
414 return -1;
415 }
416
Jouni Malinen3aa72862019-05-29 23:14:51 +0300417 res = snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
418 if (res < 0 || res >= sizeof(fname))
419 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200420 f = fopen(fname, "wb");
421 if (!f) {
422 sigma_dut_print(dut, DUT_MSG_ERROR,
423 "failed to open: %s", fname);
424 return -1;
425 }
426
427 towrite = sizeof(cmd.hdr) + length;
428 written = fwrite(&cmd, 1, towrite, f);
429 fclose(f);
430 if (written != towrite) {
431 sigma_dut_print(dut, DUT_MSG_ERROR,
432 "failed to send wmi %u", command);
433 return -1;
434 }
435
436 return 0;
437}
438
439
440static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
441 const char *pattern, unsigned int *field)
442{
443 char buf[128], fname[128];
444 FILE *f;
445 regex_t re;
446 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +0300447 int rc, ret = -1, res;
Lior David0fe101e2017-03-09 16:09:50 +0200448
449 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
450 sigma_dut_print(dut, DUT_MSG_ERROR,
451 "failed to get wil6210 debugfs dir");
452 return -1;
453 }
454
Jouni Malinen3aa72862019-05-29 23:14:51 +0300455 res = snprintf(fname, sizeof(fname), "%s/stations", buf);
456 if (res < 0 || res >= sizeof(fname))
457 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200458 f = fopen(fname, "r");
459 if (!f) {
460 sigma_dut_print(dut, DUT_MSG_ERROR,
461 "failed to open: %s", fname);
462 return -1;
463 }
464
465 if (regcomp(&re, pattern, REG_EXTENDED)) {
466 sigma_dut_print(dut, DUT_MSG_ERROR,
467 "regcomp failed: %s", pattern);
468 goto out;
469 }
470
471 /*
472 * find the entry for the mac address
473 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
474 */
475 while (fgets(buf, sizeof(buf), f)) {
476 if (strcasestr(buf, bssid)) {
477 /* extract the field (CID/AID/state) */
478 rc = regexec(&re, buf, 2, m, 0);
479 if (!rc && (m[1].rm_so >= 0)) {
480 buf[m[1].rm_eo] = 0;
481 *field = atoi(&buf[m[1].rm_so]);
482 ret = 0;
483 break;
484 }
485 }
486 }
487
488 regfree(&re);
489 if (ret)
490 sigma_dut_print(dut, DUT_MSG_ERROR,
491 "could not extract field");
492
493out:
494 fclose(f);
495
496 return ret;
497}
498
499
500static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
501 unsigned int *cid)
502{
503 const char *pattern = "\\[([0-9]+)\\]";
504
505 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
506}
507
508
509static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
510 int l_rx)
511{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700512 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200513 unsigned int cid;
514
Rakesh Sunki556237d2017-03-30 14:49:31 -0700515 memset(&cmd, 0, sizeof(cmd));
516
Lior David0fe101e2017-03-09 16:09:50 +0200517 if (wil6210_get_cid(dut, mac, &cid))
518 return -1;
519
520 cmd.bf_type = WIL_WMI_BRP_RX;
521 cmd.sta_id = cid;
522 /* training length (l_rx) is ignored, FW always uses length 16 */
523 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
524 &cmd, sizeof(cmd));
525}
526
527
528static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
529{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700530 struct wil_wmi_bf_trig_cmd cmd;
531
532 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200533
534 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
535 return -1;
536
537 cmd.bf_type = WIL_WMI_SLS;
538 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
539 &cmd, sizeof(cmd));
540}
541
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200542
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200543int wil6210_set_ese(struct sigma_dut *dut, int count,
544 struct sigma_ese_alloc *allocs)
545{
546 struct wil_wmi_ese_cfg cmd = { };
547 int i;
548
549 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
550 return -1;
551
552 if (dut->ap_bcnint <= 0) {
553 sigma_dut_print(dut, DUT_MSG_ERROR,
554 "invalid beacon interval(%d), check test",
555 dut->ap_bcnint);
556 return -1;
557 }
558
559 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
560 cmd.flags = 0x1d;
561 cmd.num_allocs = count;
562 for (i = 0; i < count; i++) {
563 /*
564 * Convert percent from BI (BI specified in milliseconds)
565 * to absolute duration in microseconds.
566 */
567 cmd.slots[i].duration =
568 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
569 switch (allocs[i].type) {
570 case ESE_CBAP:
571 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
572 break;
573 case ESE_SP:
574 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
575 break;
576 default:
577 sigma_dut_print(dut, DUT_MSG_ERROR,
578 "invalid slot type(%d) at index %d",
579 allocs[i].type, i);
580 return -1;
581 }
582 cmd.slots[i].src_aid = allocs[i].src_aid;
583 cmd.slots[i].dst_aid = allocs[i].dst_aid;
584 sigma_dut_print(dut, DUT_MSG_INFO,
585 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
586 i, cmd.slots[i].duration,
587 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
588 cmd.slots[i].dst_aid);
589 }
590
591 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
592}
593
594
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200595int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
596{
597 struct wil_wmi_force_mcs cmd = { };
598
599 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
600 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
601 cmd.force_enable = (uint32_t) force;
602 cmd.mcs = (uint32_t) mcs;
603
604 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
605 &cmd, sizeof(cmd));
606}
607
608
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200609static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
610{
611 struct wil_wmi_force_rsn_ie cmd = { };
612
613 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
614 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
615 cmd.state = (uint32_t) state;
616
617 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
618 &cmd, sizeof(cmd));
619}
620
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300621
622/*
623 * this function is also used to configure generic remain-on-channel
624 */
625static int wil6210_p2p_cfg(struct sigma_dut *dut, int freq)
626{
627 struct wil_wmi_p2p_cfg_cmd cmd = { };
628 int channel = freq_to_channel(freq);
629
630 if (channel < 0)
631 return -1;
632 cmd.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD;
633 cmd.channel = channel - 1;
634 cmd.bcon_interval = WIL_DEFAULT_BI;
635 cmd.discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER;
636
637 return wil6210_wmi_send(dut, WIL_WMI_P2P_CFG_CMDID,
638 &cmd, sizeof(cmd));
639}
640
641
642static int wil6210_remain_on_channel(struct sigma_dut *dut, int freq)
643{
644 int ret = wil6210_p2p_cfg(dut, freq);
645
646 if (ret)
647 return ret;
648
649 ret = wil6210_wmi_send(dut, WIL_WMI_START_LISTEN_CMDID, NULL, 0);
650 if (!ret) {
651 /*
652 * wait a bit to allow FW to setup the radio
653 * especially important if we switch channels
654 */
655 usleep(500000);
656 }
657
658 return ret;
659}
660
661
662static int wil6210_stop_discovery(struct sigma_dut *dut)
663{
664 return wil6210_wmi_send(dut, WIL_WMI_DISCOVERY_STOP_CMDID, NULL, 0);
665}
666
667
668static int wil6210_transmit_frame(struct sigma_dut *dut, int freq,
669 int wait_duration,
670 const char *frame, size_t frame_len)
671{
672 char buf[128], fname[128];
673 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300674 int res = 0, r;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300675 size_t written;
676
677 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
678 sigma_dut_print(dut, DUT_MSG_ERROR,
679 "failed to get wil6210 debugfs dir");
680 return -1;
681 }
Jouni Malinen3aa72862019-05-29 23:14:51 +0300682 r = snprintf(fname, sizeof(fname), "%s/tx_mgmt", buf);
683 if (r < 0 || r >= sizeof(fname))
684 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300685
686 if (wil6210_remain_on_channel(dut, freq)) {
687 sigma_dut_print(dut, DUT_MSG_ERROR,
688 "failed to listen on channel");
689 return -1;
690 }
691
692 f = fopen(fname, "wb");
693 if (!f) {
694 sigma_dut_print(dut, DUT_MSG_ERROR,
695 "failed to open: %s", fname);
696 res = -1;
697 goto out_stop;
698 }
699 written = fwrite(frame, 1, frame_len, f);
700 fclose(f);
701
702 if (written != frame_len) {
703 sigma_dut_print(dut, DUT_MSG_ERROR,
704 "failed to transmit frame (got %zd, expected %zd)",
705 written, frame_len);
706 res = -1;
707 goto out_stop;
708 }
709
710 usleep(wait_duration * 1000);
711
712out_stop:
713 wil6210_stop_discovery(dut);
714 return res;
715}
716
717
718static int find_template_frame_tag(struct template_frame_tag *tags,
719 int total_tags, int tag_num)
720{
721 int i;
722
723 for (i = 0; i < total_tags; i++) {
724 if (tag_num == tags[i].num)
725 return i;
726 }
727
728 return -1;
729}
730
731
732static int replace_p2p_attribute(struct sigma_dut *dut, char *buf, size_t len,
733 int id, const char *value, size_t val_len)
734{
735 struct wfa_p2p_attribute *attr = (struct wfa_p2p_attribute *) buf;
736
737 if (len < 3 + val_len) {
738 sigma_dut_print(dut, DUT_MSG_ERROR,
739 "not enough space to replace P2P attribute");
740 return -1;
741 }
742
743 if (attr->len != val_len) {
744 sigma_dut_print(dut, DUT_MSG_ERROR,
745 "attribute length mismatch (need %zu have %hu)",
746 val_len, attr->len);
747 return -1;
748 }
749
750 if (attr->id != id) {
751 sigma_dut_print(dut, DUT_MSG_ERROR,
752 "incorrect attribute id (expected %d actual %d)",
753 id, attr->id);
754 return -1;
755 }
756
757 memcpy(attr->variable, value, val_len);
758
759 return 0;
760}
761
762
763static int parse_template_frame_file(struct sigma_dut *dut, const char *fname,
764 char *buf, size_t *length,
765 struct template_frame_tag *tags,
766 size_t *num_tags)
767{
768 char line[512];
769 FILE *f;
770 size_t offset = 0, tag_index = 0;
771 int num, index;
772 int in_tag = 0, tag_num = 0, tag_offset = 0;
773
774 if (*length < sizeof(struct ieee80211_hdr_3addr)) {
775 sigma_dut_print(dut, DUT_MSG_ERROR,
776 "supplied buffer is too small");
777 return -1;
778 }
779
780 f = fopen(fname, "r");
781 if (!f) {
782 sigma_dut_print(dut, DUT_MSG_ERROR,
783 "failed to open template file %s", fname);
784 return -1;
785 }
786
787 /*
788 * template file format: lines beginning with # are comments and
789 * ignored.
790 * It is possible to tag bytes in the frame to make it easy
791 * to replace fields in the template, espcially if they appear
792 * in variable-sized sections (such as IEs)
793 * This is done by a line beginning with $NUM where NUM is an integer
794 * tag number. It can be followed by space(s) and comment.
795 * The next line is considered the tagged bytes. The parser will fill
796 * the tag number, offset and length of the tagged bytes.
797 * rest of the lines contain frame bytes as sequence of hex digits,
798 * 2 digits for each byte. Spaces are allowed between bytes.
799 * On bytes lines only hex digits and spaces are allowed
800 */
801 while (!feof(f)) {
802 if (!fgets(line, sizeof(line), f))
803 break;
804 index = 0;
805 while (isspace((unsigned char) line[index]))
806 index++;
807 if (!line[index] || line[index] == '#')
808 continue;
809 if (line[index] == '$') {
810 if (tags) {
811 index++;
812 tag_num = strtol(&line[index], NULL, 0);
813 tag_offset = offset;
814 in_tag = 1;
815 }
816 continue;
817 }
818 while (line[index]) {
819 if (isspace((unsigned char) line[index])) {
820 index++;
821 continue;
822 }
823 num = hex_byte(&line[index]);
824 if (num < 0)
825 break;
826 buf[offset++] = num;
827 if (offset == *length)
828 goto out;
829 index += 2;
830 }
831
832 if (in_tag) {
833 if (tag_index < *num_tags) {
834 tags[tag_index].num = tag_num;
835 tags[tag_index].offset = tag_offset;
836 tags[tag_index].len = offset - tag_offset;
837 tag_index++;
838 } else {
839 sigma_dut_print(dut, DUT_MSG_INFO,
840 "too many tags, tag ignored");
841 }
842 in_tag = 0;
843 }
844 }
845
846 if (num_tags)
847 *num_tags = tag_index;
848out:
849 fclose(f);
850 if (offset < sizeof(struct ieee80211_hdr_3addr)) {
851 sigma_dut_print(dut, DUT_MSG_ERROR,
852 "template frame is too small");
853 return -1;
854 }
855
856 *length = offset;
857 return 0;
858}
859
Lior Davidcc88b562017-01-03 18:52:09 +0200860#endif /* __linux__ */
861
862
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200863static void static_ip_file(int proto, const char *addr, const char *mask,
864 const char *gw)
865{
866 if (proto) {
867 FILE *f = fopen("static-ip", "w");
868 if (f) {
869 fprintf(f, "%d %s %s %s\n", proto, addr,
870 mask ? mask : "N/A",
871 gw ? gw : "N/A");
872 fclose(f);
873 }
874 } else {
875 unlink("static-ip");
876 }
877}
878
879
880static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
881 const char *ssid)
882{
883#ifdef __linux__
884 char buf[100];
885
886 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
887 intf, ssid);
888 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
889
890 if (system(buf) != 0) {
891 sigma_dut_print(dut, DUT_MSG_ERROR,
892 "iwpriv neighbor request failed");
893 return -1;
894 }
895
896 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
897
898 return 0;
899#else /* __linux__ */
900 return -1;
901#endif /* __linux__ */
902}
903
904
905static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530906 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200907{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530908 const char *val;
909 int reason_code = 0;
910 char buf[1024];
911
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200912 /*
913 * In the earlier builds we used WNM_QUERY and in later
914 * builds used WNM_BSS_QUERY.
915 */
916
Ashwini Patil5acd7382017-04-13 15:55:04 +0530917 val = get_param(cmd, "BTMQuery_Reason_Code");
918 if (val)
919 reason_code = atoi(val);
920
921 val = get_param(cmd, "Cand_List");
922 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
923 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
924 dut->btm_query_cand_list);
925 free(dut->btm_query_cand_list);
926 dut->btm_query_cand_list = NULL;
927 } else {
928 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
929 }
930
931 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200932 sigma_dut_print(dut, DUT_MSG_ERROR,
933 "transition management query failed");
934 return -1;
935 }
936
937 sigma_dut_print(dut, DUT_MSG_DEBUG,
938 "transition management query sent");
939
940 return 0;
941}
942
943
944int is_ip_addr(const char *str)
945{
946 const char *pos = str;
947 struct in_addr addr;
948
949 while (*pos) {
950 if (*pos != '.' && (*pos < '0' || *pos > '9'))
951 return 0;
952 pos++;
953 }
954
955 return inet_aton(str, &addr);
956}
957
958
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200959int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
960 size_t buf_len)
961{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530962 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200963 char ip[16], mask[15], dns[16], sec_dns[16];
964 int is_dhcp = 0;
965 int s;
966#ifdef ANDROID
967 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530968#else /* ANDROID */
969 FILE *f;
970#ifdef __linux__
971 const char *str_ps;
972#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200973#endif /* ANDROID */
974
975 ip[0] = '\0';
976 mask[0] = '\0';
977 dns[0] = '\0';
978 sec_dns[0] = '\0';
979
980 s = socket(PF_INET, SOCK_DGRAM, 0);
981 if (s >= 0) {
982 struct ifreq ifr;
983 struct sockaddr_in saddr;
984
985 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700986 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200987 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
988 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
989 "%s IP address: %s",
990 ifname, strerror(errno));
991 } else {
992 memcpy(&saddr, &ifr.ifr_addr,
993 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700994 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200995 }
996
997 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
998 memcpy(&saddr, &ifr.ifr_addr,
999 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -07001000 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001001 }
1002 close(s);
1003 }
1004
1005#ifdef ANDROID
1006 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
1007 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
1008 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
1009 if (property_get(tmp, prop, NULL) != 0 &&
1010 strcmp(prop, "ok") == 0) {
1011 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
1012 ifname);
1013 if (property_get(tmp, prop, NULL) != 0 &&
1014 strcmp(ip, prop) == 0)
1015 is_dhcp = 1;
1016 }
1017 }
1018
1019 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -07001020 if (property_get(tmp, prop, NULL) != 0)
1021 strlcpy(dns, prop, sizeof(dns));
1022 else if (property_get("net.dns1", prop, NULL) != 0)
1023 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001024
1025 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -07001026 if (property_get(tmp, prop, NULL) != 0)
1027 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001028#else /* ANDROID */
1029#ifdef __linux__
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001030 if (get_driver_type(dut) == DRIVER_OPENWRT)
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301031 str_ps = "ps -w";
1032 else
1033 str_ps = "ps ax";
1034 snprintf(tmp, sizeof(tmp),
1035 "%s | grep dhclient | grep -v grep | grep -q %s",
1036 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001037 if (system(tmp) == 0)
1038 is_dhcp = 1;
1039 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301040 snprintf(tmp, sizeof(tmp),
1041 "%s | grep udhcpc | grep -v grep | grep -q %s",
1042 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001043 if (system(tmp) == 0)
1044 is_dhcp = 1;
1045 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301046 snprintf(tmp, sizeof(tmp),
1047 "%s | grep dhcpcd | grep -v grep | grep -q %s",
1048 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001049 if (system(tmp) == 0)
1050 is_dhcp = 1;
1051 }
1052 }
1053#endif /* __linux__ */
1054
1055 f = fopen("/etc/resolv.conf", "r");
1056 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +05301057 char *pos, *pos2;
1058
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001059 while (fgets(tmp, sizeof(tmp), f)) {
1060 if (strncmp(tmp, "nameserver", 10) != 0)
1061 continue;
1062 pos = tmp + 10;
1063 while (*pos == ' ' || *pos == '\t')
1064 pos++;
1065 pos2 = pos;
1066 while (*pos2) {
1067 if (*pos2 == '\n' || *pos2 == '\r') {
1068 *pos2 = '\0';
1069 break;
1070 }
1071 pos2++;
1072 }
Peng Xub8fc5cc2017-05-10 17:27:28 -07001073 if (!dns[0])
1074 strlcpy(dns, pos, sizeof(dns));
1075 else if (!sec_dns[0])
1076 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001077 }
1078 fclose(f);
1079 }
1080#endif /* ANDROID */
1081
1082 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
1083 is_dhcp, ip, mask, dns);
1084 buf[buf_len - 1] = '\0';
1085
1086 return 0;
1087}
1088
1089
1090
1091
1092int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
1093 size_t buf_len)
1094{
1095#ifdef __linux__
1096#ifdef ANDROID
1097 char cmd[200], result[1000], *pos, *end;
1098 FILE *f;
1099 size_t len;
1100
1101 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
1102 f = popen(cmd, "r");
1103 if (f == NULL)
1104 return -1;
1105 len = fread(result, 1, sizeof(result) - 1, f);
1106 pclose(f);
1107 if (len == 0)
1108 return -1;
1109 result[len] = '\0';
1110 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
1111
1112 pos = strstr(result, "inet6 ");
1113 if (pos == NULL)
1114 return -1;
1115 pos += 6;
1116 end = strchr(pos, ' ');
1117 if (end)
1118 *end = '\0';
1119 end = strchr(pos, '/');
1120 if (end)
1121 *end = '\0';
1122 snprintf(buf, buf_len, "ip,%s", pos);
1123 buf[buf_len - 1] = '\0';
1124 return 0;
1125#else /* ANDROID */
1126 struct ifaddrs *ifaddr, *ifa;
1127 int res, found = 0;
1128 char host[NI_MAXHOST];
1129
1130 if (getifaddrs(&ifaddr) < 0) {
1131 perror("getifaddrs");
1132 return -1;
1133 }
1134
1135 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1136 if (strcasecmp(ifname, ifa->ifa_name) != 0)
1137 continue;
1138 if (ifa->ifa_addr == NULL ||
1139 ifa->ifa_addr->sa_family != AF_INET6)
1140 continue;
1141
1142 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
1143 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1144 if (res != 0) {
1145 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
1146 gai_strerror(res));
1147 continue;
1148 }
1149 if (strncmp(host, "fe80::", 6) == 0)
1150 continue; /* skip link-local */
1151
1152 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
1153 found = 1;
1154 break;
1155 }
1156
1157 freeifaddrs(ifaddr);
1158
1159 if (found) {
1160 char *pos;
1161 pos = strchr(host, '%');
1162 if (pos)
1163 *pos = '\0';
1164 snprintf(buf, buf_len, "ip,%s", host);
1165 buf[buf_len - 1] = '\0';
1166 return 0;
1167 }
1168
1169#endif /* ANDROID */
1170#endif /* __linux__ */
1171 return -1;
1172}
1173
1174
Jouni Malinenf7222712019-06-13 01:50:21 +03001175static enum sigma_cmd_result cmd_sta_get_ip_config(struct sigma_dut *dut,
1176 struct sigma_conn *conn,
1177 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001178{
1179 const char *intf = get_param(cmd, "Interface");
1180 const char *ifname;
1181 char buf[200];
1182 const char *val;
1183 int type = 1;
1184
1185 if (intf == NULL)
1186 return -1;
1187
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001188 if (strcmp(intf, get_main_ifname(dut)) == 0)
1189 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001190 else
1191 ifname = intf;
1192
1193 /*
1194 * UCC may assume the IP address to be available immediately after
1195 * association without trying to run sta_get_ip_config multiple times.
1196 * Sigma CAPI does not specify this command as a block command that
1197 * would wait for the address to become available, but to pass tests
1198 * more reliably, it looks like such a wait may be needed here.
1199 */
1200 if (wait_ip_addr(dut, ifname, 15) < 0) {
1201 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
1202 "for sta_get_ip_config");
1203 /*
1204 * Try to continue anyway since many UCC tests do not really
1205 * care about the return value from here..
1206 */
1207 }
1208
1209 val = get_param(cmd, "Type");
1210 if (val)
1211 type = atoi(val);
1212 if (type == 2 || dut->last_set_ip_config_ipv6) {
1213 int i;
1214
1215 /*
1216 * Since we do not have proper wait for IPv6 addresses, use a
1217 * fixed two second delay here as a workaround for UCC script
1218 * assuming IPv6 address is available when this command returns.
1219 * Some scripts did not use Type,2 properly for IPv6, so include
1220 * also the cases where the previous sta_set_ip_config indicated
1221 * use of IPv6.
1222 */
1223 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
1224 for (i = 0; i < 10; i++) {
1225 sleep(1);
1226 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
1227 {
1228 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
1229 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1230#ifdef ANDROID
1231 sigma_dut_print(dut, DUT_MSG_INFO,
1232 "Adding IPv6 rule on Android");
1233 add_ipv6_rule(dut, intf);
1234#endif /* ANDROID */
1235
1236 return 0;
1237 }
1238 }
1239 }
1240 if (type == 1) {
1241 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
1242 return -2;
1243 } else if (type == 2) {
1244 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
1245 return -2;
1246 } else {
1247 send_resp(dut, conn, SIGMA_ERROR,
1248 "errorCode,Unsupported address type");
1249 return 0;
1250 }
1251
1252 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1253 return 0;
1254}
1255
1256
1257static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
1258{
1259#ifdef __linux__
1260 char buf[200];
1261 char path[128];
1262 struct stat s;
1263
1264#ifdef ANDROID
1265 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
1266#else /* ANDROID */
1267 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
1268#endif /* ANDROID */
1269 if (stat(path, &s) == 0) {
1270 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1271 sigma_dut_print(dut, DUT_MSG_INFO,
1272 "Kill previous DHCP client: %s", buf);
1273 if (system(buf) != 0)
1274 sigma_dut_print(dut, DUT_MSG_INFO,
1275 "Failed to kill DHCP client");
1276 unlink(path);
1277 sleep(1);
1278 } else {
1279 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
1280
1281 if (stat(path, &s) == 0) {
1282 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1283 sigma_dut_print(dut, DUT_MSG_INFO,
1284 "Kill previous DHCP client: %s", buf);
1285 if (system(buf) != 0)
1286 sigma_dut_print(dut, DUT_MSG_INFO,
1287 "Failed to kill DHCP client");
1288 unlink(path);
1289 sleep(1);
1290 }
1291 }
1292#endif /* __linux__ */
1293}
1294
1295
1296static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1297{
1298#ifdef __linux__
1299 char buf[200];
1300
1301#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301302 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1303 snprintf(buf, sizeof(buf),
1304 "/system/bin/dhcpcd -b %s", ifname);
1305 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1306 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301307 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1308 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1309 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1310 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301311 } else {
1312 sigma_dut_print(dut, DUT_MSG_ERROR,
1313 "DHCP client program missing");
1314 return 0;
1315 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001316#else /* ANDROID */
1317 snprintf(buf, sizeof(buf),
1318 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1319 ifname, ifname);
1320#endif /* ANDROID */
1321 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1322 if (system(buf) != 0) {
1323 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1324 if (system(buf) != 0) {
1325 sigma_dut_print(dut, DUT_MSG_INFO,
1326 "Failed to start DHCP client");
1327#ifndef ANDROID
1328 return -1;
1329#endif /* ANDROID */
1330 }
1331 }
1332#endif /* __linux__ */
1333
1334 return 0;
1335}
1336
1337
1338static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1339{
1340#ifdef __linux__
1341 char buf[200];
1342
1343 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1344 if (system(buf) != 0) {
1345 sigma_dut_print(dut, DUT_MSG_INFO,
1346 "Failed to clear IP addresses");
1347 return -1;
1348 }
1349#endif /* __linux__ */
1350
1351 return 0;
1352}
1353
1354
1355#ifdef ANDROID
1356static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1357{
1358 char cmd[200], *result, *pos;
1359 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301360 int tableid;
1361 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001362
1363 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1364 ifname);
1365 fp = popen(cmd, "r");
1366 if (fp == NULL)
1367 return -1;
1368
1369 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301370 if (result == NULL) {
1371 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001372 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301373 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001374
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301375 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001376 fclose(fp);
1377
1378 if (len == 0) {
1379 free(result);
1380 return -1;
1381 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301382 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001383
1384 pos = strstr(result, "table ");
1385 if (pos == NULL) {
1386 free(result);
1387 return -1;
1388 }
1389
1390 pos += strlen("table ");
1391 tableid = atoi(pos);
1392 if (tableid != 0) {
1393 if (system("ip -6 rule del prio 22000") != 0) {
1394 /* ignore any error */
1395 }
1396 snprintf(cmd, sizeof(cmd),
1397 "ip -6 rule add from all lookup %d prio 22000",
1398 tableid);
1399 if (system(cmd) != 0) {
1400 sigma_dut_print(dut, DUT_MSG_INFO,
1401 "Failed to run %s", cmd);
1402 free(result);
1403 return -1;
1404 }
1405 } else {
1406 sigma_dut_print(dut, DUT_MSG_INFO,
1407 "No Valid Table Id found %s", pos);
1408 free(result);
1409 return -1;
1410 }
1411 free(result);
1412
1413 return 0;
1414}
1415#endif /* ANDROID */
1416
1417
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301418int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1419 const char *ip, const char *mask)
1420{
1421 char buf[200];
1422
1423 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1424 ifname, ip, mask);
1425 return system(buf) == 0;
1426}
1427
1428
1429int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1430{
1431 char buf[200];
1432
1433 if (!is_ip_addr(gw)) {
1434 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1435 return -1;
1436 }
1437
1438 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1439 if (!dut->no_ip_addr_set && system(buf) != 0) {
1440 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1441 gw);
1442 if (system(buf) != 0)
1443 return 0;
1444 }
1445
1446 return 1;
1447}
1448
1449
Jouni Malinenf7222712019-06-13 01:50:21 +03001450static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1451 struct sigma_conn *conn,
1452 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001453{
1454 const char *intf = get_param(cmd, "Interface");
1455 const char *ifname;
1456 char buf[200];
1457 const char *val, *ip, *mask, *gw;
1458 int type = 1;
1459
1460 if (intf == NULL)
1461 return -1;
1462
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001463 if (strcmp(intf, get_main_ifname(dut)) == 0)
1464 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001465 else
1466 ifname = intf;
1467
1468 if (if_nametoindex(ifname) == 0) {
1469 send_resp(dut, conn, SIGMA_ERROR,
1470 "ErrorCode,Unknown interface");
1471 return 0;
1472 }
1473
1474 val = get_param(cmd, "Type");
1475 if (val) {
1476 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301477 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001478 send_resp(dut, conn, SIGMA_ERROR,
1479 "ErrorCode,Unsupported address type");
1480 return 0;
1481 }
1482 }
1483
1484 dut->last_set_ip_config_ipv6 = 0;
1485
1486 val = get_param(cmd, "dhcp");
1487 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1488 static_ip_file(0, NULL, NULL, NULL);
1489#ifdef __linux__
1490 if (type == 2) {
1491 dut->last_set_ip_config_ipv6 = 1;
1492 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1493 "stateless address autoconfiguration");
1494#ifdef ANDROID
Hu Wang8fd144d2021-12-29 17:07:45 +08001495 snprintf(buf, sizeof(buf),
1496 "sysctl net.ipv6.conf.%s.disable_ipv6=0",
1497 ifname);
1498 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1499 if (system(buf) != 0) {
1500 sigma_dut_print(dut, DUT_MSG_DEBUG,
1501 "Failed to enable IPv6 address");
1502 }
1503
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001504 /*
1505 * This sleep is required as the assignment in case of
1506 * Android is taking time and is done by the kernel.
1507 * The subsequent ping for IPv6 is impacting HS20 test
1508 * case.
1509 */
1510 sleep(2);
1511 add_ipv6_rule(dut, intf);
1512#endif /* ANDROID */
1513 /* Assume this happens by default */
1514 return 1;
1515 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301516 if (type != 3) {
1517 kill_dhcp_client(dut, ifname);
1518 if (start_dhcp_client(dut, ifname) < 0)
1519 return -2;
1520 } else {
1521 sigma_dut_print(dut, DUT_MSG_DEBUG,
1522 "Using FILS HLP DHCPv4 Rapid Commit");
1523 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001524
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001525 return 1;
1526#endif /* __linux__ */
1527 return -2;
1528 }
1529
1530 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301531 if (!ip) {
1532 send_resp(dut, conn, SIGMA_INVALID,
1533 "ErrorCode,Missing IP address");
1534 return 0;
1535 }
1536
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001537 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301538 if (!mask) {
1539 send_resp(dut, conn, SIGMA_INVALID,
1540 "ErrorCode,Missing subnet mask");
1541 return 0;
1542 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001543
1544 if (type == 2) {
1545 int net = atoi(mask);
1546
1547 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1548 return -1;
1549
1550 if (dut->no_ip_addr_set) {
1551 snprintf(buf, sizeof(buf),
1552 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1553 ifname);
1554 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1555 if (system(buf) != 0) {
1556 sigma_dut_print(dut, DUT_MSG_DEBUG,
1557 "Failed to disable IPv6 address before association");
1558 }
1559 } else {
Veerendranath Jakkam176181c2020-05-16 00:19:21 +05301560 if (set_ipv6_addr(dut, ip, mask, ifname) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001561 send_resp(dut, conn, SIGMA_ERROR,
1562 "ErrorCode,Failed to set IPv6 address");
1563 return 0;
1564 }
1565 }
1566
1567 dut->last_set_ip_config_ipv6 = 1;
1568 static_ip_file(6, ip, mask, NULL);
1569 return 1;
1570 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301571 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001572 return -1;
1573 }
1574
1575 kill_dhcp_client(dut, ifname);
1576
1577 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301578 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001579 send_resp(dut, conn, SIGMA_ERROR,
1580 "ErrorCode,Failed to set IP address");
1581 return 0;
1582 }
1583 }
1584
1585 gw = get_param(cmd, "defaultGateway");
1586 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301587 if (set_ipv4_gw(dut, gw) < 1) {
1588 send_resp(dut, conn, SIGMA_ERROR,
1589 "ErrorCode,Failed to set default gateway");
1590 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001591 }
1592 }
1593
1594 val = get_param(cmd, "primary-dns");
1595 if (val) {
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301596#ifdef ANDROID
Shivani Baranwal31182012021-12-07 21:11:13 +05301597 char dns_cmd[200];
1598 int len;
1599 char dnsmasq[100];
1600
1601 kill_pid(dut, concat_sigma_tmpdir(dut, "/sigma_dut-dnsmasq.pid",
1602 dnsmasq, sizeof(dnsmasq)));
1603
1604 len = snprintf(dns_cmd, sizeof(dns_cmd),
1605 "/system/bin/dnsmasq -uroot --no-resolv -S%s -x/%s", val,
1606 dnsmasq);
1607 if (len < 0 || len >= sizeof(dns_cmd))
1608 return ERROR_SEND_STATUS;
1609 sigma_dut_print(dut, DUT_MSG_DEBUG, "Running %s", dns_cmd);
1610 if (system(dns_cmd) != 0) {
1611 send_resp(dut, conn, SIGMA_ERROR,
1612 "ErrorCode,Failed to set primary-dns");
1613 return STATUS_SENT_ERROR;
1614 }
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301615#else /* ANDROID */
1616 char dns_cmd[200];
1617 int len;
1618
1619 if (system("sed -i '/nameserver/d' /etc/resolv.conf") != 0) {
1620 sigma_dut_print(dut, DUT_MSG_ERROR,
1621 "Failed to clear nameserver entries in /etc/resolv.conf");
1622 return ERROR_SEND_STATUS;
1623 }
1624
1625 len = snprintf(dns_cmd, sizeof(dns_cmd),
1626 "sed -i '1 i nameserver %s' /etc/resolv.conf", val);
1627 if (len < 0 || len >= sizeof(dns_cmd))
1628 return ERROR_SEND_STATUS;
1629
1630 sigma_dut_print(dut, DUT_MSG_DEBUG, "Running %s", dns_cmd);
1631 if (system(dns_cmd) != 0) {
1632 send_resp(dut, conn, SIGMA_ERROR,
1633 "ErrorCode,Failed to set primary-dns");
1634 return STATUS_SENT_ERROR;
1635 }
1636#endif /* ANDROID */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001637 }
1638
1639 val = get_param(cmd, "secondary-dns");
1640 if (val) {
1641 /* TODO */
1642 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1643 "setting", val);
1644 }
1645
1646 static_ip_file(4, ip, mask, gw);
1647
1648 return 1;
1649}
1650
1651
Jouni Malinenf7222712019-06-13 01:50:21 +03001652static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1653 struct sigma_conn *conn,
1654 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001655{
1656 /* const char *intf = get_param(cmd, "Interface"); */
1657 /* TODO: could report more details here */
1658 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1659 return 0;
1660}
1661
1662
Jouni Malinenf7222712019-06-13 01:50:21 +03001663static enum sigma_cmd_result cmd_sta_get_mac_address(struct sigma_dut *dut,
1664 struct sigma_conn *conn,
1665 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001666{
1667 /* const char *intf = get_param(cmd, "Interface"); */
1668 char addr[20], resp[50];
1669
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301670 if (dut->dev_role == DEVROLE_STA_CFON)
1671 return sta_cfon_get_mac_address(dut, conn, cmd);
1672
Jouni Malinen9540e012019-11-05 17:08:42 +02001673 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001674 if (get_wpa_status(get_station_ifname(dut), "address",
1675 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001676 return -2;
1677
1678 snprintf(resp, sizeof(resp), "mac,%s", addr);
1679 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1680 return 0;
1681}
1682
1683
Jouni Malinenf7222712019-06-13 01:50:21 +03001684static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1685 struct sigma_conn *conn,
1686 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001687{
1688 /* const char *intf = get_param(cmd, "Interface"); */
1689 int connected = 0;
1690 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001691 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001692 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001693 sigma_dut_print(dut, DUT_MSG_INFO,
1694 "Could not get interface %s status",
1695 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001696 return -2;
1697 }
1698
1699 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1700 if (strncmp(result, "COMPLETED", 9) == 0)
1701 connected = 1;
1702
1703 if (connected)
1704 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1705 else
1706 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1707
1708 return 0;
1709}
1710
1711
Jouni Malinenf7222712019-06-13 01:50:21 +03001712static enum sigma_cmd_result
1713cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1714 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001715{
1716 /* const char *intf = get_param(cmd, "Interface"); */
1717 const char *dst, *timeout;
1718 int wait_time = 90;
1719 char buf[100];
1720 int res;
1721
1722 dst = get_param(cmd, "destination");
1723 if (dst == NULL || !is_ip_addr(dst))
1724 return -1;
1725
1726 timeout = get_param(cmd, "timeout");
1727 if (timeout) {
1728 wait_time = atoi(timeout);
1729 if (wait_time < 1)
1730 wait_time = 1;
1731 }
1732
1733 /* TODO: force renewal of IP lease if DHCP is enabled */
1734
1735 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1736 res = system(buf);
1737 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1738 if (res == 0)
1739 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1740 else if (res == 256)
1741 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1742 else
1743 return -2;
1744
1745 return 0;
1746}
1747
1748
Jouni Malinenf7222712019-06-13 01:50:21 +03001749static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1750 struct sigma_conn *conn,
1751 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001752{
1753 /* const char *intf = get_param(cmd, "Interface"); */
1754 char bssid[20], resp[50];
1755
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001756 if (get_wpa_status(get_station_ifname(dut), "bssid",
1757 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001758 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001759
1760 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1761 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1762 return 0;
1763}
1764
1765
1766#ifdef __SAMSUNG__
1767static int add_use_network(const char *ifname)
1768{
1769 char buf[100];
1770
1771 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1772 wpa_command(ifname, buf);
1773 return 0;
1774}
1775#endif /* __SAMSUNG__ */
1776
1777
1778static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1779 const char *ifname, struct sigma_cmd *cmd)
1780{
1781 const char *ssid = get_param(cmd, "ssid");
1782 int id;
1783 const char *val;
1784
1785 if (ssid == NULL)
1786 return -1;
1787
1788 start_sta_mode(dut);
1789
1790#ifdef __SAMSUNG__
1791 add_use_network(ifname);
1792#endif /* __SAMSUNG__ */
1793
1794 id = add_network(ifname);
1795 if (id < 0)
1796 return -2;
1797 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1798
1799 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1800 return -2;
1801
1802 dut->infra_network_id = id;
1803 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1804
1805 val = get_param(cmd, "program");
1806 if (!val)
1807 val = get_param(cmd, "prog");
1808 if (val && strcasecmp(val, "hs2") == 0) {
1809 char buf[100];
1810 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1811 wpa_command(ifname, buf);
1812
1813 val = get_param(cmd, "prefer");
1814 if (val && atoi(val) > 0)
1815 set_network(ifname, id, "priority", "1");
1816 }
1817
1818 return id;
1819}
1820
1821
Jouni Malinenf7222712019-06-13 01:50:21 +03001822static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1823 struct sigma_conn *conn,
1824 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001825{
1826 const char *intf = get_param(cmd, "Interface");
1827 const char *ssid = get_param(cmd, "ssid");
1828 const char *type = get_param(cmd, "encpType");
1829 const char *ifname;
1830 char buf[200];
1831 int id;
1832
1833 if (intf == NULL || ssid == NULL)
1834 return -1;
1835
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001836 if (strcmp(intf, get_main_ifname(dut)) == 0)
1837 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001838 else
1839 ifname = intf;
1840
1841 id = add_network_common(dut, conn, ifname, cmd);
1842 if (id < 0)
1843 return id;
1844
1845 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1846 return -2;
1847
1848 if (type && strcasecmp(type, "wep") == 0) {
1849 const char *val;
1850 int i;
1851
1852 val = get_param(cmd, "activeKey");
1853 if (val) {
1854 int keyid;
1855 keyid = atoi(val);
1856 if (keyid < 1 || keyid > 4)
1857 return -1;
1858 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1859 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1860 return -2;
1861 }
1862
1863 for (i = 0; i < 4; i++) {
1864 snprintf(buf, sizeof(buf), "key%d", i + 1);
1865 val = get_param(cmd, buf);
1866 if (val == NULL)
1867 continue;
1868 snprintf(buf, sizeof(buf), "wep_key%d", i);
1869 if (set_network(ifname, id, buf, val) < 0)
1870 return -2;
1871 }
1872 }
1873
1874 return 1;
1875}
1876
1877
Jouni Malinene4fde732019-03-25 22:29:37 +02001878static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1879 int id, const char *val)
1880{
1881 char key_mgmt[200], *end, *pos;
1882 const char *in_pos = val;
1883
Jouni Malinen8179fee2019-03-28 03:19:47 +02001884 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001885 pos = key_mgmt;
1886 end = pos + sizeof(key_mgmt);
1887 while (*in_pos) {
1888 int res, akm = atoi(in_pos);
1889 const char *str;
1890
Jouni Malinen8179fee2019-03-28 03:19:47 +02001891 if (akm >= 0 && akm < 32)
1892 dut->akm_values |= 1 << akm;
1893
Jouni Malinene4fde732019-03-25 22:29:37 +02001894 switch (akm) {
1895 case AKM_WPA_EAP:
1896 str = "WPA-EAP";
1897 break;
1898 case AKM_WPA_PSK:
1899 str = "WPA-PSK";
1900 break;
1901 case AKM_FT_EAP:
1902 str = "FT-EAP";
1903 break;
1904 case AKM_FT_PSK:
1905 str = "FT-PSK";
1906 break;
1907 case AKM_EAP_SHA256:
1908 str = "WPA-EAP-SHA256";
1909 break;
1910 case AKM_PSK_SHA256:
1911 str = "WPA-PSK-SHA256";
1912 break;
1913 case AKM_SAE:
1914 str = "SAE";
1915 break;
1916 case AKM_FT_SAE:
1917 str = "FT-SAE";
1918 break;
1919 case AKM_SUITE_B:
1920 str = "WPA-EAP-SUITE-B-192";
1921 break;
1922 case AKM_FT_SUITE_B:
1923 str = "FT-EAP-SHA384";
1924 break;
1925 case AKM_FILS_SHA256:
1926 str = "FILS-SHA256";
1927 break;
1928 case AKM_FILS_SHA384:
1929 str = "FILS-SHA384";
1930 break;
1931 case AKM_FT_FILS_SHA256:
1932 str = "FT-FILS-SHA256";
1933 break;
1934 case AKM_FT_FILS_SHA384:
1935 str = "FT-FILS-SHA384";
1936 break;
1937 default:
1938 sigma_dut_print(dut, DUT_MSG_ERROR,
1939 "Unsupported AKMSuitetype %d", akm);
1940 return -1;
1941 }
1942
1943 res = snprintf(pos, end - pos, "%s%s",
1944 pos == key_mgmt ? "" : " ", str);
1945 if (res < 0 || res >= end - pos)
1946 return -1;
1947 pos += res;
1948
1949 in_pos = strchr(in_pos, ';');
1950 if (!in_pos)
1951 break;
1952 while (*in_pos == ';')
1953 in_pos++;
1954 }
1955 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1956 val, key_mgmt);
1957 return set_network(ifname, id, "key_mgmt", key_mgmt);
1958}
1959
1960
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001961static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1962 const char *ifname, struct sigma_cmd *cmd)
1963{
1964 const char *val;
1965 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001966 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001967 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301968 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001969
1970 id = add_network_common(dut, conn, ifname, cmd);
1971 if (id < 0)
1972 return id;
1973
Jouni Malinen47dcc952017-10-09 16:43:24 +03001974 val = get_param(cmd, "Type");
1975 owe = val && strcasecmp(val, "OWE") == 0;
1976
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001977 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001978 if (!val && owe)
1979 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001980 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001981 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1982 * this missing parameter and assume proto=WPA2. */
1983 if (set_network(ifname, id, "proto", "WPA2") < 0)
1984 return ERROR_SEND_STATUS;
1985 } else if (strcasecmp(val, "wpa") == 0 ||
1986 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001987 if (set_network(ifname, id, "proto", "WPA") < 0)
1988 return -2;
1989 } else if (strcasecmp(val, "wpa2") == 0 ||
1990 strcasecmp(val, "wpa2-psk") == 0 ||
1991 strcasecmp(val, "wpa2-ft") == 0 ||
1992 strcasecmp(val, "wpa2-sha256") == 0) {
1993 if (set_network(ifname, id, "proto", "WPA2") < 0)
1994 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301995 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1996 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001997 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1998 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001999 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05302000 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03002001 if (set_network(ifname, id, "proto", "WPA2") < 0)
2002 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03002003 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002004 } else {
2005 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
2006 return 0;
2007 }
2008
2009 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03002010 if (val) {
2011 cipher_set = 1;
2012 if (strcasecmp(val, "tkip") == 0) {
2013 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
2014 return -2;
2015 } else if (strcasecmp(val, "aes-ccmp") == 0) {
2016 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2017 return -2;
2018 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
2019 if (set_network(ifname, id, "pairwise",
2020 "CCMP TKIP") < 0)
2021 return -2;
2022 } else if (strcasecmp(val, "aes-gcmp") == 0) {
2023 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2024 return -2;
2025 if (set_network(ifname, id, "group", "GCMP") < 0)
2026 return -2;
2027 } else {
2028 send_resp(dut, conn, SIGMA_ERROR,
2029 "errorCode,Unrecognized encpType value");
2030 return 0;
2031 }
2032 }
2033
2034 val = get_param(cmd, "PairwiseCipher");
2035 if (val) {
2036 cipher_set = 1;
2037 /* TODO: Support space separated list */
2038 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2039 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
2040 return -2;
2041 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2042 if (set_network(ifname, id, "pairwise",
2043 "CCMP-256") < 0)
2044 return -2;
2045 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2046 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2047 return -2;
2048 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2049 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2050 return -2;
2051 } else {
2052 send_resp(dut, conn, SIGMA_ERROR,
2053 "errorCode,Unrecognized PairwiseCipher value");
2054 return 0;
2055 }
2056 }
2057
Jouni Malinen47dcc952017-10-09 16:43:24 +03002058 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03002059 send_resp(dut, conn, SIGMA_ERROR,
2060 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002061 return 0;
2062 }
Jouni Malinenad395a22017-09-01 21:13:46 +03002063
2064 val = get_param(cmd, "GroupCipher");
2065 if (val) {
2066 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2067 if (set_network(ifname, id, "group", "GCMP-256") < 0)
2068 return -2;
2069 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2070 if (set_network(ifname, id, "group", "CCMP-256") < 0)
2071 return -2;
2072 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2073 if (set_network(ifname, id, "group", "GCMP") < 0)
2074 return -2;
2075 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2076 if (set_network(ifname, id, "group", "CCMP") < 0)
2077 return -2;
2078 } else {
2079 send_resp(dut, conn, SIGMA_ERROR,
2080 "errorCode,Unrecognized GroupCipher value");
2081 return 0;
2082 }
2083 }
2084
Jouni Malinen7b239522017-09-14 21:37:18 +03002085 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03002086 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03002087 const char *cipher;
2088
2089 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2090 cipher = "BIP-GMAC-256";
2091 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2092 cipher = "BIP-CMAC-256";
2093 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2094 cipher = "BIP-GMAC-128";
2095 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2096 cipher = "AES-128-CMAC";
2097 } else {
2098 send_resp(dut, conn, SIGMA_INVALID,
2099 "errorCode,Unsupported GroupMgntCipher");
2100 return 0;
2101 }
2102 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
2103 send_resp(dut, conn, SIGMA_INVALID,
2104 "errorCode,Failed to set GroupMgntCipher");
2105 return 0;
2106 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002107 }
2108
Jouni Malinene4fde732019-03-25 22:29:37 +02002109 val = get_param(cmd, "AKMSuiteType");
2110 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2111 return ERROR_SEND_STATUS;
2112
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002113 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302114
2115 if (dut->program == PROGRAM_OCE) {
2116 dut->sta_pmf = STA_PMF_OPTIONAL;
2117 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2118 return -2;
2119 }
2120
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002121 val = get_param(cmd, "PMF");
2122 if (val) {
2123 if (strcasecmp(val, "Required") == 0 ||
2124 strcasecmp(val, "Forced_Required") == 0) {
2125 dut->sta_pmf = STA_PMF_REQUIRED;
2126 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2127 return -2;
2128 } else if (strcasecmp(val, "Optional") == 0) {
2129 dut->sta_pmf = STA_PMF_OPTIONAL;
2130 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2131 return -2;
2132 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002133 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002134 strcasecmp(val, "Forced_Disabled") == 0) {
2135 dut->sta_pmf = STA_PMF_DISABLED;
2136 } else {
2137 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2138 return 0;
2139 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302140 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002141 dut->sta_pmf = STA_PMF_REQUIRED;
2142 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2143 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002144 }
2145
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002146 val = get_param(cmd, "BeaconProtection");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05302147 if (val)
2148 dut->beacon_prot = atoi(val);
2149 if (dut->beacon_prot && set_network(ifname, id, "beacon_prot", "1") < 0)
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002150 return ERROR_SEND_STATUS;
2151
Veerendranath Jakkam54fd51c2020-12-21 01:36:04 +05302152 if (dut->ocvc && set_network(ifname, id, "ocv", "1") < 0)
2153 return ERROR_SEND_STATUS;
2154
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002155 return id;
2156}
2157
2158
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302159static int wcn_set_ignore_h2e_rsnxe(struct sigma_dut *dut, const char *intf,
2160 uint8_t cfg)
2161{
2162#ifdef NL80211_SUPPORT
2163 return wcn_wifi_test_config_set_u8(
2164 dut, intf,
2165 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE, cfg);
2166#else /* NL80211_SUPPORT */
2167 sigma_dut_print(dut, DUT_MSG_ERROR,
2168 "Ignore SAE H2E requirement mismatch can't be set without NL80211_SUPPORT defined");
2169 return -1;
2170#endif /* NL80211_SUPPORT */
2171}
2172
2173
Jouni Malinenf7222712019-06-13 01:50:21 +03002174static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2175 struct sigma_conn *conn,
2176 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002177{
2178 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002179 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002180 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002181 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002182 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002183 const char *ifname, *val, *alg;
2184 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002185 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002186 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002187
2188 if (intf == NULL)
2189 return -1;
2190
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002191 if (strcmp(intf, get_main_ifname(dut)) == 0)
2192 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002193 else
2194 ifname = intf;
2195
2196 id = set_wpa_common(dut, conn, ifname, cmd);
2197 if (id < 0)
2198 return id;
2199
2200 val = get_param(cmd, "keyMgmtType");
2201 alg = get_param(cmd, "micAlg");
2202
Jouni Malinen992a81e2017-08-22 13:57:47 +03002203 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002204 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002205 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2206 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002207 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002208 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2209 return -2;
2210 }
2211 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2212 sigma_dut_print(dut, DUT_MSG_ERROR,
2213 "Failed to clear sae_groups to default");
2214 return -2;
2215 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002216 if (!pmf) {
2217 dut->sta_pmf = STA_PMF_REQUIRED;
2218 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2219 return -2;
2220 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002221 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2222 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2223 if (set_network(ifname, id, "key_mgmt",
2224 "FT-SAE FT-PSK") < 0)
2225 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002226 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002227 if (set_network(ifname, id, "key_mgmt",
2228 "SAE WPA-PSK") < 0)
2229 return -2;
2230 }
2231 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2232 sigma_dut_print(dut, DUT_MSG_ERROR,
2233 "Failed to clear sae_groups to default");
2234 return -2;
2235 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002236 if (!pmf) {
2237 dut->sta_pmf = STA_PMF_OPTIONAL;
2238 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2239 return -2;
2240 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002241 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002242 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2243 return -2;
2244 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2245 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2246 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302247 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2248 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2249 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002250 } else if (!akm &&
2251 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2252 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002253 if (set_network(ifname, id, "key_mgmt",
2254 "WPA-PSK WPA-PSK-SHA256") < 0)
2255 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002256 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002257 if (set_network(ifname, id, "key_mgmt",
2258 "WPA-PSK WPA-PSK-SHA256") < 0)
2259 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002260 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002261 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2262 return -2;
2263 }
2264
2265 val = get_param(cmd, "passPhrase");
2266 if (val == NULL)
2267 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002268 if (type && strcasecmp(type, "SAE") == 0) {
2269 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2270 return -2;
2271 } else {
2272 if (set_network_quoted(ifname, id, "psk", val) < 0)
2273 return -2;
2274 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002275
Jouni Malinen78d10c42019-03-25 22:34:32 +02002276 val = get_param(cmd, "PasswordId");
2277 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2278 return ERROR_SEND_STATUS;
2279
Jouni Malinen992a81e2017-08-22 13:57:47 +03002280 val = get_param(cmd, "ECGroupID");
2281 if (val) {
Jouni Malinenb54f0df2019-12-12 01:57:29 +02002282 snprintf(buf, sizeof(buf), "SET sae_groups %s", val);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002283 if (wpa_command(ifname, buf) != 0) {
2284 sigma_dut_print(dut, DUT_MSG_ERROR,
2285 "Failed to clear sae_groups");
2286 return -2;
2287 }
2288 }
2289
Jouni Malinen68143132017-09-02 02:34:08 +03002290 val = get_param(cmd, "InvalidSAEElement");
2291 if (val) {
2292 free(dut->sae_commit_override);
2293 dut->sae_commit_override = strdup(val);
2294 }
2295
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002296 val = get_param(cmd, "PMKID_Include");
2297 if (val) {
2298 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2299 get_enable_disable(val));
2300 wpa_command(intf, buf);
2301 }
2302
Jouni Malineneeb43d32019-12-06 17:40:07 +02002303 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2304 if (val) {
2305 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2306 get_enable_disable(val));
2307 wpa_command(intf, buf);
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302308 if (get_driver_type(dut) == DRIVER_WCN)
2309 wcn_set_ignore_h2e_rsnxe(dut, intf,
2310 get_enable_disable(val));
Jouni Malineneeb43d32019-12-06 17:40:07 +02002311 }
2312
Jouni Malinenf2348d22019-12-07 11:52:55 +02002313 val = get_param(cmd, "ECGroupID_RGE");
2314 if (val) {
2315 snprintf(buf, sizeof(buf), "SET extra_sae_rejected_groups %s",
2316 val);
2317 wpa_command(intf, buf);
2318 }
2319
Jouni Malinen99e55022019-12-07 13:59:41 +02002320 val = get_param(cmd, "RSNXE_Content");
2321 if (val) {
2322 const char *param;
2323
2324 if (strncasecmp(val, "AssocReq:", 9) == 0) {
2325 val += 9;
2326 param = "rsnxe_override_assoc";
2327 } else if (strncasecmp(val, "EapolM2:", 8) == 0) {
2328 val += 8;
2329 param = "rsnxe_override_eapol";
2330 } else {
2331 send_resp(dut, conn, SIGMA_ERROR,
2332 "errorCode,Unsupported RSNXE_Content value");
2333 return STATUS_SENT_ERROR;
2334 }
2335 snprintf(buf, sizeof(buf), "SET %s %s", param, val);
2336 wpa_command(intf, buf);
2337 }
2338
Jouni Malinen11e55212019-11-22 21:46:59 +02002339 val = get_param(cmd, "sae_pwe");
2340 if (val) {
2341 if (strcasecmp(val, "h2e") == 0) {
2342 dut->sae_pwe = SAE_PWE_H2E;
Jouni Malinen7244a412019-12-07 11:54:10 +02002343 } else if (strcasecmp(val, "loop") == 0 ||
2344 strcasecmp(val, "looping") == 0) {
Jouni Malinen11e55212019-11-22 21:46:59 +02002345 dut->sae_pwe = SAE_PWE_LOOP;
2346 } else {
2347 send_resp(dut, conn, SIGMA_ERROR,
2348 "errorCode,Unsupported sae_pwe value");
2349 return STATUS_SENT_ERROR;
2350 }
2351 }
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302352
2353 val = get_param(cmd, "Clear_RSNXE");
2354 if (val && strcmp(val, "1") == 0 &&
2355 (wpa_command(intf, "SET rsnxe_override_assoc ") ||
2356 wpa_command(intf, "SET rsnxe_override_eapol "))) {
2357 send_resp(dut, conn, SIGMA_ERROR,
2358 "errorCode,Failed to clear RSNXE");
Jouni Malinenb11498c2020-08-03 11:05:53 +03002359 return STATUS_SENT_ERROR;
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302360 }
2361
Jouni Malinenc0078772020-03-04 21:23:16 +02002362 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2363 sae_pwe = 3;
2364 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002365 sae_pwe = 0;
2366 else if (dut->sae_pwe == SAE_PWE_H2E)
2367 sae_pwe = 1;
2368 else if (dut->sae_h2e_default)
2369 sae_pwe = 2;
2370 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2371 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2372 return ERROR_SEND_STATUS;
2373
Veerendranath Jakkam0316be12020-06-23 20:11:41 +05302374 val = get_param(cmd, "sae_pk");
2375 if (val && strcmp(val, "0") == 0 &&
2376 set_network(ifname, id, "sae_pk", "2") < 0)
2377 return ERROR_SEND_STATUS;
2378
Veerendranath Jakkama9177042020-08-10 00:14:03 +05302379 val = get_param(cmd, "sae_pk_only");
2380 if (val && strcmp(val, "1") == 0 &&
2381 set_network(ifname, id, "sae_pk", "1") < 0)
2382 return ERROR_SEND_STATUS;
2383
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002384 if (dut->program == PROGRAM_60GHZ && network_mode &&
2385 strcasecmp(network_mode, "PBSS") == 0 &&
2386 set_network(ifname, id, "pbss", "1") < 0)
2387 return -2;
2388
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002389 return 1;
2390}
2391
2392
Jouni Malinen8ac93452019-08-14 15:19:13 +03002393static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2394 struct sigma_conn *conn,
2395 const char *ifname, int id)
2396{
2397 char buf[200];
2398
2399 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2400 if (!file_exists(buf))
2401 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2402 if (!file_exists(buf))
2403 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2404 if (!file_exists(buf)) {
2405 char msg[300];
2406
2407 snprintf(msg, sizeof(msg),
2408 "ErrorCode,trustedRootCA system store (%s) not found",
2409 buf);
2410 send_resp(dut, conn, SIGMA_ERROR, msg);
2411 return STATUS_SENT_ERROR;
2412 }
2413
2414 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2415 return ERROR_SEND_STATUS;
2416
2417 return SUCCESS_SEND_STATUS;
2418}
2419
2420
2421static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2422 struct sigma_conn *conn,
2423 const char *ifname, int id,
2424 const char *val)
2425{
2426 char buf[200];
2427#ifdef ANDROID
2428 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2429 int length;
2430#endif /* ANDROID */
2431
2432 if (strcmp(val, "DEFAULT") == 0)
2433 return set_trust_root_system(dut, conn, ifname, id);
2434
2435#ifdef ANDROID
2436 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2437 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2438 if (length > 0) {
2439 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2440 buf);
2441 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2442 goto ca_cert_selected;
2443 }
2444#endif /* ANDROID */
2445
2446 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2447#ifdef __linux__
2448 if (!file_exists(buf)) {
2449 char msg[300];
2450
2451 snprintf(msg, sizeof(msg),
2452 "ErrorCode,trustedRootCA file (%s) not found", buf);
2453 send_resp(dut, conn, SIGMA_ERROR, msg);
2454 return STATUS_SENT_ERROR;
2455 }
2456#endif /* __linux__ */
2457#ifdef ANDROID
2458ca_cert_selected:
2459#endif /* ANDROID */
2460 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2461 return ERROR_SEND_STATUS;
2462
2463 return SUCCESS_SEND_STATUS;
2464}
2465
2466
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002467static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302468 const char *ifname, int username_identity,
2469 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002470{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002471 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002472 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002473 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002474 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002475 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002476
2477 id = set_wpa_common(dut, conn, ifname, cmd);
2478 if (id < 0)
2479 return id;
2480
2481 val = get_param(cmd, "keyMgmtType");
2482 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302483 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002484 trust_root = get_param(cmd, "trustedRootCA");
2485 domain = get_param(cmd, "Domain");
2486 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002487
Jouni Malinenad395a22017-09-01 21:13:46 +03002488 if (val && strcasecmp(val, "SuiteB") == 0) {
2489 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2490 0)
2491 return -2;
2492 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002493 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2494 return -2;
2495 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2496 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2497 return -2;
2498 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2499 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2500 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002501 } else if (!akm &&
2502 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2503 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002504 if (set_network(ifname, id, "key_mgmt",
2505 "WPA-EAP WPA-EAP-SHA256") < 0)
2506 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302507 } else if (akm && atoi(akm) == 14) {
2508 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2509 dut->sta_pmf == STA_PMF_REQUIRED) {
2510 if (set_network(ifname, id, "key_mgmt",
2511 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2512 return -2;
2513 } else {
2514 if (set_network(ifname, id, "key_mgmt",
2515 "WPA-EAP FILS-SHA256") < 0)
2516 return -2;
2517 }
2518
Jouni Malinen8179fee2019-03-28 03:19:47 +02002519 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302520 } else if (akm && atoi(akm) == 15) {
2521 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2522 dut->sta_pmf == STA_PMF_REQUIRED) {
2523 if (set_network(ifname, id, "key_mgmt",
2524 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2525 return -2;
2526 } else {
2527 if (set_network(ifname, id, "key_mgmt",
2528 "WPA-EAP FILS-SHA384") < 0)
2529 return -2;
2530 }
2531
Jouni Malinen8179fee2019-03-28 03:19:47 +02002532 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002533 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002534 if (set_network(ifname, id, "key_mgmt",
2535 "WPA-EAP WPA-EAP-SHA256") < 0)
2536 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002537 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002538 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2539 return -2;
2540 }
2541
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002542 if (trust_root) {
2543 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2544 !domain_suffix) {
2545 send_resp(dut, conn, SIGMA_ERROR,
2546 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2547 return STATUS_SENT_ERROR;
2548 }
2549 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002550 if (res != SUCCESS_SEND_STATUS)
2551 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002552 }
2553
Jouni Malinen53264f62019-05-03 13:04:40 +03002554 val = get_param(cmd, "ServerCert");
2555 if (val) {
2556 FILE *f;
2557 char *result = NULL, *pos;
2558
2559 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2560 val);
2561 f = fopen(buf, "r");
2562 if (f) {
2563 result = fgets(buf, sizeof(buf), f);
2564 fclose(f);
2565 }
2566 if (!result) {
2567 snprintf(buf2, sizeof(buf2),
2568 "ErrorCode,ServerCert hash could not be read from %s",
2569 buf);
2570 send_resp(dut, conn, SIGMA_ERROR, buf2);
2571 return STATUS_SENT_ERROR;
2572 }
2573 pos = strchr(buf, '\n');
2574 if (pos)
2575 *pos = '\0';
Jouni Malinen0572a742020-10-08 13:53:25 +03002576 pos = strchr(buf, '\r');
2577 if (pos)
2578 *pos = '\0';
Jouni Malinen53264f62019-05-03 13:04:40 +03002579 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2580 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2581 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002582
2583 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2584 if (file_exists(buf)) {
2585 sigma_dut_print(dut, DUT_MSG_DEBUG,
2586 "TOD policy enabled for the configured ServerCert hash");
2587 dut->sta_tod_policy = 1;
2588 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002589 }
2590
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002591 if (domain &&
2592 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002593 return ERROR_SEND_STATUS;
2594
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002595 if (domain_suffix &&
2596 set_network_quoted(ifname, id, "domain_suffix_match",
2597 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002598 return ERROR_SEND_STATUS;
2599
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302600 if (username_identity) {
2601 val = get_param(cmd, "username");
2602 if (val) {
2603 if (set_network_quoted(ifname, id, "identity", val) < 0)
2604 return -2;
2605 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002606
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302607 val = get_param(cmd, "password");
2608 if (val) {
2609 if (set_network_quoted(ifname, id, "password", val) < 0)
2610 return -2;
2611 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002612 }
2613
Jouni Malinen8179fee2019-03-28 03:19:47 +02002614 if (dut->akm_values &
2615 ((1 << AKM_FILS_SHA256) |
2616 (1 << AKM_FILS_SHA384) |
2617 (1 << AKM_FT_FILS_SHA256) |
2618 (1 << AKM_FT_FILS_SHA384)))
2619 erp = 1;
2620 if (erp && set_network(ifname, id, "erp", "1") < 0)
2621 return ERROR_SEND_STATUS;
2622
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002623 dut->sta_associate_wait_connect = 1;
2624
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002625 return id;
2626}
2627
2628
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002629static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2630{
2631 const char *val;
2632
2633 if (!cipher)
2634 return 0;
2635
2636 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2637 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2638 else if (strcasecmp(cipher,
2639 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2640 val = "ECDHE-RSA-AES256-GCM-SHA384";
2641 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2642 val = "DHE-RSA-AES256-GCM-SHA384";
2643 else if (strcasecmp(cipher,
2644 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2645 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2646 else
2647 return -1;
2648
2649 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2650 set_network_quoted(ifname, id, "phase1", "");
2651
2652 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2653}
2654
2655
Jouni Malinenf7222712019-06-13 01:50:21 +03002656static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2657 struct sigma_conn *conn,
2658 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002659{
2660 const char *intf = get_param(cmd, "Interface");
2661 const char *ifname, *val;
2662 int id;
2663 char buf[200];
2664#ifdef ANDROID
2665 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2666 int length;
2667 int jb_or_newer = 0;
2668 char prop[PROPERTY_VALUE_MAX];
2669#endif /* ANDROID */
2670
2671 if (intf == NULL)
2672 return -1;
2673
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002674 if (strcmp(intf, get_main_ifname(dut)) == 0)
2675 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002676 else
2677 ifname = intf;
2678
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302679 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002680 if (id < 0)
2681 return id;
2682
2683 if (set_network(ifname, id, "eap", "TLS") < 0)
2684 return -2;
2685
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302686 if (!get_param(cmd, "username") &&
2687 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002688 "wifi-user@wifilabs.local") < 0)
2689 return -2;
2690
2691 val = get_param(cmd, "clientCertificate");
2692 if (val == NULL)
2693 return -1;
2694#ifdef ANDROID
2695 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2696 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2697 if (length < 0) {
2698 /*
2699 * JB started reporting keystore type mismatches, so retry with
2700 * the GET_PUBKEY command if the generic GET fails.
2701 */
2702 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2703 buf, kvalue);
2704 }
2705
2706 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2707 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2708 if (strncmp(prop, "4.0", 3) != 0)
2709 jb_or_newer = 1;
2710 } else
2711 jb_or_newer = 1; /* assume newer */
2712
2713 if (jb_or_newer && length > 0) {
2714 sigma_dut_print(dut, DUT_MSG_INFO,
2715 "Use Android keystore [%s]", buf);
2716 if (set_network(ifname, id, "engine", "1") < 0)
2717 return -2;
2718 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2719 return -2;
2720 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2721 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2722 return -2;
2723 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2724 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2725 return -2;
2726 return 1;
2727 } else if (length > 0) {
2728 sigma_dut_print(dut, DUT_MSG_INFO,
2729 "Use Android keystore [%s]", buf);
2730 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2731 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2732 return -2;
2733 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2734 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2735 return -2;
2736 return 1;
2737 }
2738#endif /* ANDROID */
2739
2740 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2741#ifdef __linux__
2742 if (!file_exists(buf)) {
2743 char msg[300];
2744 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2745 "(%s) not found", buf);
2746 send_resp(dut, conn, SIGMA_ERROR, msg);
2747 return -3;
2748 }
2749#endif /* __linux__ */
2750 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2751 return -2;
2752 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2753 return -2;
2754
2755 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2756 return -2;
2757
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002758 val = get_param(cmd, "keyMgmtType");
2759 if (val && strcasecmp(val, "SuiteB") == 0) {
2760 val = get_param(cmd, "CertType");
2761 if (val && strcasecmp(val, "RSA") == 0) {
2762 if (set_network_quoted(ifname, id, "phase1",
2763 "tls_suiteb=1") < 0)
2764 return -2;
2765 } else {
2766 if (set_network_quoted(ifname, id, "openssl_ciphers",
2767 "SUITEB192") < 0)
2768 return -2;
2769 }
2770
2771 val = get_param(cmd, "TLSCipher");
2772 if (set_tls_cipher(ifname, id, val) < 0) {
2773 send_resp(dut, conn, SIGMA_ERROR,
2774 "ErrorCode,Unsupported TLSCipher value");
2775 return -3;
2776 }
2777 }
2778
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002779 return 1;
2780}
2781
2782
Jouni Malinenf7222712019-06-13 01:50:21 +03002783static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2784 struct sigma_conn *conn,
2785 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002786{
2787 const char *intf = get_param(cmd, "Interface");
2788 const char *ifname;
2789 int id;
2790
2791 if (intf == NULL)
2792 return -1;
2793
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002794 if (strcmp(intf, get_main_ifname(dut)) == 0)
2795 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002796 else
2797 ifname = intf;
2798
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302799 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002800 if (id < 0)
2801 return id;
2802
2803 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2804 send_resp(dut, conn, SIGMA_ERROR,
2805 "errorCode,Failed to set TTLS method");
2806 return 0;
2807 }
2808
2809 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2810 send_resp(dut, conn, SIGMA_ERROR,
2811 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2812 return 0;
2813 }
2814
2815 return 1;
2816}
2817
2818
Jouni Malinenf7222712019-06-13 01:50:21 +03002819static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2820 struct sigma_conn *conn,
2821 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002822{
2823 const char *intf = get_param(cmd, "Interface");
2824 const char *ifname;
2825 int id;
2826
2827 if (intf == NULL)
2828 return -1;
2829
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002830 if (strcmp(intf, get_main_ifname(dut)) == 0)
2831 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002832 else
2833 ifname = intf;
2834
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302835 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002836 if (id < 0)
2837 return id;
2838
2839 if (set_network(ifname, id, "eap", "SIM") < 0)
2840 return -2;
2841
2842 return 1;
2843}
2844
2845
Jouni Malinenf7222712019-06-13 01:50:21 +03002846static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2847 struct sigma_conn *conn,
2848 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002849{
2850 const char *intf = get_param(cmd, "Interface");
2851 const char *ifname, *val;
2852 int id;
2853 char buf[100];
2854
2855 if (intf == NULL)
2856 return -1;
2857
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002858 if (strcmp(intf, get_main_ifname(dut)) == 0)
2859 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002860 else
2861 ifname = intf;
2862
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302863 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002864 if (id < 0)
2865 return id;
2866
2867 if (set_network(ifname, id, "eap", "PEAP") < 0)
2868 return -2;
2869
2870 val = get_param(cmd, "innerEAP");
2871 if (val) {
2872 if (strcasecmp(val, "MSCHAPv2") == 0) {
2873 if (set_network_quoted(ifname, id, "phase2",
2874 "auth=MSCHAPV2") < 0)
2875 return -2;
2876 } else if (strcasecmp(val, "GTC") == 0) {
2877 if (set_network_quoted(ifname, id, "phase2",
2878 "auth=GTC") < 0)
2879 return -2;
2880 } else
2881 return -1;
2882 }
2883
2884 val = get_param(cmd, "peapVersion");
2885 if (val) {
2886 int ver = atoi(val);
2887 if (ver < 0 || ver > 1)
2888 return -1;
2889 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2890 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2891 return -2;
2892 }
2893
2894 return 1;
2895}
2896
2897
Jouni Malinenf7222712019-06-13 01:50:21 +03002898static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2899 struct sigma_conn *conn,
2900 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002901{
2902 const char *intf = get_param(cmd, "Interface");
2903 const char *ifname, *val;
2904 int id;
2905 char buf[100];
2906
2907 if (intf == NULL)
2908 return -1;
2909
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002910 if (strcmp(intf, get_main_ifname(dut)) == 0)
2911 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002912 else
2913 ifname = intf;
2914
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302915 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002916 if (id < 0)
2917 return id;
2918
2919 if (set_network(ifname, id, "eap", "FAST") < 0)
2920 return -2;
2921
2922 val = get_param(cmd, "innerEAP");
2923 if (val) {
2924 if (strcasecmp(val, "MSCHAPV2") == 0) {
2925 if (set_network_quoted(ifname, id, "phase2",
2926 "auth=MSCHAPV2") < 0)
2927 return -2;
2928 } else if (strcasecmp(val, "GTC") == 0) {
2929 if (set_network_quoted(ifname, id, "phase2",
2930 "auth=GTC") < 0)
2931 return -2;
2932 } else
2933 return -1;
2934 }
2935
2936 val = get_param(cmd, "validateServer");
2937 if (val) {
2938 /* TODO */
2939 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2940 "validateServer=%s", val);
2941 }
2942
2943 val = get_param(cmd, "pacFile");
2944 if (val) {
2945 snprintf(buf, sizeof(buf), "blob://%s", val);
2946 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2947 return -2;
2948 }
2949
2950 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2951 0)
2952 return -2;
2953
2954 return 1;
2955}
2956
2957
Jouni Malinenf7222712019-06-13 01:50:21 +03002958static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2959 struct sigma_conn *conn,
2960 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002961{
2962 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302963 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002964 const char *ifname;
2965 int id;
2966
2967 if (intf == NULL)
2968 return -1;
2969
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002970 if (strcmp(intf, get_main_ifname(dut)) == 0)
2971 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002972 else
2973 ifname = intf;
2974
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302975 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002976 if (id < 0)
2977 return id;
2978
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302979 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2980 * hexadecimal).
2981 */
2982 if (username && username[0] == '6') {
2983 if (set_network(ifname, id, "eap", "AKA'") < 0)
2984 return -2;
2985 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002986 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302987 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002988
2989 return 1;
2990}
2991
2992
Jouni Malinenf7222712019-06-13 01:50:21 +03002993static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2994 struct sigma_conn *conn,
2995 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002996{
2997 const char *intf = get_param(cmd, "Interface");
2998 const char *ifname;
2999 int id;
3000
3001 if (intf == NULL)
3002 return -1;
3003
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003004 if (strcmp(intf, get_main_ifname(dut)) == 0)
3005 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003006 else
3007 ifname = intf;
3008
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05303009 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003010 if (id < 0)
3011 return id;
3012
3013 if (set_network(ifname, id, "eap", "AKA'") < 0)
3014 return -2;
3015
3016 return 1;
3017}
3018
3019
3020static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
3021 struct sigma_cmd *cmd)
3022{
3023 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003024 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003025 const char *ifname;
3026 int id;
3027
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003028 if (strcmp(intf, get_main_ifname(dut)) == 0)
3029 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003030 else
3031 ifname = intf;
3032
3033 id = add_network_common(dut, conn, ifname, cmd);
3034 if (id < 0)
3035 return id;
3036
3037 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
3038 return -2;
3039
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003040 if (dut->program == PROGRAM_60GHZ && network_mode &&
3041 strcasecmp(network_mode, "PBSS") == 0 &&
3042 set_network(ifname, id, "pbss", "1") < 0)
3043 return -2;
3044
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003045 return 1;
3046}
3047
3048
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003049static enum sigma_cmd_result sta_set_owe(struct sigma_dut *dut,
3050 struct sigma_conn *conn,
3051 struct sigma_cmd *cmd)
Jouni Malinen47dcc952017-10-09 16:43:24 +03003052{
3053 const char *intf = get_param(cmd, "Interface");
3054 const char *ifname, *val;
3055 int id;
3056
3057 if (intf == NULL)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003058 return INVALID_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003059
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003060 if (strcmp(intf, get_main_ifname(dut)) == 0)
3061 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003062 else
3063 ifname = intf;
3064
3065 id = set_wpa_common(dut, conn, ifname, cmd);
3066 if (id < 0)
3067 return id;
3068
3069 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003070 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003071
Hu Wangdd5eed22020-07-16 12:18:03 +08003072 if (dut->owe_ptk_workaround &&
3073 set_network(ifname, id, "owe_ptk_workaround", "1") < 0) {
3074 sigma_dut_print(dut, DUT_MSG_ERROR,
3075 "Failed to set owe_ptk_workaround to 1");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003076 return ERROR_SEND_STATUS;
Hu Wangdd5eed22020-07-16 12:18:03 +08003077 }
3078
Jouni Malinen47dcc952017-10-09 16:43:24 +03003079 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003080 if (val && strcmp(val, "0") == 0) {
3081 if (wpa_command(ifname,
3082 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
3083 sigma_dut_print(dut, DUT_MSG_ERROR,
3084 "Failed to set OWE DH Param element override");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003085 return ERROR_SEND_STATUS;
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003086 }
Hu Wangdd5eed22020-07-16 12:18:03 +08003087 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03003088 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08003089 "Failed to set owe_group");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003090 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003091 }
3092
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003093 return SUCCESS_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003094}
3095
3096
Jouni Malinenf7222712019-06-13 01:50:21 +03003097static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
3098 struct sigma_conn *conn,
3099 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003100{
3101 const char *type = get_param(cmd, "Type");
3102
3103 if (type == NULL) {
3104 send_resp(dut, conn, SIGMA_ERROR,
3105 "ErrorCode,Missing Type argument");
3106 return 0;
3107 }
3108
3109 if (strcasecmp(type, "OPEN") == 0)
3110 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003111 if (strcasecmp(type, "OWE") == 0)
3112 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03003113 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03003114 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03003115 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003116 return cmd_sta_set_psk(dut, conn, cmd);
3117 if (strcasecmp(type, "EAPTLS") == 0)
3118 return cmd_sta_set_eaptls(dut, conn, cmd);
3119 if (strcasecmp(type, "EAPTTLS") == 0)
3120 return cmd_sta_set_eapttls(dut, conn, cmd);
3121 if (strcasecmp(type, "EAPPEAP") == 0)
3122 return cmd_sta_set_peap(dut, conn, cmd);
3123 if (strcasecmp(type, "EAPSIM") == 0)
3124 return cmd_sta_set_eapsim(dut, conn, cmd);
3125 if (strcasecmp(type, "EAPFAST") == 0)
3126 return cmd_sta_set_eapfast(dut, conn, cmd);
3127 if (strcasecmp(type, "EAPAKA") == 0)
3128 return cmd_sta_set_eapaka(dut, conn, cmd);
3129 if (strcasecmp(type, "EAPAKAPRIME") == 0)
3130 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08003131 if (strcasecmp(type, "wep") == 0)
3132 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003133
3134 send_resp(dut, conn, SIGMA_ERROR,
3135 "ErrorCode,Unsupported Type value");
3136 return 0;
3137}
3138
3139
3140int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
3141{
3142#ifdef __linux__
3143 /* special handling for ath6kl */
3144 char path[128], fname[128], *pos;
3145 ssize_t res;
3146 FILE *f;
3147
Jouni Malinene39cd562019-05-29 23:39:56 +03003148 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3149 intf);
3150 if (res < 0 || res >= sizeof(fname))
3151 return 0;
3152 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003153 if (res < 0)
3154 return 0; /* not ath6kl */
3155
3156 if (res >= (int) sizeof(path))
3157 res = sizeof(path) - 1;
3158 path[res] = '\0';
3159 pos = strrchr(path, '/');
3160 if (pos == NULL)
3161 pos = path;
3162 else
3163 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003164 res = snprintf(fname, sizeof(fname),
3165 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3166 "create_qos", pos);
3167 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003168 return 0; /* not ath6kl */
3169
3170 if (uapsd) {
3171 f = fopen(fname, "w");
3172 if (f == NULL)
3173 return -1;
3174
3175 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3176 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3177 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3178 "20000 0\n");
3179 fclose(f);
3180 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003181 res = snprintf(fname, sizeof(fname),
3182 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3183 "delete_qos", pos);
3184 if (res < 0 || res >= sizeof(fname))
3185 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003186
3187 f = fopen(fname, "w");
3188 if (f == NULL)
3189 return -1;
3190
3191 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3192 fprintf(f, "2 4\n");
3193 fclose(f);
3194 }
3195#endif /* __linux__ */
3196
3197 return 0;
3198}
3199
3200
Jouni Malinenf7222712019-06-13 01:50:21 +03003201static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3202 struct sigma_conn *conn,
3203 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003204{
3205 const char *intf = get_param(cmd, "Interface");
3206 /* const char *ssid = get_param(cmd, "ssid"); */
3207 const char *val;
3208 int max_sp_len = 4;
3209 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3210 char buf[100];
3211 int ret1, ret2;
3212
3213 val = get_param(cmd, "maxSPLength");
3214 if (val) {
3215 max_sp_len = atoi(val);
3216 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3217 max_sp_len != 4)
3218 return -1;
3219 }
3220
3221 val = get_param(cmd, "acBE");
3222 if (val)
3223 ac_be = atoi(val);
3224
3225 val = get_param(cmd, "acBK");
3226 if (val)
3227 ac_bk = atoi(val);
3228
3229 val = get_param(cmd, "acVI");
3230 if (val)
3231 ac_vi = atoi(val);
3232
3233 val = get_param(cmd, "acVO");
3234 if (val)
3235 ac_vo = atoi(val);
3236
3237 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3238
3239 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3240 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3241 ret1 = wpa_command(intf, buf);
3242
3243 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3244 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3245 ret2 = wpa_command(intf, buf);
3246
3247 if (ret1 && ret2) {
3248 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3249 "UAPSD parameters.");
3250 return -2;
3251 }
3252
3253 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3254 send_resp(dut, conn, SIGMA_ERROR,
3255 "ErrorCode,Failed to set ath6kl QoS parameters");
3256 return 0;
3257 }
3258
3259 return 1;
3260}
3261
3262
Jouni Malinenf7222712019-06-13 01:50:21 +03003263static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3264 struct sigma_conn *conn,
3265 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003266{
3267 char buf[1000];
3268 const char *intf = get_param(cmd, "Interface");
3269 const char *grp = get_param(cmd, "Group");
3270 const char *act = get_param(cmd, "Action");
3271 const char *tid = get_param(cmd, "Tid");
3272 const char *dir = get_param(cmd, "Direction");
3273 const char *psb = get_param(cmd, "Psb");
3274 const char *up = get_param(cmd, "Up");
3275 const char *fixed = get_param(cmd, "Fixed");
3276 const char *size = get_param(cmd, "Size");
3277 const char *msize = get_param(cmd, "Maxsize");
3278 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3279 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3280 const char *inact = get_param(cmd, "Inactivity");
3281 const char *sus = get_param(cmd, "Suspension");
3282 const char *mindr = get_param(cmd, "Mindatarate");
3283 const char *meandr = get_param(cmd, "Meandatarate");
3284 const char *peakdr = get_param(cmd, "Peakdatarate");
3285 const char *phyrate = get_param(cmd, "Phyrate");
3286 const char *burstsize = get_param(cmd, "Burstsize");
3287 const char *sba = get_param(cmd, "Sba");
3288 int direction;
3289 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003290 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003291 int fixed_int;
3292 int psb_ts;
3293
3294 if (intf == NULL || grp == NULL || act == NULL )
3295 return -1;
3296
3297 if (strcasecmp(act, "addts") == 0) {
3298 if (tid == NULL || dir == NULL || psb == NULL ||
3299 up == NULL || fixed == NULL || size == NULL)
3300 return -1;
3301
3302 /*
3303 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3304 * possible values, but WMM-AC and V-E test scripts use "UP,
3305 * "DOWN", and "BIDI".
3306 */
3307 if (strcasecmp(dir, "uplink") == 0 ||
3308 strcasecmp(dir, "up") == 0) {
3309 direction = 0;
3310 } else if (strcasecmp(dir, "downlink") == 0 ||
3311 strcasecmp(dir, "down") == 0) {
3312 direction = 1;
3313 } else if (strcasecmp(dir, "bidi") == 0) {
3314 direction = 2;
3315 } else {
3316 sigma_dut_print(dut, DUT_MSG_ERROR,
3317 "Direction %s not supported", dir);
3318 return -1;
3319 }
3320
3321 if (strcasecmp(psb, "legacy") == 0) {
3322 psb_ts = 0;
3323 } else if (strcasecmp(psb, "uapsd") == 0) {
3324 psb_ts = 1;
3325 } else {
3326 sigma_dut_print(dut, DUT_MSG_ERROR,
3327 "PSB %s not supported", psb);
3328 return -1;
3329 }
3330
3331 if (atoi(tid) < 0 || atoi(tid) > 7) {
3332 sigma_dut_print(dut, DUT_MSG_ERROR,
3333 "TID %s not supported", tid);
3334 return -1;
3335 }
3336
3337 if (strcasecmp(fixed, "true") == 0) {
3338 fixed_int = 1;
3339 } else {
3340 fixed_int = 0;
3341 }
3342
Peng Xu93319622017-10-04 17:58:16 -07003343 if (sba)
3344 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003345
3346 dut->dialog_token++;
3347 handle = 7000 + dut->dialog_token;
3348
3349 /*
3350 * size: convert to hex
3351 * maxsi: convert to hex
3352 * mindr: convert to hex
3353 * meandr: convert to hex
3354 * peakdr: convert to hex
3355 * burstsize: convert to hex
3356 * phyrate: convert to hex
3357 * sba: convert to hex with modification
3358 * minsi: convert to integer
3359 * sus: convert to integer
3360 * inact: convert to integer
3361 * maxsi: convert to integer
3362 */
3363
3364 /*
3365 * The Nominal MSDU Size field is 2 octets long and contains an
3366 * unsigned integer that specifies the nominal size, in octets,
3367 * of MSDUs belonging to the traffic under this traffic
3368 * specification and is defined in Figure 16. If the Fixed
3369 * subfield is set to 1, then the size of the MSDU is fixed and
3370 * is indicated by the Size Subfield. If the Fixed subfield is
3371 * set to 0, then the size of the MSDU might not be fixed and
3372 * the Size indicates the nominal MSDU size.
3373 *
3374 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3375 * and specifies the excess allocation of time (and bandwidth)
3376 * over and above the stated rates required to transport an MSDU
3377 * belonging to the traffic in this TSPEC. This field is
3378 * represented as an unsigned binary number with an implicit
3379 * binary point after the leftmost 3 bits. For example, an SBA
3380 * of 1.75 is represented as 0x3800. This field is included to
3381 * account for retransmissions. As such, the value of this field
3382 * must be greater than unity.
3383 */
3384
3385 snprintf(buf, sizeof(buf),
3386 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3387 " 0x%X 0x%X 0x%X"
3388 " 0x%X 0x%X 0x%X"
3389 " 0x%X %d %d %d %d"
3390 " %d %d",
3391 intf, handle, tid, direction, psb_ts, up,
3392 (unsigned int) ((fixed_int << 15) | atoi(size)),
3393 msize ? atoi(msize) : 0,
3394 mindr ? atoi(mindr) : 0,
3395 meandr ? atoi(meandr) : 0,
3396 peakdr ? atoi(peakdr) : 0,
3397 burstsize ? atoi(burstsize) : 0,
3398 phyrate ? atoi(phyrate) : 0,
3399 sba ? ((unsigned int) (((int) sba_fv << 13) |
3400 (int)((sba_fv - (int) sba_fv) *
3401 8192))) : 0,
3402 minsi ? atoi(minsi) : 0,
3403 sus ? atoi(sus) : 0,
3404 0, 0,
3405 inact ? atoi(inact) : 0,
3406 maxsi ? atoi(maxsi) : 0);
3407
3408 if (system(buf) != 0) {
3409 sigma_dut_print(dut, DUT_MSG_ERROR,
3410 "iwpriv addtspec request failed");
3411 send_resp(dut, conn, SIGMA_ERROR,
3412 "errorCode,Failed to execute addTspec command");
3413 return 0;
3414 }
3415
3416 sigma_dut_print(dut, DUT_MSG_INFO,
3417 "iwpriv addtspec request send");
3418
3419 /* Mapping handle to a TID */
3420 dut->tid_to_handle[atoi(tid)] = handle;
3421 } else if (strcasecmp(act, "delts") == 0) {
3422 if (tid == NULL)
3423 return -1;
3424
3425 if (atoi(tid) < 0 || atoi(tid) > 7) {
3426 sigma_dut_print(dut, DUT_MSG_ERROR,
3427 "TID %s not supported", tid);
3428 send_resp(dut, conn, SIGMA_ERROR,
3429 "errorCode,Unsupported TID");
3430 return 0;
3431 }
3432
3433 handle = dut->tid_to_handle[atoi(tid)];
3434
3435 if (handle < 7000 || handle > 7255) {
3436 /* Invalid handle ie no mapping for that TID */
3437 sigma_dut_print(dut, DUT_MSG_ERROR,
3438 "handle-> %d not found", handle);
3439 }
3440
3441 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3442 intf, handle);
3443
3444 if (system(buf) != 0) {
3445 sigma_dut_print(dut, DUT_MSG_ERROR,
3446 "iwpriv deltspec request failed");
3447 send_resp(dut, conn, SIGMA_ERROR,
3448 "errorCode,Failed to execute delTspec command");
3449 return 0;
3450 }
3451
3452 sigma_dut_print(dut, DUT_MSG_INFO,
3453 "iwpriv deltspec request send");
3454
3455 dut->tid_to_handle[atoi(tid)] = 0;
3456 } else {
3457 sigma_dut_print(dut, DUT_MSG_ERROR,
3458 "Action type %s not supported", act);
3459 send_resp(dut, conn, SIGMA_ERROR,
3460 "errorCode,Unsupported Action");
3461 return 0;
3462 }
3463
3464 return 1;
3465}
3466
3467
vamsi krishna52e16f92017-08-29 12:37:34 +05303468static int find_network(struct sigma_dut *dut, const char *ssid)
3469{
3470 char list[4096];
3471 char *pos;
3472
3473 sigma_dut_print(dut, DUT_MSG_DEBUG,
3474 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003475 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303476 list, sizeof(list)) < 0)
3477 return -1;
3478 pos = strstr(list, ssid);
3479 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3480 return -1;
3481
3482 while (pos > list && pos[-1] != '\n')
3483 pos--;
3484 dut->infra_network_id = atoi(pos);
3485 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3486 return 0;
3487}
3488
3489
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303490/**
3491 * enum qca_sta_helper_config_params - This helper enum defines the config
3492 * parameters which can be delivered to sta.
3493 */
3494enum qca_sta_helper_config_params {
3495 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE */
3496 STA_SET_RSNIE,
3497
3498 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC */
3499 STA_SET_LDPC,
3500
3501 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC */
3502 STA_SET_TX_STBC,
3503
3504 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC */
3505 STA_SET_RX_STBC,
3506
3507 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION */
3508 STA_SET_TX_MSDU,
3509
3510 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION */
3511 STA_SET_RX_MSDU,
Shivani Baranwal2a572842021-09-16 12:27:15 +05303512
3513 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH */
3514 STA_SET_CHAN_WIDTH,
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303515
3516 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS */
3517 STA_SET_FT_DS,
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303518};
3519
3520
3521static int sta_config_params(struct sigma_dut *dut, const char *intf,
3522 enum qca_sta_helper_config_params config_cmd,
3523 int value)
Sunil Dutt44595082018-02-12 19:41:45 +05303524{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303525#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05303526 struct nl_msg *msg;
3527 int ret;
3528 struct nlattr *params;
3529 int ifindex;
3530
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303531 ifindex = if_nametoindex(intf);
3532 if (ifindex == 0) {
3533 sigma_dut_print(dut, DUT_MSG_ERROR,
3534 "%s: Interface %s does not exist",
3535 __func__, intf);
3536 return -1;
3537 }
3538
Sunil Dutt44595082018-02-12 19:41:45 +05303539 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3540 NL80211_CMD_VENDOR)) ||
3541 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3542 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3543 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3544 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303545 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)))
3546 goto fail;
3547
3548 switch (config_cmd) {
3549 case STA_SET_RSNIE:
3550 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, value))
3551 goto fail;
3552 break;
3553 case STA_SET_LDPC:
3554 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC, value))
3555 goto fail;
3556 break;
3557 case STA_SET_TX_STBC:
3558 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC, value))
3559 goto fail;
3560 break;
3561 case STA_SET_RX_STBC:
3562 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC, value))
3563 goto fail;
3564 break;
3565 case STA_SET_TX_MSDU:
3566 if (nla_put_u8(msg,
3567 QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION,
3568 value))
3569 goto fail;
3570 break;
3571 case STA_SET_RX_MSDU:
3572 if (nla_put_u8(msg,
3573 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION,
3574 value))
3575 goto fail;
3576 break;
Shivani Baranwal2a572842021-09-16 12:27:15 +05303577 case STA_SET_CHAN_WIDTH:
3578 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
3579 value))
3580 goto fail;
3581 break;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303582 case STA_SET_FT_DS:
3583 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS,
3584 value))
3585 goto fail;
3586 break;
Sunil Dutt44595082018-02-12 19:41:45 +05303587 }
3588 nla_nest_end(msg, params);
3589
3590 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3591 if (ret) {
3592 sigma_dut_print(dut, DUT_MSG_ERROR,
3593 "%s: err in send_and_recv_msgs, ret=%d",
3594 __func__, ret);
3595 return ret;
3596 }
3597
3598 return 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303599
3600fail:
3601 sigma_dut_print(dut, DUT_MSG_ERROR,
3602 "%s: err in adding vendor_cmd and vendor_data",
3603 __func__);
3604 nlmsg_free(msg);
Sunil Dutt44595082018-02-12 19:41:45 +05303605#endif /* NL80211_SUPPORT */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303606 return -1;
3607}
Sunil Dutt44595082018-02-12 19:41:45 +05303608
3609
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303610void free_dscp_policy_table(struct sigma_dut *dut)
3611{
3612 struct dscp_policy_data *dscp_policy;
3613
3614 while (dut->dscp_policy_table) {
3615 dscp_policy = dut->dscp_policy_table;
3616 dut->dscp_policy_table = dscp_policy->next;
3617 free(dscp_policy);
3618 }
3619}
3620
3621
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303622static char * protocol_to_str(int proto)
3623{
3624 switch (proto) {
3625 case 6:
3626 return "tcp";
3627 case 17:
3628 return "udp";
3629 case 50:
3630 return "esp";
3631 default:
3632 return "unknown";
3633 }
3634}
3635
3636
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303637static int delete_nft_table(struct sigma_dut *dut, const char *table,
3638 const char *ip_type)
3639{
3640 int res;
3641 char cmd[200];
3642
3643 res = snprintf(cmd, sizeof(cmd), "nft delete table %s %s_%s", ip_type,
3644 table, ip_type);
3645 if (snprintf_error(sizeof(cmd), res)) {
3646 sigma_dut_print(dut, DUT_MSG_ERROR,
3647 "Failed to create delete table command");
3648 return -1;
3649 }
3650
3651 if (system(cmd) != 0) {
3652 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3653 return -1;
3654 }
3655
3656 return 0;
3657}
3658
3659
3660static int remove_nft_rule(struct sigma_dut *dut, int policy_id,
3661 enum ip_version ip_ver)
3662{
3663 int res;
3664 char table[50];
3665
3666 res = snprintf(table, sizeof(table), "wifi_%s_dscp_policy_%d",
3667 dut->station_ifname, policy_id);
3668 if (snprintf_error(sizeof(table), res)) {
3669 sigma_dut_print(dut, DUT_MSG_INFO,
3670 "Failed to create table name for policy %d",
3671 policy_id);
3672 return -1;
3673 }
3674
3675
3676 if (ip_ver == IPV6)
3677 return delete_nft_table(dut, table, "ip6");
3678 else
3679 return delete_nft_table(dut, table, "ip");
3680}
3681
3682
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303683static int remove_iptable_rule(struct sigma_dut *dut,
3684 struct dscp_policy_data *dscp_policy)
3685{
3686 char ip_cmd[1000];
3687 char *pos;
3688 int ret, len;
3689 enum ip_version ip_ver = dscp_policy->ip_version;
3690
3691 pos = ip_cmd;
3692 len = sizeof(ip_cmd);
3693
3694 ret = snprintf(pos, len,
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05303695 "%s -t mangle -D OUTPUT -o %s",
3696#ifdef ANDROID
3697 ip_ver == IPV6 ? "/system/bin/ip6tables" : "/system/bin/iptables",
3698#else /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303699 ip_ver == IPV6 ? "ip6tables" : "iptables",
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05303700#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303701 dut->station_ifname);
3702 if (snprintf_error(len, ret)) {
3703 sigma_dut_print(dut, DUT_MSG_INFO,
3704 "Failed to create delete iptables command %s",
3705 ip_cmd);
3706 return -1;
3707 }
3708
3709 pos += ret;
3710 len -= ret;
3711
3712 if (strlen(dscp_policy->src_ip)) {
3713 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
3714 if (snprintf_error(len, ret)) {
3715 sigma_dut_print(dut, DUT_MSG_INFO,
3716 "Error in adding src_ip %s in delete command",
3717 dscp_policy->src_ip);
3718 return -1;
3719 }
3720 pos += ret;
3721 len -= ret;
3722 }
3723
3724 if (strlen(dscp_policy->dst_ip)) {
3725 ret = snprintf(pos, len, " -d %s",
3726 dscp_policy->dst_ip);
3727 if (snprintf_error(len, ret)) {
3728 sigma_dut_print(dut, DUT_MSG_INFO,
3729 "Error in adding dst_ip %s in delete cmd",
3730 dscp_policy->dst_ip);
3731 return -1;
3732 }
3733 pos += ret;
3734 len -= ret;
3735 }
3736
3737 if (dscp_policy->src_port || dscp_policy->dst_port ||
3738 (dscp_policy->start_port && dscp_policy->end_port)) {
3739 ret = snprintf(pos, len, " -p %s",
3740 protocol_to_str(dscp_policy->protocol));
3741 if (snprintf_error(len, ret)) {
3742 sigma_dut_print(dut, DUT_MSG_INFO,
3743 "Error in adding protocol %d in delete command",
3744 dscp_policy->protocol);
3745 return -1;
3746 }
3747 pos += ret;
3748 len -= ret;
3749 }
3750
3751 if (dscp_policy->src_port) {
3752 ret = snprintf(pos, len, " --sport %d",
3753 dscp_policy->src_port);
3754 if (snprintf_error(len, ret)) {
3755 sigma_dut_print(dut, DUT_MSG_INFO,
3756 "Error in adding src_port %d in delete command",
3757 dscp_policy->src_port);
3758 return -1;
3759 }
3760 pos += ret;
3761 len -= ret;
3762 }
3763
3764 if (dscp_policy->dst_port) {
3765 ret = snprintf(pos, len, " --dport %d",
3766 dscp_policy->dst_port);
3767 if (snprintf_error(len, ret)) {
3768 sigma_dut_print(dut, DUT_MSG_INFO,
3769 "Error in adding dst_port %d in delete command",
3770 dscp_policy->dst_port);
3771 return -1;
3772 }
3773 pos += ret;
3774 len -= ret;
3775 }
3776
3777 if (dscp_policy->start_port && dscp_policy->end_port) {
3778 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
3779 dscp_policy->start_port,
3780 dscp_policy->end_port);
3781 if (snprintf_error(len, ret)) {
3782 sigma_dut_print(dut, DUT_MSG_INFO,
3783 "Error in adding start:end port %d:%d in delete command",
3784 dscp_policy->start_port,
3785 dscp_policy->end_port);
3786 return -1;
3787 }
3788 pos += ret;
3789 len -= ret;
3790 }
3791
3792 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
3793 dscp_policy->dscp);
3794 if (snprintf_error(len, ret)) {
3795 sigma_dut_print(dut, DUT_MSG_INFO,
3796 "Error in adding dscp %0x in delete command",
3797 dscp_policy->dscp);
3798 return -1;
3799 }
3800 ret = system(ip_cmd);
3801 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
3802 ip_cmd, ret);
3803
3804 return ret;
3805}
3806
3807
3808static int remove_dscp_policy_rule(struct sigma_dut *dut,
3809 struct dscp_policy_data *dscp_policy)
3810{
3811 return dut->dscp_use_iptables ? remove_iptable_rule(dut, dscp_policy) :
3812 remove_nft_rule(dut, dscp_policy->policy_id,
3813 dscp_policy->ip_version);
3814}
3815
3816
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303817static int create_nft_table(struct sigma_dut *dut, int policy_id,
3818 const char *table_name, enum ip_version ip_ver)
3819{
3820 char cmd[200];
3821 int res;
3822
3823 res = snprintf(cmd, sizeof(cmd), "nft add table %s %s",
3824 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3825 if (snprintf_error(sizeof(cmd), res)) {
3826 sigma_dut_print(dut, DUT_MSG_INFO,
3827 "Failed to add rule to create table for policy id %d",
3828 policy_id);
3829 return -1;
3830 }
3831
3832 if (system(cmd) != 0) {
3833 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3834 return -1;
3835 }
3836
3837 res = snprintf(cmd, sizeof(cmd),
3838 "nft add chain %s %s OUTPUT { type filter hook output priority 0 \\; }",
3839 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3840 if (snprintf_error(sizeof(cmd), res)) {
3841 sigma_dut_print(dut, DUT_MSG_INFO,
3842 "Failed to add rule to create chain for table = %s",
3843 table_name);
3844 return -1;
3845 }
3846
3847 if (system(cmd) != 0) {
3848 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3849 return -1;
3850 }
3851
3852 return 0;
3853}
3854
3855
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303856static int remove_dscp_policy(struct sigma_dut *dut, u8 policy_id)
3857{
3858 struct dscp_policy_data *dscp_policy = dut->dscp_policy_table;
3859 struct dscp_policy_data *prev = NULL;
3860
3861 while (dscp_policy) {
3862 if (dscp_policy->policy_id == policy_id)
3863 break;
3864
3865 prev = dscp_policy;
3866 dscp_policy = dscp_policy->next;
3867 }
3868
3869 /*
3870 * Consider remove request for a policy id which does not exist as
3871 * success.
3872 */
3873 if (!dscp_policy)
3874 return 0;
3875
3876 if (strlen(dscp_policy->domain_name) == 0 &&
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303877 remove_dscp_policy_rule(dut, dscp_policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303878 return -1;
3879
3880 if (prev)
3881 prev->next = dscp_policy->next;
3882 else
3883 dut->dscp_policy_table = dscp_policy->next;
3884
3885 free(dscp_policy);
3886 return 0;
3887}
3888
3889
3890static int add_nft_rule(struct sigma_dut *dut,
3891 struct dscp_policy_data *dscp_policy)
3892{
3893 char nft_cmd[1000], ip[4], table_name[100];
3894 char *pos;
3895 int ret, len, policy_id = dscp_policy->policy_id;
3896 enum ip_version ip_ver = dscp_policy->ip_version;
3897
3898 if (ip_ver == IPV6)
3899 strlcpy(ip, "ip6", sizeof(ip));
3900 else
3901 strlcpy(ip, "ip", sizeof(ip));
3902
3903 ret = snprintf(table_name, sizeof(table_name),
3904 "wifi_%s_dscp_policy_%d_%s",
3905 dut->station_ifname, policy_id, ip);
3906 if (snprintf_error(sizeof(table_name), ret))
3907 return -1;
3908
3909 if (create_nft_table(dut, policy_id, table_name, ip_ver)) {
3910 sigma_dut_print(dut, DUT_MSG_INFO,
3911 "Failed to create nft table");
3912 return -1;
3913 }
3914
3915 pos = nft_cmd;
3916 len = sizeof(nft_cmd);
3917
3918 ret = snprintf(pos, len,
3919 "nft add rule %s %s OUTPUT oifname \"%s\"",
3920 ip, table_name, dut->station_ifname);
3921 if (snprintf_error(len, ret)) {
3922 sigma_dut_print(dut, DUT_MSG_INFO,
3923 "Failed to create nft cmd %s", nft_cmd);
3924 return -1;
3925 }
3926
3927 pos += ret;
3928 len -= ret;
3929
3930 if (strlen(dscp_policy->src_ip)) {
3931 ret = snprintf(pos, len, " %s saddr %s", ip,
3932 dscp_policy->src_ip);
3933 if (snprintf_error(len, ret))
3934 return -1;
3935
3936 pos += ret;
3937 len -= ret;
3938 }
3939
3940 if (strlen(dscp_policy->dst_ip)) {
3941 ret = snprintf(pos, len, " %s daddr %s", ip,
3942 dscp_policy->dst_ip);
3943 if (snprintf_error(len, ret))
3944 return -1;
3945
3946 pos += ret;
3947 len -= ret;
3948 }
3949
3950 if (dscp_policy->src_port) {
3951 ret = snprintf(pos, len, " %s sport %d",
3952 protocol_to_str(dscp_policy->protocol),
3953 dscp_policy->src_port);
3954 if (snprintf_error(len, ret))
3955 return -1;
3956
3957 pos += ret;
3958 len -= ret;
3959 }
3960
3961 if (dscp_policy->dst_port) {
3962 ret = snprintf(pos, len, " %s dport %d",
3963 protocol_to_str(dscp_policy->protocol),
3964 dscp_policy->dst_port);
3965 if (snprintf_error(len, ret))
3966 return -1;
3967
3968 pos += ret;
3969 len -= ret;
3970 }
3971
3972 if (dscp_policy->start_port && dscp_policy->end_port) {
3973 ret = snprintf(pos, len, " %s dport %d-%d",
3974 protocol_to_str(dscp_policy->protocol),
3975 dscp_policy->start_port,
3976 dscp_policy->end_port);
3977 if (snprintf_error(len, ret))
3978 return -1;
3979
3980 pos += ret;
3981 len -= ret;
3982 }
3983
3984 ret = snprintf(pos, len, " counter %s dscp set 0x%0x", ip,
3985 dscp_policy->dscp);
3986 if (snprintf_error(len, ret))
3987 return -1;
3988
3989 ret = system(nft_cmd);
3990 sigma_dut_print(dut, DUT_MSG_INFO, "nft rule: %s err: %d",
3991 nft_cmd, ret);
3992
3993 return ret;
3994}
3995
3996
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303997static int add_iptable_rule(struct sigma_dut *dut,
3998 struct dscp_policy_data *dscp_policy)
3999{
4000 char ip_cmd[1000];
4001 char *pos;
4002 int ret, len;
4003 enum ip_version ip_ver = dscp_policy->ip_version;
4004 struct dscp_policy_data *active_policy = dut->dscp_policy_table;
4005 int ipv4_rule_num = 1, ipv6_rule_num = 1;
4006
4007 pos = ip_cmd;
4008 len = sizeof(ip_cmd);
4009
4010 /*
4011 * DSCP target in the mangle table doesn't stop processing of rules
4012 * so to make sure the most granular rule is applied last, add the new
4013 * rules in granularity increasing order.
4014 */
4015 while (active_policy) {
4016 /*
4017 * Domain name rules are managed in sigma_dut thus don't count
4018 * them while counting the number of active rules.
4019 */
4020 if (strlen(active_policy->domain_name)) {
4021 active_policy = active_policy->next;
4022 continue;
4023 }
4024
4025 if (active_policy->granularity_score >
4026 dscp_policy->granularity_score)
4027 break;
4028
4029 if (active_policy->ip_version == IPV6)
4030 ipv6_rule_num++;
4031 else
4032 ipv4_rule_num++;
4033
4034 active_policy = active_policy->next;
4035 }
4036
4037 ret = snprintf(pos, len,
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304038 "%s -t mangle -I OUTPUT %d -o %s",
4039#ifdef ANDROID
4040 ip_ver == IPV6 ? "/system/bin/ip6tables" : "/system/bin/iptables",
4041#else /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304042 ip_ver == IPV6 ? "ip6tables" : "iptables",
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304043#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304044 ip_ver == IPV6 ? ipv6_rule_num : ipv4_rule_num,
4045 dut->station_ifname);
4046 if (snprintf_error(len, ret)) {
4047 sigma_dut_print(dut, DUT_MSG_INFO,
4048 "Failed to create iptables command %s", ip_cmd);
4049 return -1;
4050 }
4051
4052 pos += ret;
4053 len -= ret;
4054
4055 if (strlen(dscp_policy->src_ip)) {
4056 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
4057 if (snprintf_error(len, ret)) {
4058 sigma_dut_print(dut, DUT_MSG_INFO,
4059 "Error in adding src_ip %s",
4060 dscp_policy->src_ip);
4061 return -1;
4062 }
4063 pos += ret;
4064 len -= ret;
4065 }
4066
4067 if (strlen(dscp_policy->dst_ip)) {
4068 ret = snprintf(pos, len, " -d %s", dscp_policy->dst_ip);
4069 if (snprintf_error(len, ret)) {
4070 sigma_dut_print(dut, DUT_MSG_INFO,
4071 "Error in adding dst_ip %s",
4072 dscp_policy->dst_ip);
4073 return -1;
4074 }
4075 pos += ret;
4076 len -= ret;
4077 }
4078
4079 if (dscp_policy->src_port || dscp_policy->dst_port ||
4080 (dscp_policy->start_port && dscp_policy->end_port)) {
4081 ret = snprintf(pos, len, " -p %s",
4082 protocol_to_str(dscp_policy->protocol));
4083 if (snprintf_error(len, ret)) {
4084 sigma_dut_print(dut, DUT_MSG_INFO,
4085 "Error in adding protocol %d in add command",
4086 dscp_policy->protocol);
4087 return -1;
4088 }
4089 pos += ret;
4090 len -= ret;
4091 }
4092
4093 if (dscp_policy->src_port) {
4094 ret = snprintf(pos, len, " --sport %d", dscp_policy->src_port);
4095 if (snprintf_error(len, ret)) {
4096 sigma_dut_print(dut, DUT_MSG_INFO,
4097 "Error in adding src_port %d",
4098 dscp_policy->src_port);
4099 return -1;
4100 }
4101 pos += ret;
4102 len -= ret;
4103 }
4104
4105 if (dscp_policy->dst_port) {
4106 ret = snprintf(pos, len, " --dport %d", dscp_policy->dst_port);
4107 if (snprintf_error(len, ret)) {
4108 sigma_dut_print(dut, DUT_MSG_INFO,
4109 "Error in adding dst_port %d",
4110 dscp_policy->dst_port);
4111 return -1;
4112 }
4113 pos += ret;
4114 len -= ret;
4115 }
4116
4117 if (dscp_policy->start_port && dscp_policy->end_port) {
4118 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
4119 dscp_policy->start_port, dscp_policy->end_port);
4120 if (snprintf_error(len, ret)) {
4121 sigma_dut_print(dut, DUT_MSG_INFO,
4122 "Error in adding start:end port %d:%d",
4123 dscp_policy->start_port,
4124 dscp_policy->end_port);
4125 return -1;
4126 }
4127 pos += ret;
4128 len -= ret;
4129 }
4130
4131 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
4132 dscp_policy->dscp);
4133 if (snprintf_error(len, ret)) {
4134 sigma_dut_print(dut, DUT_MSG_INFO,
4135 "Error in adding dscp %0x", dscp_policy->dscp);
4136 return -1;
4137 }
4138 ret = system(ip_cmd);
4139 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
4140 ip_cmd, ret);
4141
4142 return ret;
4143}
4144
4145
4146static int add_dscp_policy_rule(struct sigma_dut *dut,
4147 struct dscp_policy_data *dscp_policy)
4148{
4149 return dut->dscp_use_iptables ? add_iptable_rule(dut, dscp_policy) :
4150 add_nft_rule(dut, dscp_policy);
4151}
4152
4153
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304154static void clear_all_dscp_policies(struct sigma_dut *dut)
4155{
4156 free_dscp_policy_table(dut);
4157
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304158 if (dut->dscp_use_iptables) {
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304159#ifdef ANDROID
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304160 if (system("/system/bin/iptables -t mangle -F && /system/bin/iptables -t mangle -X") != 0 ||
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304161 system("/system/bin/ip6tables -t mangle -F && /system/bin/ip6tables -t mangle -X") != 0)
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304162 sigma_dut_print(dut, DUT_MSG_ERROR,
4163 "iptables: Failed to flush DSCP policy");
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304164#else /* ANDROID */
4165 if (system("iptables -t mangle -F && iptables -t mangle -X") != 0 ||
4166 system("ip6tables -t mangle -F && ip6tables -t mangle -X") != 0)
4167 sigma_dut_print(dut, DUT_MSG_ERROR,
4168 "iptables: Failed to flush DSCP policy");
4169#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304170 } else {
4171 if (system("nft flush ruleset") != 0)
4172 sigma_dut_print(dut, DUT_MSG_ERROR,
4173 "nftables: Failed to flush DSCP policy");
4174 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304175}
4176
4177
4178static int send_dscp_response(struct sigma_dut *dut,
4179 struct dscp_policy_status *status_list,
4180 int num_status)
4181{
4182 int rem_len, ret;
4183 char buf[200] = "", *pos, cmd[256];
4184
4185 pos = buf;
4186 rem_len = sizeof(buf);
4187
4188 ret = snprintf(pos, rem_len, " solicited");
4189 if (snprintf_error(rem_len, ret)) {
4190 sigma_dut_print(dut, DUT_MSG_ERROR,
4191 "Failed to write DSCP policy response command");
4192 return -1;
4193 }
4194 pos += ret;
4195 rem_len -= ret;
4196
4197 for (int i = 0; i < num_status; i++) {
4198 ret = snprintf(pos, rem_len, " policy_id=%d status=%d",
4199 status_list[i].id, status_list[i].status);
4200 if (snprintf_error(rem_len, ret)) {
4201 sigma_dut_print(dut, DUT_MSG_ERROR,
4202 "Failed to wite DSCP policy response");
4203 return -1;
4204 }
4205
4206 pos += ret;
4207 rem_len -= ret;
4208 }
4209
4210 ret = snprintf(cmd, sizeof(cmd), "DSCP_RESP%s", buf);
4211 if (snprintf_error(sizeof(cmd), ret)) {
4212 sigma_dut_print(dut, DUT_MSG_ERROR,
4213 "Failed to create DSCP Policy Response frame");
4214 return -1;
4215 }
4216
4217 if (wpa_command(dut->station_ifname, cmd) != 0) {
4218 sigma_dut_print(dut, DUT_MSG_ERROR,
4219 "Failed to send DSCP Policy Response frame");
4220 return -1;
4221 }
4222
4223 sigma_dut_print(dut, DUT_MSG_DEBUG,
4224 "DSCP Policy Response frame sent: %s", cmd);
4225 return 0;
4226}
4227
4228
4229#ifdef ANDROID
4230static void thread_cancel_handler(int sig)
4231{
4232 if (sig == SIGUSR1)
4233 pthread_exit(0);
4234}
4235#endif /* ANDROID */
4236
4237
4238static void * mon_dscp_policies(void *ptr)
4239{
4240 struct sigma_dut *dut = ptr;
4241 int ret, policy_id;
4242 struct wpa_ctrl *ctrl;
4243 char buf[4096], *pos, *end;
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304244 struct dscp_policy_data *policy = NULL, *current_policy, *prev_policy;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304245 struct dscp_policy_status status_list[10];
4246 int num_status = 0;
4247 const char *events[] = {
4248 "CTRL-EVENT-DISCONNECTED",
4249 "CTRL-EVENT-DSCP-POLICY",
4250 NULL
4251 };
4252#ifdef ANDROID
4253 struct sigaction actions;
4254#endif /* ANDROID */
4255
4256 ctrl = open_wpa_mon(get_station_ifname(dut));
4257 if (!ctrl) {
4258 sigma_dut_print(dut, DUT_MSG_ERROR,
4259 "Failed to open wpa_supplicant monitor connection");
4260 return NULL;
4261 }
4262
4263#ifdef ANDROID
4264 memset(&actions, 0, sizeof(actions));
4265 sigemptyset(&actions.sa_mask);
4266 actions.sa_flags = 0;
4267 actions.sa_handler = thread_cancel_handler;
4268 if (sigaction(SIGUSR1, &actions, NULL) == -1) {
4269 sigma_dut_print(dut, DUT_MSG_ERROR,
4270 "Failed to register exit handler for %s",
4271 __func__);
4272 wpa_ctrl_detach(ctrl);
4273 wpa_ctrl_close(ctrl);
4274 return NULL;
4275 }
4276#endif /* ANDROID */
4277
4278 while (1) {
4279 ret = get_wpa_cli_events_timeout(dut, ctrl, events,
4280 buf, sizeof(buf), 0);
4281
4282 if (ret || strlen(buf) == 0) {
4283 sigma_dut_print(dut, DUT_MSG_INFO,
4284 "Did not receive any event");
4285 continue;
4286 }
4287
4288 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4289 clear_all_dscp_policies(dut);
4290 break;
4291 }
4292
4293 if (strstr(buf, "request_start")) {
4294 num_status = 0;
4295 if (strstr(buf, "clear_all"))
4296 clear_all_dscp_policies(dut);
4297 continue;
4298 }
4299
4300 if (strstr(buf, "request_end")) {
4301 send_dscp_response(dut, status_list, num_status);
4302 continue;
4303 }
4304
4305 if (!strstr(buf, "add") && !strstr(buf, "remove") &&
4306 !strstr(buf, "reject")) {
4307 sigma_dut_print(dut, DUT_MSG_DEBUG, "Ignore event: %s",
4308 buf);
4309 continue;
4310 }
4311
4312 pos = strstr(buf, "policy_id=");
4313 if (!pos) {
4314 sigma_dut_print(dut, DUT_MSG_INFO,
4315 "Policy id not present");
4316 continue;
4317 }
4318 policy_id = atoi(pos + 10);
4319
4320 if (num_status >= ARRAY_SIZE(status_list)) {
4321 sigma_dut_print(dut, DUT_MSG_INFO,
4322 "Max policies allowed per DSCP request reached. Drop policy id %d request",
4323 policy_id);
4324 continue;
4325 }
4326 status_list[num_status].id = policy_id;
4327
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05304328 if (dut->reject_dscp_policies) {
4329 status_list[num_status].status =
4330 dut->dscp_reject_resp_code;
4331 num_status++;
4332 continue;
4333 }
4334
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304335 if (strstr(buf, "reject"))
4336 goto reject;
4337
4338 /*
4339 * In case of "add" also if policy with same policy id exist it
4340 * shall be removed. So always call remove_dscp_policy().
4341 */
4342 if (remove_dscp_policy(dut, policy_id))
4343 goto reject;
4344
4345 if (strstr(buf, "remove"))
4346 goto success;
4347
4348 policy = malloc(sizeof(*policy));
4349 if (!policy)
4350 goto reject;
4351
4352 memset(policy, 0, sizeof(*policy));
4353
4354 policy->policy_id = policy_id;
4355
4356 pos = strstr(buf, "dscp=");
4357 if (!pos) {
4358 sigma_dut_print(dut, DUT_MSG_ERROR,
4359 "DSCP info not present");
4360 goto reject;
4361 }
4362 policy->dscp = atoi(pos + 5);
4363
4364 pos = strstr(buf, "ip_version=");
4365 if (!pos) {
4366 sigma_dut_print(dut, DUT_MSG_ERROR,
4367 "IP version info not present");
4368 goto reject;
4369 }
4370 policy->ip_version = atoi(pos + 11);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304371 if (policy->ip_version)
4372 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304373
4374 pos = strstr(buf, "domain_name=");
4375 if (pos) {
4376 pos += 12;
4377 end = strchr(pos, ' ');
4378 if (!end)
4379 end = pos + strlen(pos);
4380
4381 if (end - pos >= (int) sizeof(policy->domain_name))
4382 goto reject;
4383
4384 memcpy(policy->domain_name, pos, end - pos);
4385 policy->domain_name[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304386 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304387 }
4388
4389 pos = strstr(buf, "start_port=");
4390 if (pos) {
4391 pos += 11;
4392 policy->start_port = atoi(pos);
4393 }
4394
4395 pos = strstr(buf, "end_port=");
4396 if (pos) {
4397 pos += 9;
4398 policy->end_port = atoi(pos);
4399 }
4400
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304401 if (policy->start_port && policy->end_port)
4402 policy->granularity_score++;
4403
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304404 pos = strstr(buf, "src_ip=");
4405 if (pos) {
4406 pos += 7;
4407 end = strchr(pos, ' ');
4408 if (!end)
4409 end = pos + strlen(pos);
4410
4411 if (end - pos >= (int) sizeof(policy->src_ip))
4412 goto reject;
4413
4414 memcpy(policy->src_ip, pos, end - pos);
4415 policy->src_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304416 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304417 }
4418
4419 pos = strstr(buf, "dst_ip=");
4420 if (pos) {
4421 pos += 7;
4422 end = strchr(pos, ' ');
4423 if (!end)
4424 end = pos + strlen(pos);
4425
4426 if (end - pos >= (int) sizeof(policy->dst_ip))
4427 goto reject;
4428
4429 memcpy(policy->dst_ip, pos, end - pos);
4430 policy->dst_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304431 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304432 }
4433
4434 pos = strstr(buf, "src_port=");
4435 if (pos) {
4436 pos += 9;
4437 policy->src_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304438 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304439 }
4440
4441 pos = strstr(buf, "dst_port=");
4442 if (pos) {
4443 pos += 9;
4444 policy->dst_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304445 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304446 }
4447
4448 pos = strstr(buf, "protocol=");
4449 if (pos) {
4450 pos += 9;
4451 policy->protocol = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304452 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304453 }
4454
4455 /*
4456 * Skip adding nft rules for doman name policies.
4457 * Domain name rules are applied in sigma_dut itself.
4458 */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304459 if (!strlen(policy->domain_name) &&
4460 add_dscp_policy_rule(dut, policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304461 goto reject;
4462
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304463 /*
4464 * Add the new policy in policy table in granularity increasing
4465 * order.
4466 */
4467 current_policy = dut->dscp_policy_table;
4468 prev_policy = NULL;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304469
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304470 while (current_policy) {
4471 if (current_policy->granularity_score >
4472 policy->granularity_score)
4473 break;
4474
4475 prev_policy = current_policy;
4476 current_policy = current_policy->next;
4477 }
4478
4479 if (prev_policy)
4480 prev_policy->next = policy;
4481 else
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304482 dut->dscp_policy_table = policy;
4483
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304484 policy->next = current_policy;
4485
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304486success:
4487 status_list[num_status].status = DSCP_POLICY_SUCCESS;
4488 num_status++;
4489 policy = NULL;
4490 continue;
4491reject:
4492 status_list[num_status].status = DSCP_POLICY_REJECT;
4493 num_status++;
4494 free(policy);
4495 policy = NULL;
4496 }
4497
4498 free_dscp_policy_table(dut);
4499 wpa_ctrl_detach(ctrl);
4500 wpa_ctrl_close(ctrl);
4501
4502 pthread_exit(0);
4503 return NULL;
4504}
4505
4506
4507static void start_dscp_policy_mon_thread(struct sigma_dut *dut)
4508{
4509 /* Create event thread */
4510 pthread_create(&dut->dscp_policy_mon_thread, NULL, &mon_dscp_policies,
4511 (void *) dut);
4512}
4513
4514
4515void stop_dscp_policy_mon_thread(struct sigma_dut *dut)
4516{
4517 if (dut->dscp_policy_mon_thread) {
4518#ifdef ANDROID
4519 /* pthread_cancel not supported in Android */
4520 pthread_kill(dut->dscp_policy_mon_thread, SIGUSR1);
4521#else /* ANDROID */
4522 pthread_cancel(dut->dscp_policy_mon_thread);
4523#endif /* ANDROID */
4524 dut->dscp_policy_mon_thread = 0;
4525 }
4526}
4527
4528
Jouni Malinenf7222712019-06-13 01:50:21 +03004529static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
4530 struct sigma_conn *conn,
4531 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004532{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304533#ifdef NL80211_SUPPORT
4534 const char *intf = get_param(cmd, "Interface");
4535#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004536 const char *ssid = get_param(cmd, "ssid");
4537 const char *wps_param = get_param(cmd, "WPS");
4538 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03004539 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004540 const char *network_mode = get_param(cmd, "network_mode");
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304541 const char *ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004542 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03004543 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004544 int e;
4545 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
4546 struct wpa_ctrl *ctrl = NULL;
4547 int num_network_not_found = 0;
4548 int num_disconnected = 0;
4549 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004550
4551 if (ssid == NULL)
4552 return -1;
4553
Jouni Malinen37d5c692019-08-19 16:56:55 +03004554 dut->server_cert_tod = 0;
4555
Jouni Malinen3c367e82017-06-23 17:01:47 +03004556 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05304557#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004558 if (get_driver_type(dut) == DRIVER_WCN) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304559 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Sunil Dutt44595082018-02-12 19:41:45 +05304560 dut->config_rsnie = 1;
4561 }
4562#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03004563 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
4564 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004565 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03004566 send_resp(dut, conn, SIGMA_ERROR,
4567 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
4568 return 0;
4569 }
4570 }
4571
Jouni Malinen68143132017-09-02 02:34:08 +03004572 if (dut->sae_commit_override) {
4573 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
4574 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004575 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03004576 send_resp(dut, conn, SIGMA_ERROR,
4577 "ErrorCode,Failed to set SAE commit override");
4578 return 0;
4579 }
4580 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304581#ifdef ANDROID
4582 if (dut->fils_hlp)
4583 process_fils_hlp(dut);
4584#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03004585
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004586 if (wps_param &&
4587 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
4588 wps = 1;
4589
4590 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004591 if (dut->program == PROGRAM_60GHZ && network_mode &&
4592 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004593 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004594 "pbss", "1") < 0)
4595 return -2;
4596
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004597 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
4598 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
4599 "parameters not yet set");
4600 return 0;
4601 }
4602 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004603 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004604 return -2;
4605 } else {
4606 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
4607 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004608 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004609 return -2;
4610 }
4611 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05304612 if (strcmp(ssid, dut->infra_ssid) == 0) {
4613 sigma_dut_print(dut, DUT_MSG_DEBUG,
4614 "sta_associate for the most recently added network");
4615 } else if (find_network(dut, ssid) < 0) {
4616 sigma_dut_print(dut, DUT_MSG_DEBUG,
4617 "sta_associate for a previously stored network profile");
4618 send_resp(dut, conn, SIGMA_ERROR,
4619 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004620 return 0;
4621 }
4622
4623 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004624 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004625 "bssid", bssid) < 0) {
4626 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4627 "Invalid bssid argument");
4628 return 0;
4629 }
4630
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304631 if ((dut->program == PROGRAM_WPA3 &&
4632 dut->sta_associate_wait_connect) ||
4633 dut->program == PROGRAM_QM) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004634 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004635 if (!ctrl)
4636 return ERROR_SEND_STATUS;
4637 }
4638
Jouni Malinen46a19b62017-06-23 14:31:27 +03004639 extra[0] = '\0';
4640 if (chan)
4641 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02004642 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03004643 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
4644 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004645 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004646 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
4647 "network id %d on %s",
4648 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004649 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004650 ret = ERROR_SEND_STATUS;
4651 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004652 }
4653 }
4654
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004655 if (!ctrl)
4656 return SUCCESS_SEND_STATUS;
4657
4658 /* Wait for connection result to be able to store server certificate
4659 * hash for trust root override testing
4660 * (dev_exec_action,ServerCertTrust). */
4661
4662 for (e = 0; e < 20; e++) {
4663 const char *events[] = {
4664 "CTRL-EVENT-EAP-PEER-CERT",
4665 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
4666 "CTRL-EVENT-DISCONNECTED",
4667 "CTRL-EVENT-CONNECTED",
4668 "CTRL-EVENT-NETWORK-NOT-FOUND",
4669 NULL
4670 };
4671 char buf[1024];
4672 int res;
4673
4674 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
4675 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02004676 send_resp(dut, conn, SIGMA_COMPLETE,
4677 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004678 ret = STATUS_SENT_ERROR;
4679 break;
4680 }
4681 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
4682 buf);
4683
4684 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
4685 strstr(buf, " depth=0")) {
4686 char *pos = strstr(buf, " hash=");
4687
4688 if (pos) {
4689 char *end;
4690
Jouni Malinen34b19cb2019-08-16 16:37:17 +03004691 if (strstr(buf, " tod=1"))
4692 tod = 1;
4693 else if (strstr(buf, " tod=2"))
4694 tod = 2;
4695 else
4696 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004697 sigma_dut_print(dut, DUT_MSG_DEBUG,
4698 "Server certificate TOD policy: %d",
4699 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03004700 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004701
4702 pos += 6;
4703 end = strchr(pos, ' ');
4704 if (end)
4705 *end = '\0';
4706 strlcpy(dut->server_cert_hash, pos,
4707 sizeof(dut->server_cert_hash));
4708 sigma_dut_print(dut, DUT_MSG_DEBUG,
4709 "Server certificate hash: %s",
4710 dut->server_cert_hash);
4711 }
4712 }
4713
4714 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
4715 send_resp(dut, conn, SIGMA_COMPLETE,
4716 "Result,TLS server certificate validation failed");
4717 ret = STATUS_SENT_ERROR;
4718 break;
4719 }
4720
4721 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
4722 num_network_not_found++;
4723
4724 if (num_network_not_found > 2) {
4725 send_resp(dut, conn, SIGMA_COMPLETE,
4726 "Result,Network not found");
4727 ret = STATUS_SENT_ERROR;
4728 break;
4729 }
4730 }
4731
4732 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4733 num_disconnected++;
4734
4735 if (num_disconnected > 2) {
4736 send_resp(dut, conn, SIGMA_COMPLETE,
4737 "Result,Connection failed");
4738 ret = STATUS_SENT_ERROR;
4739 break;
4740 }
4741 }
4742
4743 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
4744 if (tod >= 0) {
4745 sigma_dut_print(dut, DUT_MSG_DEBUG,
4746 "Network profile TOD policy update: %d -> %d",
4747 dut->sta_tod_policy, tod);
4748 dut->sta_tod_policy = tod;
4749 }
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304750 if (dut->program == PROGRAM_QM) {
4751 unsigned char iface_mac_addr[ETH_ALEN];
4752 char ipv6[100];
4753
4754 if (get_hwaddr(ifname, iface_mac_addr) < 0) {
4755 sigma_dut_print(dut, DUT_MSG_ERROR,
4756 "%s: get_hwaddr %s failed",
4757 __func__, ifname);
4758 ret = ERROR_SEND_STATUS;
4759 break;
4760 }
4761
4762 convert_mac_addr_to_ipv6_lladdr(iface_mac_addr,
4763 ipv6,
4764 sizeof(ipv6));
4765
4766 if (set_ipv6_addr(dut, ipv6, "64", ifname) !=
4767 0) {
4768 ret = ERROR_SEND_STATUS;
4769 break;
4770 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304771 start_dscp_policy_mon_thread(dut);
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304772 }
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004773 break;
4774 }
4775 }
4776done:
4777 if (ctrl) {
4778 wpa_ctrl_detach(ctrl);
4779 wpa_ctrl_close(ctrl);
4780 }
4781 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004782}
4783
4784
4785static int run_hs20_osu(struct sigma_dut *dut, const char *params)
4786{
4787 char buf[500], cmd[200];
4788 int res;
4789
4790 /* Use hs20-osu-client file at the current dir, if found; otherwise use
4791 * default path */
4792 res = snprintf(cmd, sizeof(cmd),
4793 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
4794 file_exists("./hs20-osu-client") ?
4795 "./hs20-osu-client" : "hs20-osu-client",
4796 sigma_wpas_ctrl,
4797 dut->summary_log ? "-s " : "",
4798 dut->summary_log ? dut->summary_log : "");
4799 if (res < 0 || res >= (int) sizeof(cmd))
4800 return -1;
4801
4802 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
4803 if (res < 0 || res >= (int) sizeof(buf))
4804 return -1;
4805 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
4806
4807 if (system(buf) != 0) {
4808 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
4809 return -1;
4810 }
4811 sigma_dut_print(dut, DUT_MSG_DEBUG,
4812 "Completed hs20-osu-client operation");
4813
4814 return 0;
4815}
4816
4817
4818static int download_ppsmo(struct sigma_dut *dut,
4819 struct sigma_conn *conn,
4820 const char *intf,
4821 struct sigma_cmd *cmd)
4822{
4823 const char *name, *path, *val;
4824 char url[500], buf[600], fbuf[100];
4825 char *fqdn = NULL;
4826
4827 name = get_param(cmd, "FileName");
4828 path = get_param(cmd, "FilePath");
4829 if (name == NULL || path == NULL)
4830 return -1;
4831
4832 if (strcasecmp(path, "VendorSpecific") == 0) {
4833 snprintf(url, sizeof(url), "PPS/%s", name);
4834 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
4835 "from the device (%s)", url);
4836 if (!file_exists(url)) {
4837 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
4838 "PPS MO file does not exist");
4839 return 0;
4840 }
4841 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
4842 if (system(buf) != 0) {
4843 send_resp(dut, conn, SIGMA_ERROR,
4844 "errorCode,Failed to copy PPS MO");
4845 return 0;
4846 }
4847 } else if (strncasecmp(path, "http:", 5) != 0 &&
4848 strncasecmp(path, "https:", 6) != 0) {
4849 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4850 "Unsupported FilePath value");
4851 return 0;
4852 } else {
4853 snprintf(url, sizeof(url), "%s/%s", path, name);
4854 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
4855 url);
4856 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
4857 remove("pps-tnds.xml");
4858 if (system(buf) != 0) {
4859 send_resp(dut, conn, SIGMA_ERROR,
4860 "errorCode,Failed to download PPS MO");
4861 return 0;
4862 }
4863 }
4864
4865 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
4866 send_resp(dut, conn, SIGMA_ERROR,
4867 "errorCode,Failed to parse downloaded PPSMO");
4868 return 0;
4869 }
4870 unlink("pps-tnds.xml");
4871
4872 val = get_param(cmd, "managementTreeURI");
4873 if (val) {
4874 const char *pos, *end;
4875 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
4876 val);
4877 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
4878 send_resp(dut, conn, SIGMA_ERROR,
4879 "errorCode,Invalid managementTreeURI prefix");
4880 return 0;
4881 }
4882 pos = val + 8;
4883 end = strchr(pos, '/');
4884 if (end == NULL ||
4885 strcmp(end, "/PerProviderSubscription") != 0) {
4886 send_resp(dut, conn, SIGMA_ERROR,
4887 "errorCode,Invalid managementTreeURI postfix");
4888 return 0;
4889 }
4890 if (end - pos >= (int) sizeof(fbuf)) {
4891 send_resp(dut, conn, SIGMA_ERROR,
4892 "errorCode,Too long FQDN in managementTreeURI");
4893 return 0;
4894 }
4895 memcpy(fbuf, pos, end - pos);
4896 fbuf[end - pos] = '\0';
4897 fqdn = fbuf;
4898 sigma_dut_print(dut, DUT_MSG_INFO,
4899 "FQDN from managementTreeURI: %s", fqdn);
4900 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
4901 FILE *f = fopen("pps-fqdn", "r");
4902 if (f) {
4903 if (fgets(fbuf, sizeof(fbuf), f)) {
4904 fbuf[sizeof(fbuf) - 1] = '\0';
4905 fqdn = fbuf;
4906 sigma_dut_print(dut, DUT_MSG_DEBUG,
4907 "Use FQDN %s", fqdn);
4908 }
4909 fclose(f);
4910 }
4911 }
4912
4913 if (fqdn == NULL) {
4914 send_resp(dut, conn, SIGMA_ERROR,
4915 "errorCode,No FQDN specified");
4916 return 0;
4917 }
4918
4919 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4920 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
4921 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4922
4923 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
4924 if (rename("pps.xml", buf) < 0) {
4925 send_resp(dut, conn, SIGMA_ERROR,
4926 "errorCode,Could not move PPS MO");
4927 return 0;
4928 }
4929
4930 if (strcasecmp(path, "VendorSpecific") == 0) {
4931 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
4932 fqdn);
4933 if (system(buf)) {
4934 send_resp(dut, conn, SIGMA_ERROR,
4935 "errorCode,Failed to copy OSU CA cert");
4936 return 0;
4937 }
4938
4939 snprintf(buf, sizeof(buf),
4940 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
4941 fqdn);
4942 if (system(buf)) {
4943 send_resp(dut, conn, SIGMA_ERROR,
4944 "errorCode,Failed to copy AAA CA cert");
4945 return 0;
4946 }
4947 } else {
4948 snprintf(buf, sizeof(buf),
4949 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
4950 fqdn, fqdn);
4951 if (run_hs20_osu(dut, buf) < 0) {
4952 send_resp(dut, conn, SIGMA_ERROR,
4953 "errorCode,Failed to download OSU CA cert");
4954 return 0;
4955 }
4956
4957 snprintf(buf, sizeof(buf),
4958 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
4959 fqdn, fqdn);
4960 if (run_hs20_osu(dut, buf) < 0) {
4961 sigma_dut_print(dut, DUT_MSG_INFO,
4962 "Failed to download AAA CA cert");
4963 }
4964 }
4965
4966 if (file_exists("next-client-cert.pem")) {
4967 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
4968 if (rename("next-client-cert.pem", buf) < 0) {
4969 send_resp(dut, conn, SIGMA_ERROR,
4970 "errorCode,Could not move client certificate");
4971 return 0;
4972 }
4973 }
4974
4975 if (file_exists("next-client-key.pem")) {
4976 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
4977 if (rename("next-client-key.pem", buf) < 0) {
4978 send_resp(dut, conn, SIGMA_ERROR,
4979 "errorCode,Could not move client key");
4980 return 0;
4981 }
4982 }
4983
4984 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
4985 if (run_hs20_osu(dut, buf) < 0) {
4986 send_resp(dut, conn, SIGMA_ERROR,
4987 "errorCode,Failed to configure credential from "
4988 "PPSMO");
4989 return 0;
4990 }
4991
4992 return 1;
4993}
4994
4995
4996static int download_cert(struct sigma_dut *dut,
4997 struct sigma_conn *conn,
4998 const char *intf,
4999 struct sigma_cmd *cmd)
5000{
5001 const char *name, *path;
5002 char url[500], buf[600];
5003
5004 name = get_param(cmd, "FileName");
5005 path = get_param(cmd, "FilePath");
5006 if (name == NULL || path == NULL)
5007 return -1;
5008
5009 if (strcasecmp(path, "VendorSpecific") == 0) {
5010 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
5011 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
5012 "certificate from the device (%s)", url);
5013 if (!file_exists(url)) {
5014 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
5015 "certificate file does not exist");
5016 return 0;
5017 }
5018 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
5019 if (system(buf) != 0) {
5020 send_resp(dut, conn, SIGMA_ERROR,
5021 "errorCode,Failed to copy client "
5022 "certificate");
5023 return 0;
5024 }
5025
5026 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
5027 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
5028 "private key from the device (%s)", url);
5029 if (!file_exists(url)) {
5030 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
5031 "private key file does not exist");
5032 return 0;
5033 }
5034 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
5035 if (system(buf) != 0) {
5036 send_resp(dut, conn, SIGMA_ERROR,
5037 "errorCode,Failed to copy client key");
5038 return 0;
5039 }
5040 } else if (strncasecmp(path, "http:", 5) != 0 &&
5041 strncasecmp(path, "https:", 6) != 0) {
5042 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
5043 "Unsupported FilePath value");
5044 return 0;
5045 } else {
5046 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
5047 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
5048 "certificate/key from %s", url);
5049 snprintf(buf, sizeof(buf),
5050 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
5051 if (system(buf) != 0) {
5052 send_resp(dut, conn, SIGMA_ERROR,
5053 "errorCode,Failed to download client "
5054 "certificate");
5055 return 0;
5056 }
5057
5058 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
5059 {
5060 send_resp(dut, conn, SIGMA_ERROR,
5061 "errorCode,Failed to copy client key");
5062 return 0;
5063 }
5064 }
5065
5066 return 1;
5067}
5068
5069
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005070static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
5071 struct sigma_conn *conn,
5072 struct sigma_cmd *cmd)
5073{
5074 const char *val;
5075 const char *intf = get_param(cmd, "interface");
5076
5077 if (!intf)
5078 return -1;
5079
5080 val = get_param(cmd, "WscIEFragment");
5081 if (val && strcasecmp(val, "enable") == 0) {
5082 sigma_dut_print(dut, DUT_MSG_DEBUG,
5083 "Enable WSC IE fragmentation");
5084
5085 dut->wsc_fragment = 1;
5086 /* set long attributes to force fragmentation */
5087 if (wpa_command(intf, "SET device_name "
5088 WPS_LONG_DEVICE_NAME) < 0)
5089 return -2;
5090 if (wpa_command(intf, "SET manufacturer "
5091 WPS_LONG_MANUFACTURER) < 0)
5092 return -2;
5093 if (wpa_command(intf, "SET model_name "
5094 WPS_LONG_MODEL_NAME) < 0)
5095 return -2;
5096 if (wpa_command(intf, "SET model_number "
5097 WPS_LONG_MODEL_NUMBER) < 0)
5098 return -2;
5099 if (wpa_command(intf, "SET serial_number "
5100 WPS_LONG_SERIAL_NUMBER) < 0)
5101 return -2;
5102 }
5103
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005104 val = get_param(cmd, "RSN_IE");
5105 if (val) {
5106 if (strcasecmp(val, "disable") == 0)
5107 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
5108 else if (strcasecmp(val, "enable") == 0)
5109 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
5110 }
5111
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02005112 val = get_param(cmd, "WpsVersion");
5113 if (val)
5114 dut->wps_forced_version = get_wps_forced_version(dut, val);
5115
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005116 val = get_param(cmd, "WscEAPFragment");
5117 if (val && strcasecmp(val, "enable") == 0)
5118 dut->eap_fragment = 1;
5119
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005120 return 1;
5121}
5122
5123
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005124static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
5125 struct sigma_conn *conn,
5126 const char *intf,
5127 struct sigma_cmd *cmd)
5128{
5129 const char *val;
5130
5131 val = get_param(cmd, "FileType");
5132 if (val && strcasecmp(val, "PPSMO") == 0)
5133 return download_ppsmo(dut, conn, intf, cmd);
5134 if (val && strcasecmp(val, "CERT") == 0)
5135 return download_cert(dut, conn, intf, cmd);
5136 if (val) {
5137 send_resp(dut, conn, SIGMA_ERROR,
5138 "ErrorCode,Unsupported FileType");
5139 return 0;
5140 }
5141
5142 return 1;
5143}
5144
5145
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305146static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
5147 struct sigma_conn *conn,
5148 const char *intf,
5149 struct sigma_cmd *cmd)
5150{
5151 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305152 char buf[1000];
5153 char text[20];
5154 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305155
5156 val = get_param(cmd, "OCESupport");
5157 if (val && strcasecmp(val, "Disable") == 0) {
5158 if (wpa_command(intf, "SET oce 0") < 0) {
5159 send_resp(dut, conn, SIGMA_ERROR,
5160 "ErrorCode,Failed to disable OCE");
5161 return 0;
5162 }
5163 } else if (val && strcasecmp(val, "Enable") == 0) {
5164 if (wpa_command(intf, "SET oce 1") < 0) {
5165 send_resp(dut, conn, SIGMA_ERROR,
5166 "ErrorCode,Failed to enable OCE");
5167 return 0;
5168 }
5169 }
5170
vamsi krishnaa2799492017-12-05 14:28:01 +05305171 val = get_param(cmd, "FILScap");
5172 if (val && (atoi(val) == 1)) {
5173 if (wpa_command(intf, "SET disable_fils 0") < 0) {
5174 send_resp(dut, conn, SIGMA_ERROR,
5175 "ErrorCode,Failed to enable FILS");
5176 return 0;
5177 }
5178 } else if (val && (atoi(val) == 0)) {
5179 if (wpa_command(intf, "SET disable_fils 1") < 0) {
5180 send_resp(dut, conn, SIGMA_ERROR,
5181 "ErrorCode,Failed to disable FILS");
5182 return 0;
5183 }
5184 }
5185
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305186 val = get_param(cmd, "FILSHLP");
5187 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005188 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305189 sizeof(text)) < 0)
5190 return -2;
5191 hwaddr_aton(text, addr);
5192 snprintf(buf, sizeof(buf),
5193 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
5194 "080045100140000040004011399e00000000ffffffff00440043"
5195 "012cb30001010600fd4f46410000000000000000000000000000"
5196 "000000000000"
5197 "%02x%02x%02x%02x%02x%02x"
5198 "0000000000000000000000000000000000000000000000000000"
5199 "0000000000000000000000000000000000000000000000000000"
5200 "0000000000000000000000000000000000000000000000000000"
5201 "0000000000000000000000000000000000000000000000000000"
5202 "0000000000000000000000000000000000000000000000000000"
5203 "0000000000000000000000000000000000000000000000000000"
5204 "0000000000000000000000000000000000000000000000000000"
5205 "0000000000000000000000000000000000000000638253633501"
5206 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
5207 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
5208 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
5209 if (wpa_command(intf, buf)) {
5210 send_resp(dut, conn, SIGMA_ERROR,
5211 "ErrorCode,Failed to add HLP");
5212 return 0;
5213 }
5214 dut->fils_hlp = 1;
5215 }
5216
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305217 return 1;
5218}
5219
5220
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005221static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
5222 const char *val)
5223{
5224 int counter = 0;
5225 char token[50];
5226 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305227 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005228
Peng Xub8fc5cc2017-05-10 17:27:28 -07005229 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005230 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305231 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005232 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005233 if (strcmp(result, "disable") == 0)
5234 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
5235 else
5236 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305237 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005238 counter++;
5239 }
5240}
5241
5242
5243static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
5244 const char *val)
5245{
5246 char buf[100];
5247
5248 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
5249 if (system(buf) != 0) {
5250 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
5251 }
5252}
5253
5254
5255static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5256 const char *val)
5257{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005258 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005259 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005260 }
5261}
5262
5263
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005264static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5265 const char *val)
5266{
5267#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005268 int wmmenable = 1;
5269
5270 if (val &&
5271 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
5272 wmmenable = 0;
5273
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305274 return wcn_wifi_test_config_set_u8(
5275 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
5276 wmmenable);
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005277#else /* NL80211_SUPPORT */
5278 sigma_dut_print(dut, DUT_MSG_ERROR,
5279 "WMM cannot be changed without NL80211_SUPPORT defined");
5280 return -1;
5281#endif /* NL80211_SUPPORT */
5282}
5283
5284
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005285static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
5286 const char *val)
5287{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005288 int sgi20;
5289
5290 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5291
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005292 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005293}
5294
5295
5296static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
5297 const char *val)
5298{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305299 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005300
5301 /* Disable Tx Beam forming when using a fixed rate */
5302 ath_disable_txbf(dut, intf);
5303
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305304 v = atoi(val);
5305 if (v < 0 || v > 32) {
5306 sigma_dut_print(dut, DUT_MSG_ERROR,
5307 "Invalid Fixed MCS rate: %d", v);
5308 return;
5309 }
5310 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005311
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005312 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005313
5314 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005315 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005316}
5317
5318
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005319static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
5320 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005321{
5322 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305323 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005324
5325 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
5326 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
5327 else
5328 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5329
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305330 ret = system(buf);
5331#ifdef NL80211_SUPPORT
5332 if (ret) {
5333 int value = (strcasecmp(val, "Enable") == 0) ? 2 : 1;
5334
5335 ret = sta_config_params(dut, intf, STA_SET_TX_MSDU, value);
5336 ret |= sta_config_params(dut, intf, STA_SET_RX_MSDU, value);
5337 }
5338#endif /* NL80211_SUPPORT */
5339 if (ret)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005340 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
5341}
5342
5343
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005344static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
5345 int ampdu)
5346{
5347 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005348 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005349
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005350 if (ampdu)
5351 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005352 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
5353 if (system(buf) != 0) {
5354 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
5355 return -1;
5356 }
5357
5358 return 0;
5359}
5360
5361
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005362static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5363 const char *val)
5364{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005365 run_iwpriv(dut, intf, "tx_stbc %s", val);
5366 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005367}
5368
5369
5370static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
5371 const char *val)
5372{
5373 char buf[60];
5374
Peng Xucc317ed2017-05-18 16:44:37 -07005375 if (strcmp(val, "160") == 0) {
5376 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
5377 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005378 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5379 } else if (strcmp(val, "40") == 0) {
5380 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
5381 } else if (strcmp(val, "20") == 0) {
5382 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
5383 } else if (strcasecmp(val, "Auto") == 0) {
5384 buf[0] = '\0';
5385 } else {
5386 sigma_dut_print(dut, DUT_MSG_ERROR,
5387 "WIDTH/CTS_WIDTH value not supported");
5388 return -1;
5389 }
5390
5391 if (buf[0] != '\0' && system(buf) != 0) {
5392 sigma_dut_print(dut, DUT_MSG_ERROR,
5393 "Failed to set WIDTH/CTS_WIDTH");
5394 return -1;
5395 }
5396
5397 return 0;
5398}
5399
5400
5401int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
5402 const char *intf, const char *val)
5403{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005404 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005405 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005406 dut->chwidth = 0;
5407 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005408 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005409 dut->chwidth = 0;
5410 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005411 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005412 dut->chwidth = 1;
5413 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005414 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005415 dut->chwidth = 2;
5416 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005417 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005418 dut->chwidth = 3;
5419 } else {
5420 send_resp(dut, conn, SIGMA_ERROR,
5421 "ErrorCode,WIDTH not supported");
5422 return -1;
5423 }
5424
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005425 return 0;
5426}
5427
5428
5429static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
5430 const char *val)
5431{
5432 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07005433 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005434
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005435 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005436 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005437 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005438 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005439 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005440 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005441 } else {
5442 sigma_dut_print(dut, DUT_MSG_ERROR,
5443 "SP_STREAM value not supported");
5444 return -1;
5445 }
5446
5447 if (system(buf) != 0) {
5448 sigma_dut_print(dut, DUT_MSG_ERROR,
5449 "Failed to set SP_STREAM");
5450 return -1;
5451 }
5452
Arif Hussainac6c5112018-05-25 17:34:00 -07005453 dut->sta_nss = sta_nss;
5454
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005455 return 0;
5456}
5457
5458
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305459static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5460 const char *val)
5461{
5462 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305463 int ret;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305464
5465 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305466 ret = system(buf);
5467#ifdef NL80211_SUPPORT
5468 if (ret)
5469 ret = sta_config_params(dut, intf, STA_SET_TX_STBC,
5470 strcmp(val, "0") == 0 ? 0 : 1);
5471#endif /* NL80211_SUPPORT */
5472 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305473 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
5474
5475 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305476 ret = system(buf);
5477#ifdef NL80211_SUPPORT
5478 if (ret)
5479 ret = sta_config_params(dut, intf, STA_SET_RX_STBC,
5480 strcmp(val, "0") == 0 ? 0 : 1);
5481#endif /* NL80211_SUPPORT */
5482 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305483 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
5484}
5485
5486
Ashwini Patil68d02cd2017-01-10 15:39:16 +05305487static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
5488 struct sigma_conn *conn,
5489 const char *intf, int capa)
5490{
5491 char buf[32];
5492
5493 if (capa > 0 && capa < 4) {
5494 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
5495 if (wpa_command(intf, buf) < 0) {
5496 send_resp(dut, conn, SIGMA_ERROR,
5497 "ErrorCode, Failed to set cellular data capability");
5498 return 0;
5499 }
5500 return 1;
5501 }
5502
5503 sigma_dut_print(dut, DUT_MSG_ERROR,
5504 "Invalid Cellular data capability: %d", capa);
5505 send_resp(dut, conn, SIGMA_INVALID,
5506 "ErrorCode,Invalid cellular data capability");
5507 return 0;
5508}
5509
5510
Ashwini Patil9183fdb2017-04-13 16:58:25 +05305511static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
5512 const char *intf, const char *val)
5513{
5514 if (strcasecmp(val, "Disable") == 0) {
5515 if (wpa_command(intf, "SET roaming 0") < 0) {
5516 send_resp(dut, conn, SIGMA_ERROR,
5517 "ErrorCode,Failed to disable roaming");
5518 return 0;
5519 }
5520 return 1;
5521 }
5522
5523 if (strcasecmp(val, "Enable") == 0) {
5524 if (wpa_command(intf, "SET roaming 1") < 0) {
5525 send_resp(dut, conn, SIGMA_ERROR,
5526 "ErrorCode,Failed to enable roaming");
5527 return 0;
5528 }
5529 return 1;
5530 }
5531
5532 sigma_dut_print(dut, DUT_MSG_ERROR,
5533 "Invalid value provided for roaming: %s", val);
5534 send_resp(dut, conn, SIGMA_INVALID,
5535 "ErrorCode,Unknown value provided for Roaming");
5536 return 0;
5537}
5538
5539
Ashwini Patila75de5a2017-04-13 16:35:05 +05305540static int mbo_set_assoc_disallow(struct sigma_dut *dut,
5541 struct sigma_conn *conn,
5542 const char *intf, const char *val)
5543{
5544 if (strcasecmp(val, "Disable") == 0) {
5545 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
5546 send_resp(dut, conn, SIGMA_ERROR,
5547 "ErrorCode,Failed to disable Assoc_disallow");
5548 return 0;
5549 }
5550 return 1;
5551 }
5552
5553 if (strcasecmp(val, "Enable") == 0) {
5554 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
5555 send_resp(dut, conn, SIGMA_ERROR,
5556 "ErrorCode,Failed to enable Assoc_disallow");
5557 return 0;
5558 }
5559 return 1;
5560 }
5561
5562 sigma_dut_print(dut, DUT_MSG_ERROR,
5563 "Invalid value provided for Assoc_disallow: %s", val);
5564 send_resp(dut, conn, SIGMA_INVALID,
5565 "ErrorCode,Unknown value provided for Assoc_disallow");
5566 return 0;
5567}
5568
5569
Ashwini Patilc63161e2017-04-13 16:30:23 +05305570static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
5571 const char *intf, const char *val)
5572{
5573 if (strcasecmp(val, "Reject") == 0) {
5574 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
5575 send_resp(dut, conn, SIGMA_ERROR,
5576 "ErrorCode,Failed to Reject BTM Request");
5577 return 0;
5578 }
5579 return 1;
5580 }
5581
5582 if (strcasecmp(val, "Accept") == 0) {
5583 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
5584 send_resp(dut, conn, SIGMA_ERROR,
5585 "ErrorCode,Failed to Accept BTM Request");
5586 return 0;
5587 }
5588 return 1;
5589 }
5590
5591 sigma_dut_print(dut, DUT_MSG_ERROR,
5592 "Invalid value provided for BSS_Transition: %s", val);
5593 send_resp(dut, conn, SIGMA_INVALID,
5594 "ErrorCode,Unknown value provided for BSS_Transition");
5595 return 0;
5596}
5597
5598
Ashwini Patil00402582017-04-13 12:29:39 +05305599static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
5600 struct sigma_conn *conn,
5601 const char *intf,
5602 struct sigma_cmd *cmd)
5603{
5604 const char *ch, *pref, *op_class, *reason;
5605 char buf[120];
5606 int len, ret;
5607
5608 pref = get_param(cmd, "Ch_Pref");
5609 if (!pref)
5610 return 1;
5611
5612 if (strcasecmp(pref, "clear") == 0) {
5613 free(dut->non_pref_ch_list);
5614 dut->non_pref_ch_list = NULL;
5615 } else {
5616 op_class = get_param(cmd, "Ch_Op_Class");
5617 if (!op_class) {
5618 send_resp(dut, conn, SIGMA_INVALID,
5619 "ErrorCode,Ch_Op_Class not provided");
5620 return 0;
5621 }
5622
5623 ch = get_param(cmd, "Ch_Pref_Num");
5624 if (!ch) {
5625 send_resp(dut, conn, SIGMA_INVALID,
5626 "ErrorCode,Ch_Pref_Num not provided");
5627 return 0;
5628 }
5629
5630 reason = get_param(cmd, "Ch_Reason_Code");
5631 if (!reason) {
5632 send_resp(dut, conn, SIGMA_INVALID,
5633 "ErrorCode,Ch_Reason_Code not provided");
5634 return 0;
5635 }
5636
5637 if (!dut->non_pref_ch_list) {
5638 dut->non_pref_ch_list =
5639 calloc(1, NON_PREF_CH_LIST_SIZE);
5640 if (!dut->non_pref_ch_list) {
5641 send_resp(dut, conn, SIGMA_ERROR,
5642 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
5643 return 0;
5644 }
5645 }
5646 len = strlen(dut->non_pref_ch_list);
5647 ret = snprintf(dut->non_pref_ch_list + len,
5648 NON_PREF_CH_LIST_SIZE - len,
5649 " %s:%s:%s:%s", op_class, ch, pref, reason);
5650 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
5651 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
5652 dut->non_pref_ch_list);
5653 } else {
5654 sigma_dut_print(dut, DUT_MSG_ERROR,
5655 "snprintf failed for non_pref_list, ret = %d",
5656 ret);
5657 send_resp(dut, conn, SIGMA_ERROR,
5658 "ErrorCode,snprintf failed");
5659 free(dut->non_pref_ch_list);
5660 dut->non_pref_ch_list = NULL;
5661 return 0;
5662 }
5663 }
5664
5665 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
5666 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
5667 if (ret < 0 || ret >= (int) sizeof(buf)) {
5668 sigma_dut_print(dut, DUT_MSG_DEBUG,
5669 "snprintf failed for set non_pref_chan, ret: %d",
5670 ret);
5671 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
5672 return 0;
5673 }
5674
5675 if (wpa_command(intf, buf) < 0) {
5676 send_resp(dut, conn, SIGMA_ERROR,
5677 "ErrorCode,Failed to set non-preferred channel list");
5678 return 0;
5679 }
5680
5681 return 1;
5682}
5683
5684
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005685#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005686
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005687static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
5688 uint8_t cfg)
5689{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305690 return wcn_wifi_test_config_set_u8(
5691 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
5692 cfg);
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005693}
5694
5695
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005696static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
5697 enum he_fragmentation_val frag)
5698{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305699 return wcn_wifi_test_config_set_u8(
5700 dut, intf,
5701 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION, frag);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005702}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005703
5704
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08005705int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
5706 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005707{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305708 return wcn_wifi_test_config_set_u8(
5709 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF, ltf);
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005710}
5711
5712
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005713static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
5714 int noack, enum qca_wlan_ac_type ac)
5715{
5716 struct nl_msg *msg;
5717 int ret = 0;
5718 struct nlattr *params;
5719 int ifindex;
5720
5721 ifindex = if_nametoindex(intf);
5722 if (ifindex == 0) {
5723 sigma_dut_print(dut, DUT_MSG_ERROR,
5724 "%s: Index for interface %s failed",
5725 __func__, intf);
5726 return -1;
5727 }
5728
5729 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5730 NL80211_CMD_VENDOR)) ||
5731 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5732 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5733 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5734 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5735 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5736 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
5737 noack) ||
5738 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
5739 ac)) {
5740 sigma_dut_print(dut, DUT_MSG_ERROR,
5741 "%s: err in adding vendor_cmd and vendor_data",
5742 __func__);
5743 nlmsg_free(msg);
5744 return -1;
5745 }
5746 nla_nest_end(msg, params);
5747
5748 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5749 if (ret) {
5750 sigma_dut_print(dut, DUT_MSG_ERROR,
5751 "%s: err in send_and_recv_msgs, ret=%d",
5752 __func__, ret);
5753 }
5754 return ret;
5755}
5756
5757
5758static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
5759 const char *val)
5760{
5761 int noack, ret;
5762 char token[100];
5763 char *result;
5764 char *saveptr;
5765 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
5766
5767 strlcpy(token, val, sizeof(token));
5768 token[sizeof(token) - 1] = '\0';
5769 result = strtok_r(token, ":", &saveptr);
5770 while (result) {
5771 noack = strcasecmp(result, "Disable") != 0;
5772 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
5773 if (ret) {
5774 sigma_dut_print(dut, DUT_MSG_ERROR,
5775 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
5776 ac, ret);
5777 }
5778 result = strtok_r(NULL, ":", &saveptr);
5779 ac++;
5780 }
5781}
5782
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305783
5784static int nlvendor_sta_set_phymode(struct sigma_dut *dut, const char *intf,
5785 enum qca_wlan_vendor_phy_mode val)
5786{
5787 struct nl_msg *msg;
5788 struct nlattr *params;
5789 int ifindex, ret;
5790
5791 ifindex = if_nametoindex(intf);
5792 if (ifindex == 0) {
5793 sigma_dut_print(dut, DUT_MSG_ERROR,
5794 "%s: Index for interface %s not found",
5795 __func__, intf);
5796 return -1;
5797 }
5798
5799 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5800 NL80211_CMD_VENDOR);
5801 if (!msg) {
5802 sigma_dut_print(dut, DUT_MSG_ERROR,
5803 "%s: err in adding vendor_cmd", __func__);
5804 return -1;
5805 }
5806
5807 if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5808 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5809 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION)) {
5810 sigma_dut_print(dut, DUT_MSG_ERROR,
5811 "%s: err in adding vendor_attr", __func__);
5812 nlmsg_free(msg);
5813 return -1;
5814 }
5815
5816 params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
5817 if (!params || nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE,
5818 val)) {
5819 sigma_dut_print(dut, DUT_MSG_ERROR,
5820 "%s: err in adding vendor_data", __func__);
5821 nlmsg_free(msg);
5822 return -1;
5823 }
5824
5825 nla_nest_end(msg, params);
5826 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5827 if (ret) {
5828 sigma_dut_print(dut, DUT_MSG_ERROR,
5829 "%s: err in send_and_recv_msgs, ret=%d (%s)",
5830 __func__, ret, strerror(-ret));
5831 return ret;
5832 }
5833
5834 return 0;
5835}
5836
5837
5838static enum qca_wlan_vendor_phy_mode get_qca_vendor_phymode(const char *val)
5839{
5840 if (strcmp(val, "11a") == 0) {
5841 /* IEEE80211_MODE_11A */
5842 return QCA_WLAN_VENDOR_PHY_MODE_11A;
5843 }
5844
5845 if (strcmp(val, "11g") == 0) {
5846 /* IEEE80211_MODE_11G */
5847 return QCA_WLAN_VENDOR_PHY_MODE_11G;
5848 }
5849
5850 if (strcmp(val, "11b") == 0) {
5851 /* IEEE80211_MODE_11B */
5852 return QCA_WLAN_VENDOR_PHY_MODE_11B;
5853 }
5854
5855 if (strcmp(val, "11n") == 0 ||
5856 strcmp(val, "11nl") == 0 ||
5857 strcmp(val, "11nl(nabg)") == 0) {
5858 /* IEEE80211_MODE_11AGN */
5859 return QCA_WLAN_VENDOR_PHY_MODE_11AGN;
5860 }
5861
5862 if (strcmp(val, "11ng") == 0) {
5863 /* IEEE80211_MODE_11NG_HT40 */
5864 return QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40;
5865 }
5866
5867 if (strcmp(val, "AC") == 0 ||
5868 strcasecmp(val, "11AC") == 0) {
5869 /* IEEE80211_MODE_11AC_VHT80 */
5870 return QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80;
5871 }
5872
5873 if (strcmp(val, "11na") == 0 ||
5874 strcasecmp(val, "11an") == 0) {
5875 /* IEEE80211_MODE_11NA_HT40 */
5876 return QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40;
5877 }
5878
5879 if (strcmp(val, "11ax") == 0 ||
5880 strcmp(val, "auto") == 0) {
5881 /* IEEE80211_MODE_AUTO */
5882 return QCA_WLAN_VENDOR_PHY_MODE_AUTO;
5883 }
5884
5885 return -1;
5886}
5887
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005888#endif /* NL80211_SUPPORT */
5889
5890
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305891static int get_phymode(const char *val)
5892{
5893 if (strcmp(val, "11a") == 0)
5894 return 1; /* IEEE80211_MODE_11A */
5895 if (strcmp(val, "11g") == 0)
5896 return 3; /* IEEE80211_MODE_11G */
5897 if (strcmp(val, "11b") == 0)
5898 return 2; /* IEEE80211_MODE_11B */
5899 if (strcmp(val, "11n") == 0 ||
5900 strcmp(val, "11nl") == 0 ||
5901 strcmp(val, "11nl(nabg)") == 0)
5902 return 22; /* IEEE80211_MODE_11AGN */
5903 if (strcmp(val, "11ng") == 0)
5904 return 13; /* IEEE80211_MODE_11NG_HT40 */
5905 if (strcmp(val, "AC") == 0 ||
5906 strcasecmp(val, "11AC") == 0)
5907 return 19; /* IEEE80211_MODE_11AC_VHT80 */
5908 if (strcmp(val, "11na") == 0 ||
5909 strcasecmp(val, "11an") == 0)
5910 return 14; /* IEEE80211_MODE_11NA_HT40 */
5911 if (strcmp(val, "11ax") == 0 ||
5912 strcmp(val, "auto") == 0)
5913 return 0; /* IEEE80211_MODE_AUTO */
5914 return -1;
5915}
5916
5917
5918static void sta_set_phymode(struct sigma_dut *dut, const char *intf,
5919 const char *val)
5920{
5921 char buf[100];
5922 int len, phymode;
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305923#ifdef NL80211_SUPPORT
5924 enum qca_wlan_vendor_phy_mode qca_phymode;
5925
5926 qca_phymode = get_qca_vendor_phymode(val);
5927 if (qca_phymode == -1) {
5928 sigma_dut_print(dut, DUT_MSG_DEBUG,
5929 "Ignoring mode change for mode: %s",
5930 val);
5931 return;
5932 }
5933
5934 if (nlvendor_sta_set_phymode(dut, intf, qca_phymode) == 0)
5935 return;
5936#endif /* NL80211_SUPPORT */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305937
5938 phymode = get_phymode(val);
5939 if (phymode == -1) {
5940 sigma_dut_print(dut, DUT_MSG_DEBUG,
5941 "Ignoring mode change for mode: %s",
5942 val);
5943 return;
5944 }
5945
5946 len = snprintf(buf, sizeof(buf), "iwpriv %s setphymode %d", intf,
5947 phymode);
5948 if (len < 0 || len >= sizeof(buf)) {
5949 sigma_dut_print(dut, DUT_MSG_ERROR,
5950 "Failed to set phymode");
5951 return;
5952 }
5953
5954 if (system(buf) != 0)
5955 sigma_dut_print(dut, DUT_MSG_ERROR,
5956 "iwpriv setting of phymode failed");
5957}
5958
5959
Jouni Malinenf7222712019-06-13 01:50:21 +03005960static enum sigma_cmd_result
5961cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
5962 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005963{
5964 const char *intf = get_param(cmd, "Interface");
5965 const char *val;
5966
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005967 val = get_param(cmd, "FT_DS");
5968 if (val) {
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05305969 int sta_ft_ds;
5970
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005971 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05305972 sta_ft_ds = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005973 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05305974 sta_ft_ds = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005975 } else {
5976 send_resp(dut, conn, SIGMA_ERROR,
5977 "errorCode,Unsupported value for FT_DS");
5978 return STATUS_SENT_ERROR;
5979 }
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05305980
5981 if (dut->sta_ft_ds != sta_ft_ds &&
5982 get_driver_type(dut) == DRIVER_WCN &&
Shivani Baranwal7aa48602021-09-29 10:53:38 +05305983 sta_config_params(dut, intf, STA_SET_FT_DS,
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05305984 sta_ft_ds) != 0) {
Shivani Baranwal7aa48602021-09-29 10:53:38 +05305985 send_resp(dut, conn, SIGMA_ERROR,
5986 "errorCode,Failed to enable/disable FT_DS");
5987 return STATUS_SENT_ERROR;
5988 }
Veerendranath Jakkam19cc24c2022-03-28 18:47:03 +05305989
5990 dut->sta_ft_ds = sta_ft_ds;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005991 }
5992
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005993 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03005994 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02005995 strcasecmp(val, "HS2-R3") == 0 ||
5996 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005997 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
5998 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005999
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07006000 if (val && strcasecmp(val, "LOC") == 0)
6001 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02006002 if (val && strcasecmp(val, "60GHZ") == 0) {
6003 val = get_param(cmd, "WPS");
6004 if (val && strcasecmp(val, "disable") == 0) {
6005 dut->wps_disable = 1;
6006 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
6007 } else {
6008 /* wps_disable can have other value from the previous
6009 * test, so make sure it has the correct value.
6010 */
6011 dut->wps_disable = 0;
6012 }
6013
6014 val = get_param(cmd, "P2P");
6015 if (val && strcasecmp(val, "disable") == 0)
6016 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
6017 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07006018
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006019 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
6020 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
6021
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006022#ifdef ANDROID_NAN
6023 if (val && strcasecmp(val, "NAN") == 0)
6024 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
6025#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006026#ifdef MIRACAST
6027 if (val && (strcasecmp(val, "WFD") == 0 ||
6028 strcasecmp(val, "DisplayR2") == 0))
6029 return miracast_preset_testparameters(dut, conn, cmd);
6030#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006031
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07006032 if (val &&
6033 (strcasecmp(val, "MBO") == 0 || strcasecmp(val, "HE") == 0)) {
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306034 val = get_param(cmd, "Cellular_Data_Cap");
6035 if (val &&
6036 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
6037 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05306038
6039 val = get_param(cmd, "Ch_Pref");
6040 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
6041 return 0;
6042
Ashwini Patilc63161e2017-04-13 16:30:23 +05306043 val = get_param(cmd, "BSS_Transition");
6044 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
6045 return 0;
6046
Ashwini Patila75de5a2017-04-13 16:35:05 +05306047 val = get_param(cmd, "Assoc_Disallow");
6048 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
6049 return 0;
6050
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306051 val = get_param(cmd, "Roaming");
6052 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
6053 return 0;
6054
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306055 return 1;
6056 }
6057
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306058 if (val && strcasecmp(val, "OCE") == 0)
6059 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
6060
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006061#if 0
6062 val = get_param(cmd, "Supplicant");
6063 if (val && strcasecmp(val, "Default") != 0) {
6064 send_resp(dut, conn, SIGMA_ERROR,
6065 "ErrorCode,Only default(Vendor) supplicant "
6066 "supported");
6067 return 0;
6068 }
6069#endif
6070
6071 val = get_param(cmd, "RTS");
6072 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006073 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006074 case DRIVER_ATHEROS:
6075 ath_sta_set_rts(dut, intf, val);
6076 break;
6077 default:
6078#if 0
6079 send_resp(dut, conn, SIGMA_ERROR,
6080 "ErrorCode,Setting RTS not supported");
6081 return 0;
6082#else
6083 sigma_dut_print(dut, DUT_MSG_DEBUG,
6084 "Setting RTS not supported");
6085 break;
6086#endif
6087 }
6088 }
6089
6090#if 0
6091 val = get_param(cmd, "FRGMNT");
6092 if (val) {
6093 /* TODO */
6094 send_resp(dut, conn, SIGMA_ERROR,
6095 "ErrorCode,Setting FRGMNT not supported");
6096 return 0;
6097 }
6098#endif
6099
6100#if 0
6101 val = get_param(cmd, "Preamble");
6102 if (val) {
6103 /* TODO: Long/Short */
6104 send_resp(dut, conn, SIGMA_ERROR,
6105 "ErrorCode,Setting Preamble not supported");
6106 return 0;
6107 }
6108#endif
6109
6110 val = get_param(cmd, "Mode");
6111 if (val) {
6112 if (strcmp(val, "11b") == 0 ||
6113 strcmp(val, "11g") == 0 ||
6114 strcmp(val, "11a") == 0 ||
6115 strcmp(val, "11n") == 0 ||
6116 strcmp(val, "11ng") == 0 ||
6117 strcmp(val, "11nl") == 0 ||
6118 strcmp(val, "11nl(nabg)") == 0 ||
6119 strcmp(val, "AC") == 0 ||
6120 strcmp(val, "11AC") == 0 ||
6121 strcmp(val, "11ac") == 0 ||
6122 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08006123 strcmp(val, "11an") == 0 ||
6124 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006125 /* STA supports all modes by default */
6126 } else {
6127 send_resp(dut, conn, SIGMA_ERROR,
6128 "ErrorCode,Setting Mode not supported");
6129 return 0;
6130 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006131
6132 /* Change the mode only in case of testbed for HE program
6133 * and for 11a and 11g modes only. */
6134 if (dut->program == PROGRAM_HE &&
6135 dut->device_type == STA_testbed) {
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05306136 sta_set_phymode(dut, intf, val);
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006137 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006138 }
6139
6140 val = get_param(cmd, "wmm");
6141 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006142 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006143 case DRIVER_ATHEROS:
6144 ath_sta_set_wmm(dut, intf, val);
6145 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08006146 case DRIVER_WCN:
6147 wcn_sta_set_wmm(dut, intf, val);
6148 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006149 default:
6150 sigma_dut_print(dut, DUT_MSG_DEBUG,
6151 "Setting wmm not supported");
6152 break;
6153 }
6154 }
6155
6156 val = get_param(cmd, "Powersave");
6157 if (val) {
6158 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006159 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306160 if (set_power_save_wcn(dut, intf, 2) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006161 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006162 }
6163
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006164 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006165 "P2P_SET ps 0") < 0)
6166 return -2;
6167 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006168 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6169 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006170 } else if (strcmp(val, "1") == 0 ||
6171 strcasecmp(val, "PSPoll") == 0 ||
6172 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006173 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306174 if (set_power_save_wcn(dut, intf, 1) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006175 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006176 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006177 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006178 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006179 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006180 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006181 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006182 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006183 "P2P_SET ps 99") < 0)
6184 return -2;
6185 } else if (strcmp(val, "2") == 0 ||
6186 strcasecmp(val, "Fast") == 0) {
6187 /* TODO */
6188 send_resp(dut, conn, SIGMA_ERROR,
6189 "ErrorCode,Powersave=Fast not supported");
6190 return 0;
6191 } else if (strcmp(val, "3") == 0 ||
6192 strcasecmp(val, "PSNonPoll") == 0) {
6193 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006194 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6195 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006196
6197 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006198 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006199 "P2P_SET ps 1") < 0)
6200 return -2;
6201 } else
6202 return -1;
6203 }
6204
6205 val = get_param(cmd, "NoAck");
6206 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006207 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006208 case DRIVER_ATHEROS:
6209 ath_sta_set_noack(dut, intf, val);
6210 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08006211#ifdef NL80211_SUPPORT
6212 case DRIVER_WCN:
6213 wcn_sta_set_noack(dut, intf, val);
6214 break;
6215#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006216 default:
6217 send_resp(dut, conn, SIGMA_ERROR,
6218 "ErrorCode,Setting NoAck not supported");
6219 return 0;
6220 }
6221 }
6222
6223 val = get_param(cmd, "IgnoreChswitchProhibit");
6224 if (val) {
6225 /* TODO: Enabled/disabled */
6226 if (strcasecmp(val, "Enabled") == 0) {
6227 send_resp(dut, conn, SIGMA_ERROR,
6228 "ErrorCode,Enabling IgnoreChswitchProhibit "
6229 "not supported");
6230 return 0;
6231 }
6232 }
6233
6234 val = get_param(cmd, "TDLS");
6235 if (val) {
6236 if (strcasecmp(val, "Disabled") == 0) {
6237 if (wpa_command(intf, "SET tdls_disabled 1")) {
6238 send_resp(dut, conn, SIGMA_ERROR,
6239 "ErrorCode,Failed to disable TDLS");
6240 return 0;
6241 }
6242 } else if (strcasecmp(val, "Enabled") == 0) {
6243 if (wpa_command(intf, "SET tdls_disabled 0")) {
6244 send_resp(dut, conn, SIGMA_ERROR,
6245 "ErrorCode,Failed to enable TDLS");
6246 return 0;
6247 }
6248 } else {
6249 send_resp(dut, conn, SIGMA_ERROR,
6250 "ErrorCode,Unsupported TDLS value");
6251 return 0;
6252 }
6253 }
6254
6255 val = get_param(cmd, "TDLSmode");
6256 if (val) {
6257 if (strcasecmp(val, "Default") == 0) {
6258 wpa_command(intf, "SET tdls_testing 0");
6259 } else if (strcasecmp(val, "APProhibit") == 0) {
6260 if (wpa_command(intf, "SET tdls_testing 0x400")) {
6261 send_resp(dut, conn, SIGMA_ERROR,
6262 "ErrorCode,Failed to enable ignore "
6263 "APProhibit TDLS mode");
6264 return 0;
6265 }
6266 } else if (strcasecmp(val, "HiLoMac") == 0) {
6267 /* STA should respond with TDLS setup req for a TDLS
6268 * setup req */
6269 if (wpa_command(intf, "SET tdls_testing 0x80")) {
6270 send_resp(dut, conn, SIGMA_ERROR,
6271 "ErrorCode,Failed to enable HiLoMac "
6272 "TDLS mode");
6273 return 0;
6274 }
6275 } else if (strcasecmp(val, "WeakSecurity") == 0) {
6276 /*
6277 * Since all security modes are enabled by default when
6278 * Sigma control is used, there is no need to do
6279 * anything here.
6280 */
6281 } else if (strcasecmp(val, "ExistLink") == 0) {
6282 /*
6283 * Since we allow new TDLS Setup Request even if there
6284 * is an existing link, nothing needs to be done for
6285 * this.
6286 */
6287 } else {
6288 /* TODO:
6289 * ExistLink: STA should send TDLS setup req even if
6290 * direct link already exists
6291 */
6292 send_resp(dut, conn, SIGMA_ERROR,
6293 "ErrorCode,Unsupported TDLSmode value");
6294 return 0;
6295 }
6296 }
6297
6298 val = get_param(cmd, "FakePubKey");
6299 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
6300 send_resp(dut, conn, SIGMA_ERROR,
6301 "ErrorCode,Failed to enable FakePubKey");
6302 return 0;
6303 }
6304
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08006305#ifdef NL80211_SUPPORT
6306 val = get_param(cmd, "FrgmntSupport");
6307 if (val) {
6308 if (strcasecmp(val, "Enable") == 0) {
6309 if (sta_set_he_fragmentation(dut, intf,
6310 HE_FRAG_LEVEL1)) {
6311 send_resp(dut, conn, SIGMA_ERROR,
6312 "ErrorCode,Failed to enable HE Fragmentation");
6313 return 0;
6314 }
6315 } else if (strcasecmp(val, "Disable") == 0) {
6316 if (sta_set_he_fragmentation(dut, intf,
6317 HE_FRAG_DISABLE)) {
6318 send_resp(dut, conn, SIGMA_ERROR,
6319 "ErrorCode,Failed to disable HE Fragmentation");
6320 return 0;
6321 }
6322 }
6323 }
6324#endif /* NL80211_SUPPORT */
6325
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306326 val = get_param(cmd, "IncludeMSCSDescriptor");
6327 if (val && strcasecmp(val, "1") == 0) {
6328 char buf[128];
6329 int len;
6330
6331 len = snprintf(buf, sizeof(buf),
Veerendranath Jakkam62cde372020-08-19 18:03:06 +05306332 "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=60000 frame_classifier=045F%032x",
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306333 0);
6334
6335 if (len < 0 || len >= sizeof(buf)) {
6336 sigma_dut_print(dut, DUT_MSG_ERROR,
6337 "Failed to build MSCS Descriptor IE");
6338 return ERROR_SEND_STATUS;
6339 }
6340
6341 if (wpa_command(intf, buf) != 0) {
6342 send_resp(dut, conn, SIGMA_ERROR,
6343 "ErrorCode,Failed to include MSCS descriptor");
6344 return STATUS_SENT_ERROR;
6345 }
6346 }
6347
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306348 val = get_param(cmd, "SCSSupport");
6349 if (val) {
6350 char buf[30];
6351 int disable_scs, len;
6352
6353 if (strcasecmp(val, "Enable") == 0) {
6354 disable_scs = 0;
6355 } else if (strcasecmp(val, "Disable") == 0) {
6356 disable_scs = 1;
6357 } else {
6358 sigma_dut_print(dut, DUT_MSG_ERROR,
6359 "Invalid SCSsupport parameter");
6360 return INVALID_SEND_STATUS;
6361 }
6362
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306363 if (disable_scs || dut->prev_disable_scs_support) {
6364 len = snprintf(buf, sizeof(buf),
6365 "SET disable_scs_support %d",
6366 disable_scs);
6367 if (len < 0 || len >= sizeof(buf) ||
6368 wpa_command(intf, buf) != 0) {
6369 send_resp(dut, conn, SIGMA_ERROR,
6370 "ErrorCode,Failed to update SCS support");
6371 return STATUS_SENT_ERROR;
6372 }
6373 dut->prev_disable_scs_support = disable_scs;
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306374 }
6375 }
6376
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306377 val = get_param(cmd, "MSCSSupport");
6378 if (val) {
6379 char buf[30];
6380 int disable_mscs, len;
6381
6382 if (strcasecmp(val, "Enable") == 0) {
6383 disable_mscs = 0;
6384 } else if (strcasecmp(val, "Disable") == 0) {
6385 disable_mscs = 1;
6386 } else {
6387 sigma_dut_print(dut, DUT_MSG_ERROR,
6388 "Invalid MSCSsupport parameter");
6389 return INVALID_SEND_STATUS;
6390 }
6391
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306392 if (disable_mscs || dut->prev_disable_mscs_support) {
6393 len = snprintf(buf, sizeof(buf),
6394 "SET disable_mscs_support %d",
6395 disable_mscs);
6396 if (len < 0 || len >= sizeof(buf) ||
6397 wpa_command(intf, buf) != 0) {
6398 send_resp(dut, conn, SIGMA_ERROR,
6399 "ErrorCode,Failed to update MSCS support");
6400 return STATUS_SENT_ERROR;
6401 }
6402 dut->prev_disable_mscs_support = disable_mscs;
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306403 }
6404 }
6405
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05306406 val = get_param(cmd, "DSCPPolicyCapability");
6407 if (val) {
6408 char buf[35];
6409 int len;
6410
6411 if (strcasecmp(val, "Enable") == 0) {
6412 len = snprintf(buf, sizeof(buf),
6413 "SET enable_dscp_policy_capa 1");
6414 } else if (strcasecmp(val, "Disable") == 0) {
6415 len = snprintf(buf, sizeof(buf),
6416 "SET enable_dscp_policy_capa 0");
6417 } else {
6418 sigma_dut_print(dut, DUT_MSG_ERROR,
6419 "Invalid DSCP policy parameter");
6420 return INVALID_SEND_STATUS;
6421 }
6422
6423 if (len < 0 || len >= sizeof(buf) ||
6424 wpa_command(intf, buf) != 0) {
6425 send_resp(dut, conn, SIGMA_ERROR,
6426 "ErrorCode,Failed to update DSCP policy capability");
6427 return STATUS_SENT_ERROR;
6428 }
6429 }
6430
6431 val = get_param(cmd, "DSCPPolicyRespParams");
6432 if (val) {
6433 if (strcasecmp(val, "RejectAll") == 0) {
6434 dut->reject_dscp_policies = 1;
6435 dut->dscp_reject_resp_code = DSCP_POLICY_REJECT;
6436 } else if (strcasecmp(val, "AcceptAll") == 0) {
6437 dut->reject_dscp_policies = 0;
6438 }
6439 }
6440
6441 val = get_param(cmd, "DSCPPolicyResp_StatusCode");
6442 if (val)
6443 dut->dscp_reject_resp_code = atoi(val);
6444
Veerendranath Jakkamf6c8ab52022-03-10 05:43:02 -08006445 val = get_param(cmd, "Deauth_Reconnect_Policy");
6446 if (val) {
6447 char buf[35];
6448 int len;
6449
6450 if (strcasecmp(val, "0") == 0) {
6451 len = snprintf(buf, sizeof(buf),
6452 "STA_AUTOCONNECT %d",
6453 dut->autoconnect_default);
6454 } else if (strcasecmp(val, "1") == 0) {
6455 len = snprintf(buf, sizeof(buf),
6456 "STA_AUTOCONNECT 0");
6457 } else if (strcasecmp(val, "2") == 0) {
6458 len = snprintf(buf, sizeof(buf),
6459 "STA_AUTOCONNECT 1");
6460 } else {
6461 sigma_dut_print(dut, DUT_MSG_ERROR,
6462 "Invalid Deauth_Reconnect_Policy");
6463 return INVALID_SEND_STATUS;
6464 }
6465
6466 if (len < 0 || len >= sizeof(buf) ||
6467 wpa_command(intf, buf) != 0) {
6468 send_resp(dut, conn, SIGMA_ERROR,
6469 "ErrorCode,Failed to update Deauth_Reconnect_Policy");
6470 return STATUS_SENT_ERROR;
6471 }
6472 }
6473
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006474 return 1;
6475}
6476
6477
6478static const char * ath_get_radio_name(const char *radio_name)
6479{
6480 if (radio_name == NULL)
6481 return "wifi0";
6482 if (strcmp(radio_name, "wifi1") == 0)
6483 return "wifi1";
6484 if (strcmp(radio_name, "wifi2") == 0)
6485 return "wifi2";
6486 return "wifi0";
6487}
6488
6489
6490static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
6491 const char *val)
6492{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006493 unsigned int vht_mcsmap = 0;
6494 int txchainmask = 0;
6495 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6496
6497 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6498 if (dut->testbed_flag_txsp == 1) {
6499 vht_mcsmap = 0xfffc;
6500 dut->testbed_flag_txsp = 0;
6501 } else {
6502 vht_mcsmap = 0xfffe;
6503 }
6504 txchainmask = 1;
6505 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6506 if (dut->testbed_flag_txsp == 1) {
6507 vht_mcsmap = 0xfff0;
6508 dut->testbed_flag_txsp = 0;
6509 } else {
6510 vht_mcsmap = 0xfffa;
6511 }
6512 txchainmask = 3;
6513 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6514 if (dut->testbed_flag_txsp == 1) {
6515 vht_mcsmap = 0xffc0;
6516 dut->testbed_flag_txsp = 0;
6517 } else {
6518 vht_mcsmap = 0xffea;
6519 }
6520 txchainmask = 7;
6521 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6522 if (dut->testbed_flag_txsp == 1) {
6523 vht_mcsmap = 0xff00;
6524 dut->testbed_flag_txsp = 0;
6525 } else {
6526 vht_mcsmap = 0xffaa;
6527 }
6528 txchainmask = 15;
6529 } else {
6530 if (dut->testbed_flag_txsp == 1) {
6531 vht_mcsmap = 0xffc0;
6532 dut->testbed_flag_txsp = 0;
6533 } else {
6534 vht_mcsmap = 0xffea;
6535 }
6536 }
6537
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006538 if (txchainmask)
6539 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006540
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006541 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006542}
6543
6544
6545static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
6546 const char *val)
6547{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006548 unsigned int vht_mcsmap = 0;
6549 int rxchainmask = 0;
6550 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6551
6552 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6553 if (dut->testbed_flag_rxsp == 1) {
6554 vht_mcsmap = 0xfffc;
6555 dut->testbed_flag_rxsp = 0;
6556 } else {
6557 vht_mcsmap = 0xfffe;
6558 }
6559 rxchainmask = 1;
6560 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6561 if (dut->testbed_flag_rxsp == 1) {
6562 vht_mcsmap = 0xfff0;
6563 dut->testbed_flag_rxsp = 0;
6564 } else {
6565 vht_mcsmap = 0xfffa;
6566 }
6567 rxchainmask = 3;
6568 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6569 if (dut->testbed_flag_rxsp == 1) {
6570 vht_mcsmap = 0xffc0;
6571 dut->testbed_flag_rxsp = 0;
6572 } else {
6573 vht_mcsmap = 0xffea;
6574 }
6575 rxchainmask = 7;
6576 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6577 if (dut->testbed_flag_rxsp == 1) {
6578 vht_mcsmap = 0xff00;
6579 dut->testbed_flag_rxsp = 0;
6580 } else {
6581 vht_mcsmap = 0xffaa;
6582 }
6583 rxchainmask = 15;
6584 } else {
6585 if (dut->testbed_flag_rxsp == 1) {
6586 vht_mcsmap = 0xffc0;
6587 dut->testbed_flag_rxsp = 0;
6588 } else {
6589 vht_mcsmap = 0xffea;
6590 }
6591 }
6592
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006593 if (rxchainmask)
6594 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006595
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006596 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006597}
6598
6599
6600void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
6601{
6602 if (strcasecmp(val, "enable") == 0) {
6603 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
6604 != 0) {
6605 sigma_dut_print(dut, DUT_MSG_ERROR,
6606 "Disable BB_VHTSIGB_CRC_CALC failed");
6607 }
6608
6609 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
6610 != 0) {
6611 sigma_dut_print(dut, DUT_MSG_ERROR,
6612 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6613 }
6614 } else {
6615 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
6616 != 0) {
6617 sigma_dut_print(dut, DUT_MSG_ERROR,
6618 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6619 }
6620
6621 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
6622 != 0) {
6623 sigma_dut_print(dut, DUT_MSG_ERROR,
6624 "Enable BB_VHTSIGB_CRC_CALC failed");
6625 }
6626 }
6627}
6628
6629
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006630static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
6631 const char *val)
6632{
6633 char buf[60];
6634
Shivani Baranwal2a572842021-09-16 12:27:15 +05306635#ifdef NL80211_SUPPORT
6636 enum nl80211_chan_width qca_channel_width;
6637
6638 if (strcmp(val, "20") == 0) {
6639 qca_channel_width = NL80211_CHAN_WIDTH_20;
6640 dut->chwidth = 0;
6641 } else if (strcmp(val, "40") == 0) {
6642 qca_channel_width = NL80211_CHAN_WIDTH_40;
6643 dut->chwidth = 1;
6644 } else if (strcmp(val, "80") == 0) {
6645 qca_channel_width = NL80211_CHAN_WIDTH_80;
6646 dut->chwidth = 2;
6647 } else if (strcmp(val, "160") == 0) {
6648 qca_channel_width = NL80211_CHAN_WIDTH_160;
6649 dut->chwidth = 3;
6650 } else if (strcasecmp(val, "Auto") == 0) {
6651 return 0;
6652 } else {
6653 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6654 val);
6655 return -1;
6656 }
6657 if (sta_config_params(dut, intf, STA_SET_CHAN_WIDTH,
6658 qca_channel_width) == 0)
6659 return 0;
6660#endif /* NL80211_SUPPORT */
6661
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006662 if (strcmp(val, "20") == 0) {
6663 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
6664 dut->chwidth = 0;
6665 } else if (strcmp(val, "40") == 0) {
6666 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
6667 dut->chwidth = 1;
6668 } else if (strcmp(val, "80") == 0) {
6669 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
6670 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05306671 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006672 buf[0] = '\0';
6673 } else {
6674 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6675 val);
6676 return -1;
6677 }
6678
6679 if (buf[0] != '\0' && system(buf) != 0) {
6680 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
6681 return -1;
6682 }
6683
6684 return 0;
6685}
6686
6687
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006688static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
6689 const char *intf, int addbareject)
6690{
6691#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306692 return wcn_wifi_test_config_set_u8(
6693 dut, intf,
6694 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
6695 !addbareject);
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006696#else /* NL80211_SUPPORT */
6697 sigma_dut_print(dut, DUT_MSG_ERROR,
6698 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
6699 return -1;
6700#endif /* NL80211_SUPPORT */
6701}
6702
6703
6704static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
6705 int addbareject)
6706{
6707 int ret;
6708
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006709 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006710 case DRIVER_WCN:
6711 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
6712 if (ret) {
6713 sigma_dut_print(dut, DUT_MSG_ERROR,
6714 "nlvendor_sta_set_addba_reject failed, ret:%d",
6715 ret);
6716 return ret;
6717 }
6718 break;
6719 default:
6720 sigma_dut_print(dut, DUT_MSG_ERROR,
6721 "errorCode,Unsupported ADDBA_REJECT with the current driver");
6722 ret = -1;
6723 break;
6724 }
6725
6726 return ret;
6727}
6728
6729
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006730static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
6731 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006732{
6733#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306734 return wcn_wifi_test_config_set_u8(
6735 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
6736 enable);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006737#else /* NL80211_SUPPORT */
6738 sigma_dut_print(dut, DUT_MSG_ERROR,
6739 "Disable addba not possible without NL80211_SUPPORT defined");
6740 return -1;
6741#endif /* NL80211_SUPPORT */
6742}
6743
6744
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306745#ifdef NL80211_SUPPORT
6746static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6747{
6748 struct nl_msg *msg;
6749 int ret = 0;
6750 int ifindex;
6751
6752 ifindex = if_nametoindex(intf);
6753 if (ifindex == 0) {
6754 sigma_dut_print(dut, DUT_MSG_ERROR,
6755 "%s: Index for interface %s failed",
6756 __func__, intf);
6757 return -1;
6758 }
6759
6760 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6761 NL80211_CMD_SET_WIPHY)) ||
6762 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
6763 sigma_dut_print(dut, DUT_MSG_ERROR,
6764 "%s: err in adding RTS threshold",
6765 __func__);
6766 nlmsg_free(msg);
6767 return -1;
6768 }
6769
6770 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6771 if (ret) {
6772 sigma_dut_print(dut, DUT_MSG_ERROR,
6773 "%s: err in send_and_recv_msgs, ret=%d",
6774 __func__, ret);
6775 }
6776 return ret;
6777}
6778#endif /* NL80211_SUPPORT */
6779
6780
6781static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6782{
6783 char buf[100];
6784
6785#ifdef NL80211_SUPPORT
6786 if (nl80211_sta_set_rts(dut, intf, val) == 0)
6787 return 0;
6788 sigma_dut_print(dut, DUT_MSG_DEBUG,
6789 "Fall back to using iwconfig for setting RTS threshold");
6790#endif /* NL80211_SUPPORT */
6791
6792 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
6793 if (system(buf) != 0) {
6794 sigma_dut_print(dut, DUT_MSG_ERROR,
6795 "Failed to set RTS threshold %d", val);
6796 return -1;
6797 }
6798 return 0;
6799}
6800
6801
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006802static enum sigma_cmd_result
6803cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
6804 struct sigma_conn *conn, struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006805{
6806 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006807 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006808 char buf[128];
6809 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006810
6811 val = get_param(cmd, "40_INTOLERANT");
6812 if (val) {
6813 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6814 /* TODO: iwpriv ht40intol through wpa_supplicant */
6815 send_resp(dut, conn, SIGMA_ERROR,
6816 "ErrorCode,40_INTOLERANT not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006817 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006818 }
6819 }
6820
6821 val = get_param(cmd, "ADDBA_REJECT");
6822 if (val) {
6823 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6824 /* reject any ADDBA with status "decline" */
6825 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006826 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006827 } else {
6828 /* accept ADDBA */
6829 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006830 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006831 }
6832 }
6833
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006834 if (addbareject >= 0 &&
6835 sta_set_addba_reject(dut, intf, addbareject) < 0) {
6836 send_resp(dut, conn, SIGMA_ERROR,
6837 "ErrorCode,set addba_reject failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006838 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006839 }
6840
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006841 val = get_param(cmd, "AMPDU");
6842 if (val) {
6843 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6844 /* enable AMPDU Aggregation */
6845 if (ampdu == 0) {
6846 send_resp(dut, conn, SIGMA_ERROR,
6847 "ErrorCode,Mismatch in "
6848 "addba_reject/ampdu - "
6849 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006850 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006851 }
6852 ampdu = 1;
6853 } else {
6854 /* disable AMPDU Aggregation */
6855 if (ampdu == 1) {
6856 send_resp(dut, conn, SIGMA_ERROR,
6857 "ErrorCode,Mismatch in "
6858 "addba_reject/ampdu - "
6859 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006860 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006861 }
6862 ampdu = 0;
6863 }
6864 }
6865
6866 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006867 int ret;
6868
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006869 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
6870 ampdu ? "Enabling" : "Disabling");
6871 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07006872 if (wpa_command(intf, buf) < 0 &&
6873 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006874 send_resp(dut, conn, SIGMA_ERROR,
6875 "ErrorCode,set aggr failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006876 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006877 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006878
6879 if (ampdu == 0) {
6880 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006881 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006882 if (ret) {
6883 sigma_dut_print(dut, DUT_MSG_ERROR,
6884 "Failed to disable addba, ret:%d",
6885 ret);
6886 }
6887 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006888 }
6889
6890 val = get_param(cmd, "AMSDU");
6891 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006892 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006893 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006894 case DRIVER_WCN:
6895 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006896 break;
6897 default:
6898 if (strcmp(val, "1") == 0 ||
6899 strcasecmp(val, "Enable") == 0) {
6900 /* Enable AMSDU Aggregation */
6901 send_resp(dut, conn, SIGMA_ERROR,
6902 "ErrorCode,AMSDU aggregation not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006903 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006904 }
6905 break;
6906 }
6907 }
6908
6909 val = get_param(cmd, "STBC_RX");
6910 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006911 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006912 case DRIVER_ATHEROS:
6913 ath_sta_set_stbc(dut, intf, val);
6914 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05306915 case DRIVER_WCN:
6916 wcn_sta_set_stbc(dut, intf, val);
6917 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006918 default:
6919 send_resp(dut, conn, SIGMA_ERROR,
6920 "ErrorCode,STBC_RX not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006921 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006922 }
6923 }
6924
6925 val = get_param(cmd, "WIDTH");
6926 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006927 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006928 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006929 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006930 send_resp(dut, conn, SIGMA_ERROR,
6931 "ErrorCode,Failed to set WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006932 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006933 }
6934 break;
6935 case DRIVER_ATHEROS:
6936 if (ath_set_width(dut, conn, intf, val) < 0)
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006937 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006938 break;
6939 default:
6940 sigma_dut_print(dut, DUT_MSG_ERROR,
6941 "Setting WIDTH not supported");
6942 break;
6943 }
6944 }
6945
6946 val = get_param(cmd, "SMPS");
6947 if (val) {
6948 /* TODO: Dynamic/0, Static/1, No Limit/2 */
6949 send_resp(dut, conn, SIGMA_ERROR,
6950 "ErrorCode,SMPS not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006951 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006952 }
6953
6954 val = get_param(cmd, "TXSP_STREAM");
6955 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006956 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006957 case DRIVER_WCN:
6958 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6959 send_resp(dut, conn, SIGMA_ERROR,
6960 "ErrorCode,Failed to set TXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006961 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006962 }
6963 break;
6964 case DRIVER_ATHEROS:
6965 ath_sta_set_txsp_stream(dut, intf, val);
6966 break;
6967 default:
6968 sigma_dut_print(dut, DUT_MSG_ERROR,
6969 "Setting TXSP_STREAM not supported");
6970 break;
6971 }
6972 }
6973
6974 val = get_param(cmd, "RXSP_STREAM");
6975 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006976 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006977 case DRIVER_WCN:
6978 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6979 send_resp(dut, conn, SIGMA_ERROR,
6980 "ErrorCode,Failed to set RXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006981 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006982 }
6983 break;
6984 case DRIVER_ATHEROS:
6985 ath_sta_set_rxsp_stream(dut, intf, val);
6986 break;
6987 default:
6988 sigma_dut_print(dut, DUT_MSG_ERROR,
6989 "Setting RXSP_STREAM not supported");
6990 break;
6991 }
6992 }
6993
6994 val = get_param(cmd, "DYN_BW_SGNL");
6995 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006996 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006997 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08006998 if (strcasecmp(val, "enable") == 0) {
6999 snprintf(buf, sizeof(buf),
7000 "iwpriv %s cwmenable 1", intf);
7001 if (system(buf) != 0) {
7002 sigma_dut_print(dut, DUT_MSG_ERROR,
7003 "iwpriv cwmenable 1 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007004 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08007005 }
7006 } else if (strcasecmp(val, "disable") == 0) {
7007 snprintf(buf, sizeof(buf),
7008 "iwpriv %s cwmenable 0", intf);
7009 if (system(buf) != 0) {
7010 sigma_dut_print(dut, DUT_MSG_ERROR,
7011 "iwpriv cwmenable 0 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007012 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08007013 }
7014 } else {
7015 sigma_dut_print(dut, DUT_MSG_ERROR,
7016 "Unsupported DYN_BW_SGL");
7017 }
7018
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007019 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
7020 if (system(buf) != 0) {
7021 sigma_dut_print(dut, DUT_MSG_ERROR,
7022 "Failed to set cts_cbw in DYN_BW_SGNL");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007023 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007024 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08007025 break;
7026 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07007027 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08007028 ath_config_dyn_bw_sig(dut, intf, val);
7029 break;
7030 default:
7031 sigma_dut_print(dut, DUT_MSG_ERROR,
7032 "Failed to set DYN_BW_SGNL");
7033 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007034 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007035 }
7036
7037 val = get_param(cmd, "RTS_FORCE");
7038 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07007039 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007040 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307041 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007042 sigma_dut_print(dut, DUT_MSG_ERROR,
7043 "Failed to set RTS_FORCE 64");
7044 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03007045 res = snprintf(buf, sizeof(buf),
7046 "wifitool %s beeliner_fw_test 100 1",
7047 intf);
7048 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08007049 sigma_dut_print(dut, DUT_MSG_ERROR,
7050 "wifitool beeliner_fw_test 100 1 failed");
7051 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007052 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307053 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007054 sigma_dut_print(dut, DUT_MSG_ERROR,
7055 "Failed to set RTS_FORCE 2347");
7056 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007057 } else {
7058 send_resp(dut, conn, SIGMA_ERROR,
7059 "ErrorCode,RTS_FORCE value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007060 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007061 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007062 }
7063
7064 val = get_param(cmd, "CTS_WIDTH");
7065 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007066 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007067 case DRIVER_WCN:
7068 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
7069 send_resp(dut, conn, SIGMA_ERROR,
7070 "ErrorCode,Failed to set CTS_WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007071 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007072 }
7073 break;
7074 case DRIVER_ATHEROS:
7075 ath_set_cts_width(dut, intf, val);
7076 break;
7077 default:
7078 sigma_dut_print(dut, DUT_MSG_ERROR,
7079 "Setting CTS_WIDTH not supported");
7080 break;
7081 }
7082 }
7083
7084 val = get_param(cmd, "BW_SGNL");
7085 if (val) {
7086 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007087 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007088 } else if (strcasecmp(val, "Disable") == 0) {
7089 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007090 } else {
7091 send_resp(dut, conn, SIGMA_ERROR,
7092 "ErrorCode,BW_SGNL value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007093 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007094 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007095 }
7096
7097 val = get_param(cmd, "Band");
7098 if (val) {
7099 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
7100 /* STA supports all bands by default */
7101 } else {
7102 send_resp(dut, conn, SIGMA_ERROR,
7103 "ErrorCode,Unsupported Band");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007104 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007105 }
7106 }
7107
7108 val = get_param(cmd, "zero_crc");
7109 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007110 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007111 case DRIVER_ATHEROS:
7112 ath_set_zero_crc(dut, val);
7113 break;
7114 default:
7115 break;
7116 }
7117 }
7118
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007119 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007120}
7121
7122
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007123static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7124{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007125 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007126#ifdef __linux__
7127 case DRIVER_WIL6210:
7128 return wil6210_set_force_mcs(dut, force, mcs);
7129#endif /* __linux__ */
7130 default:
7131 sigma_dut_print(dut, DUT_MSG_ERROR,
7132 "Unsupported sta_set_force_mcs with the current driver");
7133 return -1;
7134 }
7135}
7136
7137
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007138static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
7139{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007140 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007141#ifdef __linux__
7142 case DRIVER_WIL6210:
7143 return wil6210_force_rsn_ie(dut, state);
7144#endif /* __linux__ */
7145 default:
7146 sigma_dut_print(dut, DUT_MSG_ERROR,
7147 "Unsupported sta_60g_force_rsn_ie with the current driver");
7148 return -1;
7149 }
7150}
7151
7152
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007153static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
7154 struct sigma_cmd *cmd)
7155{
7156 const char *val;
7157 char buf[100];
7158
7159 val = get_param(cmd, "MSDUSize");
7160 if (val) {
7161 int mtu;
7162
7163 dut->amsdu_size = atoi(val);
7164 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
7165 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
7166 sigma_dut_print(dut, DUT_MSG_ERROR,
7167 "MSDUSize %d is above max %d or below min %d",
7168 dut->amsdu_size,
7169 IEEE80211_MAX_DATA_LEN_DMG,
7170 IEEE80211_SNAP_LEN_DMG);
7171 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007172 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007173 }
7174
7175 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
7176 sigma_dut_print(dut, DUT_MSG_DEBUG,
7177 "Setting amsdu_size to %d", mtu);
7178 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007179 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007180
7181 if (system(buf) != 0) {
7182 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7183 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007184 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007185 }
7186 }
7187
7188 val = get_param(cmd, "BAckRcvBuf");
7189 if (val) {
7190 dut->back_rcv_buf = atoi(val);
7191 if (dut->back_rcv_buf == 0) {
7192 sigma_dut_print(dut, DUT_MSG_ERROR,
7193 "Failed to convert %s or value is 0",
7194 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007195 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007196 }
7197
7198 sigma_dut_print(dut, DUT_MSG_DEBUG,
7199 "Setting BAckRcvBuf to %s", val);
7200 }
7201
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007202 val = get_param(cmd, "MCS_FixedRate");
7203 if (val) {
7204 if (sta_set_force_mcs(dut, 1, atoi(val))) {
7205 sigma_dut_print(dut, DUT_MSG_ERROR,
7206 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007207 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007208 }
7209 }
7210
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007211 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007212}
7213
7214
7215static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
7216 struct sigma_cmd *cmd)
7217{
7218 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007219 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007220 const char *val;
7221 char buf[100];
7222
7223 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007224 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007225 if (wpa_command(ifname, "PING") != 0) {
7226 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007227 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007228 }
7229
7230 wpa_command(ifname, "FLUSH");
7231 net_id = add_network_common(dut, conn, ifname, cmd);
7232 if (net_id < 0) {
7233 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
7234 return net_id;
7235 }
7236
7237 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
7238 if (set_network(ifname, net_id, "mode", "2") < 0) {
7239 sigma_dut_print(dut, DUT_MSG_ERROR,
7240 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007241 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007242 }
7243
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02007244 if (set_network(ifname, net_id, "pbss", "1") < 0)
7245 return -2;
7246
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007247 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007248 "Supplicant set network with mode 2. network_id %d",
7249 net_id);
7250
7251 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
7252 sigma_dut_print(dut, DUT_MSG_INFO,
7253 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007254 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007255 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007256
7257 val = get_param(cmd, "Security");
7258 if (val && strcasecmp(val, "OPEN") == 0) {
7259 dut->ap_key_mgmt = AP_OPEN;
7260 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
7261 sigma_dut_print(dut, DUT_MSG_ERROR,
7262 "Failed to set supplicant to %s security",
7263 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007264 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007265 }
7266 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
7267 dut->ap_key_mgmt = AP_WPA2_PSK;
7268 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
7269 sigma_dut_print(dut, DUT_MSG_ERROR,
7270 "Failed to set supplicant to %s security",
7271 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007272 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007273 }
7274
7275 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
7276 sigma_dut_print(dut, DUT_MSG_ERROR,
7277 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007278 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007279 }
7280 } else if (val) {
7281 sigma_dut_print(dut, DUT_MSG_ERROR,
7282 "Requested Security %s is not supported on 60GHz",
7283 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007284 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007285 }
7286
7287 val = get_param(cmd, "Encrypt");
7288 if (val && strcasecmp(val, "AES-GCMP") == 0) {
7289 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
7290 sigma_dut_print(dut, DUT_MSG_ERROR,
7291 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007292 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007293 }
7294 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
7295 sigma_dut_print(dut, DUT_MSG_ERROR,
7296 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007297 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007298 }
7299 } else if (val) {
7300 sigma_dut_print(dut, DUT_MSG_ERROR,
7301 "Requested Encrypt %s is not supported on 60 GHz",
7302 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007303 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007304 }
7305
7306 val = get_param(cmd, "PSK");
7307 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
7308 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
7309 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007310 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007311 }
7312
7313 /* Convert 60G channel to freq */
7314 switch (dut->ap_channel) {
7315 case 1:
7316 val = "58320";
7317 break;
7318 case 2:
7319 val = "60480";
7320 break;
7321 case 3:
7322 val = "62640";
7323 break;
7324 default:
7325 sigma_dut_print(dut, DUT_MSG_ERROR,
7326 "Failed to configure channel %d. Not supported",
7327 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007328 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007329 }
7330
7331 if (set_network(ifname, net_id, "frequency", val) < 0) {
7332 sigma_dut_print(dut, DUT_MSG_ERROR,
7333 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007334 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007335 }
7336
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02007337 if (dut->eap_fragment) {
7338 sigma_dut_print(dut, DUT_MSG_DEBUG,
7339 "Set EAP fragment size to 128 bytes.");
7340 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
7341 return ERROR_SEND_STATUS;
7342 }
7343
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007344 sigma_dut_print(dut, DUT_MSG_DEBUG,
7345 "Supplicant set network with frequency");
7346
7347 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
7348 if (wpa_command(ifname, buf) < 0) {
7349 sigma_dut_print(dut, DUT_MSG_INFO,
7350 "Failed to select network id %d on %s",
7351 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007352 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007353 }
7354
7355 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
7356
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007357 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007358}
7359
7360
Lior David67543f52017-01-03 19:04:22 +02007361static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
7362{
7363 char buf[128], fname[128];
7364 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03007365 int res;
Lior David67543f52017-01-03 19:04:22 +02007366
7367 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
7368 sigma_dut_print(dut, DUT_MSG_ERROR,
7369 "failed to get wil6210 debugfs dir");
7370 return -1;
7371 }
7372
Jouni Malinen3aa72862019-05-29 23:14:51 +03007373 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
7374 if (res < 0 || res >= sizeof(fname))
7375 return -1;
Lior David67543f52017-01-03 19:04:22 +02007376 f = fopen(fname, "w");
7377 if (!f) {
7378 sigma_dut_print(dut, DUT_MSG_ERROR,
7379 "failed to open: %s", fname);
7380 return -1;
7381 }
7382
7383 fprintf(f, "%d\n", abft_len);
7384 fclose(f);
7385
7386 return 0;
7387}
7388
7389
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02007390int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
7391 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02007392{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007393 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02007394 case DRIVER_WIL6210:
7395 return wil6210_set_abft_len(dut, abft_len);
7396 default:
7397 sigma_dut_print(dut, DUT_MSG_ERROR,
7398 "set abft_len not supported");
7399 return -1;
7400 }
7401}
7402
7403
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007404static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
7405 struct sigma_cmd *cmd)
7406{
7407 const char *val;
Lior David67543f52017-01-03 19:04:22 +02007408 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007409
7410 if (dut->dev_role != DEVROLE_PCP) {
7411 send_resp(dut, conn, SIGMA_INVALID,
7412 "ErrorCode,Invalid DevRole");
7413 return 0;
7414 }
7415
7416 val = get_param(cmd, "SSID");
7417 if (val) {
7418 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
7419 send_resp(dut, conn, SIGMA_INVALID,
7420 "ErrorCode,Invalid SSID");
7421 return -1;
7422 }
7423
Peng Xub8fc5cc2017-05-10 17:27:28 -07007424 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007425 }
7426
7427 val = get_param(cmd, "CHANNEL");
7428 if (val) {
7429 const char *pos;
7430
7431 dut->ap_channel = atoi(val);
7432 pos = strchr(val, ';');
7433 if (pos) {
7434 pos++;
7435 dut->ap_channel_1 = atoi(pos);
7436 }
7437 }
7438
7439 switch (dut->ap_channel) {
7440 case 1:
7441 case 2:
7442 case 3:
7443 break;
7444 default:
7445 sigma_dut_print(dut, DUT_MSG_ERROR,
7446 "Channel %d is not supported", dut->ap_channel);
7447 send_resp(dut, conn, SIGMA_ERROR,
7448 "Requested channel is not supported");
7449 return -1;
7450 }
7451
7452 val = get_param(cmd, "BCNINT");
7453 if (val)
7454 dut->ap_bcnint = atoi(val);
7455
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007456 val = get_param(cmd, "AllocType");
7457 if (val) {
7458 send_resp(dut, conn, SIGMA_ERROR,
7459 "ErrorCode,AllocType is not supported yet");
7460 return -1;
7461 }
7462
7463 val = get_param(cmd, "PercentBI");
7464 if (val) {
7465 send_resp(dut, conn, SIGMA_ERROR,
7466 "ErrorCode,PercentBI is not supported yet");
7467 return -1;
7468 }
7469
7470 val = get_param(cmd, "CBAPOnly");
7471 if (val) {
7472 send_resp(dut, conn, SIGMA_ERROR,
7473 "ErrorCode,CBAPOnly is not supported yet");
7474 return -1;
7475 }
7476
7477 val = get_param(cmd, "AMPDU");
7478 if (val) {
7479 if (strcasecmp(val, "Enable") == 0)
7480 dut->ap_ampdu = 1;
7481 else if (strcasecmp(val, "Disable") == 0)
7482 dut->ap_ampdu = 2;
7483 else {
7484 send_resp(dut, conn, SIGMA_ERROR,
7485 "ErrorCode,AMPDU value is not Enable nor Disabled");
7486 return -1;
7487 }
7488 }
7489
7490 val = get_param(cmd, "AMSDU");
7491 if (val) {
7492 if (strcasecmp(val, "Enable") == 0)
7493 dut->ap_amsdu = 1;
7494 else if (strcasecmp(val, "Disable") == 0)
7495 dut->ap_amsdu = 2;
7496 }
7497
7498 val = get_param(cmd, "NumMSDU");
7499 if (val) {
7500 send_resp(dut, conn, SIGMA_ERROR,
7501 "ErrorCode, NumMSDU is not supported yet");
7502 return -1;
7503 }
7504
7505 val = get_param(cmd, "ABFTLRang");
7506 if (val) {
7507 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02007508 "ABFTLRang parameter %s", val);
7509 if (strcmp(val, "Gt1") == 0)
7510 abft_len = 2; /* 2 slots in this case */
7511 }
7512
7513 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
7514 send_resp(dut, conn, SIGMA_ERROR,
7515 "ErrorCode, Can't set ABFT length");
7516 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007517 }
7518
7519 if (sta_pcp_start(dut, conn, cmd) < 0) {
7520 send_resp(dut, conn, SIGMA_ERROR,
7521 "ErrorCode, Can't start PCP role");
7522 return -1;
7523 }
7524
7525 return sta_set_60g_common(dut, conn, cmd);
7526}
7527
7528
7529static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
7530 struct sigma_cmd *cmd)
7531{
7532 const char *val = get_param(cmd, "DiscoveryMode");
7533
7534 if (dut->dev_role != DEVROLE_STA) {
7535 send_resp(dut, conn, SIGMA_INVALID,
7536 "ErrorCode,Invalid DevRole");
7537 return 0;
7538 }
7539
7540 if (val) {
7541 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
7542 /* Ignore Discovery mode till Driver expose API. */
7543#if 0
7544 if (strcasecmp(val, "1") == 0) {
7545 send_resp(dut, conn, SIGMA_INVALID,
7546 "ErrorCode,DiscoveryMode 1 not supported");
7547 return 0;
7548 }
7549
7550 if (strcasecmp(val, "0") == 0) {
7551 /* OK */
7552 } else {
7553 send_resp(dut, conn, SIGMA_INVALID,
7554 "ErrorCode,DiscoveryMode not supported");
7555 return 0;
7556 }
7557#endif
7558 }
7559
7560 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007561 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007562 return sta_set_60g_common(dut, conn, cmd);
7563}
7564
7565
Jouni Malinenf7222712019-06-13 01:50:21 +03007566static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
7567 struct sigma_conn *conn,
7568 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007569{
7570 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02007571 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05307572
Jouni Malinened77e672018-01-10 16:45:13 +02007573 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08007574 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02007575 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05307576 wpa_command(intf, "DISCONNECT");
7577 return 1;
7578 }
7579
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007580 disconnect_station(dut);
7581 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
7582 * due to cached results. */
7583 wpa_command(intf, "SET ignore_old_scan_res 1");
7584 wpa_command(intf, "BSS_FLUSH");
7585 return 1;
7586}
7587
7588
Jouni Malinenf7222712019-06-13 01:50:21 +03007589static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
7590 struct sigma_conn *conn,
7591 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007592{
7593 const char *intf = get_param(cmd, "Interface");
7594 const char *bssid = get_param(cmd, "bssid");
7595 const char *val = get_param(cmd, "CHANNEL");
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007596 const char *freq_val = get_param(cmd, "ChnlFreq");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007597 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307598 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05307599 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007600 int res;
7601 int chan = 0;
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007602 int freq = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007603 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05307604 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007605 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007606
7607 if (bssid == NULL) {
7608 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
7609 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007610 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007611 }
7612
7613 if (val)
7614 chan = atoi(val);
7615
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007616 if (freq_val)
7617 freq = atoi(freq_val);
7618
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007619 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
7620 /* The current network may be from sta_associate or
7621 * sta_hs2_associate
7622 */
7623 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
7624 0 ||
7625 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007626 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007627 }
7628
7629 ctrl = open_wpa_mon(intf);
7630 if (ctrl == NULL) {
7631 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7632 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007633 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007634 }
7635
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007636 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05307637 sizeof(result)) < 0 ||
7638 strncmp(result, "COMPLETED", 9) != 0) {
7639 sigma_dut_print(dut, DUT_MSG_DEBUG,
7640 "sta_reassoc: Not connected");
7641 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007642 } else if (dut->sta_ft_ds) {
7643 sigma_dut_print(dut, DUT_MSG_DEBUG,
7644 "sta_reassoc: Use FT-over-DS");
7645 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05307646 }
7647
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307648 if (dut->rsne_override) {
7649#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007650 if (get_driver_type(dut) == DRIVER_WCN &&
7651 dut->config_rsnie == 0) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05307652 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307653 dut->config_rsnie = 1;
7654 }
7655#endif /* NL80211_SUPPORT */
7656 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
7657 dut->rsne_override);
7658 if (wpa_command(intf, buf) < 0) {
7659 send_resp(dut, conn, SIGMA_ERROR,
7660 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
7661 return 0;
7662 }
7663 }
7664
Shivani Baranwal7aa48602021-09-29 10:53:38 +05307665 if (ft_ds && get_driver_type(dut) != DRIVER_WCN) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007666 if (chan || freq) {
7667 if (!freq)
7668 freq = channel_to_freq(dut, chan);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007669 if (!freq) {
7670 sigma_dut_print(dut, DUT_MSG_ERROR,
7671 "Invalid channel number provided: %d",
7672 chan);
7673 send_resp(dut, conn, SIGMA_INVALID,
7674 "ErrorCode,Invalid channel number");
7675 goto close_mon_conn;
7676 }
7677 res = snprintf(buf, sizeof(buf),
7678 "SCAN TYPE=ONLY freq=%d", freq);
7679 } else {
7680 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7681 }
7682 if (res < 0 || res >= (int) sizeof(buf)) {
7683 send_resp(dut, conn, SIGMA_ERROR,
7684 "ErrorCode,snprintf failed");
7685 goto close_mon_conn;
7686 }
7687 if (wpa_command(intf, buf) < 0) {
7688 sigma_dut_print(dut, DUT_MSG_INFO,
7689 "Failed to start scan");
7690 send_resp(dut, conn, SIGMA_ERROR,
7691 "ErrorCode,scan failed");
7692 goto close_mon_conn;
7693 }
7694
7695 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7696 buf, sizeof(buf));
7697 if (res < 0) {
7698 sigma_dut_print(dut, DUT_MSG_INFO,
7699 "Scan did not complete");
7700 send_resp(dut, conn, SIGMA_ERROR,
7701 "ErrorCode,scan did not complete");
7702 goto close_mon_conn;
7703 }
7704
7705 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
7706 if (res > 0 && res < (int) sizeof(buf))
7707 res = wpa_command(intf, buf);
7708
7709 if (res < 0 || res >= (int) sizeof(buf)) {
7710 send_resp(dut, conn, SIGMA_ERROR,
7711 "errorCode,FT_DS command failed");
7712 status = STATUS_SENT_ERROR;
7713 goto close_mon_conn;
7714 }
7715 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007716 if (chan || freq) {
7717 if (!freq)
7718 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05307719 if (!freq) {
7720 sigma_dut_print(dut, DUT_MSG_ERROR,
7721 "Invalid channel number provided: %d",
7722 chan);
7723 send_resp(dut, conn, SIGMA_INVALID,
7724 "ErrorCode,Invalid channel number");
7725 goto close_mon_conn;
7726 }
7727 res = snprintf(buf, sizeof(buf),
7728 "SCAN TYPE=ONLY freq=%d", freq);
7729 } else {
7730 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7731 }
7732 if (res < 0 || res >= (int) sizeof(buf)) {
7733 send_resp(dut, conn, SIGMA_ERROR,
7734 "ErrorCode,snprintf failed");
7735 goto close_mon_conn;
7736 }
7737 if (wpa_command(intf, buf) < 0) {
7738 sigma_dut_print(dut, DUT_MSG_INFO,
7739 "Failed to start scan");
7740 send_resp(dut, conn, SIGMA_ERROR,
7741 "ErrorCode,scan failed");
7742 goto close_mon_conn;
7743 }
7744
7745 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7746 buf, sizeof(buf));
7747 if (res < 0) {
7748 sigma_dut_print(dut, DUT_MSG_INFO,
7749 "Scan did not complete");
7750 send_resp(dut, conn, SIGMA_ERROR,
7751 "ErrorCode,scan did not complete");
7752 goto close_mon_conn;
7753 }
7754
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007755 if (set_network(intf, dut->infra_network_id, "bssid", "any")
7756 < 0) {
7757 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7758 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007759 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05307760 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007761 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307762 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007763 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307764 if (res < 0 || res >= (int) sizeof(buf) ||
7765 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007766 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307767 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05307768 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007769 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007770 sigma_dut_print(dut, DUT_MSG_INFO,
7771 "sta_reassoc: Run %s successful", buf);
7772 } else if (wpa_command(intf, "REASSOCIATE")) {
7773 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
7774 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05307775 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007776 }
7777
7778 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
7779 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05307780 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007781 send_resp(dut, conn, SIGMA_ERROR,
7782 "errorCode,Connection did not complete");
7783 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05307784 goto close_mon_conn;
7785 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007786 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007787
Ashwini Patil467efef2017-05-25 12:18:27 +05307788close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007789 wpa_ctrl_detach(ctrl);
7790 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05307791 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007792}
7793
7794
7795static void hs2_clear_credentials(const char *intf)
7796{
7797 wpa_command(intf, "REMOVE_CRED all");
7798}
7799
7800
Lior Davidcc88b562017-01-03 18:52:09 +02007801#ifdef __linux__
7802static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
7803 unsigned int *aid)
7804{
Lior David0fe101e2017-03-09 16:09:50 +02007805 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02007806
Lior David0fe101e2017-03-09 16:09:50 +02007807 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02007808}
7809#endif /* __linux__ */
7810
7811
7812static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
7813 unsigned int *aid)
7814{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007815 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02007816#ifdef __linux__
7817 case DRIVER_WIL6210:
7818 return wil6210_get_aid(dut, bssid, aid);
7819#endif /* __linux__ */
7820 default:
7821 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
7822 return -1;
7823 }
7824}
7825
7826
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007827static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7828 struct sigma_cmd *cmd)
7829{
7830 char buf[MAX_CMD_LEN];
7831 char bss_list[MAX_CMD_LEN];
7832 const char *parameter = get_param(cmd, "Parameter");
7833
7834 if (parameter == NULL)
7835 return -1;
7836
Lior Davidcc88b562017-01-03 18:52:09 +02007837 if (strcasecmp(parameter, "AID") == 0) {
7838 unsigned int aid = 0;
7839 char bssid[20];
7840
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007841 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02007842 bssid, sizeof(bssid)) < 0) {
7843 sigma_dut_print(dut, DUT_MSG_ERROR,
7844 "could not get bssid");
7845 return -2;
7846 }
7847
7848 if (sta_get_aid_60g(dut, bssid, &aid))
7849 return -2;
7850
7851 snprintf(buf, sizeof(buf), "aid,%d", aid);
7852 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
7853 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7854 return 0;
7855 }
7856
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007857 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
7858 char *bss_line;
7859 char *bss_id = NULL;
7860 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307861 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007862
7863 if (ifname == NULL) {
7864 sigma_dut_print(dut, DUT_MSG_INFO,
7865 "For get DiscoveredDevList need Interface name.");
7866 return -1;
7867 }
7868
7869 /*
7870 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
7871 * of BSSIDs in "bssid=<BSSID>\n"
7872 */
7873 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
7874 bss_list,
7875 sizeof(bss_list)) < 0) {
7876 sigma_dut_print(dut, DUT_MSG_ERROR,
7877 "Failed to get bss list");
7878 return -1;
7879 }
7880
7881 sigma_dut_print(dut, DUT_MSG_DEBUG,
7882 "bss list for ifname:%s is:%s",
7883 ifname, bss_list);
7884
7885 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307886 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007887 while (bss_line) {
7888 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
7889 bss_id) {
7890 int len;
7891
7892 len = snprintf(buf + strlen(buf),
7893 sizeof(buf) - strlen(buf),
7894 ",%s", bss_id);
7895 free(bss_id);
7896 bss_id = NULL;
7897 if (len < 0) {
7898 sigma_dut_print(dut,
7899 DUT_MSG_ERROR,
7900 "Failed to read BSSID");
7901 send_resp(dut, conn, SIGMA_ERROR,
7902 "ErrorCode,Failed to read BSS ID");
7903 return 0;
7904 }
7905
7906 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
7907 sigma_dut_print(dut,
7908 DUT_MSG_ERROR,
7909 "Response buf too small for list");
7910 send_resp(dut, conn,
7911 SIGMA_ERROR,
7912 "ErrorCode,Response buf too small for list");
7913 return 0;
7914 }
7915 }
7916
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307917 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007918 }
7919
7920 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
7921 buf);
7922 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7923 return 0;
7924 }
7925
7926 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7927 return 0;
7928}
7929
7930
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007931static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
7932 struct sigma_cmd *cmd)
7933{
7934 char buf[MAX_CMD_LEN];
7935 const char *parameter = get_param(cmd, "Parameter");
7936
7937 if (!parameter)
7938 return -1;
7939
7940 if (strcasecmp(parameter, "RSSI") == 0) {
7941 char rssi[10];
7942
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007943 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007944 rssi, sizeof(rssi)) < 0) {
7945 sigma_dut_print(dut, DUT_MSG_ERROR,
7946 "Could not get RSSI");
7947 return -2;
7948 }
7949
7950 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
7951 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
7952 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7953 return 0;
7954 }
7955
7956 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7957 return 0;
7958}
7959
7960
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05307961#ifdef NL80211_SUPPORT
7962
7963struct station_info {
7964 uint64_t filled;
7965 uint32_t beacon_mic_error_count;
7966 uint32_t beacon_replay_count;
7967};
7968
7969
7970static int qca_get_sta_info_handler(struct nl_msg *msg, void *arg)
7971{
7972 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7973 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7974 struct station_info *data = arg;
7975 struct nlattr *info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
7976 static struct nla_policy info_policy[
7977 QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = {
7978 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT] = {
7979 .type = NLA_U32
7980 },
7981 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT] = {
7982 .type = NLA_U32
7983 },
7984 };
7985
7986 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7987 genlmsg_attrlen(gnlh, 0), NULL);
7988
7989 if (!tb[NL80211_ATTR_VENDOR_DATA])
7990 return NL_SKIP;
7991
7992 if (nla_parse_nested(info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
7993 tb[NL80211_ATTR_VENDOR_DATA], info_policy)) {
7994 return NL_SKIP;
7995 }
7996
7997 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]) {
7998 data->filled |=
7999 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT);
8000 data->beacon_mic_error_count =
8001 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]);
8002 }
8003
8004 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]) {
8005 data->filled |=
8006 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT);
8007 data->beacon_replay_count =
8008 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]);
8009 }
8010
8011 return NL_SKIP;
8012}
8013
8014
8015static int qca_nl80211_get_sta_info(struct sigma_dut *dut, const char *intf,
8016 struct station_info *sta_data)
8017{
8018 struct nl_msg *msg;
8019 int ifindex, ret;
8020
8021 ifindex = if_nametoindex(intf);
8022 if (ifindex == 0) {
8023 sigma_dut_print(dut, DUT_MSG_ERROR,
8024 "%s: Index for interface %s not found",
8025 __func__, intf);
8026 return -1;
8027 }
8028
8029 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8030 NL80211_CMD_VENDOR)) ||
8031 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8032 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8033 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8034 QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
8035 sigma_dut_print(dut, DUT_MSG_ERROR,
8036 "%s: err in adding vendor_cmd", __func__);
8037 nlmsg_free(msg);
8038 return -1;
8039 }
8040
8041 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg,
8042 qca_get_sta_info_handler, sta_data);
8043 if (ret) {
8044 sigma_dut_print(dut, DUT_MSG_ERROR,
8045 "%s: err in send_and_recv_msgs, ret=%d",
8046 __func__, ret);
8047 }
8048 return ret;
8049}
8050#endif /* NL80211_SUPPORT */
8051
8052
8053static int get_bip_mic_error_count(struct sigma_dut *dut,
8054 const char *ifname,
8055 unsigned int *count)
8056{
8057#ifdef NL80211_SUPPORT
8058 struct station_info sta_data;
8059#endif /* NL80211_SUPPORT */
8060
8061 if (get_driver_type(dut) != DRIVER_WCN) {
8062 sigma_dut_print(dut, DUT_MSG_ERROR,
8063 "BIP MIC error count not supported");
8064 return -1;
8065 }
8066
8067#ifdef NL80211_SUPPORT
8068 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8069 !(sta_data.filled &
8070 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT))) {
8071 sigma_dut_print(dut, DUT_MSG_ERROR,
8072 "BIP MIC error count fetching failed");
8073 return -1;
8074 }
8075
8076 *count = sta_data.beacon_mic_error_count;
8077 return 0;
8078#else /* NL80211_SUPPORT */
8079 sigma_dut_print(dut, DUT_MSG_ERROR,
8080 "BIP MIC error count cannot be fetched without NL80211_SUPPORT defined");
8081 return -1;
8082#endif /* NL80211_SUPPORT */
8083}
8084
8085
8086static int get_cmac_replay_count(struct sigma_dut *dut, const char *ifname,
8087 unsigned int *count)
8088{
8089#ifdef NL80211_SUPPORT
8090 struct station_info sta_data;
8091#endif /* NL80211_SUPPORT */
8092
8093 if (get_driver_type(dut) != DRIVER_WCN) {
8094 sigma_dut_print(dut, DUT_MSG_ERROR,
8095 "CMAC reply count not supported");
8096 return -1;
8097 }
8098
8099#ifdef NL80211_SUPPORT
8100 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8101 !(sta_data.filled &
8102 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT))) {
8103 sigma_dut_print(dut, DUT_MSG_ERROR,
8104 "CMAC replay count fetching failed");
8105 return -1;
8106 }
8107
8108 *count = sta_data.beacon_replay_count;
8109 return 0;
8110#else /* NL80211_SUPPORT */
8111 sigma_dut_print(dut, DUT_MSG_ERROR,
8112 "CMAC replay count cannot be fetched without NL80211_SUPPORT defined");
8113 return -1;
8114#endif /* NL80211_SUPPORT */
8115}
8116
8117
8118static enum sigma_cmd_result sta_get_parameter_wpa3(struct sigma_dut *dut,
8119 struct sigma_conn *conn,
8120 struct sigma_cmd *cmd)
8121{
8122 char buf[MAX_CMD_LEN];
8123 const char *ifname = get_param(cmd, "interface");
8124 const char *parameter = get_param(cmd, "Parameter");
8125 unsigned int val;
8126
8127 if (!ifname || !parameter)
8128 return INVALID_SEND_STATUS;
8129
8130 if (strcasecmp(parameter, "BIPMICErrors") == 0) {
8131 if (get_bip_mic_error_count(dut, ifname, &val)) {
8132 send_resp(dut, conn, SIGMA_ERROR,
8133 "ErrorCode,Failed to get BIPMICErrors");
8134 return STATUS_SENT_ERROR;
8135 }
8136 snprintf(buf, sizeof(buf), "BIPMICErrors,%d", val);
8137 sigma_dut_print(dut, DUT_MSG_INFO, "BIPMICErrors %s", buf);
8138 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8139 return STATUS_SENT;
8140 }
8141
8142 if (strcasecmp(parameter, "CMACReplays") == 0) {
8143 if (get_cmac_replay_count(dut, ifname, &val)) {
8144 send_resp(dut, conn, SIGMA_ERROR,
8145 "ErrorCode,Failed to get CMACReplays");
8146 return STATUS_SENT_ERROR;
8147 }
8148 snprintf(buf, sizeof(buf), "CMACReplays,%d", val);
8149 sigma_dut_print(dut, DUT_MSG_INFO, "CMACReplays %s", buf);
8150 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8151 return STATUS_SENT;
8152 }
8153
8154 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8155 return STATUS_SENT_ERROR;
8156}
8157
8158
Jouni Malinenca0abd32020-02-09 20:18:10 +02008159static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
8160 struct sigma_conn *conn,
8161 struct sigma_cmd *cmd)
8162{
8163 const char *intf = get_param(cmd, "Interface");
8164 char buf[4096], bssid[20], resp[200], *pos, *tmp;
8165
8166 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
8167 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8168 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
8169 send_resp(dut, conn, SIGMA_ERROR,
8170 "ErrorCode,PMKSA_GET not supported");
8171 return STATUS_SENT_ERROR;
8172 }
8173
8174 if (strncmp(buf, "FAIL", 4) == 0 ||
8175 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
8176 send_resp(dut, conn, SIGMA_ERROR,
8177 "ErrorCode,Could not find current network");
8178 return STATUS_SENT_ERROR;
8179 }
8180
8181 pos = buf;
8182 while (pos) {
8183 if (strncmp(pos, bssid, 17) == 0) {
8184 pos = strchr(pos, ' ');
8185 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308186 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008187 pos++;
8188 pos = strchr(pos, ' ');
8189 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308190 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008191 pos++;
8192 tmp = strchr(pos, ' ');
8193 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308194 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008195 *tmp = '\0';
8196 break;
8197 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02008198 pos = strchr(pos, '\n');
8199 if (pos)
8200 pos++;
8201 }
8202
8203 if (!pos) {
8204 send_resp(dut, conn, SIGMA_ERROR,
8205 "ErrorCode,PMK not available");
8206 return STATUS_SENT_ERROR;
8207 }
8208
8209 snprintf(resp, sizeof(resp), "PMK,%s", pos);
8210 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8211 return STATUS_SENT;
8212}
8213
8214
Jouni Malinenf7222712019-06-13 01:50:21 +03008215static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
8216 struct sigma_conn *conn,
8217 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008218{
8219 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02008220 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008221
Jouni Malinenca0abd32020-02-09 20:18:10 +02008222 if (!parameter)
8223 return INVALID_SEND_STATUS;
8224
8225 if (strcasecmp(parameter, "PMK") == 0)
8226 return sta_get_pmk(dut, conn, cmd);
8227
8228 if (!program)
8229 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008230
8231 if (strcasecmp(program, "P2PNFC") == 0)
8232 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
8233
8234 if (strcasecmp(program, "60ghz") == 0)
8235 return sta_get_parameter_60g(dut, conn, cmd);
8236
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07008237 if (strcasecmp(program, "he") == 0)
8238 return sta_get_parameter_he(dut, conn, cmd);
8239
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008240#ifdef ANDROID_NAN
8241 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07008242 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008243#endif /* ANDROID_NAN */
8244
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008245#ifdef MIRACAST
8246 if (strcasecmp(program, "WFD") == 0 ||
8247 strcasecmp(program, "DisplayR2") == 0)
8248 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
8249#endif /* MIRACAST */
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05308250 if (strcasecmp(program, "WPA3") == 0)
8251 return sta_get_parameter_wpa3(dut, conn, cmd);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008252
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008253 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8254 return 0;
8255}
8256
8257
8258static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
8259 const char *type)
8260{
8261 char buf[100];
8262
8263 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008264 run_iwpriv(dut, intf, "chwidth 2");
8265 run_iwpriv(dut, intf, "mode 11ACVHT80");
8266 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008267 }
8268
8269 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008270 run_iwpriv(dut, intf, "chwidth 0");
8271 run_iwpriv(dut, intf, "mode 11naht40");
8272 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008273 }
8274
8275 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008276 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008277
8278 /* Reset CTS width */
8279 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
8280 intf);
8281 if (system(buf) != 0) {
8282 sigma_dut_print(dut, DUT_MSG_ERROR,
8283 "wifitool %s beeliner_fw_test 54 0 failed",
8284 intf);
8285 }
8286
8287 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008288 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008289
8290 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
8291 if (system(buf) != 0) {
8292 sigma_dut_print(dut, DUT_MSG_ERROR,
8293 "iwpriv rts failed");
8294 }
8295 }
8296
8297 if (type && strcasecmp(type, "Testbed") == 0) {
8298 dut->testbed_flag_txsp = 1;
8299 dut->testbed_flag_rxsp = 1;
8300 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008301 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008302
8303 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008304 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008305
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008306 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008307
8308 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008309 run_iwpriv(dut, intf, "tx_stbc 0");
8310 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008311
8312 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008313 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008314 }
8315
8316 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008317 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07008318 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008319
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008320 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008321 }
8322}
8323
8324
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008325#ifdef NL80211_SUPPORT
8326static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
8327 enum he_mcs_config mcs)
8328{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308329 return wcn_wifi_test_config_set_u8(
8330 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS, mcs);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008331}
8332#endif /* NL80211_SUPPORT */
8333
8334
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008335static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
8336 const char *intf, int enable)
8337{
8338#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308339 return wcn_wifi_test_config_set_u8(
8340 dut, intf,
8341 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
8342 enable);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008343#else /* NL80211_SUPPORT */
8344 sigma_dut_print(dut, DUT_MSG_ERROR,
8345 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
8346 return -1;
8347#endif /* NL80211_SUPPORT */
8348}
8349
8350
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008351static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
8352 const char *intf, int enable)
8353{
8354#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308355 return wcn_wifi_test_config_set_u8(
8356 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
8357 enable);
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008358#else /* NL80211_SUPPORT */
8359 sigma_dut_print(dut, DUT_MSG_ERROR,
8360 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
8361 return -1;
8362#endif /* NL80211_SUPPORT */
8363}
8364
8365
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008366#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008367
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008368static int sta_set_he_testbed_def(struct sigma_dut *dut,
8369 const char *intf, int cfg)
8370{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308371 return wcn_wifi_test_config_set_u8(
8372 dut, intf,
8373 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
8374 cfg);
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008375}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008376
8377
8378static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
8379{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308380 return wcn_wifi_test_config_set_u8(
8381 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
8382 cfg);
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008383}
8384
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008385#endif /* NL80211_SUPPORT */
8386
8387
Qiwei Caib6806972020-01-15 13:52:11 +08008388int sta_set_addba_buf_size(struct sigma_dut *dut,
8389 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008390{
8391#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308392 return wcn_wifi_test_config_set_u16(
8393 dut, intf,
8394 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE, bufsize);
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008395#else /* NL80211_SUPPORT */
8396 sigma_dut_print(dut, DUT_MSG_ERROR,
8397 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
8398 return -1;
8399#endif /* NL80211_SUPPORT */
8400}
8401
8402
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008403static int sta_set_scan_unicast_probe(struct sigma_dut *dut,
8404 const char *intf, int val)
8405{
8406#ifdef NL80211_SUPPORT
8407 return wcn_wifi_test_config_set_u8(
8408 dut, intf,
8409 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA,
8410 val);
8411#else /* NL80211_SUPPORT */
8412 sigma_dut_print(dut, DUT_MSG_ERROR,
8413 "Unicast RA in Probe Request frame cannot be set without NL80211_SUPPORT defined");
8414 return -1;
8415#endif /* NL80211_SUPPORT */
8416}
8417
8418
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07008419static int sta_set_rx_ctrl_multi_bss(struct sigma_dut *dut, const char *intf,
8420 int enable)
8421{
8422#ifdef NL80211_SUPPORT
8423 return wcn_wifi_test_config_set_u8(
8424 dut, intf,
8425 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS,
8426 enable);
8427#else /* NL80211_SUPPORT */
8428 sigma_dut_print(dut, DUT_MSG_ERROR,
8429 "Rx ctrl frame to Multi-BSS cannot be changed without NL80211_SUPPORT defined");
8430 return -1;
8431#endif /* NL80211_SUPPORT */
8432}
8433
8434
8435static int sta_set_bcast_twt_support(struct sigma_dut *dut, const char *intf,
8436 int enable)
8437{
8438#ifdef NL80211_SUPPORT
8439 return wcn_wifi_test_config_set_u8(
8440 dut, intf,
8441 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT,
8442 enable);
8443#else /* NL80211_SUPPORT */
8444 sigma_dut_print(dut, DUT_MSG_ERROR,
8445 "BCAST TWT cannot be changed without NL80211_SUPPORT defined");
8446 return -1;
8447#endif /* NL80211_SUPPORT */
8448}
8449
8450
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008451static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
8452 int enable)
8453{
8454#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308455 return wcn_wifi_test_config_set_u8(
8456 dut, intf,
8457 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
8458 enable);
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008459#else /* NL80211_SUPPORT */
8460 sigma_dut_print(dut, DUT_MSG_ERROR,
8461 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
8462 return -1;
8463#endif /* NL80211_SUPPORT */
8464}
8465
8466
Arif Hussain9765f7d2018-07-03 08:28:26 -07008467static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
8468 int val)
8469{
8470#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308471 return wcn_wifi_test_config_set_u8(
8472 dut, intf,
8473 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
8474 val);
Arif Hussain9765f7d2018-07-03 08:28:26 -07008475#else /* NL80211_SUPPORT */
8476 sigma_dut_print(dut, DUT_MSG_ERROR,
8477 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
8478 return -1;
8479#endif /* NL80211_SUPPORT */
8480}
8481
8482
Arif Hussain68d23f52018-07-11 13:39:08 -07008483#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008484static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
8485 enum qca_wlan_he_mac_padding_dur val)
8486{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308487 return wcn_wifi_test_config_set_u8(
8488 dut, intf,
8489 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR, val);
Arif Hussain68d23f52018-07-11 13:39:08 -07008490}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008491#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008492
8493
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008494static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
8495 int val)
8496{
8497#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308498 return wcn_wifi_test_config_set_u8(
8499 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
8500 val);
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008501#else /* NL80211_SUPPORT */
8502 sigma_dut_print(dut, DUT_MSG_ERROR,
8503 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
8504 return -1;
8505#endif /* NL80211_SUPPORT */
8506}
8507
8508
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008509static int sta_set_mgmt_data_tx_disable_cfg(struct sigma_dut *dut,
8510 const char *intf, int val)
8511{
8512#ifdef NL80211_SUPPORT
8513 return wcn_wifi_test_config_set_u8(
8514 dut, intf,
8515 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX,
8516 val);
8517#else /* NL80211_SUPPORT */
8518 sigma_dut_print(dut, DUT_MSG_ERROR,
8519 "Tx disable config cannot be set without NL80211_SUPPORT defined");
8520 return -1;
8521#endif /* NL80211_SUPPORT */
8522}
8523
8524
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -07008525static int sta_set_keep_alive_data_cfg(struct sigma_dut *dut, const char *intf,
8526 int val)
8527{
8528#ifdef NL80211_SUPPORT
8529 return wcn_wifi_test_config_set_u8(
8530 dut, intf,
8531 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE,
8532 val);
8533#else /* NL80211_SUPPORT */
8534 sigma_dut_print(dut, DUT_MSG_ERROR,
8535 "Keep alive data type cannot be set without NL80211_SUPPORT defined");
8536 return -1;
8537#endif /* NL80211_SUPPORT */
8538}
8539
8540
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008541#ifdef NL80211_SUPPORT
8542static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
8543{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308544 return wcn_wifi_test_config_set_flag(
8545 dut, intf,
8546 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG);
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008547}
8548#endif /* NL80211_SUPPORT */
8549
8550
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008551static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
8552 int val)
8553{
8554#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308555 return wcn_wifi_test_config_set_u8(
8556 dut, intf,
8557 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA, val);
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008558#else /* NL80211_SUPPORT */
8559 sigma_dut_print(dut, DUT_MSG_ERROR,
8560 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
8561 return -1;
8562#endif /* NL80211_SUPPORT */
8563}
8564
8565
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008566static int sta_set_er_su_ppdu_type_tx(struct sigma_dut *dut, const char *intf,
8567 int val)
8568{
8569#ifdef NL80211_SUPPORT
8570 return wcn_wifi_test_config_set_u8(
8571 dut, intf,
8572 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE, val);
8573#else /* NL80211_SUPPORT */
8574 sigma_dut_print(dut, DUT_MSG_ERROR,
8575 "ER-SU PPDU type cannot be set without NL80211_SUPPORT defined");
8576 return -1;
8577#endif /* NL80211_SUPPORT */
8578}
8579
8580
8581static int sta_set_ru_242_tone_tx(struct sigma_dut *dut, const char *intf,
8582 int val)
8583{
8584#ifdef NL80211_SUPPORT
8585 return wcn_wifi_test_config_set_u8(
8586 dut, intf,
8587 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX, val);
8588#else /* NL80211_SUPPORT */
8589 sigma_dut_print(dut, DUT_MSG_ERROR,
8590 "RU 242 tone cannot be set without NL80211_SUPPORT defined");
8591 return -1;
8592#endif /* NL80211_SUPPORT */
8593}
8594
8595
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008596static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
8597 int val)
8598{
8599#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308600 return wcn_wifi_test_config_set_u8(
8601 dut, intf,
8602 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP, val);
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008603#else /* NL80211_SUPPORT */
8604 sigma_dut_print(dut, DUT_MSG_ERROR,
8605 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
8606 return -1;
8607#endif /* NL80211_SUPPORT */
8608}
8609
8610
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008611#ifdef NL80211_SUPPORT
8612
8613struct features_info {
8614 unsigned char flags[8];
8615 size_t flags_len;
8616};
8617
8618static int features_info_handler(struct nl_msg *msg, void *arg)
8619{
8620 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8621 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8622 struct features_info *info = arg;
8623 struct nlattr *nl_vend, *attr;
8624
8625 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8626 genlmsg_attrlen(gnlh, 0), NULL);
8627
8628 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
8629 if (nl_vend) {
8630 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
8631
8632 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
8633 nla_data(nl_vend), nla_len(nl_vend), NULL);
8634
8635 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
8636 if (attr) {
8637 int len = nla_len(attr);
8638
Vamsi Krishna79a91132021-08-16 21:40:22 +05308639 if (info && len <= sizeof(info->flags)) {
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008640 memcpy(info->flags, nla_data(attr), len);
8641 info->flags_len = len;
8642 }
8643 }
8644 }
8645
8646 return NL_SKIP;
8647}
8648
8649
8650static int check_feature(enum qca_wlan_vendor_features feature,
8651 struct features_info *info)
8652{
8653 size_t idx = feature / 8;
8654
Vamsi Krishna79a91132021-08-16 21:40:22 +05308655 if (!info)
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008656 return 0;
8657
8658 return (idx < info->flags_len) &&
8659 (info->flags[idx] & BIT(feature % 8));
8660}
8661
8662#endif /* NL80211_SUPPORT */
8663
8664
8665static void sta_get_twt_feature_async_supp(struct sigma_dut *dut,
8666 const char *intf)
8667{
8668#ifdef NL80211_SUPPORT
8669 struct nl_msg *msg;
8670 struct features_info info = { 0 };
8671 int ifindex, ret;
8672
8673 ifindex = if_nametoindex(intf);
8674 if (ifindex == 0) {
8675 sigma_dut_print(dut, DUT_MSG_ERROR,
8676 "%s: Index for interface %s failed",
8677 __func__, intf);
8678 return;
8679 }
8680
8681 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8682 NL80211_CMD_VENDOR)) ||
8683 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8684 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8685 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8686 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
8687 sigma_dut_print(dut, DUT_MSG_ERROR,
8688 "%s: err in adding vendor_cmd and vendor_data",
8689 __func__);
8690 nlmsg_free(msg);
8691 return;
8692 }
8693
8694 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, features_info_handler,
8695 &info);
8696 if (ret) {
8697 sigma_dut_print(dut, DUT_MSG_ERROR,
8698 "%s: err in send_and_recv_msgs, ret=%d",
8699 __func__, ret);
8700 return;
8701 }
8702
8703 if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info))
8704 dut->sta_async_twt_supp = 1;
8705 else
8706 dut->sta_async_twt_supp = 0;
8707
8708 sigma_dut_print(dut, DUT_MSG_DEBUG,
8709 "%s: sta_async_twt_supp %d",
8710 __func__, dut->sta_async_twt_supp);
8711#else /* NL80211_SUPPORT */
8712 sigma_dut_print(dut, DUT_MSG_INFO,
8713 "TWT async supp get cannot be done without NL80211_SUPPORT defined");
8714 dut->sta_async_twt_supp = 0;
8715#endif /* NL80211_SUPPORT */
8716}
8717
8718
Arif Hussain480d5f42019-03-12 14:40:42 -07008719static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
8720 int val)
8721{
8722#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308723 return wcn_wifi_test_config_set_u8(
8724 dut, intf,
8725 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT, val);
Arif Hussain480d5f42019-03-12 14:40:42 -07008726#else /* NL80211_SUPPORT */
8727 sigma_dut_print(dut, DUT_MSG_ERROR,
8728 "TWT Request cannot be changed without NL80211_SUPPORT defined");
8729 return -1;
8730#endif /* NL80211_SUPPORT */
8731}
8732
8733
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07008734static int sta_set_bss_max_idle_period(struct sigma_dut *dut, const char *intf,
8735 int val)
8736{
8737#ifdef NL80211_SUPPORT
8738 return wcn_wifi_test_config_set_u16(
8739 dut, intf,
8740 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD, val);
8741#else /* NL80211_SUPPORT */
8742 sigma_dut_print(dut, DUT_MSG_ERROR,
8743 "BSS max idle period cannot be set without NL80211_SUPPORT defined");
8744 return -1;
8745#endif /* NL80211_SUPPORT */
8746}
8747
8748
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07008749static int sta_set_bss_max_idle_support(struct sigma_dut *dut, const char *intf,
8750 int val)
8751{
8752#ifdef NL80211_SUPPORT
8753 return wcn_wifi_test_config_set_u8(
8754 dut, intf,
8755 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE,
8756 val);
8757#else /* NL80211_SUPPORT */
8758 sigma_dut_print(dut, DUT_MSG_ERROR,
8759 "BSS max idle support cannot be set without NL80211_SUPPORT defined");
8760 return -1;
8761#endif /* NL80211_SUPPORT */
8762}
8763
8764
Srinivas Girigowda0525e292020-11-12 13:28:21 -08008765static int sta_set_fullbw_ulmumimo(struct sigma_dut *dut, const char *intf,
8766 int val)
8767{
8768#ifdef NL80211_SUPPORT
8769 return wcn_wifi_test_config_set_u8(
8770 dut, intf,
8771 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO, val);
8772#else /* NL80211_SUPPORT */
8773 sigma_dut_print(dut, DUT_MSG_ERROR,
8774 "Full BW UL MU MIMO cannot be changed without NL80211_SUPPORT defined");
8775 return -1;
8776#endif /* NL80211_SUPPORT */
8777}
8778
8779
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07008780static int sta_set_punctured_preamble_rx(struct sigma_dut *dut,
8781 const char *intf, int val)
8782{
8783#ifdef NL80211_SUPPORT
8784 return wcn_wifi_test_config_set_u8(
8785 dut, intf,
8786 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX,
8787 val);
8788#else /* NL80211_SUPPORT */
8789 sigma_dut_print(dut, DUT_MSG_ERROR,
8790 "Punctured preamble Rx cannot be set without NL80211_SUPPORT defined");
8791 return -1;
8792#endif /* NL80211_SUPPORT */
8793}
8794
8795
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -08008796int wcn_set_he_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8797{
8798 #ifdef NL80211_SUPPORT
8799 struct nlattr *attr;
8800 struct nlattr *attr1;
8801 int ifindex, ret;
8802 struct nl_msg *msg;
8803
8804 ifindex = if_nametoindex(intf);
8805 if (ifindex == 0) {
8806 sigma_dut_print(dut, DUT_MSG_ERROR,
8807 "%s: Index for interface %s failed",
8808 __func__, intf);
8809 return -1;
8810 }
8811
8812 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8813 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8814 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8815 sigma_dut_print(dut, DUT_MSG_ERROR,
8816 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8817 __func__);
8818 nlmsg_free(msg);
8819 return -1;
8820 }
8821
8822 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting HE GI %d",
8823 __func__, gi_val);
8824
8825 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8826 if (!attr1) {
8827 sigma_dut_print(dut, DUT_MSG_ERROR,
8828 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8829 __func__);
8830 nlmsg_free(msg);
8831 return -1;
8832 }
8833 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8834 nla_nest_end(msg, attr1);
8835
8836 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8837 if (!attr1) {
8838 sigma_dut_print(dut, DUT_MSG_ERROR,
8839 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8840 __func__);
8841 nlmsg_free(msg);
8842 return -1;
8843 }
8844 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8845 nla_nest_end(msg, attr1);
8846
8847 nla_nest_end(msg, attr);
8848 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8849 if (ret) {
8850 sigma_dut_print(dut, DUT_MSG_ERROR,
8851 "%s: send_and_recv_msgs failed, ret=%d",
8852 __func__, ret);
8853 }
8854 return ret;
8855#else /* NL80211_SUPPORT */
8856 return -1;
8857#endif /* NL80211_SUPPORT */
8858}
8859
8860
8861static int sta_set_vht_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8862{
8863 #ifdef NL80211_SUPPORT
8864 struct nlattr *attr;
8865 struct nlattr *attr1;
8866 int ifindex, ret;
8867 struct nl_msg *msg;
8868
8869 ifindex = if_nametoindex(intf);
8870 if (ifindex == 0) {
8871 sigma_dut_print(dut, DUT_MSG_ERROR,
8872 "%s: Index for interface %s failed",
8873 __func__, intf);
8874 return -1;
8875 }
8876
8877 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8878 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8879 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8880 sigma_dut_print(dut, DUT_MSG_ERROR,
8881 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8882 __func__);
8883 nlmsg_free(msg);
8884 return -1;
8885 }
8886
8887 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting VHT GI %d",
8888 __func__, gi_val);
8889
8890 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8891 if (!attr1) {
8892 sigma_dut_print(dut, DUT_MSG_ERROR,
8893 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8894 __func__);
8895 nlmsg_free(msg);
8896 return -1;
8897 }
8898 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8899 nla_nest_end(msg, attr1);
8900
8901 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8902 if (!attr1) {
8903 sigma_dut_print(dut, DUT_MSG_ERROR,
8904 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8905 __func__);
8906 nlmsg_free(msg);
8907 return -1;
8908 }
8909 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8910 nla_nest_end(msg, attr1);
8911 nla_nest_end(msg, attr);
8912
8913 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8914 if (ret) {
8915 sigma_dut_print(dut, DUT_MSG_ERROR,
8916 "%s: send_and_recv_msgs failed, ret=%d",
8917 __func__, ret);
8918 }
8919 return ret;
8920#else /* NL80211_SUPPORT */
8921 return -1;
8922#endif /* NL80211_SUPPORT */
8923}
8924
8925
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008926static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
8927 const char *type)
8928{
8929 char buf[60];
8930
8931 if (dut->program == PROGRAM_HE) {
8932 /* resetting phymode to auto in case of HE program */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05308933 sta_set_phymode(dut, intf, "auto");
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008934
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07008935 /* reset the rate to Auto rate */
8936 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
8937 intf);
8938 if (system(buf) != 0) {
8939 sigma_dut_print(dut, DUT_MSG_ERROR,
8940 "iwpriv %s set_11ax_rate 0xff failed",
8941 intf);
8942 }
8943
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07008944 /* reset the LDPC setting */
8945 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
8946 if (system(buf) != 0) {
8947 sigma_dut_print(dut, DUT_MSG_ERROR,
8948 "iwpriv %s ldpc 1 failed", intf);
8949 }
8950
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008951 /* reset the power save setting */
Vinita S. Malooa8b62722020-04-23 01:45:41 +05308952 set_power_save_wcn(dut, intf, 2);
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008953
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008954 /* remove all network profiles */
8955 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008956
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008957 /* Configure ADDBA Req/Rsp buffer size to be 64 */
8958 sta_set_addba_buf_size(dut, intf, 64);
8959
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008960 if (dut->sta_async_twt_supp == -1)
8961 sta_get_twt_feature_async_supp(dut, intf);
8962
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008963 sta_set_scan_unicast_probe(dut, intf, 0);
8964
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008965#ifdef NL80211_SUPPORT
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08008966 nl80211_close_event_sock(dut);
8967
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008968 /* Reset the device HE capabilities to its default supported
8969 * configuration. */
8970 sta_set_he_testbed_def(dut, intf, 0);
8971
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008972 /* Disable noackpolicy for all AC */
8973 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
8974 sigma_dut_print(dut, DUT_MSG_ERROR,
8975 "Disable of noackpolicy for all AC failed");
8976 }
8977#endif /* NL80211_SUPPORT */
8978
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08008979 /* Enable WMM by default */
8980 if (wcn_sta_set_wmm(dut, intf, "on")) {
8981 sigma_dut_print(dut, DUT_MSG_ERROR,
8982 "Enable of WMM in sta_reset_default_wcn failed");
8983 }
8984
8985 /* Disable ADDBA_REJECT by default */
8986 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
8987 sigma_dut_print(dut, DUT_MSG_ERROR,
8988 "Disable of addba_reject in sta_reset_default_wcn failed");
8989 }
8990
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08008991 /* Enable sending of ADDBA by default */
8992 if (nlvendor_config_send_addba(dut, intf, 1)) {
8993 sigma_dut_print(dut, DUT_MSG_ERROR,
8994 "Enable sending of ADDBA in sta_reset_default_wcn failed");
8995 }
8996
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08008997 /* Enable AMPDU by default */
8998 iwpriv_sta_set_ampdu(dut, intf, 1);
8999
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009000#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08009001 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009002 sigma_dut_print(dut, DUT_MSG_ERROR,
9003 "Set LTF config to default in sta_reset_default_wcn failed");
9004 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07009005
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009006 /* set the beamformee NSTS(maximum number of
9007 * space-time streams) to default DUT config
9008 */
9009 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07009010 sigma_dut_print(dut, DUT_MSG_ERROR,
9011 "Failed to set BeamformeeSTS");
9012 }
Arif Hussain68d23f52018-07-11 13:39:08 -07009013
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07009014 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, 0)) {
9015 sigma_dut_print(dut, DUT_MSG_ERROR,
9016 "Failed to reset mgmt/data Tx disable config");
9017 }
9018
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07009019 if (sta_set_mac_padding_duration(
9020 dut, intf,
9021 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07009022 sigma_dut_print(dut, DUT_MSG_ERROR,
9023 "Failed to set MAC padding duration");
9024 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07009025
9026 if (sta_set_mu_edca_override(dut, intf, 0)) {
9027 sigma_dut_print(dut, DUT_MSG_ERROR,
9028 "ErrorCode,Failed to set MU EDCA override disable");
9029 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009030
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07009031 if (sta_set_ru_242_tone_tx(dut, intf, 0)) {
9032 sigma_dut_print(dut, DUT_MSG_ERROR,
9033 "Failed to set RU 242 tone Tx");
9034 }
9035
9036 if (sta_set_er_su_ppdu_type_tx(dut, intf, 0)) {
9037 sigma_dut_print(dut, DUT_MSG_ERROR,
9038 "Failed to set ER-SU PPDU type Tx");
9039 }
9040
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009041 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
9042 sigma_dut_print(dut, DUT_MSG_ERROR,
9043 "Failed to set OM ctrl supp");
9044 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07009045
9046 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
9047 sigma_dut_print(dut, DUT_MSG_ERROR,
9048 "Failed to set Tx SU PPDU enable");
9049 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009050
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009051 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
9052 sigma_dut_print(dut, DUT_MSG_ERROR,
9053 "failed to send TB PPDU Tx cfg");
9054 }
9055
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009056 if (sta_set_he_om_ctrl_reset(dut, intf)) {
9057 sigma_dut_print(dut, DUT_MSG_ERROR,
9058 "Failed to set OM ctrl reset");
9059 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009060
9061 /* +HTC-HE support default on */
9062 if (sta_set_he_htc_supp(dut, intf, 1)) {
9063 sigma_dut_print(dut, DUT_MSG_ERROR,
9064 "Setting of +HTC-HE support failed");
9065 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009066#endif /* NL80211_SUPPORT */
9067
Arif Hussain8d5b27b2018-05-14 14:31:03 -07009068 if (sta_set_tx_beamformee(dut, intf, 1)) {
9069 sigma_dut_print(dut, DUT_MSG_ERROR,
9070 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
9071 }
9072
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009073 wpa_command(intf, "SET oce 1");
9074
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009075 /* Set nss to 1 and MCS 0-7 in case of testbed */
9076 if (type && strcasecmp(type, "Testbed") == 0) {
9077#ifdef NL80211_SUPPORT
9078 int ret;
9079#endif /* NL80211_SUPPORT */
9080
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009081 wpa_command(intf, "SET oce 0");
9082
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009083 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
9084 if (system(buf) != 0) {
9085 sigma_dut_print(dut, DUT_MSG_ERROR,
9086 "iwpriv %s nss failed", intf);
9087 }
9088
9089#ifdef NL80211_SUPPORT
9090 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
9091 if (ret) {
9092 sigma_dut_print(dut, DUT_MSG_ERROR,
9093 "Setting of MCS failed, ret:%d",
9094 ret);
9095 }
9096#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08009097
9098 /* Disable STBC as default */
9099 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08009100
9101 /* Disable AMSDU as default */
9102 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009103
9104#ifdef NL80211_SUPPORT
9105 /* HE fragmentation default off */
9106 if (sta_set_he_fragmentation(dut, intf,
9107 HE_FRAG_DISABLE)) {
9108 sigma_dut_print(dut, DUT_MSG_ERROR,
9109 "Setting of HE fragmentation failed");
9110 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009111
9112 /* set the beamformee NSTS(maximum number of
9113 * space-time streams) to default testbed config
9114 */
9115 if (sta_set_beamformee_sts(dut, intf, 3)) {
9116 sigma_dut_print(dut, DUT_MSG_ERROR,
9117 "Failed to set BeamformeeSTS");
9118 }
9119
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07009120 if (sta_set_punctured_preamble_rx(dut, intf, 0)) {
9121 sigma_dut_print(dut, DUT_MSG_ERROR,
9122 "Failed to reset PreamblePunctRx support");
9123 }
9124
Kiran Kumar Lokere727687f2021-06-24 00:35:49 -07009125 if (sta_set_bss_max_idle_period(dut, intf, 0)) {
9126 sigma_dut_print(dut, DUT_MSG_ERROR,
9127 "Failed to reset BSS max idle period");
9128 }
9129
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009130 /* +HTC-HE support default off */
9131 if (sta_set_he_htc_supp(dut, intf, 0)) {
9132 sigma_dut_print(dut, DUT_MSG_ERROR,
9133 "Setting of +HTC-HE support failed");
9134 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08009135
9136 /* Set device HE capabilities to testbed default
9137 * configuration. */
9138 if (sta_set_he_testbed_def(dut, intf, 1)) {
9139 sigma_dut_print(dut, DUT_MSG_DEBUG,
9140 "Failed to set HE defaults");
9141 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08009142
9143 /* Disable VHT support in 2.4 GHz for testbed */
9144 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009145#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08009146
9147 /* Enable WEP/TKIP with HE capability in testbed */
9148 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
9149 sigma_dut_print(dut, DUT_MSG_ERROR,
9150 "Enabling HE config with WEP/TKIP failed");
9151 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009152 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009153
9154 /* Defaults in case of DUT */
9155 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07009156 /* Enable STBC by default */
9157 wcn_sta_set_stbc(dut, intf, "1");
9158
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009159 /* set nss to 2 */
9160 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
9161 if (system(buf) != 0) {
9162 sigma_dut_print(dut, DUT_MSG_ERROR,
9163 "iwpriv %s nss 2 failed", intf);
9164 }
Arif Hussainac6c5112018-05-25 17:34:00 -07009165 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009166
9167#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07009168 /* Set HE_MCS to 0-11 */
9169 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009170 sigma_dut_print(dut, DUT_MSG_ERROR,
9171 "Setting of MCS failed");
9172 }
9173#endif /* NL80211_SUPPORT */
9174
9175 /* Disable WEP/TKIP with HE capability in DUT */
9176 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
9177 sigma_dut_print(dut, DUT_MSG_ERROR,
9178 "Enabling HE config with WEP/TKIP failed");
9179 }
9180 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009181 }
9182}
9183
9184
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309185static int sta_set_client_privacy(struct sigma_dut *dut,
9186 struct sigma_conn *conn, const char *intf,
9187 int enable)
9188{
9189 if (enable &&
9190 (wpa_command(intf, "SET mac_addr 1") < 0 ||
9191 wpa_command(intf, "SET rand_addr_lifetime 1") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309192 (wpa_command(intf, "MAC_RAND_SCAN enable=1 all") < 0 &&
9193 wpa_command(intf, "SET preassoc_mac_addr 1") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309194 wpa_command(intf, "SET gas_rand_mac_addr 1") < 0 ||
9195 wpa_command(intf, "SET gas_rand_addr_lifetime 1") < 0))
9196 return -1;
9197
9198 if (!enable &&
9199 (wpa_command(intf, "SET mac_addr 0") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309200 (wpa_command(intf, "MAC_RAND_SCAN enable=0 all") < 0 &&
9201 wpa_command(intf, "SET preassoc_mac_addr 0") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309202 wpa_command(intf, "SET gas_rand_mac_addr 0") < 0))
9203 return -1;
9204
9205 dut->client_privacy = enable;
9206 return 0;
9207}
9208
9209
Jouni Malinenf7222712019-06-13 01:50:21 +03009210static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
9211 struct sigma_conn *conn,
9212 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009213{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009214 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009215 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009216 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009217 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309218 const char *dev_role = get_param(cmd, "DevRole");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309219 char resp[20];
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309220 char buf[100];
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309221 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009222
Shivani Baranwal31182012021-12-07 21:11:13 +05309223#ifdef ANDROID
9224 kill_pid(dut, concat_sigma_tmpdir(dut, "/sigma_dut-dnsmasq.pid",
9225 buf, sizeof(buf)));
9226#endif /* ANDROID */
9227
Jouni Malinenb21f0542019-11-04 17:53:38 +02009228 if (dut->station_ifname_2g &&
9229 strcmp(dut->station_ifname_2g, intf) == 0)
9230 dut->use_5g = 0;
9231 else if (dut->station_ifname_5g &&
9232 strcmp(dut->station_ifname_5g, intf) == 0)
9233 dut->use_5g = 1;
9234
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009235 if (!program)
9236 program = get_param(cmd, "prog");
9237 dut->program = sigma_program_to_enum(program);
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05309238
9239 if (dut->program == PROGRAM_WFD && dut->user_config_timeout)
9240 dut->default_timeout = dut->user_config_timeout;
9241
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009242 dut->device_type = STA_unknown;
9243 type = get_param(cmd, "type");
9244 if (type && strcasecmp(type, "Testbed") == 0)
9245 dut->device_type = STA_testbed;
9246 if (type && strcasecmp(type, "DUT") == 0)
9247 dut->device_type = STA_dut;
9248
9249 if (dut->program == PROGRAM_TDLS) {
9250 /* Clear TDLS testing mode */
9251 wpa_command(intf, "SET tdls_disabled 0");
9252 wpa_command(intf, "SET tdls_testing 0");
9253 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009254 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05309255 /* Enable the WCN driver in TDLS Explicit trigger mode
9256 */
9257 wpa_command(intf, "SET tdls_external_control 0");
9258 wpa_command(intf, "SET tdls_trigger_control 0");
9259 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009260 }
9261
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009262#ifdef MIRACAST
9263 if (dut->program == PROGRAM_WFD ||
9264 dut->program == PROGRAM_DISPLAYR2)
9265 miracast_sta_reset_default(dut, conn, cmd);
9266#endif /* MIRACAST */
9267
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009268 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009269 case DRIVER_ATHEROS:
9270 sta_reset_default_ath(dut, intf, type);
9271 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009272 case DRIVER_WCN:
9273 sta_reset_default_wcn(dut, intf, type);
9274 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009275 default:
9276 break;
9277 }
9278
9279#ifdef ANDROID_NAN
9280 if (dut->program == PROGRAM_NAN)
9281 nan_cmd_sta_reset_default(dut, conn, cmd);
9282#endif /* ANDROID_NAN */
9283
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05309284 if (dut->program == PROGRAM_LOC &&
9285 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
9286 return ERROR_SEND_STATUS;
9287
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009288 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
9289 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009290 unlink("SP/wi-fi.org/pps.xml");
9291 if (system("rm -r SP/*") != 0) {
9292 }
9293 unlink("next-client-cert.pem");
9294 unlink("next-client-key.pem");
9295 }
9296
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009297 /* For WPS program of the 60 GHz band the band type needs to be saved */
9298 if (dut->program == PROGRAM_WPS) {
9299 if (band && strcasecmp(band, "60GHz") == 0) {
9300 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009301 /* For 60 GHz enable WPS for WPS TCs */
9302 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009303 } else {
9304 dut->band = WPS_BAND_NON_60G;
9305 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009306 } else if (dut->program == PROGRAM_60GHZ) {
9307 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
9308 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009309 }
9310
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02009311 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009312 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009313 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009314
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009315 sigma_dut_print(dut, DUT_MSG_INFO,
9316 "WPS 60 GHz program, wps_disable = %d",
9317 dut->wps_disable);
9318
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009319 if (!dev_role) {
9320 send_resp(dut, conn, SIGMA_ERROR,
9321 "errorCode,Missing DevRole argument");
9322 return 0;
9323 }
9324
9325 if (strcasecmp(dev_role, "STA") == 0)
9326 dut->dev_role = DEVROLE_STA;
9327 else if (strcasecmp(dev_role, "PCP") == 0)
9328 dut->dev_role = DEVROLE_PCP;
9329 else {
9330 send_resp(dut, conn, SIGMA_ERROR,
9331 "errorCode,Unknown DevRole");
9332 return 0;
9333 }
9334
9335 if (dut->device_type == STA_unknown) {
9336 sigma_dut_print(dut, DUT_MSG_ERROR,
9337 "Device type is not STA testbed or DUT");
9338 send_resp(dut, conn, SIGMA_ERROR,
9339 "errorCode,Unknown device type");
9340 return 0;
9341 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009342
9343 sigma_dut_print(dut, DUT_MSG_DEBUG,
9344 "Setting msdu_size to MAX: 7912");
9345 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009346 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009347
9348 if (system(buf) != 0) {
9349 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9350 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009351 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009352 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009353
9354 if (sta_set_force_mcs(dut, 0, 1)) {
9355 sigma_dut_print(dut, DUT_MSG_ERROR,
9356 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009357 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009358 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009359 }
9360
9361 wpa_command(intf, "WPS_ER_STOP");
9362 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05309363 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009364 wpa_command(intf, "SET radio_disabled 0");
9365
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02009366 dut->wps_forced_version = 0;
9367
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009368 if (dut->wsc_fragment) {
9369 dut->wsc_fragment = 0;
9370 wpa_command(intf, "SET device_name Test client");
9371 wpa_command(intf, "SET manufacturer ");
9372 wpa_command(intf, "SET model_name ");
9373 wpa_command(intf, "SET model_number ");
9374 wpa_command(intf, "SET serial_number ");
9375 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02009376 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
9377 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
9378 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
9379 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009380
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009381 if (dut->tmp_mac_addr && dut->set_macaddr) {
9382 dut->tmp_mac_addr = 0;
9383 if (system(dut->set_macaddr) != 0) {
9384 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
9385 "temporary MAC address");
9386 }
9387 }
9388
9389 set_ps(intf, dut, 0);
9390
Jouni Malinenba630452018-06-22 11:49:59 +03009391 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009392 dut->program == PROGRAM_HS2_R3 || dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009393 wpa_command(intf, "SET interworking 1");
9394 wpa_command(intf, "SET hs20 1");
9395 }
9396
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009397 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03009398 dut->program == PROGRAM_HS2_R3 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009399 dut->program == PROGRAM_HS2_R4 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009400 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009401 wpa_command(intf, "SET pmf 1");
9402 } else {
9403 wpa_command(intf, "SET pmf 0");
9404 }
9405
9406 hs2_clear_credentials(intf);
9407 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
9408 wpa_command(intf, "SET access_network_type 15");
9409
9410 static_ip_file(0, NULL, NULL, NULL);
9411 kill_dhcp_client(dut, intf);
9412 clear_ip_addr(dut, intf);
9413
9414 dut->er_oper_performed = 0;
9415 dut->er_oper_bssid[0] = '\0';
9416
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009417 if (dut->program == PROGRAM_LOC) {
9418 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009419 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009420 }
9421
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07009422 if (dut->program == PROGRAM_MBO || dut->program == PROGRAM_HE) {
Ashwini Patil00402582017-04-13 12:29:39 +05309423 free(dut->non_pref_ch_list);
9424 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309425 free(dut->btm_query_cand_list);
9426 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05309427 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05309428 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05309429 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05309430 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05309431 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05309432 }
9433
Jouni Malinen3c367e82017-06-23 17:01:47 +03009434 free(dut->rsne_override);
9435 dut->rsne_override = NULL;
9436
Jouni Malinen68143132017-09-02 02:34:08 +03009437 free(dut->sae_commit_override);
9438 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03009439 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02009440 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03009441
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009442 dut->sta_associate_wait_connect = 0;
9443 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03009444 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009445 dut->sta_tod_policy = 0;
9446
Jouni Malinend86e5822017-08-29 03:55:32 +03009447 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02009448 free(dut->dpp_peer_uri);
9449 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02009450 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02009451 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03009452 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinen29a63f42022-04-13 22:08:47 +03009453 dpp_mdns_stop(dut);
Jouni Malinend86e5822017-08-29 03:55:32 +03009454
Jouni Malinenfac9cad2017-10-10 18:35:55 +03009455 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
9456
vamsi krishnaa2799492017-12-05 14:28:01 +05309457 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309458 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05309459 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05309460 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
9461 dut->fils_hlp = 0;
9462#ifdef ANDROID
9463 hlp_thread_cleanup(dut);
9464#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05309465 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309466
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309467 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309468 wpa_command(intf, "SET interworking 1");
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309469 wpa_command(intf, "SET enable_dscp_policy_capa 1");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05309470 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309471 dut->reject_dscp_policies = 0;
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +05309472 dut->num_dscp_status = 0;
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309473 snprintf(buf, sizeof(buf),
9474 "ip -6 route replace fe80::/64 dev %s table local",
9475 intf);
9476 if (system(buf) != 0)
9477 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
9478 buf);
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05309479
9480 stop_dscp_policy_mon_thread(dut);
9481 clear_all_dscp_policies(dut);
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309482 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309483
Jouni Malinen8179fee2019-03-28 03:19:47 +02009484 dut->akm_values = 0;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05309485
9486#ifdef NL80211_SUPPORT
9487 if (get_driver_type(dut) == DRIVER_WCN)
9488 sta_config_params(dut, intf, STA_SET_FT_DS, 0);
9489#endif /* NL80211_SUPPORT */
9490
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03009491 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02009492
Sunil Dutt076081f2018-02-05 19:45:50 +05309493#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009494 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05309495 dut->config_rsnie == 1) {
9496 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309497 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05309498 }
9499#endif /* NL80211_SUPPORT */
9500
Sunil Duttfebf8a82018-02-09 18:50:13 +05309501 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
9502 dut->dev_role = DEVROLE_STA_CFON;
9503 return sta_cfon_reset_default(dut, conn, cmd);
9504 }
9505
Jouni Malinen439352d2018-09-13 03:42:23 +03009506 wpa_command(intf, "SET setband AUTO");
9507
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309508 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
9509 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
9510
9511 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
9512 sizeof(resp));
9513 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
9514
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309515 if (sta_set_client_privacy(dut, conn, intf,
9516 dut->program == PROGRAM_WPA3 &&
9517 dut->device_type == STA_dut &&
9518 dut->client_privacy_default)) {
9519 sigma_dut_print(dut, DUT_MSG_ERROR,
9520 "Failed to set client privacy functionality");
9521 /* sta_reset_default command is not really supposed to fail,
9522 * so allow this to continue. */
9523 }
9524
Veerendranath Jakkamca239592021-10-11 20:48:00 +05309525 if (get_driver_type(dut) == DRIVER_WCN)
9526 wcn_set_ignore_h2e_rsnxe(dut, intf, 0);
9527
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05309528 dut->saquery_oci_freq = 0;
Shivani Baranwalebde8f62021-10-19 12:26:02 +05309529 dut->prev_disable_scs_support = 0;
9530 dut->prev_disable_mscs_support = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309531
Veerendranath Jakkamf6c8ab52022-03-10 05:43:02 -08009532 if (dut->autoconnect_default)
9533 wpa_command(intf, "STA_AUTOCONNECT 1");
9534 else
9535 wpa_command(intf, "STA_AUTOCONNECT 0");
9536
Sunil Duttfebf8a82018-02-09 18:50:13 +05309537 if (dut->program != PROGRAM_VHT)
9538 return cmd_sta_p2p_reset(dut, conn, cmd);
9539
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08009540 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009541}
9542
9543
Jouni Malinenf7222712019-06-13 01:50:21 +03009544static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
9545 struct sigma_conn *conn,
9546 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009547{
9548 const char *program = get_param(cmd, "Program");
9549
9550 if (program == NULL)
9551 return -1;
9552#ifdef ANDROID_NAN
9553 if (strcasecmp(program, "NAN") == 0)
9554 return nan_cmd_sta_get_events(dut, conn, cmd);
9555#endif /* ANDROID_NAN */
9556 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9557 return 0;
9558}
9559
9560
Jouni Malinen82905202018-04-29 17:20:10 +03009561static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
9562 struct sigma_cmd *cmd)
9563{
9564 const char *url = get_param(cmd, "url");
9565 const char *method = get_param(cmd, "method");
9566 pid_t pid;
9567 int status;
9568
9569 if (!url || !method)
9570 return -1;
9571
9572 /* TODO: Add support for method,post */
9573 if (strcasecmp(method, "get") != 0) {
9574 send_resp(dut, conn, SIGMA_ERROR,
9575 "ErrorCode,Unsupported method");
9576 return 0;
9577 }
9578
9579 pid = fork();
9580 if (pid < 0) {
9581 perror("fork");
9582 return -1;
9583 }
9584
9585 if (pid == 0) {
9586 char * argv[5] = { "wget", "-O", "/dev/null",
9587 (char *) url, NULL };
9588
9589 execv("/usr/bin/wget", argv);
9590 perror("execv");
9591 exit(0);
9592 return -1;
9593 }
9594
9595 if (waitpid(pid, &status, 0) < 0) {
9596 perror("waitpid");
9597 return -1;
9598 }
9599
9600 if (WIFEXITED(status)) {
9601 const char *errmsg;
9602
9603 if (WEXITSTATUS(status) == 0)
9604 return 1;
9605 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
9606 WEXITSTATUS(status));
9607 switch (WEXITSTATUS(status)) {
9608 case 4:
9609 errmsg = "errmsg,Network failure";
9610 break;
9611 case 8:
9612 errmsg = "errmsg,Server issued an error response";
9613 break;
9614 default:
9615 errmsg = "errmsg,Unknown failure from wget";
9616 break;
9617 }
9618 send_resp(dut, conn, SIGMA_ERROR, errmsg);
9619 return 0;
9620 }
9621
9622 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
9623 return 0;
9624}
9625
9626
Jouni Malinenf7222712019-06-13 01:50:21 +03009627static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
9628 struct sigma_conn *conn,
9629 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009630{
9631 const char *program = get_param(cmd, "Prog");
9632
Jouni Malinen82905202018-04-29 17:20:10 +03009633 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009634 return -1;
9635#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03009636 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009637 return nan_cmd_sta_exec_action(dut, conn, cmd);
9638#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03009639
9640 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009641 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03009642
9643 if (get_param(cmd, "url"))
9644 return sta_exec_action_url(dut, conn, cmd);
9645
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009646 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9647 return 0;
9648}
9649
9650
Jouni Malinenf7222712019-06-13 01:50:21 +03009651static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
9652 struct sigma_conn *conn,
9653 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009654{
9655 const char *intf = get_param(cmd, "Interface");
9656 const char *val, *mcs32, *rate;
9657
9658 val = get_param(cmd, "GREENFIELD");
9659 if (val) {
9660 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
9661 /* Enable GD */
9662 send_resp(dut, conn, SIGMA_ERROR,
9663 "ErrorCode,GF not supported");
9664 return 0;
9665 }
9666 }
9667
9668 val = get_param(cmd, "SGI20");
9669 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009670 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009671 case DRIVER_ATHEROS:
9672 ath_sta_set_sgi(dut, intf, val);
9673 break;
9674 default:
9675 send_resp(dut, conn, SIGMA_ERROR,
9676 "ErrorCode,SGI20 not supported");
9677 return 0;
9678 }
9679 }
9680
9681 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
9682 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
9683 if (mcs32 && rate) {
9684 /* TODO */
9685 send_resp(dut, conn, SIGMA_ERROR,
9686 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
9687 return 0;
9688 } else if (mcs32 && !rate) {
9689 /* TODO */
9690 send_resp(dut, conn, SIGMA_ERROR,
9691 "ErrorCode,MCS32 not supported");
9692 return 0;
9693 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009694 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009695 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07009696 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009697 ath_sta_set_11nrates(dut, intf, rate);
9698 break;
9699 default:
9700 send_resp(dut, conn, SIGMA_ERROR,
9701 "ErrorCode,MCS32_FIXEDRATE not supported");
9702 return 0;
9703 }
9704 }
9705
9706 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9707}
9708
9709
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009710static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
9711 int mcs_config)
9712{
9713#ifdef NL80211_SUPPORT
9714 int ret;
9715
9716 switch (mcs_config) {
9717 case HE_80_MCS0_7:
9718 case HE_80_MCS0_9:
9719 case HE_80_MCS0_11:
9720 ret = sta_set_he_mcs(dut, intf, mcs_config);
9721 if (ret) {
9722 sigma_dut_print(dut, DUT_MSG_ERROR,
9723 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
9724 mcs_config, ret);
9725 }
9726 break;
9727 default:
9728 sigma_dut_print(dut, DUT_MSG_ERROR,
9729 "cmd_set_max_he_mcs: Invalid mcs %d",
9730 mcs_config);
9731 break;
9732 }
9733#else /* NL80211_SUPPORT */
9734 sigma_dut_print(dut, DUT_MSG_ERROR,
9735 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
9736#endif /* NL80211_SUPPORT */
9737}
9738
9739
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009740struct wait_event {
9741 struct sigma_dut *dut;
9742 int cmd;
9743 unsigned int twt_op;
9744};
9745
9746#ifdef NL80211_SUPPORT
9747
9748static int twt_event_handler(struct nl_msg *msg, void *arg)
9749{
9750 struct wait_event *wait = arg;
9751 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9752 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9753 uint32_t subcmd;
9754 uint8_t *data = NULL;
9755 size_t len = 0;
9756 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
9757 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
9758 int cmd_id;
9759 unsigned char val;
9760
9761 if (!wait)
9762 return NL_SKIP;
9763
9764 if (gnlh->cmd != NL80211_CMD_VENDOR) {
9765 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9766 "%s: NL cmd is not vendor %d", __func__,
9767 gnlh->cmd);
9768 return NL_SKIP;
9769 }
9770
9771 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9772 genlmsg_attrlen(gnlh, 0), NULL);
9773
9774 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
9775 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9776 "%s: vendor ID not found", __func__);
9777 return NL_SKIP;
9778 }
9779 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
9780
9781 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
9782 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9783 "%s: Not a TWT_cmd %d", __func__, subcmd);
9784 return NL_SKIP;
9785 }
9786 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9787 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
9788 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
9789 } else {
9790 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9791 "%s: vendor data not present", __func__);
9792 return NL_SKIP;
9793 }
9794 if (!data || !len) {
9795 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9796 "Invalid vendor data or len");
9797 return NL_SKIP;
9798 }
9799 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
9800 "event data len %ld", len);
9801 hex_dump(wait->dut, data, len);
9802 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
9803 (struct nlattr *) data, len, NULL)) {
9804 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9805 "vendor data parse error");
9806 return NL_SKIP;
9807 }
9808
9809 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
9810 if (val != wait->twt_op) {
9811 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9812 "Invalid TWT operation, expected %d, rcvd %d",
9813 wait->twt_op, val);
9814 return NL_SKIP;
9815 }
9816 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
9817 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
9818 NULL)) {
9819 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9820 "nla_parse failed for TWT event");
9821 return NL_SKIP;
9822 }
9823
9824 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
9825 if (!twt_status[cmd_id]) {
9826 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9827 "%s TWT resp status missing", __func__);
9828 wait->cmd = -1;
9829 } else {
9830 val = nla_get_u8(twt_status[cmd_id]);
9831 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
9832 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9833 "%s TWT resp status %d", __func__, val);
9834 wait->cmd = -1;
9835 } else {
9836 wait->cmd = 1;
9837 }
9838 }
9839
9840 return NL_SKIP;
9841}
9842
9843
9844static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
9845 unsigned int timeout)
9846{
9847 fd_set read_fd_set;
9848 int retval;
9849 int sock_fd;
9850 struct timeval time_out;
9851
9852 time_out.tv_sec = timeout;
9853 time_out.tv_usec = 0;
9854
9855 FD_ZERO(&read_fd_set);
9856
9857 if (!sock)
9858 return -1;
9859
9860 sock_fd = nl_socket_get_fd(sock);
9861 FD_SET(sock_fd, &read_fd_set);
9862
9863 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
9864
9865 if (retval == 0)
9866 sigma_dut_print(dut, DUT_MSG_ERROR,
9867 "%s: TWT event response timedout", __func__);
9868
9869 if (retval < 0)
9870 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
9871 __func__, retval);
9872
9873 return retval;
9874}
9875
9876
9877#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
9878
9879static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
9880{
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009881 struct nl_cb *cb = NULL;
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009882 int err_code = 0, select_retval = 0;
9883 struct wait_event wait_info;
9884
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009885 if (dut->nl_ctx->event_sock)
9886 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009887 if (!cb) {
9888 sigma_dut_print(dut, DUT_MSG_ERROR,
9889 "event callback not found");
9890 return ERROR_SEND_STATUS;
9891 }
9892
9893 wait_info.cmd = 0;
9894 wait_info.dut = dut;
9895 wait_info.twt_op = twt_op;
9896
9897 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
9898
9899 while (!wait_info.cmd) {
9900 select_retval = wait_on_nl_socket(
9901 dut->nl_ctx->event_sock, dut,
9902 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
9903
9904 if (select_retval > 0) {
9905 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
9906 if (err_code < 0) {
9907 sigma_dut_print(dut, DUT_MSG_ERROR,
9908 "%s: nl rcv failed, err_code %d",
9909 __func__, err_code);
9910 break;
9911 }
9912 } else {
9913 sigma_dut_print(dut, DUT_MSG_ERROR,
9914 "%s: wait on socket failed %d",
9915 __func__, select_retval);
9916 err_code = 1;
9917 break;
9918 }
9919
9920 }
9921 nl_cb_put(cb);
9922
9923 if (wait_info.cmd < 0)
9924 err_code = 1;
9925
9926 sigma_dut_print(dut, DUT_MSG_DEBUG,
9927 "%s: rcvd cmd %d, err_code %d, s_ret %d",
9928 __func__, wait_info.cmd, err_code, select_retval);
9929
9930 return err_code;
9931}
9932
9933#endif /* NL80211_SUPPORT */
9934
9935
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009936static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
9937 struct sigma_cmd *cmd)
9938{
9939#ifdef NL80211_SUPPORT
9940 struct nlattr *attr, *attr1;
9941 struct nl_msg *msg;
9942 int ifindex, ret;
9943 const char *intf = get_param(cmd, "Interface");
9944
9945 ifindex = if_nametoindex(intf);
9946 if (ifindex == 0) {
9947 sigma_dut_print(dut, DUT_MSG_ERROR,
9948 "%s: Index for interface %s failed",
9949 __func__, intf);
9950 return ERROR_SEND_STATUS;
9951 }
9952
9953 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9954 NL80211_CMD_VENDOR)) ||
9955 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9956 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9957 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9958 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9959 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9960 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9961 QCA_WLAN_TWT_SUSPEND) ||
9962 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07009963 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009964 sigma_dut_print(dut, DUT_MSG_ERROR,
9965 "%s: err in adding vendor_cmd and vendor_data",
9966 __func__);
9967 nlmsg_free(msg);
9968 return ERROR_SEND_STATUS;
9969 }
9970 nla_nest_end(msg, attr1);
9971 nla_nest_end(msg, attr);
9972
9973 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9974 if (ret) {
9975 sigma_dut_print(dut, DUT_MSG_ERROR,
9976 "%s: err in send_and_recv_msgs, ret=%d",
9977 __func__, ret);
9978 }
9979
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009980 if (!dut->sta_async_twt_supp)
9981 return ret;
9982
9983 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009984#else /* NL80211_SUPPORT */
9985 sigma_dut_print(dut, DUT_MSG_ERROR,
9986 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9987 return ERROR_SEND_STATUS;
9988#endif /* NL80211_SUPPORT */
9989}
9990
9991
9992static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
9993 struct sigma_cmd *cmd,
9994 unsigned int suspend_duration)
9995{
9996#ifdef NL80211_SUPPORT
9997 struct nlattr *attr, *attr1;
9998 struct nl_msg *msg;
9999 int ifindex, ret;
10000 const char *intf = get_param(cmd, "Interface");
10001 int next_twt_size = 1;
10002
10003 ifindex = if_nametoindex(intf);
10004 if (ifindex == 0) {
10005 sigma_dut_print(dut, DUT_MSG_ERROR,
10006 "%s: Index for interface %s failed",
10007 __func__, intf);
10008 return ERROR_SEND_STATUS;
10009 }
10010
10011 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10012 NL80211_CMD_VENDOR)) ||
10013 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10014 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10015 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10016 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10017 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10018 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10019 QCA_WLAN_TWT_NUDGE) ||
10020 !(attr1 = nla_nest_start(msg,
10021 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10022 (suspend_duration &&
10023 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
10024 suspend_duration)) ||
10025 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010026 next_twt_size) ||
10027 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010028 sigma_dut_print(dut, DUT_MSG_ERROR,
10029 "%s: err in adding vendor_cmd and vendor_data",
10030 __func__);
10031 nlmsg_free(msg);
10032 return ERROR_SEND_STATUS;
10033 }
10034 nla_nest_end(msg, attr1);
10035 nla_nest_end(msg, attr);
10036
10037 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10038 if (ret) {
10039 sigma_dut_print(dut, DUT_MSG_ERROR,
10040 "%s: err in send_and_recv_msgs, ret=%d",
10041 __func__, ret);
10042 }
10043
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010044 if (!dut->sta_async_twt_supp)
10045 return ret;
10046
10047 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010048#else /* NL80211_SUPPORT */
10049 sigma_dut_print(dut, DUT_MSG_ERROR,
10050 "TWT suspend cannot be done without NL80211_SUPPORT defined");
10051 return ERROR_SEND_STATUS;
10052#endif /* NL80211_SUPPORT */
10053}
10054
10055
10056static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
10057 struct sigma_conn *conn,
10058 struct sigma_cmd *cmd)
10059{
10060 const char *val;
10061
10062 val = get_param(cmd, "TWT_SuspendDuration");
10063 if (val) {
10064 unsigned int suspend_duration;
10065
10066 suspend_duration = atoi(val);
10067 suspend_duration = suspend_duration * 1000 * 1000;
10068 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
10069 }
10070
10071 return sta_twt_send_suspend(dut, conn, cmd);
10072}
10073
10074
10075static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
10076 struct sigma_cmd *cmd)
10077{
10078#ifdef NL80211_SUPPORT
10079 struct nlattr *attr, *attr1;
10080 struct nl_msg *msg;
10081 int ifindex, ret;
10082 const char *intf = get_param(cmd, "Interface");
10083 int next2_twt_size = 1;
10084 unsigned int resume_duration = 0;
10085 const char *val;
10086
10087 ifindex = if_nametoindex(intf);
10088 if (ifindex == 0) {
10089 sigma_dut_print(dut, DUT_MSG_ERROR,
10090 "%s: Index for interface %s failed",
10091 __func__, intf);
10092 return ERROR_SEND_STATUS;
10093 }
10094
10095 val = get_param(cmd, "TWT_ResumeDuration");
10096 if (val) {
10097 resume_duration = atoi(val);
10098 resume_duration = resume_duration * 1000 * 1000;
10099 }
10100
10101 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10102 NL80211_CMD_VENDOR)) ||
10103 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10104 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10105 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10106 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10107 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10108 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10109 QCA_WLAN_TWT_RESUME) ||
10110 !(attr1 = nla_nest_start(msg,
10111 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10112 (resume_duration &&
10113 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
10114 resume_duration)) ||
10115 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
10116 next2_twt_size)) {
10117 sigma_dut_print(dut, DUT_MSG_ERROR,
10118 "%s: err in adding vendor_cmd and vendor_data",
10119 __func__);
10120 nlmsg_free(msg);
10121 return ERROR_SEND_STATUS;
10122 }
10123 nla_nest_end(msg, attr1);
10124 nla_nest_end(msg, attr);
10125
10126 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10127 if (ret) {
10128 sigma_dut_print(dut, DUT_MSG_ERROR,
10129 "%s: err in send_and_recv_msgs, ret=%d",
10130 __func__, ret);
10131 }
10132
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010133 if (!dut->sta_async_twt_supp)
10134 return ret;
10135
10136 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010137#else /* NL80211_SUPPORT */
10138 sigma_dut_print(dut, DUT_MSG_ERROR,
10139 "TWT resume cannot be done without NL80211_SUPPORT defined");
10140 return ERROR_SEND_STATUS;
10141#endif /* NL80211_SUPPORT */
10142}
10143
10144
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010145#define TWT_REQUEST_CMD 0
10146#define TWT_SUGGEST_CMD 1
10147#define TWT_DEMAND_CMD 2
10148
Arif Hussain480d5f42019-03-12 14:40:42 -070010149static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
10150 struct sigma_cmd *cmd)
10151{
10152#ifdef NL80211_SUPPORT
10153 struct nlattr *params;
10154 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010155 struct nl_msg *msg;
10156 int ifindex, ret;
10157 const char *val;
10158 const char *intf = get_param(cmd, "Interface");
10159 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
10160 wake_interval_mantissa = 512;
10161 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010162 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010163 int bcast_twt = 0;
10164 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -070010165
10166 ifindex = if_nametoindex(intf);
10167 if (ifindex == 0) {
10168 sigma_dut_print(dut, DUT_MSG_ERROR,
10169 "%s: Index for interface %s failed",
10170 __func__, intf);
10171 return -1;
10172 }
10173
10174 val = get_param(cmd, "FlowType");
10175 if (val) {
10176 flow_type = atoi(val);
10177 if (flow_type != 0 && flow_type != 1) {
10178 sigma_dut_print(dut, DUT_MSG_ERROR,
10179 "TWT: Invalid FlowType %d", flow_type);
10180 return -1;
10181 }
10182 }
10183
10184 val = get_param(cmd, "TWT_Trigger");
10185 if (val) {
10186 twt_trigger = atoi(val);
10187 if (twt_trigger != 0 && twt_trigger != 1) {
10188 sigma_dut_print(dut, DUT_MSG_ERROR,
10189 "TWT: Invalid TWT_Trigger %d",
10190 twt_trigger);
10191 return -1;
10192 }
10193 }
10194
10195 val = get_param(cmd, "Protection");
10196 if (val) {
10197 protection = atoi(val);
10198 if (protection != 0 && protection != 1) {
10199 sigma_dut_print(dut, DUT_MSG_ERROR,
10200 "TWT: Invalid Protection %d",
10201 protection);
10202 return -1;
10203 }
10204 }
10205
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010206 val = get_param(cmd, "SetupCommand");
10207 if (val) {
10208 cmd_type = atoi(val);
10209 if (cmd_type == TWT_REQUEST_CMD)
10210 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
10211 else if (cmd_type == TWT_SUGGEST_CMD)
10212 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
10213 else if (cmd_type == TWT_DEMAND_CMD)
10214 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
10215 else
10216 sigma_dut_print(dut, DUT_MSG_ERROR,
10217 "Default suggest is used for cmd %d",
10218 cmd_type);
10219 }
10220
Arif Hussain480d5f42019-03-12 14:40:42 -070010221 val = get_param(cmd, "TargetWakeTime");
10222 if (val)
10223 target_wake_time = atoi(val);
10224
10225 val = get_param(cmd, "WakeIntervalMantissa");
10226 if (val)
10227 wake_interval_mantissa = atoi(val);
10228
10229 val = get_param(cmd, "WakeIntervalExp");
10230 if (val)
10231 wake_interval_exp = atoi(val);
10232
10233 val = get_param(cmd, "NominalMinWakeDur");
10234 if (val)
10235 nominal_min_wake_dur = atoi(val);
10236
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010237 val = get_param(cmd, "BTWT_ID");
10238 if (val) {
10239 bcast_twt_id = atoi(val);
10240 bcast_twt = 1;
10241 }
10242
10243 val = get_param(cmd, "BTWT_Persistence");
10244 if (val) {
10245 bcast_twt_persis = atoi(val);
10246 bcast_twt = 1;
10247 }
10248
10249 val = get_param(cmd, "BTWT_Recommendation");
10250 if (val) {
10251 bcast_twt_recommdn = atoi(val);
10252 bcast_twt = 1;
10253 }
10254
10255 if (bcast_twt)
10256 sigma_dut_print(dut, DUT_MSG_DEBUG,
10257 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
10258 bcast_twt_id, bcast_twt_recommdn,
10259 bcast_twt_persis);
10260
Arif Hussain480d5f42019-03-12 14:40:42 -070010261 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10262 NL80211_CMD_VENDOR)) ||
10263 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10264 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10265 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010266 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010267 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010268 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10269 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010270 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010271 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010272 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
10273 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010274 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010275 (twt_trigger &&
10276 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010277 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
10278 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010279 (protection &&
10280 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010281 (bcast_twt &&
10282 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10283 (bcast_twt &&
10284 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10285 bcast_twt_id)) ||
10286 (bcast_twt &&
10287 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
10288 bcast_twt_persis)) ||
10289 (bcast_twt &&
10290 nla_put_u8(msg,
10291 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
10292 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010293 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
10294 target_wake_time) ||
10295 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
10296 nominal_min_wake_dur) ||
10297 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
10298 wake_interval_mantissa)) {
10299 sigma_dut_print(dut, DUT_MSG_ERROR,
10300 "%s: err in adding vendor_cmd and vendor_data",
10301 __func__);
10302 nlmsg_free(msg);
10303 return -1;
10304 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010305 nla_nest_end(msg, params);
10306 nla_nest_end(msg, attr);
10307
10308 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10309 if (ret) {
10310 sigma_dut_print(dut, DUT_MSG_ERROR,
10311 "%s: err in send_and_recv_msgs, ret=%d",
10312 __func__, ret);
10313 }
10314
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010315 if (!dut->sta_async_twt_supp)
10316 return ret;
10317
10318 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -070010319#else /* NL80211_SUPPORT */
10320 sigma_dut_print(dut, DUT_MSG_ERROR,
10321 "TWT request cannot be done without NL80211_SUPPORT defined");
10322 return -1;
10323#endif /* NL80211_SUPPORT */
10324}
10325
10326
10327static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
10328 struct sigma_cmd *cmd)
10329{
10330 #ifdef NL80211_SUPPORT
10331 struct nlattr *params;
10332 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010333 int ifindex, ret;
10334 struct nl_msg *msg;
10335 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010336 int bcast_twt = 0;
10337 int bcast_twt_id = 0;
10338 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -070010339
10340 ifindex = if_nametoindex(intf);
10341 if (ifindex == 0) {
10342 sigma_dut_print(dut, DUT_MSG_ERROR,
10343 "%s: Index for interface %s failed",
10344 __func__, intf);
10345 return -1;
10346 }
10347
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010348 val = get_param(cmd, "BTWT_ID");
10349 if (val) {
10350 bcast_twt_id = atoi(val);
10351 bcast_twt = 1;
10352 }
10353
Arif Hussain480d5f42019-03-12 14:40:42 -070010354 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10355 NL80211_CMD_VENDOR)) ||
10356 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10357 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10358 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010359 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010360 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010361 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10362 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010363 !(params = nla_nest_start(
10364 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010365 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010366 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
10367 (bcast_twt &&
10368 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10369 (bcast_twt &&
10370 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10371 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -070010372 sigma_dut_print(dut, DUT_MSG_ERROR,
10373 "%s: err in adding vendor_cmd and vendor_data",
10374 __func__);
10375 nlmsg_free(msg);
10376 return -1;
10377 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010378 nla_nest_end(msg, params);
10379 nla_nest_end(msg, attr);
10380
10381 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10382 if (ret) {
10383 sigma_dut_print(dut, DUT_MSG_ERROR,
10384 "%s: err in send_and_recv_msgs, ret=%d",
10385 __func__, ret);
10386 }
10387
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010388 if (!dut->sta_async_twt_supp)
10389 return ret;
10390
10391 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -070010392#else /* NL80211_SUPPORT */
10393 sigma_dut_print(dut, DUT_MSG_ERROR,
10394 "TWT teardown cannot be done without NL80211_SUPPORT defined");
10395 return -1;
10396#endif /* NL80211_SUPPORT */
10397}
10398
10399
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080010400static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
10401 struct sigma_cmd *cmd)
10402{
10403#ifdef NL80211_SUPPORT
10404 struct nlattr *params;
10405 struct nlattr *attr;
10406 struct nlattr *attr1;
10407 struct nl_msg *msg;
10408 int ifindex, ret;
10409 const char *val;
10410 const char *intf = get_param(cmd, "Interface");
10411 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
10412 ulmu_data_dis = 0;
10413
10414 ifindex = if_nametoindex(intf);
10415 if (ifindex == 0) {
10416 sigma_dut_print(dut, DUT_MSG_ERROR,
10417 "%s: Index for interface %s failed",
10418 __func__, intf);
10419 return -1;
10420 }
10421 val = get_param(cmd, "OMCtrl_RxNSS");
10422 if (val)
10423 rx_nss = atoi(val);
10424
10425 val = get_param(cmd, "OMCtrl_ChnlWidth");
10426 if (val)
10427 ch_bw = atoi(val);
10428
10429 val = get_param(cmd, "OMCtrl_ULMUDisable");
10430 if (val)
10431 ulmu_dis = atoi(val);
10432
10433 val = get_param(cmd, "OMCtrl_TxNSTS");
10434 if (val)
10435 tx_nsts = atoi(val);
10436
10437 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
10438 if (val)
10439 ulmu_data_dis = atoi(val);
10440
10441 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10442 NL80211_CMD_VENDOR)) ||
10443 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10444 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10445 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10446 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10447 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10448 !(params = nla_nest_start(
10449 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
10450 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10451 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
10452 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
10453 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
10454 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
10455 ulmu_data_dis) ||
10456 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
10457 ulmu_dis)) {
10458 sigma_dut_print(dut, DUT_MSG_ERROR,
10459 "%s: err in adding vendor_cmd and vendor_data",
10460 __func__);
10461 nlmsg_free(msg);
10462 return -1;
10463 }
10464 nla_nest_end(msg, attr1);
10465 nla_nest_end(msg, params);
10466 nla_nest_end(msg, attr);
10467
10468 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10469 if (ret) {
10470 sigma_dut_print(dut, DUT_MSG_ERROR,
10471 "%s: err in send_and_recv_msgs, ret=%d",
10472 __func__, ret);
10473 }
10474
10475 return ret;
10476#else /* NL80211_SUPPORT */
10477 sigma_dut_print(dut, DUT_MSG_ERROR,
10478 "OMI TX cannot be processed without NL80211_SUPPORT defined");
10479 return -1;
10480#endif /* NL80211_SUPPORT */
10481}
10482
10483
Jouni Malinen224e3902021-06-09 16:41:27 +030010484static enum sigma_cmd_result
10485cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10486 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010487{
10488 const char *intf = get_param(cmd, "Interface");
10489 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -070010490 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010491 int tkip = -1;
10492 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010493 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010494
Arif Hussaina37e9552018-06-20 17:05:59 -070010495 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010496 val = get_param(cmd, "SGI80");
10497 if (val) {
10498 int sgi80;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010499 enum nl80211_txrate_gi gi_val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010500
10501 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010502 if (sgi80)
10503 gi_val = NL80211_TXRATE_FORCE_LGI;
10504 else
10505 gi_val = NL80211_TXRATE_FORCE_SGI;
10506 if (sta_set_vht_gi(dut, intf, (u8) gi_val)) {
10507 sigma_dut_print(dut, DUT_MSG_INFO,
10508 "sta_set_vht_gi failed, using iwpriv");
10509 run_iwpriv(dut, intf, "shortgi %d", sgi80);
10510 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010511 }
10512
10513 val = get_param(cmd, "TxBF");
10514 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010515 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010516 case DRIVER_WCN:
10517 if (sta_set_tx_beamformee(dut, intf, 1)) {
10518 send_resp(dut, conn, SIGMA_ERROR,
10519 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010520 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010521 }
10522 break;
10523 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010524 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010525 send_resp(dut, conn, SIGMA_ERROR,
10526 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010527 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010528 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010529 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010530 send_resp(dut, conn, SIGMA_ERROR,
10531 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010532 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010533 }
10534 break;
10535 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010536 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010537 "Unsupported driver type");
10538 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010539 }
10540 }
10541
10542 val = get_param(cmd, "MU_TxBF");
10543 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010544 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010545 case DRIVER_ATHEROS:
10546 ath_sta_set_txsp_stream(dut, intf, "1SS");
10547 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010548 run_iwpriv(dut, intf, "vhtmubfee 1");
10549 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +053010550 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010551 case DRIVER_WCN:
10552 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
10553 send_resp(dut, conn, SIGMA_ERROR,
10554 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +030010555 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010556 }
Sunil Duttae9e5d12018-06-29 11:50:47 +053010557 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010558 default:
10559 sigma_dut_print(dut, DUT_MSG_ERROR,
10560 "Setting SP_STREAM not supported");
10561 break;
10562 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010563 }
10564
10565 val = get_param(cmd, "LDPC");
10566 if (val) {
10567 int ldpc;
10568
10569 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010570 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
10571 if (iwpriv_status)
10572 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010573 }
10574
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010575 val = get_param(cmd, "BCC");
10576 if (val) {
10577 int bcc;
10578
10579 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10580 /* use LDPC iwpriv itself to set bcc coding, bcc coding
10581 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010582 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
10583 if (iwpriv_status)
10584 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010585 }
10586
Arif Hussain7b47d2d2018-05-09 10:44:02 -070010587 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
10588 if (val && dut->sta_nss == 1)
10589 cmd_set_max_he_mcs(dut, intf, atoi(val));
10590
10591 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
10592 if (val && dut->sta_nss == 2)
10593 cmd_set_max_he_mcs(dut, intf, atoi(val));
10594
Arif Hussainac6c5112018-05-25 17:34:00 -070010595 val = get_param(cmd, "MCS_FixedRate");
10596 if (val) {
10597#ifdef NL80211_SUPPORT
10598 int mcs, ratecode = 0;
10599 enum he_mcs_config mcs_config;
10600 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +030010601 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -070010602
10603 ratecode = (0x07 & dut->sta_nss) << 5;
10604 mcs = atoi(val);
10605 /* Add the MCS to the ratecode */
10606 if (mcs >= 0 && mcs <= 11) {
10607 ratecode += mcs;
10608 if (dut->device_type == STA_testbed &&
10609 mcs > 7 && mcs <= 11) {
10610 if (mcs <= 9)
10611 mcs_config = HE_80_MCS0_9;
10612 else
10613 mcs_config = HE_80_MCS0_11;
10614 ret = sta_set_he_mcs(dut, intf, mcs_config);
10615 if (ret) {
10616 sigma_dut_print(dut, DUT_MSG_ERROR,
10617 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10618 mcs, mcs_config, ret);
10619 }
10620 }
10621 snprintf(buf, sizeof(buf),
10622 "iwpriv %s set_11ax_rate 0x%03x",
10623 intf, ratecode);
10624 if (system(buf) != 0) {
10625 sigma_dut_print(dut, DUT_MSG_ERROR,
10626 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
10627 ratecode);
10628 }
10629 } else {
10630 sigma_dut_print(dut, DUT_MSG_ERROR,
10631 "MCS_FixedRate: HE MCS %d not supported",
10632 mcs);
10633 }
10634#else /* NL80211_SUPPORT */
10635 sigma_dut_print(dut, DUT_MSG_ERROR,
10636 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
10637#endif /* NL80211_SUPPORT */
10638 }
10639
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010640 val = get_param(cmd, "opt_md_notif_ie");
10641 if (val) {
10642 char *result = NULL;
10643 char delim[] = ";";
10644 char token[30];
10645 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010646 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010647
Peng Xub8fc5cc2017-05-10 17:27:28 -070010648 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010649 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010650
10651 /* Extract the NSS information */
10652 if (result) {
10653 value = atoi(result);
10654 switch (value) {
10655 case 1:
10656 config_val = 1;
10657 break;
10658 case 2:
10659 config_val = 3;
10660 break;
10661 case 3:
10662 config_val = 7;
10663 break;
10664 case 4:
10665 config_val = 15;
10666 break;
10667 default:
10668 config_val = 3;
10669 break;
10670 }
10671
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010672 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
10673 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010674
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010675 }
10676
10677 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010678 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010679 if (result) {
10680 value = atoi(result);
10681 switch (value) {
10682 case 20:
10683 config_val = 0;
10684 break;
10685 case 40:
10686 config_val = 1;
10687 break;
10688 case 80:
10689 config_val = 2;
10690 break;
10691 case 160:
10692 config_val = 3;
10693 break;
10694 default:
10695 config_val = 2;
10696 break;
10697 }
10698
10699 dut->chwidth = config_val;
10700
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010701 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010702 }
10703
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010704 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010705 }
10706
10707 val = get_param(cmd, "nss_mcs_cap");
10708 if (val) {
10709 int nss, mcs;
10710 char token[20];
10711 char *result = NULL;
10712 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010713 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010714
Peng Xub8fc5cc2017-05-10 17:27:28 -070010715 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010716 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010717 if (!result) {
10718 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010719 "NSS not specified");
10720 send_resp(dut, conn, SIGMA_ERROR,
10721 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010722 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010723 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010724 nss = atoi(result);
10725
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010726 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -070010727 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010728
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010729 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010730 if (result == NULL) {
10731 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010732 "MCS not specified");
10733 send_resp(dut, conn, SIGMA_ERROR,
10734 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010735 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010736 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010737 result = strtok_r(result, "-", &saveptr);
10738 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010739 if (!result) {
10740 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010741 "MCS not specified");
10742 send_resp(dut, conn, SIGMA_ERROR,
10743 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010744 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010745 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010746 mcs = atoi(result);
10747
Arif Hussaina37e9552018-06-20 17:05:59 -070010748 if (program && strcasecmp(program, "HE") == 0) {
10749#ifdef NL80211_SUPPORT
10750 enum he_mcs_config mcs_config;
10751 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010752
Arif Hussaina37e9552018-06-20 17:05:59 -070010753 if (mcs >= 0 && mcs <= 7) {
10754 mcs_config = HE_80_MCS0_7;
10755 } else if (mcs > 7 && mcs <= 9) {
10756 mcs_config = HE_80_MCS0_9;
10757 } else if (mcs > 9 && mcs <= 11) {
10758 mcs_config = HE_80_MCS0_11;
10759 } else {
10760 sigma_dut_print(dut, DUT_MSG_ERROR,
10761 "nss_mcs_cap: HE: Invalid mcs: %d",
10762 mcs);
10763 send_resp(dut, conn, SIGMA_ERROR,
10764 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010765 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010766 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010767
10768 ret = sta_set_he_mcs(dut, intf, mcs_config);
10769 if (ret) {
10770 sigma_dut_print(dut, DUT_MSG_ERROR,
10771 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
10772 mcs_config, ret);
10773 send_resp(dut, conn, SIGMA_ERROR,
10774 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010775 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010776 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010777#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010778 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010779 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
10780#endif /* NL80211_SUPPORT */
10781 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010782 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -070010783
10784 switch (nss) {
10785 case 1:
10786 switch (mcs) {
10787 case 7:
10788 vht_mcsmap = 0xfffc;
10789 break;
10790 case 8:
10791 vht_mcsmap = 0xfffd;
10792 break;
10793 case 9:
10794 vht_mcsmap = 0xfffe;
10795 break;
10796 default:
10797 vht_mcsmap = 0xfffe;
10798 break;
10799 }
10800 break;
10801 case 2:
10802 switch (mcs) {
10803 case 7:
10804 vht_mcsmap = 0xfff0;
10805 break;
10806 case 8:
10807 vht_mcsmap = 0xfff5;
10808 break;
10809 case 9:
10810 vht_mcsmap = 0xfffa;
10811 break;
10812 default:
10813 vht_mcsmap = 0xfffa;
10814 break;
10815 }
10816 break;
10817 case 3:
10818 switch (mcs) {
10819 case 7:
10820 vht_mcsmap = 0xffc0;
10821 break;
10822 case 8:
10823 vht_mcsmap = 0xffd5;
10824 break;
10825 case 9:
10826 vht_mcsmap = 0xffea;
10827 break;
10828 default:
10829 vht_mcsmap = 0xffea;
10830 break;
10831 }
10832 break;
10833 default:
10834 vht_mcsmap = 0xffea;
10835 break;
10836 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010837 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010838 }
10839 }
10840
10841 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
10842
10843 val = get_param(cmd, "Vht_tkip");
10844 if (val)
10845 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10846
10847 val = get_param(cmd, "Vht_wep");
10848 if (val)
10849 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10850
10851 if (tkip != -1 || wep != -1) {
10852 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010853 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010854 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010855 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010856 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +030010857 send_resp(dut, conn, SIGMA_ERROR,
10858 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
10859 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010860 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010861 }
10862
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -070010863 val = get_param(cmd, "TWTSchedSTASupport");
10864 if (val) {
10865 int set_val;
10866
10867 switch (get_driver_type(dut)) {
10868 case DRIVER_WCN:
10869 if (strcasecmp(val, "Enable") == 0) {
10870 set_val = 1;
10871 } else if (strcasecmp(val, "Disable") == 0) {
10872 set_val = 0;
10873 } else {
10874 send_resp(dut, conn, SIGMA_ERROR,
10875 "ErrorCode,Invalid TWTSchedSTASupport");
10876 return STATUS_SENT_ERROR;
10877 }
10878
10879 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
10880 send_resp(dut, conn, SIGMA_ERROR,
10881 "ErrorCode,Failed to set TWTSchedSTASupport");
10882 return STATUS_SENT_ERROR;
10883 }
10884 break;
10885 default:
10886 sigma_dut_print(dut, DUT_MSG_ERROR,
10887 "Setting TWTSchedSTASupport not supported");
10888 break;
10889 }
10890 }
10891
10892 val = get_param(cmd, "MBSSID_RxCtrl");
10893 if (val) {
10894 int set_val;
10895
10896 switch (get_driver_type(dut)) {
10897 case DRIVER_WCN:
10898 if (strcasecmp(val, "Enable") == 0) {
10899 set_val = 1;
10900 } else if (strcasecmp(val, "Disable") == 0) {
10901 set_val = 0;
10902 } else {
10903 send_resp(dut, conn, SIGMA_ERROR,
10904 "ErrorCode,Invalid MBSSID_RxCtrl");
10905 return STATUS_SENT_ERROR;
10906 }
10907
10908 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
10909 send_resp(dut, conn, SIGMA_ERROR,
10910 "ErrorCode,Failed to set MBSSID_RxCtrl");
10911 return STATUS_SENT_ERROR;
10912 }
10913 break;
10914 default:
10915 sigma_dut_print(dut, DUT_MSG_ERROR,
10916 "Setting MBSSID_RxCtrl not supported");
10917 break;
10918 }
10919 }
10920
Arif Hussain55f00da2018-07-03 08:28:26 -070010921 val = get_param(cmd, "txBandwidth");
10922 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010923 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -070010924 case DRIVER_WCN:
10925 if (wcn_sta_set_width(dut, intf, val) < 0) {
10926 send_resp(dut, conn, SIGMA_ERROR,
10927 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010928 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010929 }
10930 break;
10931 case DRIVER_ATHEROS:
10932 if (ath_set_width(dut, conn, intf, val) < 0) {
10933 send_resp(dut, conn, SIGMA_ERROR,
10934 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010935 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010936 }
10937 break;
10938 default:
10939 sigma_dut_print(dut, DUT_MSG_ERROR,
10940 "Setting txBandwidth not supported");
10941 break;
10942 }
10943 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010944
Arif Hussain9765f7d2018-07-03 08:28:26 -070010945 val = get_param(cmd, "BeamformeeSTS");
10946 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010947 if (sta_set_tx_beamformee(dut, intf, 1)) {
10948 send_resp(dut, conn, SIGMA_ERROR,
10949 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010950 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010951 }
10952
Arif Hussain9765f7d2018-07-03 08:28:26 -070010953 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
10954 send_resp(dut, conn, SIGMA_ERROR,
10955 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010956 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -070010957 }
10958 }
10959
Arif Hussain68d23f52018-07-11 13:39:08 -070010960 val = get_param(cmd, "Trig_MAC_Padding_Dur");
10961 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010962#ifdef NL80211_SUPPORT
10963 enum qca_wlan_he_mac_padding_dur set_val;
10964
10965 switch (atoi(val)) {
10966 case 16:
10967 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
10968 break;
10969 case 8:
10970 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
10971 break;
10972 default:
10973 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
10974 break;
10975 }
10976 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -070010977 send_resp(dut, conn, SIGMA_ERROR,
10978 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +030010979 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -070010980 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010981#else /* NL80211_SUPPORT */
10982 sigma_dut_print(dut, DUT_MSG_ERROR,
10983 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
10984#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -070010985 }
10986
Arif Hussain480d5f42019-03-12 14:40:42 -070010987 val = get_param(cmd, "TWT_ReqSupport");
10988 if (val) {
10989 int set_val;
10990
10991 if (strcasecmp(val, "Enable") == 0) {
10992 set_val = 1;
10993 } else if (strcasecmp(val, "Disable") == 0) {
10994 set_val = 0;
10995 } else {
10996 send_resp(dut, conn, SIGMA_ERROR,
10997 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010998 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010999 }
11000
11001 if (sta_set_twt_req_support(dut, intf, set_val)) {
11002 sigma_dut_print(dut, DUT_MSG_ERROR,
11003 "Failed to set TWT req support %d",
11004 set_val);
11005 send_resp(dut, conn, SIGMA_ERROR,
11006 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030011007 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070011008 }
11009 }
11010
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -070011011 val = get_param(cmd, "PreamblePunctRx");
11012 if (val && get_driver_type(dut) == DRIVER_WCN) {
11013 int set_val;
11014
11015 if (strcasecmp(val, "Enable") == 0) {
11016 set_val = 1;
11017 } else if (strcasecmp(val, "Disable") == 0) {
11018 set_val = 0;
11019 } else {
11020 send_resp(dut, conn, SIGMA_ERROR,
11021 "ErrorCode,Invalid PreamblePunctRx");
11022 return STATUS_SENT_ERROR;
11023 }
11024
11025 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
11026 sigma_dut_print(dut, DUT_MSG_ERROR,
11027 "Failed to set PreamblePunctRx support %d",
11028 set_val);
11029 send_resp(dut, conn, SIGMA_ERROR,
11030 "ErrorCode,Failed to set PreamblePunctRx");
11031 return STATUS_SENT_ERROR;
11032 }
11033 }
11034
Srinivas Girigowda0525e292020-11-12 13:28:21 -080011035 val = get_param(cmd, "FullBW_ULMUMIMO");
11036 if (val) {
11037 int set_val;
11038
11039 if (strcasecmp(val, "Enable") == 0) {
11040 set_val = 1;
11041 } else if (strcasecmp(val, "Disable") == 0) {
11042 set_val = 0;
11043 } else {
11044 send_resp(dut, conn, SIGMA_ERROR,
11045 "ErrorCode,Invalid FullBW_ULMUMIMO");
11046 return STATUS_SENT_ERROR;
11047 }
11048
11049 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
11050 sigma_dut_print(dut, DUT_MSG_ERROR,
11051 "Failed to set FullBW_ULMUMIMO %d",
11052 set_val);
11053 send_resp(dut, conn, SIGMA_ERROR,
11054 "ErrorCode,Failed to set FullBW_ULMUMIMO");
11055 return STATUS_SENT_ERROR;
11056 }
11057 }
11058
Srinivas Girigowda6707f032020-10-26 15:24:46 -070011059 val = get_param(cmd, "TWTInfoFrameTx");
11060 if (val) {
11061 if (strcasecmp(val, "Enable") == 0) {
11062 /* No-op */
11063 } else if (strcasecmp(val, "Disable") == 0) {
11064 /* No-op */
11065 } else {
11066 send_resp(dut, conn, SIGMA_ERROR,
11067 "ErrorCode,Invalid TWTInfoFrameTx");
11068 return STATUS_SENT_ERROR;
11069 }
11070 }
11071
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011072 val = get_param(cmd, "MU_EDCA");
11073 if (val && (strcasecmp(val, "Override") == 0)) {
11074 if (sta_set_mu_edca_override(dut, intf, 1)) {
11075 send_resp(dut, conn, SIGMA_ERROR,
11076 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +030011077 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011078 }
11079 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011080
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070011081 val = get_param(cmd, "PPDUTxType");
11082 if (val && strcasecmp(val, "ER-SU") == 0) {
11083 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
11084 send_resp(dut, conn, SIGMA_ERROR,
11085 "ErrorCode,Failed to set ER-SU PPDU type Tx");
11086 return STATUS_SENT_ERROR;
11087 }
11088 }
11089
11090 val = get_param(cmd, "RUAllocTone");
11091 if (val && strcasecmp(val, "242") == 0) {
11092 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
11093 send_resp(dut, conn, SIGMA_ERROR,
11094 "ErrorCode,Failed to set RU 242 tone Tx");
11095 return STATUS_SENT_ERROR;
11096 }
11097 }
11098
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011099 val = get_param(cmd, "OMControl");
11100 if (val) {
11101 int set_val = 1;
11102
11103 if (strcasecmp(val, "Enable") == 0)
11104 set_val = 1;
11105 else if (strcasecmp(val, "Disable") == 0)
11106 set_val = 0;
11107
11108 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
11109 send_resp(dut, conn, SIGMA_ERROR,
11110 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +030011111 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011112 }
11113 }
11114
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -070011115 val = get_param(cmd, "BSSMaxIdlePeriod");
11116 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
11117 send_resp(dut, conn, SIGMA_ERROR,
11118 "ErrorCode,Failed to set BSS max idle period");
11119 return STATUS_SENT_ERROR;
11120 }
11121
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -070011122 val = get_param(cmd, "BSS_max_idle");
11123 if (val) {
11124 int set_val = 0;
11125
11126 if (strcasecmp(val, "Enable") == 0)
11127 set_val = 1;
11128 else if (strcasecmp(val, "Disable") == 0)
11129 set_val = 0;
11130 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
11131 send_resp(dut, conn, SIGMA_ERROR,
11132 "ErrorCode,Failed to set BSS max idle support");
11133 return STATUS_SENT_ERROR;
11134 }
11135 }
11136
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011137 val = get_param(cmd, "ADDBAResp_BufSize");
11138 if (val) {
11139 int buf_size;
11140
11141 if (strcasecmp(val, "gt64") == 0)
11142 buf_size = 256;
11143 else
11144 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011145 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011146 sta_set_addba_buf_size(dut, intf, buf_size)) {
11147 send_resp(dut, conn, SIGMA_ERROR,
11148 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011149 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011150 }
11151 }
11152
11153 val = get_param(cmd, "ADDBAReq_BufSize");
11154 if (val) {
11155 int buf_size;
11156
11157 if (strcasecmp(val, "gt64") == 0)
11158 buf_size = 256;
11159 else
11160 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011161 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011162 sta_set_addba_buf_size(dut, intf, buf_size)) {
11163 send_resp(dut, conn, SIGMA_ERROR,
11164 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011165 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011166 }
11167 }
11168
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011169 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11170}
11171
11172
11173static int sta_set_wireless_60g(struct sigma_dut *dut,
11174 struct sigma_conn *conn,
11175 struct sigma_cmd *cmd)
11176{
11177 const char *dev_role = get_param(cmd, "DevRole");
11178
11179 if (!dev_role) {
11180 send_resp(dut, conn, SIGMA_INVALID,
11181 "ErrorCode,DevRole not specified");
11182 return 0;
11183 }
11184
11185 if (strcasecmp(dev_role, "PCP") == 0)
11186 return sta_set_60g_pcp(dut, conn, cmd);
11187 if (strcasecmp(dev_role, "STA") == 0)
11188 return sta_set_60g_sta(dut, conn, cmd);
11189 send_resp(dut, conn, SIGMA_INVALID,
11190 "ErrorCode,DevRole not supported");
11191 return 0;
11192}
11193
11194
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011195static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
11196 struct sigma_cmd *cmd)
11197{
11198 int status;
11199 const char *intf = get_param(cmd, "Interface");
11200 const char *val = get_param(cmd, "DevRole");
11201
11202 if (val && strcasecmp(val, "STA-CFON") == 0) {
11203 status = sta_cfon_set_wireless(dut, conn, cmd);
11204 if (status)
11205 return status;
11206 }
11207 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11208}
11209
11210
Jouni Malinen67433fc2020-06-26 22:50:33 +030011211static enum sigma_cmd_result
11212sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
11213 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011214{
11215 const char *intf = get_param(cmd, "Interface");
11216 const char *val;
11217
11218 val = get_param(cmd, "ocvc");
11219 if (val)
11220 dut->ocvc = atoi(val);
11221
Jouni Malinen67433fc2020-06-26 22:50:33 +030011222 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +053011223 if (val && dut->client_privacy != atoi(val) &&
11224 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
11225 send_resp(dut, conn, SIGMA_ERROR,
11226 "errorCode,Failed to configure random MAC address use");
11227 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +030011228 }
11229
Veerendranath Jakkam9ce2b642022-02-28 18:49:25 +053011230 val = get_param(cmd, "GKH_G2_Tx");
11231 if (val) {
11232 char buf[50];
11233
11234 snprintf(buf, sizeof(buf), "SET disable_eapol_g2_tx %d",
11235 strcasecmp(val, "disable") == 0);
11236
11237 if (wpa_command(intf, buf) < 0) {
11238 send_resp(dut, conn, SIGMA_ERROR,
11239 "errorCode,Failed to enable/disable G2 transmit");
11240 return STATUS_SENT_ERROR;
11241 }
11242 }
11243
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011244 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11245}
11246
11247
Jouni Malinenf7222712019-06-13 01:50:21 +030011248static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
11249 struct sigma_conn *conn,
11250 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011251{
11252 const char *val;
11253
11254 val = get_param(cmd, "Program");
Veerendranath Jakkam9ce2b642022-02-28 18:49:25 +053011255 if (!val)
11256 val = get_param(cmd, "Prog");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011257 if (val) {
11258 if (strcasecmp(val, "11n") == 0)
11259 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080011260 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011261 return cmd_sta_set_wireless_vht(dut, conn, cmd);
11262 if (strcasecmp(val, "60ghz") == 0)
11263 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011264 if (strcasecmp(val, "OCE") == 0)
11265 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020011266 /* sta_set_wireless in WPS program is only used for 60G */
11267 if (is_60g_sigma_dut(dut))
11268 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011269 if (strcasecmp(val, "WPA3") == 0)
11270 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011271 send_resp(dut, conn, SIGMA_ERROR,
11272 "ErrorCode,Program value not supported");
11273 } else {
11274 send_resp(dut, conn, SIGMA_ERROR,
11275 "ErrorCode,Program argument not available");
11276 }
11277
11278 return 0;
11279}
11280
11281
11282static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
11283 int tid)
11284{
11285 char buf[100];
11286 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
11287
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053011288 if (tid < 0 ||
11289 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
11290 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
11291 return;
11292 }
11293
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011294 /*
11295 * Two ways to ensure that addba request with a
11296 * non zero TID could be sent out. EV 117296
11297 */
11298 snprintf(buf, sizeof(buf),
11299 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
11300 tid);
11301 if (system(buf) != 0) {
11302 sigma_dut_print(dut, DUT_MSG_ERROR,
11303 "Ping did not send out");
11304 }
11305
11306 snprintf(buf, sizeof(buf),
11307 "iwconfig %s | grep Access | awk '{print $6}' > %s",
11308 intf, VI_QOS_TMP_FILE);
11309 if (system(buf) != 0)
11310 return;
11311
11312 snprintf(buf, sizeof(buf),
11313 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
11314 intf, VI_QOS_TMP_FILE);
11315 if (system(buf) != 0)
11316 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
11317
11318 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
11319 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
11320 if (system(buf) != 0) {
11321 sigma_dut_print(dut, DUT_MSG_ERROR,
11322 "VI_QOS_TEMP_FILE generation error failed");
11323 }
11324 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11325 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11326 if (system(buf) != 0) {
11327 sigma_dut_print(dut, DUT_MSG_ERROR,
11328 "VI_QOS_FILE generation failed");
11329 }
11330
11331 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11332 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11333 if (system(buf) != 0) {
11334 sigma_dut_print(dut, DUT_MSG_ERROR,
11335 "VI_QOS_FILE generation failed");
11336 }
11337
11338 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
11339 if (system(buf) != 0) {
11340 }
11341}
11342
11343
11344static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11345 struct sigma_cmd *cmd)
11346{
11347 const char *intf = get_param(cmd, "Interface");
11348 const char *val;
11349 int tid = 0;
11350 char buf[100];
11351
11352 val = get_param(cmd, "TID");
11353 if (val) {
11354 tid = atoi(val);
11355 if (tid)
11356 ath_sta_inject_frame(dut, intf, tid);
11357 }
11358
11359 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011360 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011361
11362 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
11363 if (system(buf) != 0) {
11364 sigma_dut_print(dut, DUT_MSG_ERROR,
11365 "wifitool senddelba failed");
11366 }
11367
11368 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
11369 if (system(buf) != 0) {
11370 sigma_dut_print(dut, DUT_MSG_ERROR,
11371 "wifitool sendaddba failed");
11372 }
11373
11374 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11375
11376 return 1;
11377}
11378
11379
Lior David9981b512017-01-20 13:16:40 +020011380#ifdef __linux__
11381
11382static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
11383 int agg_size)
11384{
11385 char dir[128], buf[128];
11386 FILE *f;
11387 regex_t re;
11388 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030011389 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020011390
11391 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
11392 sigma_dut_print(dut, DUT_MSG_ERROR,
11393 "failed to get wil6210 debugfs dir");
11394 return -1;
11395 }
11396
Jouni Malinen3aa72862019-05-29 23:14:51 +030011397 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
11398 if (res < 0 || res >= sizeof(buf))
11399 return -1;
Lior David9981b512017-01-20 13:16:40 +020011400 f = fopen(buf, "r");
11401 if (!f) {
11402 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011403 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030011404 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
11405 if (res < 0 || res >= sizeof(buf))
11406 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011407 f = fopen(buf, "r");
11408 if (!f) {
11409 sigma_dut_print(dut, DUT_MSG_ERROR,
11410 "failed to open: %s", buf);
11411 return -1;
11412 }
Lior David9981b512017-01-20 13:16:40 +020011413 }
11414
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011415 /* can be either VRING tx... or RING... */
11416 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020011417 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
11418 goto out;
11419 }
11420
11421 /* find TX VRING for the mac address */
11422 found = 0;
11423 while (fgets(buf, sizeof(buf), f)) {
11424 if (strcasestr(buf, dest_mac)) {
11425 found = 1;
11426 break;
11427 }
11428 }
11429
11430 if (!found) {
11431 sigma_dut_print(dut, DUT_MSG_ERROR,
11432 "no TX VRING for %s", dest_mac);
11433 goto out;
11434 }
11435
11436 /* extract VRING ID, "VRING tx_<id> = {" */
11437 if (!fgets(buf, sizeof(buf), f)) {
11438 sigma_dut_print(dut, DUT_MSG_ERROR,
11439 "no VRING start line for %s", dest_mac);
11440 goto out;
11441 }
11442
11443 rc = regexec(&re, buf, 2, m, 0);
11444 regfree(&re);
11445 if (rc || m[1].rm_so < 0) {
11446 sigma_dut_print(dut, DUT_MSG_ERROR,
11447 "no VRING TX ID for %s", dest_mac);
11448 goto out;
11449 }
11450 buf[m[1].rm_eo] = 0;
11451 vring_id = atoi(&buf[m[1].rm_so]);
11452
11453 /* send the addba command */
11454 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011455 res = snprintf(buf, sizeof(buf), "%s/back", dir);
11456 if (res < 0 || res >= sizeof(buf))
11457 return -1;
Lior David9981b512017-01-20 13:16:40 +020011458 f = fopen(buf, "w");
11459 if (!f) {
11460 sigma_dut_print(dut, DUT_MSG_ERROR,
11461 "failed to open: %s", buf);
11462 return -1;
11463 }
11464
11465 fprintf(f, "add %d %d\n", vring_id, agg_size);
11466
11467 ret = 0;
11468
11469out:
11470 fclose(f);
11471
11472 return ret;
11473}
11474
11475
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011476int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11477 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011478{
11479 const char *val;
11480 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011481
11482 val = get_param(cmd, "TID");
11483 if (val) {
11484 tid = atoi(val);
11485 if (tid != 0) {
11486 sigma_dut_print(dut, DUT_MSG_ERROR,
11487 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
11488 tid);
11489 }
11490 }
11491
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011492 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011493 if (!val) {
11494 sigma_dut_print(dut, DUT_MSG_ERROR,
11495 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011496 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011497 }
11498
Lior David9981b512017-01-20 13:16:40 +020011499 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011500 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011501
11502 return 1;
11503}
11504
Lior David9981b512017-01-20 13:16:40 +020011505#endif /* __linux__ */
11506
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011507
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011508static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11509 struct sigma_cmd *cmd)
11510{
11511#ifdef NL80211_SUPPORT
11512 const char *intf = get_param(cmd, "Interface");
11513 const char *val;
11514 int tid = -1;
11515 int bufsize = 64;
11516 struct nl_msg *msg;
11517 int ret = 0;
11518 struct nlattr *params;
11519 int ifindex;
11520
11521 val = get_param(cmd, "TID");
11522 if (val)
11523 tid = atoi(val);
11524
11525 if (tid == -1) {
11526 send_resp(dut, conn, SIGMA_ERROR,
11527 "ErrorCode,sta_send_addba tid invalid");
11528 return 0;
11529 }
11530
11531 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11532
11533 ifindex = if_nametoindex(intf);
11534 if (ifindex == 0) {
11535 sigma_dut_print(dut, DUT_MSG_ERROR,
11536 "%s: Index for interface %s failed",
11537 __func__, intf);
11538 send_resp(dut, conn, SIGMA_ERROR,
11539 "ErrorCode,sta_send_addba interface invalid");
11540 return 0;
11541 }
11542
11543 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11544 NL80211_CMD_VENDOR)) ||
11545 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
11546 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
11547 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
11548 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
11549 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
11550 nla_put_u8(msg,
11551 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
11552 QCA_WLAN_ADD_BA) ||
11553 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
11554 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070011555 nla_put_u16(msg,
11556 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
11557 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011558 sigma_dut_print(dut, DUT_MSG_ERROR,
11559 "%s: err in adding vendor_cmd and vendor_data",
11560 __func__);
11561 nlmsg_free(msg);
11562 send_resp(dut, conn, SIGMA_ERROR,
11563 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
11564 return 0;
11565 }
11566 nla_nest_end(msg, params);
11567
11568 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11569 if (ret) {
11570 sigma_dut_print(dut, DUT_MSG_ERROR,
11571 "%s: err in send_and_recv_msgs, ret=%d",
11572 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053011573 if (ret == -EOPNOTSUPP)
11574 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011575 send_resp(dut, conn, SIGMA_ERROR,
11576 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
11577 return 0;
11578 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011579#else /* NL80211_SUPPORT */
11580 sigma_dut_print(dut, DUT_MSG_ERROR,
11581 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011582#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053011583
11584 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011585}
11586
11587
Jouni Malinenf7222712019-06-13 01:50:21 +030011588static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
11589 struct sigma_conn *conn,
11590 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011591{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011592 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011593 case DRIVER_ATHEROS:
11594 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011595 case DRIVER_WCN:
11596 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020011597#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011598 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011599 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020011600#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011601 default:
11602 /*
11603 * There is no driver specific implementation for other drivers.
11604 * Ignore the command and report COMPLETE since the following
11605 * throughput test operation will end up sending ADDBA anyway.
11606 */
11607 return 1;
11608 }
11609}
11610
11611
11612int inject_eth_frame(int s, const void *data, size_t len,
11613 unsigned short ethtype, char *dst, char *src)
11614{
11615 struct iovec iov[4] = {
11616 {
11617 .iov_base = dst,
11618 .iov_len = ETH_ALEN,
11619 },
11620 {
11621 .iov_base = src,
11622 .iov_len = ETH_ALEN,
11623 },
11624 {
11625 .iov_base = &ethtype,
11626 .iov_len = sizeof(unsigned short),
11627 },
11628 {
11629 .iov_base = (void *) data,
11630 .iov_len = len,
11631 }
11632 };
11633 struct msghdr msg = {
11634 .msg_name = NULL,
11635 .msg_namelen = 0,
11636 .msg_iov = iov,
11637 .msg_iovlen = 4,
11638 .msg_control = NULL,
11639 .msg_controllen = 0,
11640 .msg_flags = 0,
11641 };
11642
11643 return sendmsg(s, &msg, 0);
11644}
11645
11646#if defined(__linux__) || defined(__QNXNTO__)
11647
11648int inject_frame(int s, const void *data, size_t len, int encrypt)
11649{
11650#define IEEE80211_RADIOTAP_F_WEP 0x04
11651#define IEEE80211_RADIOTAP_F_FRAG 0x08
11652 unsigned char rtap_hdr[] = {
11653 0x00, 0x00, /* radiotap version */
11654 0x0e, 0x00, /* radiotap length */
11655 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
11656 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
11657 0x00, /* padding */
11658 0x00, 0x00, /* RX and TX flags to indicate that */
11659 0x00, 0x00, /* this is the injected frame directly */
11660 };
11661 struct iovec iov[2] = {
11662 {
11663 .iov_base = &rtap_hdr,
11664 .iov_len = sizeof(rtap_hdr),
11665 },
11666 {
11667 .iov_base = (void *) data,
11668 .iov_len = len,
11669 }
11670 };
11671 struct msghdr msg = {
11672 .msg_name = NULL,
11673 .msg_namelen = 0,
11674 .msg_iov = iov,
11675 .msg_iovlen = 2,
11676 .msg_control = NULL,
11677 .msg_controllen = 0,
11678 .msg_flags = 0,
11679 };
11680
11681 if (encrypt)
11682 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
11683
11684 return sendmsg(s, &msg, 0);
11685}
11686
11687
11688int open_monitor(const char *ifname)
11689{
11690#ifdef __QNXNTO__
11691 struct sockaddr_dl ll;
11692 int s;
11693
11694 memset(&ll, 0, sizeof(ll));
11695 ll.sdl_family = AF_LINK;
11696 ll.sdl_index = if_nametoindex(ifname);
11697 if (ll.sdl_index == 0) {
11698 perror("if_nametoindex");
11699 return -1;
11700 }
11701 s = socket(PF_INET, SOCK_RAW, 0);
11702#else /* __QNXNTO__ */
11703 struct sockaddr_ll ll;
11704 int s;
11705
11706 memset(&ll, 0, sizeof(ll));
11707 ll.sll_family = AF_PACKET;
11708 ll.sll_ifindex = if_nametoindex(ifname);
11709 if (ll.sll_ifindex == 0) {
11710 perror("if_nametoindex");
11711 return -1;
11712 }
11713 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
11714#endif /* __QNXNTO__ */
11715 if (s < 0) {
11716 perror("socket[PF_PACKET,SOCK_RAW]");
11717 return -1;
11718 }
11719
11720 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
11721 perror("monitor socket bind");
11722 close(s);
11723 return -1;
11724 }
11725
11726 return s;
11727}
11728
11729
11730static int hex2num(char c)
11731{
11732 if (c >= '0' && c <= '9')
11733 return c - '0';
11734 if (c >= 'a' && c <= 'f')
11735 return c - 'a' + 10;
11736 if (c >= 'A' && c <= 'F')
11737 return c - 'A' + 10;
11738 return -1;
11739}
11740
11741
11742int hwaddr_aton(const char *txt, unsigned char *addr)
11743{
11744 int i;
11745
11746 for (i = 0; i < 6; i++) {
11747 int a, b;
11748
11749 a = hex2num(*txt++);
11750 if (a < 0)
11751 return -1;
11752 b = hex2num(*txt++);
11753 if (b < 0)
11754 return -1;
11755 *addr++ = (a << 4) | b;
11756 if (i < 5 && *txt++ != ':')
11757 return -1;
11758 }
11759
11760 return 0;
11761}
11762
11763#endif /* defined(__linux__) || defined(__QNXNTO__) */
11764
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011765
11766#ifdef NL80211_SUPPORT
11767static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
11768 const u8 *data, size_t data_len, int freq)
11769{
11770 struct nl_msg *msg;
11771 int ret = 0;
11772 int ifindex;
11773
11774 ifindex = if_nametoindex(intf);
11775 if (ifindex == 0) {
11776 sigma_dut_print(dut, DUT_MSG_ERROR,
11777 "%s: Index for interface %s failed",
11778 __func__, intf);
11779 return -1;
11780 }
11781
11782 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11783 NL80211_CMD_FRAME)) ||
11784 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11785 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
11786 sigma_dut_print(dut, DUT_MSG_ERROR,
11787 "%s: Error in adding NL80211_CMD_FRAME",
11788 __func__);
11789 nlmsg_free(msg);
11790 return -1;
11791 }
11792
11793 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11794 if (ret) {
11795 sigma_dut_print(dut, DUT_MSG_ERROR,
11796 "nl80211: Frame command failed: ret=%d (%s) req=%u",
11797 ret, strerror(-ret), freq);
11798 return -1;
11799 }
11800
11801 return 0;
11802}
11803#endif /* NL80211_SUPPORT */
11804
11805
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011806enum send_frame_type {
11807 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
11808};
11809enum send_frame_protection {
11810 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
11811};
11812
11813
11814static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011815 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011816 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011817 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011818{
11819#ifdef __linux__
11820 unsigned char buf[1000], *pos;
11821 int s, res;
11822 char bssid[20], addr[20];
11823 char result[32], ssid[100];
11824 size_t ssid_len;
11825
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011826 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011827 sizeof(result)) < 0 ||
11828 strncmp(result, "COMPLETED", 9) != 0) {
11829 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
11830 return 0;
11831 }
11832
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011833 if (get_wpa_status(get_station_ifname(dut), "bssid",
11834 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011835 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11836 "current BSSID");
11837 return 0;
11838 }
11839
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011840 if (get_wpa_status(get_station_ifname(dut), "address",
11841 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011842 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11843 "own MAC address");
11844 return 0;
11845 }
11846
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011847 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011848 < 0) {
11849 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11850 "current SSID");
11851 return 0;
11852 }
11853 ssid_len = strlen(ssid);
11854
11855 pos = buf;
11856
11857 /* Frame Control */
11858 switch (frame) {
11859 case DISASSOC:
11860 *pos++ = 0xa0;
11861 break;
11862 case DEAUTH:
11863 *pos++ = 0xc0;
11864 break;
11865 case SAQUERY:
11866 *pos++ = 0xd0;
11867 break;
11868 case AUTH:
11869 *pos++ = 0xb0;
11870 break;
11871 case ASSOCREQ:
11872 *pos++ = 0x00;
11873 break;
11874 case REASSOCREQ:
11875 *pos++ = 0x20;
11876 break;
11877 case DLS_REQ:
11878 *pos++ = 0xd0;
11879 break;
11880 }
11881
11882 if (protected == INCORRECT_KEY)
11883 *pos++ = 0x40; /* Set Protected field to 1 */
11884 else
11885 *pos++ = 0x00;
11886
11887 /* Duration */
11888 *pos++ = 0x00;
11889 *pos++ = 0x00;
11890
11891 /* addr1 = DA (current AP) */
11892 hwaddr_aton(bssid, pos);
11893 pos += 6;
11894 /* addr2 = SA (own address) */
11895 hwaddr_aton(addr, pos);
11896 pos += 6;
11897 /* addr3 = BSSID (current AP) */
11898 hwaddr_aton(bssid, pos);
11899 pos += 6;
11900
11901 /* Seq# (to be filled by driver/mac80211) */
11902 *pos++ = 0x00;
11903 *pos++ = 0x00;
11904
11905 if (protected == INCORRECT_KEY) {
11906 /* CCMP parameters */
11907 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
11908 pos += 8;
11909 }
11910
11911 if (protected == INCORRECT_KEY) {
11912 switch (frame) {
11913 case DEAUTH:
11914 /* Reason code (encrypted) */
11915 memcpy(pos, "\xa7\x39", 2);
11916 pos += 2;
11917 break;
11918 case DISASSOC:
11919 /* Reason code (encrypted) */
11920 memcpy(pos, "\xa7\x39", 2);
11921 pos += 2;
11922 break;
11923 case SAQUERY:
11924 /* Category|Action|TransID (encrypted) */
11925 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
11926 pos += 4;
11927 break;
11928 default:
11929 return -1;
11930 }
11931
11932 /* CCMP MIC */
11933 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
11934 pos += 8;
11935 } else {
11936 switch (frame) {
11937 case DEAUTH:
11938 /* reason code = 8 */
11939 *pos++ = 0x08;
11940 *pos++ = 0x00;
11941 break;
11942 case DISASSOC:
11943 /* reason code = 8 */
11944 *pos++ = 0x08;
11945 *pos++ = 0x00;
11946 break;
11947 case SAQUERY:
11948 /* Category - SA Query */
11949 *pos++ = 0x08;
11950 /* SA query Action - Request */
11951 *pos++ = 0x00;
11952 /* Transaction ID */
11953 *pos++ = 0x12;
11954 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011955 if (dut->saquery_oci_freq) {
11956 /* OCI IE - Extended ID */
11957 *pos++ = 0xFF;
11958 *pos++ = 0x04;
11959 *pos++ = 0x36;
11960 /* Operating Class */
11961 *pos++ = 0x74;
11962 /* Primary Channel */
11963 *pos++ = freq_to_channel(dut->saquery_oci_freq);
11964 /* Frequency Segment 1 Channel Number */
11965 *pos++ = 0x00;
11966 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011967 break;
11968 case AUTH:
11969 /* Auth Alg (Open) */
11970 *pos++ = 0x00;
11971 *pos++ = 0x00;
11972 /* Seq# */
11973 *pos++ = 0x01;
11974 *pos++ = 0x00;
11975 /* Status code */
11976 *pos++ = 0x00;
11977 *pos++ = 0x00;
11978 break;
11979 case ASSOCREQ:
11980 /* Capability Information */
11981 *pos++ = 0x31;
11982 *pos++ = 0x04;
11983 /* Listen Interval */
11984 *pos++ = 0x0a;
11985 *pos++ = 0x00;
11986 /* SSID */
11987 *pos++ = 0x00;
11988 *pos++ = ssid_len;
11989 memcpy(pos, ssid, ssid_len);
11990 pos += ssid_len;
11991 /* Supported Rates */
11992 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11993 10);
11994 pos += 10;
11995 /* Extended Supported Rates */
11996 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11997 pos += 6;
11998 /* RSN */
11999 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
12000 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
12001 "\x00\x00\x00\x00\x0f\xac\x06", 28);
12002 pos += 28;
12003 break;
12004 case REASSOCREQ:
12005 /* Capability Information */
12006 *pos++ = 0x31;
12007 *pos++ = 0x04;
12008 /* Listen Interval */
12009 *pos++ = 0x0a;
12010 *pos++ = 0x00;
12011 /* Current AP */
12012 hwaddr_aton(bssid, pos);
12013 pos += 6;
12014 /* SSID */
12015 *pos++ = 0x00;
12016 *pos++ = ssid_len;
12017 memcpy(pos, ssid, ssid_len);
12018 pos += ssid_len;
12019 /* Supported Rates */
12020 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
12021 10);
12022 pos += 10;
12023 /* Extended Supported Rates */
12024 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
12025 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053012026 /* RSNE - Group and Pairwise ciphers */
12027 memcpy(pos,
12028 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
12029 14);
12030 pos += 14;
12031 /* RSNE - AKM Suite count */
12032 *pos++ = 0x01;
12033 *pos++ = 0x00;
12034 /* RSNE - AKM Suites */
12035 if (dut->program == PROGRAM_WPA3)
12036 memcpy(pos, "\x00\x0f\xac\x08", 4);
12037 else
12038 memcpy(pos, "\x00\x0f\xac\x02", 4);
12039 pos += 4;
12040 /* RSNE - Capabilities */
12041 *pos++ = 0xc0;
12042 if (dut->ocvc)
12043 *pos++ = 0x40;
12044 else
12045 *pos++ = 0x00;
12046 /* RSNE - PMKID list and Group Management Ciphers */
12047 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
12048 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012049 break;
12050 case DLS_REQ:
12051 /* Category - DLS */
12052 *pos++ = 0x02;
12053 /* DLS Action - Request */
12054 *pos++ = 0x00;
12055 /* Destination MACAddress */
12056 if (dest)
12057 hwaddr_aton(dest, pos);
12058 else
12059 memset(pos, 0, 6);
12060 pos += 6;
12061 /* Source MACAddress */
12062 hwaddr_aton(addr, pos);
12063 pos += 6;
12064 /* Capability Information */
12065 *pos++ = 0x10; /* Privacy */
12066 *pos++ = 0x06; /* QoS */
12067 /* DLS Timeout Value */
12068 *pos++ = 0x00;
12069 *pos++ = 0x01;
12070 /* Supported rates */
12071 *pos++ = 0x01;
12072 *pos++ = 0x08;
12073 *pos++ = 0x0c; /* 6 Mbps */
12074 *pos++ = 0x12; /* 9 Mbps */
12075 *pos++ = 0x18; /* 12 Mbps */
12076 *pos++ = 0x24; /* 18 Mbps */
12077 *pos++ = 0x30; /* 24 Mbps */
12078 *pos++ = 0x48; /* 36 Mbps */
12079 *pos++ = 0x60; /* 48 Mbps */
12080 *pos++ = 0x6c; /* 54 Mbps */
12081 /* TODO: Extended Supported Rates */
12082 /* TODO: HT Capabilities */
12083 break;
12084 }
12085 }
12086
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012087 if (use_monitor) {
12088 s = open_monitor("sigmadut");
12089 if (s < 0) {
12090 send_resp(dut, conn, SIGMA_ERROR,
12091 "errorCode,Failed to open monitor socket");
12092 return 0;
12093 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012094
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012095 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
12096 if (res < 0) {
12097 send_resp(dut, conn, SIGMA_ERROR,
12098 "errorCode,Failed to inject frame");
12099 close(s);
12100 return 0;
12101 }
12102 if (res < pos - buf) {
12103 send_resp(dut, conn, SIGMA_ERROR,
12104 "errorCode,Only partial frame sent");
12105 close(s);
12106 return 0;
12107 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012108
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012109 close(s);
12110 } else {
12111#ifdef NL80211_SUPPORT
12112 int freq;
12113 char freq_str[10];
12114
12115 if (get_wpa_status(get_station_ifname(dut), "freq",
12116 freq_str, sizeof(freq_str)) < 0) {
12117 send_resp(dut, conn, SIGMA_ERROR,
12118 "errorCode,Could not get current operating frequency");
12119 return 0;
12120 }
12121 freq = atoi(freq_str);
12122
12123 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
12124 send_resp(dut, conn, SIGMA_ERROR,
12125 "errorCode,Failed to inject frame");
12126 return 0;
12127 }
12128#else /* NL80211_SUPPORT */
12129 send_resp(dut, conn, SIGMA_ERROR,
12130 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
12131 return 0;
12132#endif /* NL80211_SUPPORT */
12133 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012134
12135 return 1;
12136#else /* __linux__ */
12137 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
12138 "yet supported");
12139 return 0;
12140#endif /* __linux__ */
12141}
12142
12143
12144static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
12145 struct sigma_conn *conn,
12146 struct sigma_cmd *cmd)
12147{
12148 const char *intf = get_param(cmd, "Interface");
12149 const char *sta, *val;
12150 unsigned char addr[ETH_ALEN];
12151 char buf[100];
12152
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012153 if (!intf)
12154 return -1;
12155
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012156 sta = get_param(cmd, "peer");
12157 if (sta == NULL)
12158 sta = get_param(cmd, "station");
12159 if (sta == NULL) {
12160 send_resp(dut, conn, SIGMA_ERROR,
12161 "ErrorCode,Missing peer address");
12162 return 0;
12163 }
12164 if (hwaddr_aton(sta, addr) < 0) {
12165 send_resp(dut, conn, SIGMA_ERROR,
12166 "ErrorCode,Invalid peer address");
12167 return 0;
12168 }
12169
12170 val = get_param(cmd, "type");
12171 if (val == NULL)
12172 return -1;
12173
12174 if (strcasecmp(val, "DISCOVERY") == 0) {
12175 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
12176 if (wpa_command(intf, buf) < 0) {
12177 send_resp(dut, conn, SIGMA_ERROR,
12178 "ErrorCode,Failed to send TDLS discovery");
12179 return 0;
12180 }
12181 return 1;
12182 }
12183
12184 if (strcasecmp(val, "SETUP") == 0) {
12185 int status = 0, timeout = 0;
12186
12187 val = get_param(cmd, "Status");
12188 if (val)
12189 status = atoi(val);
12190
12191 val = get_param(cmd, "Timeout");
12192 if (val)
12193 timeout = atoi(val);
12194
12195 if (status != 0 && status != 37) {
12196 send_resp(dut, conn, SIGMA_ERROR,
12197 "ErrorCode,Unsupported status value");
12198 return 0;
12199 }
12200
12201 if (timeout != 0 && timeout != 301) {
12202 send_resp(dut, conn, SIGMA_ERROR,
12203 "ErrorCode,Unsupported timeout value");
12204 return 0;
12205 }
12206
12207 if (status && timeout) {
12208 send_resp(dut, conn, SIGMA_ERROR,
12209 "ErrorCode,Unsupported timeout+status "
12210 "combination");
12211 return 0;
12212 }
12213
12214 if (status == 37 &&
12215 wpa_command(intf, "SET tdls_testing 0x200")) {
12216 send_resp(dut, conn, SIGMA_ERROR,
12217 "ErrorCode,Failed to enable "
12218 "decline setup response test mode");
12219 return 0;
12220 }
12221
12222 if (timeout == 301) {
12223 int res;
12224 if (dut->no_tpk_expiration)
12225 res = wpa_command(intf,
12226 "SET tdls_testing 0x108");
12227 else
12228 res = wpa_command(intf,
12229 "SET tdls_testing 0x8");
12230 if (res) {
12231 send_resp(dut, conn, SIGMA_ERROR,
12232 "ErrorCode,Failed to set short TPK "
12233 "lifetime");
12234 return 0;
12235 }
12236 }
12237
12238 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
12239 if (wpa_command(intf, buf) < 0) {
12240 send_resp(dut, conn, SIGMA_ERROR,
12241 "ErrorCode,Failed to send TDLS setup");
12242 return 0;
12243 }
12244 return 1;
12245 }
12246
12247 if (strcasecmp(val, "TEARDOWN") == 0) {
12248 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
12249 if (wpa_command(intf, buf) < 0) {
12250 send_resp(dut, conn, SIGMA_ERROR,
12251 "ErrorCode,Failed to send TDLS teardown");
12252 return 0;
12253 }
12254 return 1;
12255 }
12256
12257 send_resp(dut, conn, SIGMA_ERROR,
12258 "ErrorCode,Unsupported TDLS frame");
12259 return 0;
12260}
12261
12262
12263static int sta_ap_known(const char *ifname, const char *bssid)
12264{
12265 char buf[4096];
12266
Jouni Malinendd32f192018-09-15 02:55:19 +030012267 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012268 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
12269 return 0;
12270 if (strncmp(buf, "id=", 3) != 0)
12271 return 0;
12272 return 1;
12273}
12274
12275
12276static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
12277 const char *bssid)
12278{
12279 int res;
12280 struct wpa_ctrl *ctrl;
12281 char buf[256];
12282
12283 if (sta_ap_known(ifname, bssid))
12284 return 0;
12285 sigma_dut_print(dut, DUT_MSG_DEBUG,
12286 "AP not in BSS table - start scan");
12287
12288 ctrl = open_wpa_mon(ifname);
12289 if (ctrl == NULL) {
12290 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12291 "wpa_supplicant monitor connection");
12292 return -1;
12293 }
12294
12295 if (wpa_command(ifname, "SCAN") < 0) {
12296 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
12297 wpa_ctrl_detach(ctrl);
12298 wpa_ctrl_close(ctrl);
12299 return -1;
12300 }
12301
12302 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12303 buf, sizeof(buf));
12304
12305 wpa_ctrl_detach(ctrl);
12306 wpa_ctrl_close(ctrl);
12307
12308 if (res < 0) {
12309 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
12310 return -1;
12311 }
12312
12313 if (sta_ap_known(ifname, bssid))
12314 return 0;
12315 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
12316 return -1;
12317}
12318
12319
12320static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
12321 struct sigma_conn *conn,
12322 struct sigma_cmd *cmd,
12323 const char *intf)
12324{
12325 char buf[200];
12326
12327 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
12328 if (system(buf) != 0) {
12329 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
12330 "ndsend");
12331 return 0;
12332 }
12333
12334 return 1;
12335}
12336
12337
12338static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
12339 struct sigma_conn *conn,
12340 struct sigma_cmd *cmd,
12341 const char *intf)
12342{
12343 char buf[200];
12344 const char *ip = get_param(cmd, "SenderIP");
12345
Peng Xu26b356d2017-10-04 17:58:16 -070012346 if (!ip)
12347 return 0;
12348
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012349 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
12350 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12351 if (system(buf) == 0) {
12352 sigma_dut_print(dut, DUT_MSG_INFO,
12353 "Neighbor Solicitation got a response "
12354 "for %s@%s", ip, intf);
12355 }
12356
12357 return 1;
12358}
12359
12360
12361static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
12362 struct sigma_conn *conn,
12363 struct sigma_cmd *cmd,
12364 const char *ifname)
12365{
12366 char buf[200];
12367 const char *ip = get_param(cmd, "SenderIP");
12368
12369 if (ip == NULL) {
12370 send_resp(dut, conn, SIGMA_ERROR,
12371 "ErrorCode,Missing SenderIP parameter");
12372 return 0;
12373 }
12374 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
12375 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12376 if (system(buf) != 0) {
12377 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
12378 "for %s@%s", ip, ifname);
12379 }
12380
12381 return 1;
12382}
12383
12384
12385static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
12386 struct sigma_conn *conn,
12387 struct sigma_cmd *cmd,
12388 const char *ifname)
12389{
12390 char buf[200];
12391 char ip[16];
12392 int s;
Peng Xub3756882017-10-04 14:39:09 -070012393 struct ifreq ifr;
12394 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012395
12396 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070012397 if (s < 0) {
12398 perror("socket");
12399 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012400 }
12401
Peng Xub3756882017-10-04 14:39:09 -070012402 memset(&ifr, 0, sizeof(ifr));
12403 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
12404 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
12405 sigma_dut_print(dut, DUT_MSG_INFO,
12406 "Failed to get %s IP address: %s",
12407 ifname, strerror(errno));
12408 close(s);
12409 return -1;
12410 }
12411 close(s);
12412
12413 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
12414 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
12415
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012416 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
12417 ip);
12418 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12419 if (system(buf) != 0) {
12420 }
12421
12422 return 1;
12423}
12424
12425
12426static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
12427 struct sigma_conn *conn,
12428 struct sigma_cmd *cmd,
12429 const char *ifname)
12430{
12431 char buf[200], addr[20];
12432 char dst[ETH_ALEN], src[ETH_ALEN];
12433 short ethtype = htons(ETH_P_ARP);
12434 char *pos;
12435 int s, res;
12436 const char *val;
12437 struct sockaddr_in taddr;
12438
12439 val = get_param(cmd, "dest");
12440 if (val)
12441 hwaddr_aton(val, (unsigned char *) dst);
12442
12443 val = get_param(cmd, "DestIP");
12444 if (val)
12445 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070012446 else
12447 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012448
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012449 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012450 sizeof(addr)) < 0)
12451 return -2;
12452 hwaddr_aton(addr, (unsigned char *) src);
12453
12454 pos = buf;
12455 *pos++ = 0x00;
12456 *pos++ = 0x01;
12457 *pos++ = 0x08;
12458 *pos++ = 0x00;
12459 *pos++ = 0x06;
12460 *pos++ = 0x04;
12461 *pos++ = 0x00;
12462 *pos++ = 0x02;
12463 memcpy(pos, src, ETH_ALEN);
12464 pos += ETH_ALEN;
12465 memcpy(pos, &taddr.sin_addr, 4);
12466 pos += 4;
12467 memcpy(pos, dst, ETH_ALEN);
12468 pos += ETH_ALEN;
12469 memcpy(pos, &taddr.sin_addr, 4);
12470 pos += 4;
12471
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012472 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012473 if (s < 0) {
12474 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
12475 "monitor socket");
12476 return 0;
12477 }
12478
12479 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
12480 if (res < 0) {
12481 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
12482 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053012483 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012484 return 0;
12485 }
12486
12487 close(s);
12488
12489 return 1;
12490}
12491
12492
12493static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
12494 struct sigma_conn *conn,
12495 struct sigma_cmd *cmd,
12496 const char *intf, const char *dest)
12497{
12498 char buf[100];
12499
12500 if (if_nametoindex("sigmadut") == 0) {
12501 snprintf(buf, sizeof(buf),
12502 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012503 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012504 if (system(buf) != 0 ||
12505 if_nametoindex("sigmadut") == 0) {
12506 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12507 "monitor interface with '%s'", buf);
12508 return -2;
12509 }
12510 }
12511
12512 if (system("ifconfig sigmadut up") != 0) {
12513 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12514 "monitor interface up");
12515 return -2;
12516 }
12517
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012518 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012519}
12520
12521
12522static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
12523 struct sigma_conn *conn,
12524 struct sigma_cmd *cmd)
12525{
12526 const char *intf = get_param(cmd, "Interface");
12527 const char *dest = get_param(cmd, "Dest");
12528 const char *type = get_param(cmd, "FrameName");
12529 const char *val;
12530 char buf[200], *pos, *end;
12531 int count, count2;
12532
12533 if (type == NULL)
12534 type = get_param(cmd, "Type");
12535
12536 if (intf == NULL || dest == NULL || type == NULL)
12537 return -1;
12538
12539 if (strcasecmp(type, "NeighAdv") == 0)
12540 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
12541
12542 if (strcasecmp(type, "NeighSolicitReq") == 0)
12543 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
12544
12545 if (strcasecmp(type, "ARPProbe") == 0)
12546 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
12547
12548 if (strcasecmp(type, "ARPAnnounce") == 0)
12549 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
12550
12551 if (strcasecmp(type, "ARPReply") == 0)
12552 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
12553
12554 if (strcasecmp(type, "DLS-request") == 0 ||
12555 strcasecmp(type, "DLSrequest") == 0)
12556 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
12557 dest);
12558
12559 if (strcasecmp(type, "ANQPQuery") != 0 &&
12560 strcasecmp(type, "Query") != 0) {
12561 send_resp(dut, conn, SIGMA_ERROR,
12562 "ErrorCode,Unsupported HS 2.0 send frame type");
12563 return 0;
12564 }
12565
12566 if (sta_scan_ap(dut, intf, dest) < 0) {
12567 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
12568 "the requested AP");
12569 return 0;
12570 }
12571
12572 pos = buf;
12573 end = buf + sizeof(buf);
12574 count = 0;
12575 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
12576
12577 val = get_param(cmd, "ANQP_CAP_LIST");
12578 if (val && atoi(val)) {
12579 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
12580 count++;
12581 }
12582
12583 val = get_param(cmd, "VENUE_NAME");
12584 if (val && atoi(val)) {
12585 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
12586 count++;
12587 }
12588
12589 val = get_param(cmd, "NETWORK_AUTH_TYPE");
12590 if (val && atoi(val)) {
12591 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
12592 count++;
12593 }
12594
12595 val = get_param(cmd, "ROAMING_CONS");
12596 if (val && atoi(val)) {
12597 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
12598 count++;
12599 }
12600
12601 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
12602 if (val && atoi(val)) {
12603 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
12604 count++;
12605 }
12606
12607 val = get_param(cmd, "NAI_REALM_LIST");
12608 if (val && atoi(val)) {
12609 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
12610 count++;
12611 }
12612
12613 val = get_param(cmd, "3GPP_INFO");
12614 if (val && atoi(val)) {
12615 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
12616 count++;
12617 }
12618
12619 val = get_param(cmd, "DOMAIN_LIST");
12620 if (val && atoi(val)) {
12621 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
12622 count++;
12623 }
12624
Jouni Malinen34cf9532018-04-29 19:26:33 +030012625 val = get_param(cmd, "Venue_URL");
12626 if (val && atoi(val)) {
12627 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
12628 count++;
12629 }
12630
Jouni Malinend3bca5d2018-04-29 17:25:23 +030012631 val = get_param(cmd, "Advice_Of_Charge");
12632 if (val && atoi(val)) {
12633 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
12634 count++;
12635 }
12636
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012637 if (count && wpa_command(intf, buf)) {
12638 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
12639 return 0;
12640 }
12641
12642 pos = buf;
12643 end = buf + sizeof(buf);
12644 count2 = 0;
12645 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
12646
12647 val = get_param(cmd, "HS_CAP_LIST");
12648 if (val && atoi(val)) {
12649 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
12650 count2++;
12651 }
12652
12653 val = get_param(cmd, "OPER_NAME");
12654 if (val && atoi(val)) {
12655 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
12656 count2++;
12657 }
12658
12659 val = get_param(cmd, "WAN_METRICS");
12660 if (!val)
12661 val = get_param(cmd, "WAN_MAT");
12662 if (!val)
12663 val = get_param(cmd, "WAN_MET");
12664 if (val && atoi(val)) {
12665 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
12666 count2++;
12667 }
12668
12669 val = get_param(cmd, "CONNECTION_CAPABILITY");
12670 if (val && atoi(val)) {
12671 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
12672 count2++;
12673 }
12674
12675 val = get_param(cmd, "OP_CLASS");
12676 if (val && atoi(val)) {
12677 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
12678 count2++;
12679 }
12680
12681 val = get_param(cmd, "OSU_PROVIDER_LIST");
12682 if (val && atoi(val)) {
12683 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
12684 count2++;
12685 }
12686
Jouni Malinenf67afec2018-04-29 19:24:58 +030012687 val = get_param(cmd, "OPER_ICON_METADATA");
12688 if (!val)
12689 val = get_param(cmd, "OPERATOR_ICON_METADATA");
12690 if (val && atoi(val)) {
12691 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
12692 count2++;
12693 }
12694
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012695 if (count && count2) {
12696 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
12697 "second query");
12698 sleep(1);
12699 }
12700
12701 if (count2 && wpa_command(intf, buf)) {
12702 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
12703 "failed");
12704 return 0;
12705 }
12706
12707 val = get_param(cmd, "NAI_HOME_REALM_LIST");
12708 if (val) {
12709 if (count || count2) {
12710 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12711 "sending out second query");
12712 sleep(1);
12713 }
12714
12715 if (strcmp(val, "1") == 0)
12716 val = "mail.example.com";
12717 snprintf(buf, end - pos,
12718 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
12719 dest, val);
12720 if (wpa_command(intf, buf)) {
12721 send_resp(dut, conn, SIGMA_ERROR,
12722 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
12723 "failed");
12724 return 0;
12725 }
12726 }
12727
12728 val = get_param(cmd, "ICON_REQUEST");
12729 if (val) {
12730 if (count || count2) {
12731 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12732 "sending out second query");
12733 sleep(1);
12734 }
12735
12736 snprintf(buf, end - pos,
12737 "HS20_ICON_REQUEST %s %s", dest, val);
12738 if (wpa_command(intf, buf)) {
12739 send_resp(dut, conn, SIGMA_ERROR,
12740 "ErrorCode,HS20_ICON_REQUEST failed");
12741 return 0;
12742 }
12743 }
12744
12745 return 1;
12746}
12747
12748
12749static int ath_sta_send_frame_vht(struct sigma_dut *dut,
12750 struct sigma_conn *conn,
12751 struct sigma_cmd *cmd)
12752{
12753 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012754 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012755 int chwidth, nss;
12756
12757 val = get_param(cmd, "framename");
12758 if (!val)
12759 return -1;
12760 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12761
12762 /* Command sequence to generate Op mode notification */
12763 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012764 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012765
12766 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012767 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012768
12769 /* Extract Channel width */
12770 val = get_param(cmd, "Channel_width");
12771 if (val) {
12772 switch (atoi(val)) {
12773 case 20:
12774 chwidth = 0;
12775 break;
12776 case 40:
12777 chwidth = 1;
12778 break;
12779 case 80:
12780 chwidth = 2;
12781 break;
12782 case 160:
12783 chwidth = 3;
12784 break;
12785 default:
12786 chwidth = 2;
12787 break;
12788 }
12789
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012790 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012791 }
12792
12793 /* Extract NSS */
12794 val = get_param(cmd, "NSS");
12795 if (val) {
12796 switch (atoi(val)) {
12797 case 1:
12798 nss = 1;
12799 break;
12800 case 2:
12801 nss = 3;
12802 break;
12803 case 3:
12804 nss = 7;
12805 break;
12806 default:
12807 /* We do not support NSS > 3 */
12808 nss = 3;
12809 break;
12810 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012811 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012812 }
12813
12814 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012815 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012816 }
12817
12818 return 1;
12819}
12820
12821
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012822static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
12823 enum send_frame_protection protected)
12824{
12825#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012826 return wcn_wifi_test_config_set_u8(
12827 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
12828 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012829#else /* NL80211_SUPPORT */
12830 sigma_dut_print(dut, DUT_MSG_ERROR,
12831 "PMF config cannot be set without NL80211_SUPPORT defined");
12832 return -1;
12833#endif /* NL80211_SUPPORT */
12834}
12835
12836
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012837static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
12838 struct sigma_conn *conn,
12839 struct sigma_cmd *cmd)
12840{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012841 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012842 case DRIVER_ATHEROS:
12843 return ath_sta_send_frame_vht(dut, conn, cmd);
12844 default:
12845 send_resp(dut, conn, SIGMA_ERROR,
12846 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
12847 return 0;
12848 }
12849}
12850
12851
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012852static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
12853{
12854#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012855 return wcn_wifi_test_config_set_flag(
12856 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012857#else /* NL80211_SUPPORT */
12858 sigma_dut_print(dut, DUT_MSG_ERROR,
12859 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
12860 return -1;
12861#endif /* NL80211_SUPPORT */
12862}
12863
12864
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012865static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
12866 struct sigma_cmd *cmd)
12867{
12868 const char *val;
12869 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012870 enum send_frame_protection protected;
12871 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012872
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012873 if (!intf)
12874 return -1;
12875
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012876 val = get_param(cmd, "framename");
12877 if (!val)
12878 return -1;
12879 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12880
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012881 pmf = get_param(cmd, "PMFProtected");
12882 if (!pmf)
12883 pmf = get_param(cmd, "Protected");
12884 if (pmf) {
12885 if (strcasecmp(pmf, "Correct-key") == 0 ||
12886 strcasecmp(pmf, "CorrectKey") == 0) {
12887 protected = CORRECT_KEY;
12888 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
12889 protected = INCORRECT_KEY;
12890 } else if (strcasecmp(pmf, "Unprotected") == 0) {
12891 protected = UNPROTECTED;
12892 } else {
12893 send_resp(dut, conn, SIGMA_ERROR,
12894 "errorCode,Unsupported PMFProtected");
12895 return STATUS_SENT_ERROR;
12896 }
12897 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
12898 protected);
12899 wcn_sta_set_pmf_config(dut, intf, protected);
12900 }
12901
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012902 /* Command sequence to generate Op mode notification */
12903 if (val && strcasecmp(val, "action") == 0) {
12904 val = get_param(cmd, "PPDUTxType");
12905 if (val && strcasecmp(val, "TB") == 0) {
12906 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
12907 sigma_dut_print(dut, DUT_MSG_ERROR,
12908 "failed to send TB PPDU Tx cfg");
12909 send_resp(dut, conn, SIGMA_ERROR,
12910 "ErrorCode,set TB PPDU Tx cfg failed");
12911 return 0;
12912 }
12913 return 1;
12914 }
12915
12916 sigma_dut_print(dut, DUT_MSG_ERROR,
12917 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012918
12919 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012920 }
12921
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012922 if (strcasecmp(val, "disassoc") == 0)
12923 wcn_sta_send_disassoc(dut, intf);
12924
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012925 return 1;
12926}
12927
12928
12929static int cmd_sta_send_frame_he(struct sigma_dut *dut,
12930 struct sigma_conn *conn,
12931 struct sigma_cmd *cmd)
12932{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012933 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012934 case DRIVER_WCN:
12935 return wcn_sta_send_frame_he(dut, conn, cmd);
12936 default:
12937 send_resp(dut, conn, SIGMA_ERROR,
12938 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
12939 return 0;
12940 }
12941}
12942
12943
Lior David0fe101e2017-03-09 16:09:50 +020012944#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012945
12946static int
12947wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
12948 const char *frame_name, const char *dest_mac)
12949{
12950 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
12951 const char *ssid = get_param(cmd, "ssid");
12952 const char *countstr = get_param(cmd, "count");
12953 const char *channelstr = get_param(cmd, "channel");
12954 const char *group_id = get_param(cmd, "groupid");
12955 const char *client_id = get_param(cmd, "clientmac");
12956 int count, channel, freq, i;
12957 const char *fname;
12958 char frame[1024], src_mac[20], group_id_attr[25],
12959 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
12960 const char *group_ssid;
12961 const int group_ssid_prefix_len = 9;
12962 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
12963 size_t framelen = sizeof(frame);
12964 struct template_frame_tag tags[2];
12965 size_t tags_total = ARRAY_SIZE(tags);
12966 int tag_index, len, dst_len;
12967
12968 if (!countstr || !channelstr) {
12969 sigma_dut_print(dut, DUT_MSG_ERROR,
12970 "Missing argument: count, channel");
12971 return -1;
12972 }
12973 if (isprobereq && !ssid) {
12974 sigma_dut_print(dut, DUT_MSG_ERROR,
12975 "Missing argument: ssid");
12976 return -1;
12977 }
12978 if (!isprobereq && (!group_id || !client_id)) {
12979 sigma_dut_print(dut, DUT_MSG_ERROR,
12980 "Missing argument: group_id, client_id");
12981 return -1;
12982 }
12983
12984 count = atoi(countstr);
12985 channel = atoi(channelstr);
12986 freq = channel_to_freq(dut, channel);
12987
12988 if (!freq) {
12989 sigma_dut_print(dut, DUT_MSG_ERROR,
12990 "invalid channel: %s", channelstr);
12991 return -1;
12992 }
12993
12994 if (isprobereq) {
12995 if (strcasecmp(ssid, "wildcard") == 0) {
12996 fname = "probe_req_wildcard.txt";
12997 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
12998 fname = "probe_req_P2P_Wildcard.txt";
12999 } else {
13000 sigma_dut_print(dut, DUT_MSG_ERROR,
13001 "invalid probe request type");
13002 return -1;
13003 }
13004 } else {
13005 fname = "P2P_device_discovery_req.txt";
13006 }
13007
13008 if (parse_template_frame_file(dut, fname, frame, &framelen,
13009 tags, &tags_total)) {
13010 sigma_dut_print(dut, DUT_MSG_ERROR,
13011 "invalid frame template: %s", fname);
13012 return -1;
13013 }
13014
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013015 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013016 src_mac, sizeof(src_mac)) < 0 ||
13017 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
13018 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
13019 return -1;
13020 /* Use wildcard BSSID, since we are in PBSS */
13021 memset(&hdr->addr3, 0xFF, ETH_ALEN);
13022
13023 if (!isprobereq) {
13024 tag_index = find_template_frame_tag(tags, tags_total, 1);
13025 if (tag_index < 0) {
13026 sigma_dut_print(dut, DUT_MSG_ERROR,
13027 "can't find device id attribute");
13028 return -1;
13029 }
13030 if (parse_mac_address(dut, client_id,
13031 (unsigned char *) client_mac)) {
13032 sigma_dut_print(dut, DUT_MSG_ERROR,
13033 "invalid client_id: %s", client_id);
13034 return -1;
13035 }
13036 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13037 framelen - tags[tag_index].offset,
13038 IEEE80211_P2P_ATTR_DEVICE_ID,
13039 client_mac, ETH_ALEN)) {
13040 sigma_dut_print(dut, DUT_MSG_ERROR,
13041 "fail to replace device id attribute");
13042 return -1;
13043 }
13044
13045 /*
13046 * group_id arg contains device MAC address followed by
13047 * space and SSID (DIRECT-somessid).
13048 * group id attribute contains device address (6 bytes)
13049 * followed by SSID prefix DIRECT-XX (9 bytes)
13050 */
13051 if (strlen(group_id) < sizeof(device_macstr)) {
13052 sigma_dut_print(dut, DUT_MSG_ERROR,
13053 "group_id arg too short");
13054 return -1;
13055 }
13056 memcpy(device_macstr, group_id, sizeof(device_macstr));
13057 device_macstr[sizeof(device_macstr) - 1] = '\0';
13058 if (parse_mac_address(dut, device_macstr,
13059 (unsigned char *) group_id_attr)) {
13060 sigma_dut_print(dut, DUT_MSG_ERROR,
13061 "fail to parse device address from group_id");
13062 return -1;
13063 }
13064 group_ssid = strchr(group_id, ' ');
13065 if (!group_ssid) {
13066 sigma_dut_print(dut, DUT_MSG_ERROR,
13067 "invalid group_id arg, no ssid");
13068 return -1;
13069 }
13070 group_ssid++;
13071 len = strlen(group_ssid);
13072 if (len < group_ssid_prefix_len) {
13073 sigma_dut_print(dut, DUT_MSG_ERROR,
13074 "group_id SSID too short");
13075 return -1;
13076 }
13077 dst_len = sizeof(group_id_attr) - ETH_ALEN;
13078 if (len > dst_len) {
13079 sigma_dut_print(dut, DUT_MSG_ERROR,
13080 "group_id SSID (%s) too long",
13081 group_ssid);
13082 return -1;
13083 }
13084
13085 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
13086 tag_index = find_template_frame_tag(tags, tags_total, 2);
13087 if (tag_index < 0) {
13088 sigma_dut_print(dut, DUT_MSG_ERROR,
13089 "can't find group id attribute");
13090 return -1;
13091 }
13092 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13093 framelen - tags[tag_index].offset,
13094 IEEE80211_P2P_ATTR_GROUP_ID,
13095 group_id_attr,
13096 sizeof(group_id_attr))) {
13097 sigma_dut_print(dut, DUT_MSG_ERROR,
13098 "fail to replace group id attribute");
13099 return -1;
13100 }
13101 }
13102
13103 for (i = 0; i < count; i++) {
13104 if (wil6210_transmit_frame(dut, freq,
13105 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
13106 frame, framelen)) {
13107 sigma_dut_print(dut, DUT_MSG_ERROR,
13108 "fail to transmit probe request frame");
13109 return -1;
13110 }
13111 }
13112
13113 return 0;
13114}
13115
13116
Lior David0fe101e2017-03-09 16:09:50 +020013117int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
13118 struct sigma_cmd *cmd)
13119{
13120 const char *frame_name = get_param(cmd, "framename");
13121 const char *mac = get_param(cmd, "dest_mac");
13122
13123 if (!frame_name || !mac) {
13124 sigma_dut_print(dut, DUT_MSG_ERROR,
13125 "framename and dest_mac must be provided");
13126 return -1;
13127 }
13128
13129 if (strcasecmp(frame_name, "brp") == 0) {
13130 const char *l_rx = get_param(cmd, "L-RX");
13131 int l_rx_i;
13132
13133 if (!l_rx) {
13134 sigma_dut_print(dut, DUT_MSG_ERROR,
13135 "L-RX must be provided");
13136 return -1;
13137 }
13138 l_rx_i = atoi(l_rx);
13139
13140 sigma_dut_print(dut, DUT_MSG_INFO,
13141 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
13142 mac, l_rx);
13143 if (l_rx_i != 16) {
13144 sigma_dut_print(dut, DUT_MSG_ERROR,
13145 "unsupported L-RX: %s", l_rx);
13146 return -1;
13147 }
13148
13149 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
13150 return -1;
13151 } else if (strcasecmp(frame_name, "ssw") == 0) {
13152 sigma_dut_print(dut, DUT_MSG_INFO,
13153 "dev_send_frame: SLS, dest_mac %s", mac);
13154 if (wil6210_send_sls(dut, mac))
13155 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013156 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
13157 (strcasecmp(frame_name, "devdiscreq") == 0)) {
13158 sigma_dut_print(dut, DUT_MSG_INFO,
13159 "dev_send_frame: %s, dest_mac %s", frame_name,
13160 mac);
13161 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
13162 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020013163 } else {
13164 sigma_dut_print(dut, DUT_MSG_ERROR,
13165 "unsupported frame type: %s", frame_name);
13166 return -1;
13167 }
13168
13169 return 1;
13170}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013171
Lior David0fe101e2017-03-09 16:09:50 +020013172#endif /* __linux__ */
13173
13174
13175static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
13176 struct sigma_conn *conn,
13177 struct sigma_cmd *cmd)
13178{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013179 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020013180#ifdef __linux__
13181 case DRIVER_WIL6210:
13182 return wil6210_send_frame_60g(dut, conn, cmd);
13183#endif /* __linux__ */
13184 default:
13185 send_resp(dut, conn, SIGMA_ERROR,
13186 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
13187 return 0;
13188 }
13189}
13190
13191
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013192static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13193 const char *intf, struct sigma_cmd *cmd)
13194{
13195 const char *val, *addr;
13196 char buf[100];
13197
13198 addr = get_param(cmd, "DestMac");
13199 if (!addr) {
13200 send_resp(dut, conn, SIGMA_INVALID,
13201 "ErrorCode,AP MAC address is missing");
13202 return 0;
13203 }
13204
13205 val = get_param(cmd, "ANQPQuery_ID");
13206 if (!val) {
13207 send_resp(dut, conn, SIGMA_INVALID,
13208 "ErrorCode,Missing ANQPQuery_ID");
13209 return 0;
13210 }
13211
13212 if (strcasecmp(val, "NeighborReportReq") == 0) {
13213 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
13214 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
13215 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
13216 } else {
13217 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
13218 val);
13219 send_resp(dut, conn, SIGMA_INVALID,
13220 "ErrorCode,Invalid ANQPQuery_ID");
13221 return 0;
13222 }
13223
Ashwini Patild174f2c2017-04-13 16:49:46 +053013224 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
13225 * (Address3 = Wildcard BSSID when sent to not-associated AP;
13226 * if associated, AP BSSID).
13227 */
13228 if (wpa_command(intf, "SET gas_address3 1") < 0) {
13229 send_resp(dut, conn, SIGMA_ERROR,
13230 "ErrorCode,Failed to set gas_address3");
13231 return 0;
13232 }
13233
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013234 if (wpa_command(intf, buf) < 0) {
13235 send_resp(dut, conn, SIGMA_ERROR,
13236 "ErrorCode,Failed to send ANQP query");
13237 return 0;
13238 }
13239
13240 return 1;
13241}
13242
13243
13244static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
13245 struct sigma_conn *conn,
13246 const char *intf,
13247 struct sigma_cmd *cmd)
13248{
13249 const char *val = get_param(cmd, "FrameName");
13250
13251 if (val && strcasecmp(val, "ANQPQuery") == 0)
13252 return mbo_send_anqp_query(dut, conn, intf, cmd);
13253
13254 return 2;
13255}
13256
13257
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013258static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
13259 struct sigma_conn *conn,
13260 const char *intf,
13261 struct sigma_cmd *cmd)
13262{
13263 const char *val = get_param(cmd, "framename");
13264
13265 if (!val)
13266 return INVALID_SEND_STATUS;
13267
13268 if (strcasecmp(val, "SAQueryReq") == 0) {
13269 val = get_param(cmd, "OCIChannel");
13270
13271 if (!val) {
13272 send_resp(dut, conn, SIGMA_ERROR,
13273 "errorCode,OCIChannel not present");
13274 return STATUS_SENT_ERROR;
13275 }
13276
13277 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
13278 if (!dut->saquery_oci_freq) {
13279 send_resp(dut, conn, SIGMA_ERROR,
13280 "errorCode,Invalid OCIChannel number");
13281 return STATUS_SENT_ERROR;
13282 }
13283
13284 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
13285 NULL, 0);
13286 }
13287
13288 if (strcasecmp(val, "reassocreq") == 0)
13289 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
13290 CORRECT_KEY, NULL, 0);
13291
Veerendranath9f81dfb2020-08-10 01:21:29 -070013292 if (strcasecmp(val, "ANQPQuery") == 0) {
13293 char buf[50];
13294 const char *dest = get_param(cmd, "DestMac");
13295 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013296 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070013297 int len, freq;
13298
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013299 if (freq_str)
13300 freq = atoi(freq_str);
13301 else
13302 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
13303
Veerendranath9f81dfb2020-08-10 01:21:29 -070013304 if (!dest || !freq)
13305 return INVALID_SEND_STATUS;
13306
13307 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
13308 dest, freq);
13309 if (len < 0 || len >= sizeof(buf)) {
13310 sigma_dut_print(dut, DUT_MSG_ERROR,
13311 "Failed to allocate buf");
13312 return ERROR_SEND_STATUS;
13313 }
13314
13315 if (wpa_command(intf, buf) != 0) {
13316 send_resp(dut, conn, SIGMA_ERROR,
13317 "ErrorCode,Failed to send ANQP Query frame");
13318 return STATUS_SENT_ERROR;
13319 }
13320
13321 sigma_dut_print(dut, DUT_MSG_DEBUG,
13322 "ANQP Query sent: %s", buf);
13323
13324 return SUCCESS_SEND_STATUS;
13325 }
13326
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013327 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
13328 return STATUS_SENT_ERROR;
13329}
13330
13331
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013332static int
13333get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13334 char *pos, int rem_len, int num_of_scs_desc,
13335 int num_of_tclas_elem)
13336{
13337 const char *val;
13338 int ipv6;
13339 int len, total_len = 0;
13340
13341 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
13342 num_of_tclas_elem);
13343 if (!val) {
13344 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
13345 __func__);
13346 return -1;
13347 }
13348
13349 if (strcmp(val, "6") == 0) {
13350 ipv6 = 1;
13351 } else if (strcmp(val, "4") == 0) {
13352 ipv6 = 0;
13353 } else {
13354 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
13355 __func__);
13356 return -1;
13357 }
13358
13359 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
13360 if (len < 0 || len >= rem_len)
13361 return -1;
13362
13363 pos += len;
13364 rem_len -= len;
13365 total_len += len;
13366
13367 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
13368 num_of_scs_desc, num_of_tclas_elem);
13369 if (val) {
13370 len = snprintf(pos, rem_len, " src_ip=%s", val);
13371 if (len < 0 || len >= rem_len)
13372 return -1;
13373
13374 pos += len;
13375 rem_len -= len;
13376 total_len += len;
13377 }
13378
13379 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
13380 num_of_scs_desc, num_of_tclas_elem);
13381 if (val) {
13382 len = snprintf(pos, rem_len, " dst_ip=%s", val);
13383 if (len < 0 || len >= rem_len)
13384 return -1;
13385
13386 pos += len;
13387 rem_len -= len;
13388 total_len += len;
13389 }
13390
13391 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
13392 num_of_tclas_elem);
13393 if (val) {
13394 len = snprintf(pos, rem_len, " src_port=%s", val);
13395 if (len < 0 || len >= rem_len)
13396 return -1;
13397
13398 pos += len;
13399 rem_len -= len;
13400 total_len += len;
13401 }
13402
13403 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
13404 num_of_scs_desc, num_of_tclas_elem);
13405 if (val) {
13406 len = snprintf(pos, rem_len, " dst_port=%s", val);
13407 if (len < 0 || len >= rem_len)
13408 return -1;
13409
13410 pos += len;
13411 rem_len -= len;
13412 total_len += len;
13413 }
13414
13415 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
13416 num_of_tclas_elem);
13417 if (val) {
13418 len = snprintf(pos, rem_len, " dscp=%s", val);
13419 if (len < 0 || len >= rem_len)
13420 return -1;
13421
13422 pos += len;
13423 rem_len -= len;
13424 total_len += len;
13425 }
13426
13427 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
13428 num_of_scs_desc, num_of_tclas_elem);
13429 if (val) {
13430 char *prot;
13431
13432 switch (atoi(val)) {
13433 case 17:
13434 prot = "udp";
13435 break;
13436 case 6:
13437 prot = "tcp";
13438 break;
13439 case 50:
13440 prot = "esp";
13441 break;
13442 default:
13443 sigma_dut_print(dut, DUT_MSG_ERROR,
13444 "Invalid protocol %d", atoi(val));
13445 return -1;
13446 }
13447
13448 if (ipv6)
13449 len = snprintf(pos, rem_len, " next_header=%s", prot);
13450 else
13451 len = snprintf(pos, rem_len, " protocol=%s", prot);
13452 if (len < 0 || len >= rem_len)
13453 return -1;
13454
13455 pos += len;
13456 rem_len -= len;
13457 total_len += len;
13458 }
13459
13460 return total_len;
13461}
13462
13463
13464static int
13465get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13466 char *pos, int rem_len, int num_of_scs_desc,
13467 int num_of_tclas_elem)
13468{
13469 const char *val;
13470 int len, total_len = 0;
13471
13472 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
13473 num_of_scs_desc, num_of_tclas_elem);
13474 if (val) {
13475 len = snprintf(pos, rem_len, " prot_instance=%s",
13476 val);
13477 if (len < 0 || len >= rem_len)
13478 return -1;
13479
13480 pos += len;
13481 rem_len -= len;
13482 total_len += len;
13483 }
13484
13485 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
13486 num_of_scs_desc, num_of_tclas_elem);
13487 if (val) {
13488 char *prot;
13489
13490 switch (atoi(val)) {
13491 case 17:
13492 prot = "udp";
13493 break;
13494 case 6:
13495 prot = "tcp";
13496 break;
13497 case 50:
13498 prot = "esp";
13499 break;
13500 default:
13501 sigma_dut_print(dut, DUT_MSG_ERROR,
13502 "Invalid protocol %d",
13503 atoi(val));
13504 return -1;
13505 }
13506
13507 len = snprintf(pos, rem_len, " prot_number=%s", prot);
13508 if (len < 0 || len >= rem_len)
13509 return -1;
13510
13511 pos += len;
13512 rem_len -= len;
13513 total_len += len;
13514 }
13515
13516 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
13517 num_of_scs_desc, num_of_tclas_elem);
13518 if (val) {
13519 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
13520 if (len < 0 || len >= rem_len)
13521 return -1;
13522
13523 pos += len;
13524 rem_len -= len;
13525 total_len += len;
13526 }
13527
13528 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
13529 num_of_tclas_elem);
13530 if (val && strlen(val) >= 2) {
13531 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
13532 if (len < 0 || len >= rem_len)
13533 return -1;
13534
13535 pos += len;
13536 rem_len -= len;
13537 total_len += len;
13538 }
13539
13540 return total_len;
13541}
13542
13543
13544static enum sigma_cmd_result
13545cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
13546 const char *intf, struct sigma_cmd *cmd)
13547{
13548 char buf[4096], *pos;
13549 const char *val, *scs_id, *classifier_type;
13550 int len, rem_len, total_bytes;
13551 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
13552
13553 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
13554 if (!scs_id) {
13555 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
13556 return INVALID_SEND_STATUS;
13557 }
13558
13559 rem_len = sizeof(buf);
13560 pos = buf;
13561
13562 len = snprintf(buf, sizeof(buf), "SCS");
13563 if (len < 0 || len > rem_len)
13564 goto fail;
13565
13566 pos += len;
13567 rem_len -= len;
13568
13569 while (scs_id) {
13570 num_of_scs_desc++;
13571
13572 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
13573 num_of_scs_desc);
13574 if (!val)
13575 return INVALID_SEND_STATUS;
13576
13577 if (strcasecmp(val, "Add") == 0) {
13578 len = snprintf(pos, rem_len, " scs_id=%s add",
13579 scs_id);
13580 } else if (strcasecmp(val, "Change") == 0) {
13581 len = snprintf(pos, rem_len, " scs_id=%s change",
13582 scs_id);
13583 } else if (strcasecmp(val, "Remove") == 0) {
13584 len = snprintf(pos, rem_len, " scs_id=%s remove",
13585 scs_id);
13586 if (len < 0 || len >= rem_len)
13587 goto fail;
13588
13589 pos += len;
13590 rem_len -= len;
13591 goto scs_desc_end;
13592 } else {
13593 sigma_dut_print(dut, DUT_MSG_ERROR,
13594 "%s: request type - %s is invalid",
13595 __func__, val);
13596 return INVALID_SEND_STATUS;
13597 }
13598
13599 if (len < 0 || len >= rem_len)
13600 goto fail;
13601
13602 pos += len;
13603 rem_len -= len;
13604
13605 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
13606 num_of_scs_desc);
13607 if (!val) {
13608 sigma_dut_print(dut, DUT_MSG_ERROR,
13609 "IntraAccess Priority empty");
13610 return INVALID_SEND_STATUS;
13611 }
13612
13613 len = snprintf(pos, rem_len, " scs_up=%s", val);
13614 if (len < 0 || len >= rem_len)
13615 goto fail;
13616
13617 pos += len;
13618 rem_len -= len;
13619
13620 classifier_type = get_param_fmt(cmd,
13621 "TCLASElem_ClassifierType_%d_1",
13622 num_of_scs_desc);
13623 if (!classifier_type) {
13624 sigma_dut_print(dut, DUT_MSG_ERROR,
13625 "classifier type missing");
13626 return INVALID_SEND_STATUS;
13627 }
13628
13629 while (classifier_type) {
13630 num_of_tclas_elem++;
13631
13632 len = snprintf(pos, rem_len, " classifier_type=%s",
13633 classifier_type);
13634 if (len < 0 || len >= rem_len)
13635 goto fail;
13636
13637 pos += len;
13638 rem_len -= len;
13639
13640 if (strcmp(classifier_type, "10") == 0) {
13641 total_bytes = get_type10_frame_classifier(
13642 dut, cmd, pos, rem_len,
13643 num_of_scs_desc,
13644 num_of_tclas_elem);
13645 } else if (strcmp(classifier_type, "4") == 0) {
13646 total_bytes = get_type4_frame_classifier(
13647 dut, cmd, pos, rem_len,
13648 num_of_scs_desc,
13649 num_of_tclas_elem);
13650 } else {
13651 sigma_dut_print(dut, DUT_MSG_ERROR,
13652 "classifier_type invalid");
13653 goto fail;
13654 }
13655
13656 if (total_bytes < 0)
13657 goto fail;
13658
13659 pos += total_bytes;
13660 rem_len -= total_bytes;
13661
13662 classifier_type = get_param_fmt(
13663 cmd, "TCLASElem_ClassifierType_%d_%d",
13664 num_of_scs_desc, num_of_tclas_elem + 1);
13665 }
13666
13667 if (num_of_tclas_elem > 1) {
13668 val = get_param_fmt(cmd,
13669 "TCLASProcessingElem_Processing_%d",
13670 num_of_scs_desc);
13671 if (!val) {
13672 sigma_dut_print(dut, DUT_MSG_ERROR,
13673 "Tclas_processing element %d empty",
13674 num_of_scs_desc);
13675 goto fail;
13676 }
13677
13678 len = snprintf(pos, rem_len,
13679 " tclas_processing=%s", val);
13680 if (len < 0 || len >= rem_len)
13681 goto fail;
13682
13683 pos += len;
13684 rem_len -= len;
13685 }
13686scs_desc_end:
13687 num_of_tclas_elem = 0;
13688 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
13689 num_of_scs_desc + 1);
13690 }
13691
13692 if (wpa_command(intf, buf) != 0) {
13693 send_resp(dut, conn, SIGMA_ERROR,
13694 "ErrorCode,Failed to send SCS frame request");
13695 return STATUS_SENT_ERROR;
13696 }
13697
13698 sigma_dut_print(dut, DUT_MSG_DEBUG,
13699 "SCS frame request sent: %s", buf);
13700
13701 return SUCCESS_SEND_STATUS;
13702fail:
13703 sigma_dut_print(dut, DUT_MSG_ERROR,
13704 "Failed to create SCS frame request");
13705 return ERROR_SEND_STATUS;
13706}
13707
13708
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013709static enum sigma_cmd_result
13710cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
13711 const char *intf, struct sigma_cmd *cmd)
13712{
13713 char buf[128], *pos;
13714 const char *val, *classifier_type = "04", *type;
13715 int len, rem_len;
13716 u8 up_bitmap;
13717
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013718 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013719 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013720 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013721 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013722 return INVALID_SEND_STATUS;
13723 }
13724
13725 rem_len = sizeof(buf);
13726 pos = buf;
13727 if (strcasecmp(type, "add") == 0) {
13728 len = snprintf(pos, rem_len, "MSCS add");
13729 } else if (strcasecmp(type, "update") == 0) {
13730 len = snprintf(pos, rem_len, "MSCS change");
13731 } else if (strcasecmp(type, "remove") == 0) {
13732 if (wpa_command(intf, "MSCS remove") != 0) {
13733 send_resp(dut, conn, SIGMA_ERROR,
13734 "ErrorCode,Failed to send MSCS frame req");
13735 return STATUS_SENT_ERROR;
13736 }
13737 return SUCCESS_SEND_STATUS;
13738 } else {
13739 sigma_dut_print(dut, DUT_MSG_ERROR,
13740 "%s: request type invalid", __func__);
13741 return INVALID_SEND_STATUS;
13742 }
13743
13744 if (len < 0 || len >= rem_len)
13745 goto fail;
13746
13747 pos += len;
13748 rem_len -= len;
13749
13750 val = get_param(cmd, "User_Priority_Bitmap");
13751 if (!val) {
13752 sigma_dut_print(dut, DUT_MSG_ERROR,
13753 "%s: user priority bitmap empty", __func__);
13754 return INVALID_SEND_STATUS;
13755 }
13756
13757 switch (atoi(val)) {
13758 case 0:
13759 up_bitmap = 0x00;
13760 break;
13761 case 1:
13762 up_bitmap = 0xF0;
13763 break;
13764 case 2:
13765 up_bitmap = 0xF6;
13766 break;
13767 default:
13768 sigma_dut_print(dut, DUT_MSG_ERROR,
13769 "%s: Unknown User_Priority_Bitmap value %d",
13770 __func__, atoi(val));
13771 return INVALID_SEND_STATUS;
13772 }
13773
13774 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
13775 if (len < 0 || len >= rem_len)
13776 goto fail;
13777
13778 pos += len;
13779 rem_len -= len;
13780
13781 val = get_param(cmd, "User_Priority_Limit");
13782 if (!val) {
13783 sigma_dut_print(dut, DUT_MSG_ERROR,
13784 "%s: invalid user priority limit", __func__);
13785 return INVALID_SEND_STATUS;
13786 }
13787
13788 len = snprintf(pos, rem_len, " up_limit=%s", val);
13789 if (len < 0 || len >= rem_len)
13790 goto fail;
13791
13792 pos += len;
13793 rem_len -= len;
13794
13795 val = get_param(cmd, "Stream_Timeout");
13796 if (!val)
13797 val = get_param(cmd, "Stream_Timtout");
13798 if (!val) {
13799 sigma_dut_print(dut, DUT_MSG_ERROR,
13800 "%s: invalid stream timeout", __func__);
13801 return INVALID_SEND_STATUS;
13802 }
13803
13804 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
13805 if (len < 0 || len >= rem_len)
13806 goto fail;
13807
13808 pos += len;
13809 rem_len -= len;
13810
13811 val = get_param(cmd, "TCLAS_Mask");
13812 if (!val) {
13813 sigma_dut_print(dut, DUT_MSG_ERROR,
13814 "%s: invalid tclas mask", __func__);
13815 return INVALID_SEND_STATUS;
13816 }
13817
13818 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
13819 classifier_type, strtol(val, NULL, 2), 0);
13820 if (len < 0 || len >= rem_len)
13821 goto fail;
13822
13823 if (wpa_command(intf, buf) != 0) {
13824 send_resp(dut, conn, SIGMA_ERROR,
13825 "ErrorCode,Failed to send MSCS frame req");
13826 return STATUS_SENT_ERROR;
13827 }
13828
13829 sigma_dut_print(dut, DUT_MSG_DEBUG,
13830 "MSCS frame request sent: %s", buf);
13831
13832 return SUCCESS_SEND_STATUS;
13833fail:
13834 sigma_dut_print(dut, DUT_MSG_ERROR,
13835 "Failed to create MSCS frame req");
13836 return ERROR_SEND_STATUS;
13837}
13838
13839
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013840static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013841cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13842 const char *intf, struct sigma_cmd *cmd)
13843{
13844 char buf[150], *pos;
13845 const char *val;
13846 int len, rem_len;
13847
13848 rem_len = sizeof(buf);
13849 pos = buf;
13850
13851 len = snprintf(pos, rem_len, "DSCP_QUERY");
13852 if (len < 0 || len >= rem_len)
13853 goto fail;
13854
13855 pos += len;
13856 rem_len -= len;
13857
13858 val = get_param(cmd, "Wildcard");
13859 if (val && strcasecmp(val, "Yes") == 0) {
13860 len = snprintf(pos, rem_len, " wildcard");
13861 if (len < 0 || len >= rem_len)
13862 goto fail;
13863 } else if (strlen(dut->qm_domain_name)) {
13864 len = snprintf(pos, rem_len, " domain_name=%s",
13865 dut->qm_domain_name);
13866 if (len < 0 || len >= rem_len)
13867 goto fail;
13868 } else {
13869 sigma_dut_print(dut, DUT_MSG_ERROR,
13870 "Invalid DSCP Query configuration");
13871 return INVALID_SEND_STATUS;
13872 }
13873
13874 if (wpa_command(intf, buf) != 0) {
13875 send_resp(dut, conn, SIGMA_ERROR,
13876 "ErrorCode,Failed to send DSCP policy query frame");
13877 return STATUS_SENT_ERROR;
13878 }
13879
13880 sigma_dut_print(dut, DUT_MSG_DEBUG,
13881 "DSCP policy query frame sent: %s", buf);
13882 return SUCCESS_SEND_STATUS;
13883fail:
13884 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
13885 return ERROR_SEND_STATUS;
13886}
13887
13888
13889static enum sigma_cmd_result
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013890cmd_sta_send_frame_dscp_response(struct sigma_dut *dut, struct sigma_conn *conn,
13891 const char *intf, struct sigma_cmd *cmd)
13892{
13893 char buf[256], *pos, *item, *list, *saveptr;
13894 const char *val;
13895 int len, rem_len;
13896
13897 pos = buf;
13898 rem_len = sizeof(buf);
13899
13900 len = snprintf(pos, rem_len, "DSCP_RESP");
13901 if (snprintf_error(rem_len, len)) {
13902 sigma_dut_print(dut, DUT_MSG_ERROR,
13903 "Failed to create DSCP Policy Response command");
13904 return ERROR_SEND_STATUS;
13905 }
13906
13907 pos += len;
13908 rem_len -= len;
13909
13910 val = get_param(cmd, "PolicyID_List");
13911 if (!val) {
13912 sigma_dut_print(dut, DUT_MSG_ERROR,
13913 "DSCP policy ID list missing");
13914 return INVALID_SEND_STATUS;
13915 }
13916
13917 list = strdup(val);
13918 if (!list)
13919 return ERROR_SEND_STATUS;
13920
13921 item = strtok_r(list, "_", &saveptr);
13922 while (item) {
13923 unsigned int i;
13924 int policy_id = atoi(item);
13925
13926 for (i = 0; i < dut->num_dscp_status; i++)
13927 if (dut->dscp_status[i].id == policy_id)
13928 break;
13929
13930 if (i == dut->num_dscp_status) {
13931 free(list);
13932 send_resp(dut, conn, SIGMA_ERROR,
13933 "ErrorCode,DSCP policy id not found in status list");
13934 return STATUS_SENT_ERROR;
13935 }
13936
13937 len = snprintf(pos, rem_len, " policy_id=%d status=%d",
13938 policy_id, dut->dscp_status[i].status);
13939 if (snprintf_error(rem_len, len)) {
13940 free(list);
13941 sigma_dut_print(dut, DUT_MSG_ERROR,
13942 "Failed to write DSCP policy list");
13943 return ERROR_SEND_STATUS;
13944 }
13945
13946 pos += len;
13947 rem_len -= len;
13948
13949 if (dut->dscp_status[i].status)
13950 remove_dscp_policy(dut, policy_id);
13951
13952 item = strtok_r(NULL, "_", &saveptr);
13953 }
13954
13955 free(list);
13956
13957 if (wpa_command(intf, buf) != 0) {
13958 send_resp(dut, conn, SIGMA_ERROR,
13959 "ErrorCode,Failed to send DSCP Policy Response frame");
13960 return STATUS_SENT_ERROR;
13961 }
13962
13963 sigma_dut_print(dut, DUT_MSG_DEBUG,
13964 "DSCP Policy Response frame sent: %s", buf);
13965 return SUCCESS_SEND_STATUS;
13966}
13967
13968
13969static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013970cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
13971 const char *intf, struct sigma_cmd *cmd)
13972{
13973 const char *val;
13974
13975 val = get_param(cmd, "FrameName");
13976 if (val) {
13977 if (strcasecmp(val, "MSCSReq") == 0)
13978 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
13979 if (strcasecmp(val, "SCSReq") == 0)
13980 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013981 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
13982 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
13983 cmd);
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013984 if (strcasecmp(val, "DSCPPolicyResponse") == 0)
13985 return cmd_sta_send_frame_dscp_response(dut, conn, intf,
13986 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013987
13988 sigma_dut_print(dut, DUT_MSG_ERROR,
13989 "%s: frame name - %s is invalid",
13990 __func__, val);
13991 }
13992
13993 return INVALID_SEND_STATUS;
13994}
13995
13996
Jouni Malinenf7222712019-06-13 01:50:21 +030013997enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
13998 struct sigma_conn *conn,
13999 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014000{
14001 const char *intf = get_param(cmd, "Interface");
14002 const char *val;
14003 enum send_frame_type frame;
14004 enum send_frame_protection protected;
14005 char buf[100];
14006 unsigned char addr[ETH_ALEN];
14007 int res;
14008
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030014009 if (!intf)
14010 return -1;
14011
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014012 val = get_param(cmd, "program");
14013 if (val == NULL)
14014 val = get_param(cmd, "frame");
14015 if (val && strcasecmp(val, "TDLS") == 0)
14016 return cmd_sta_send_frame_tdls(dut, conn, cmd);
14017 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014018 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014019 strcasecmp(val, "HS2-R3") == 0 ||
14020 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014021 return cmd_sta_send_frame_hs2(dut, conn, cmd);
14022 if (val && strcasecmp(val, "VHT") == 0)
14023 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070014024 if (val && strcasecmp(val, "HE") == 0)
14025 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070014026 if (val && strcasecmp(val, "LOC") == 0)
14027 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020014028 if (val && strcasecmp(val, "60GHz") == 0)
14029 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053014030 if (val && strcasecmp(val, "MBO") == 0) {
14031 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
14032 if (res != 2)
14033 return res;
14034 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053014035 if (val && strcasecmp(val, "WPA3") == 0)
14036 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053014037 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053014038 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014039
14040 val = get_param(cmd, "TD_DISC");
14041 if (val) {
14042 if (hwaddr_aton(val, addr) < 0)
14043 return -1;
14044 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
14045 if (wpa_command(intf, buf) < 0) {
14046 send_resp(dut, conn, SIGMA_ERROR,
14047 "ErrorCode,Failed to send TDLS discovery");
14048 return 0;
14049 }
14050 return 1;
14051 }
14052
14053 val = get_param(cmd, "TD_Setup");
14054 if (val) {
14055 if (hwaddr_aton(val, addr) < 0)
14056 return -1;
14057 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
14058 if (wpa_command(intf, buf) < 0) {
14059 send_resp(dut, conn, SIGMA_ERROR,
14060 "ErrorCode,Failed to start TDLS setup");
14061 return 0;
14062 }
14063 return 1;
14064 }
14065
14066 val = get_param(cmd, "TD_TearDown");
14067 if (val) {
14068 if (hwaddr_aton(val, addr) < 0)
14069 return -1;
14070 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
14071 if (wpa_command(intf, buf) < 0) {
14072 send_resp(dut, conn, SIGMA_ERROR,
14073 "ErrorCode,Failed to tear down TDLS link");
14074 return 0;
14075 }
14076 return 1;
14077 }
14078
14079 val = get_param(cmd, "TD_ChannelSwitch");
14080 if (val) {
14081 /* TODO */
14082 send_resp(dut, conn, SIGMA_ERROR,
14083 "ErrorCode,TD_ChannelSwitch not yet supported");
14084 return 0;
14085 }
14086
14087 val = get_param(cmd, "TD_NF");
14088 if (val) {
14089 /* TODO */
14090 send_resp(dut, conn, SIGMA_ERROR,
14091 "ErrorCode,TD_NF not yet supported");
14092 return 0;
14093 }
14094
14095 val = get_param(cmd, "PMFFrameType");
14096 if (val == NULL)
14097 val = get_param(cmd, "FrameName");
14098 if (val == NULL)
14099 val = get_param(cmd, "Type");
14100 if (val == NULL)
14101 return -1;
14102 if (strcasecmp(val, "disassoc") == 0)
14103 frame = DISASSOC;
14104 else if (strcasecmp(val, "deauth") == 0)
14105 frame = DEAUTH;
14106 else if (strcasecmp(val, "saquery") == 0)
14107 frame = SAQUERY;
14108 else if (strcasecmp(val, "auth") == 0)
14109 frame = AUTH;
14110 else if (strcasecmp(val, "assocreq") == 0)
14111 frame = ASSOCREQ;
14112 else if (strcasecmp(val, "reassocreq") == 0)
14113 frame = REASSOCREQ;
14114 else if (strcasecmp(val, "neigreq") == 0) {
14115 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
14116
14117 val = get_param(cmd, "ssid");
14118 if (val == NULL)
14119 return -1;
14120
14121 res = send_neighbor_request(dut, intf, val);
14122 if (res) {
14123 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14124 "Failed to send neighbor report request");
14125 return 0;
14126 }
14127
14128 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053014129 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
14130 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014131 sigma_dut_print(dut, DUT_MSG_DEBUG,
14132 "Got Transition Management Query");
14133
Ashwini Patil5acd7382017-04-13 15:55:04 +053014134 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014135 if (res) {
14136 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14137 "Failed to send Transition Management Query");
14138 return 0;
14139 }
14140
14141 return 1;
14142 } else {
14143 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14144 "PMFFrameType");
14145 return 0;
14146 }
14147
14148 val = get_param(cmd, "PMFProtected");
14149 if (val == NULL)
14150 val = get_param(cmd, "Protected");
14151 if (val == NULL)
14152 return -1;
14153 if (strcasecmp(val, "Correct-key") == 0 ||
14154 strcasecmp(val, "CorrectKey") == 0)
14155 protected = CORRECT_KEY;
14156 else if (strcasecmp(val, "IncorrectKey") == 0)
14157 protected = INCORRECT_KEY;
14158 else if (strcasecmp(val, "Unprotected") == 0)
14159 protected = UNPROTECTED;
14160 else {
14161 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14162 "PMFProtected");
14163 return 0;
14164 }
14165
14166 if (protected != UNPROTECTED &&
14167 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
14168 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
14169 "PMFProtected for auth/assocreq/reassocreq");
14170 return 0;
14171 }
14172
14173 if (if_nametoindex("sigmadut") == 0) {
14174 snprintf(buf, sizeof(buf),
14175 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014176 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014177 if (system(buf) != 0 ||
14178 if_nametoindex("sigmadut") == 0) {
14179 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
14180 "monitor interface with '%s'", buf);
14181 return -2;
14182 }
14183 }
14184
14185 if (system("ifconfig sigmadut up") != 0) {
14186 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
14187 "monitor interface up");
14188 return -2;
14189 }
14190
Veerendranath Jakkam49774122020-07-05 09:52:18 +053014191 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014192}
14193
14194
14195static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
14196 struct sigma_conn *conn,
14197 struct sigma_cmd *cmd,
14198 const char *ifname)
14199{
14200 char buf[200];
14201 const char *val;
14202
14203 val = get_param(cmd, "ClearARP");
14204 if (val && atoi(val) == 1) {
14205 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
14206 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14207 if (system(buf) != 0) {
14208 send_resp(dut, conn, SIGMA_ERROR,
14209 "errorCode,Failed to clear ARP cache");
14210 return 0;
14211 }
14212 }
14213
14214 return 1;
14215}
14216
14217
14218int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
14219 struct sigma_cmd *cmd)
14220{
14221 const char *intf = get_param(cmd, "Interface");
14222 const char *val;
14223
14224 if (intf == NULL)
14225 return -1;
14226
14227 val = get_param(cmd, "program");
14228 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014229 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014230 strcasecmp(val, "HS2-R3") == 0 ||
14231 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014232 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
14233
14234 return -1;
14235}
14236
14237
Jouni Malinenf7222712019-06-13 01:50:21 +030014238static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
14239 struct sigma_conn *conn,
14240 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014241{
14242 const char *intf = get_param(cmd, "Interface");
14243 const char *mac = get_param(cmd, "MAC");
14244
14245 if (intf == NULL || mac == NULL)
14246 return -1;
14247
14248 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
14249 "interface %s to %s", intf, mac);
14250
14251 if (dut->set_macaddr) {
14252 char buf[128];
14253 int res;
14254 if (strcasecmp(mac, "default") == 0) {
14255 res = snprintf(buf, sizeof(buf), "%s",
14256 dut->set_macaddr);
14257 dut->tmp_mac_addr = 0;
14258 } else {
14259 res = snprintf(buf, sizeof(buf), "%s %s",
14260 dut->set_macaddr, mac);
14261 dut->tmp_mac_addr = 1;
14262 }
14263 if (res < 0 || res >= (int) sizeof(buf))
14264 return -1;
14265 if (system(buf) != 0) {
14266 send_resp(dut, conn, SIGMA_ERROR,
14267 "errorCode,Failed to set MAC "
14268 "address");
14269 return 0;
14270 }
14271 return 1;
14272 }
14273
14274 if (strcasecmp(mac, "default") == 0)
14275 return 1;
14276
14277 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14278 "command");
14279 return 0;
14280}
14281
14282
14283static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
14284 struct sigma_conn *conn, const char *intf,
14285 int val)
14286{
14287 char buf[200];
14288 int res;
14289
14290 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
14291 intf, val);
14292 if (res < 0 || res >= (int) sizeof(buf))
14293 return -1;
14294 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14295 if (system(buf) != 0) {
14296 send_resp(dut, conn, SIGMA_ERROR,
14297 "errorCode,Failed to configure offchannel mode");
14298 return 0;
14299 }
14300
14301 return 1;
14302}
14303
14304
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014305static int off_chan_val(enum sec_ch_offset off)
14306{
14307 switch (off) {
14308 case SEC_CH_NO:
14309 return 0;
14310 case SEC_CH_40ABOVE:
14311 return 40;
14312 case SEC_CH_40BELOW:
14313 return -40;
14314 }
14315
14316 return 0;
14317}
14318
14319
14320static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
14321 const char *intf, int off_ch_num,
14322 enum sec_ch_offset sec)
14323{
14324 char buf[200];
14325 int res;
14326
14327 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
14328 intf, off_ch_num);
14329 if (res < 0 || res >= (int) sizeof(buf))
14330 return -1;
14331 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14332 if (system(buf) != 0) {
14333 send_resp(dut, conn, SIGMA_ERROR,
14334 "errorCode,Failed to set offchan");
14335 return 0;
14336 }
14337
14338 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
14339 intf, off_chan_val(sec));
14340 if (res < 0 || res >= (int) sizeof(buf))
14341 return -1;
14342 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14343 if (system(buf) != 0) {
14344 send_resp(dut, conn, SIGMA_ERROR,
14345 "errorCode,Failed to set sec chan offset");
14346 return 0;
14347 }
14348
14349 return 1;
14350}
14351
14352
14353static int tdls_set_offchannel_offset(struct sigma_dut *dut,
14354 struct sigma_conn *conn,
14355 const char *intf, int off_ch_num,
14356 enum sec_ch_offset sec)
14357{
14358 char buf[200];
14359 int res;
14360
14361 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
14362 off_ch_num);
14363 if (res < 0 || res >= (int) sizeof(buf))
14364 return -1;
14365 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14366
14367 if (wpa_command(intf, buf) < 0) {
14368 send_resp(dut, conn, SIGMA_ERROR,
14369 "ErrorCode,Failed to set offchan");
14370 return 0;
14371 }
14372 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
14373 off_chan_val(sec));
14374 if (res < 0 || res >= (int) sizeof(buf))
14375 return -1;
14376
14377 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14378
14379 if (wpa_command(intf, buf) < 0) {
14380 send_resp(dut, conn, SIGMA_ERROR,
14381 "ErrorCode,Failed to set sec chan offset");
14382 return 0;
14383 }
14384
14385 return 1;
14386}
14387
14388
14389static int tdls_set_offchannel_mode(struct sigma_dut *dut,
14390 struct sigma_conn *conn,
14391 const char *intf, int val)
14392{
14393 char buf[200];
14394 int res;
14395
14396 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
14397 val);
14398 if (res < 0 || res >= (int) sizeof(buf))
14399 return -1;
14400 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14401
14402 if (wpa_command(intf, buf) < 0) {
14403 send_resp(dut, conn, SIGMA_ERROR,
14404 "ErrorCode,Failed to configure offchannel mode");
14405 return 0;
14406 }
14407
14408 return 1;
14409}
14410
14411
14412static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
14413 struct sigma_conn *conn,
14414 struct sigma_cmd *cmd)
14415{
14416 const char *val;
14417 enum {
14418 CHSM_NOT_SET,
14419 CHSM_ENABLE,
14420 CHSM_DISABLE,
14421 CHSM_REJREQ,
14422 CHSM_UNSOLRESP
14423 } chsm = CHSM_NOT_SET;
14424 int off_ch_num = -1;
14425 enum sec_ch_offset sec_ch = SEC_CH_NO;
14426 int res;
14427
14428 val = get_param(cmd, "Uapsd");
14429 if (val) {
14430 char buf[100];
14431 if (strcasecmp(val, "Enable") == 0)
14432 snprintf(buf, sizeof(buf), "SET ps 99");
14433 else if (strcasecmp(val, "Disable") == 0)
14434 snprintf(buf, sizeof(buf), "SET ps 98");
14435 else {
14436 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14437 "Unsupported uapsd parameter value");
14438 return 0;
14439 }
14440 if (wpa_command(intf, buf)) {
14441 send_resp(dut, conn, SIGMA_ERROR,
14442 "ErrorCode,Failed to change U-APSD "
14443 "powersave mode");
14444 return 0;
14445 }
14446 }
14447
14448 val = get_param(cmd, "TPKTIMER");
14449 if (val && strcasecmp(val, "DISABLE") == 0) {
14450 if (wpa_command(intf, "SET tdls_testing 0x100")) {
14451 send_resp(dut, conn, SIGMA_ERROR,
14452 "ErrorCode,Failed to enable no TPK "
14453 "expiration test mode");
14454 return 0;
14455 }
14456 dut->no_tpk_expiration = 1;
14457 }
14458
14459 val = get_param(cmd, "ChSwitchMode");
14460 if (val) {
14461 if (strcasecmp(val, "Enable") == 0 ||
14462 strcasecmp(val, "Initiate") == 0)
14463 chsm = CHSM_ENABLE;
14464 else if (strcasecmp(val, "Disable") == 0 ||
14465 strcasecmp(val, "passive") == 0)
14466 chsm = CHSM_DISABLE;
14467 else if (strcasecmp(val, "RejReq") == 0)
14468 chsm = CHSM_REJREQ;
14469 else if (strcasecmp(val, "UnSolResp") == 0)
14470 chsm = CHSM_UNSOLRESP;
14471 else {
14472 send_resp(dut, conn, SIGMA_ERROR,
14473 "ErrorCode,Unknown ChSwitchMode value");
14474 return 0;
14475 }
14476 }
14477
14478 val = get_param(cmd, "OffChNum");
14479 if (val) {
14480 off_ch_num = atoi(val);
14481 if (off_ch_num == 0) {
14482 send_resp(dut, conn, SIGMA_ERROR,
14483 "ErrorCode,Invalid OffChNum");
14484 return 0;
14485 }
14486 }
14487
14488 val = get_param(cmd, "SecChOffset");
14489 if (val) {
14490 if (strcmp(val, "20") == 0)
14491 sec_ch = SEC_CH_NO;
14492 else if (strcasecmp(val, "40above") == 0)
14493 sec_ch = SEC_CH_40ABOVE;
14494 else if (strcasecmp(val, "40below") == 0)
14495 sec_ch = SEC_CH_40BELOW;
14496 else {
14497 send_resp(dut, conn, SIGMA_ERROR,
14498 "ErrorCode,Unknown SecChOffset value");
14499 return 0;
14500 }
14501 }
14502
14503 if (chsm == CHSM_NOT_SET) {
14504 /* no offchannel changes requested */
14505 return 1;
14506 }
14507
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014508 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
14509 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014510 send_resp(dut, conn, SIGMA_ERROR,
14511 "ErrorCode,Unknown interface");
14512 return 0;
14513 }
14514
14515 switch (chsm) {
14516 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030014517 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014518 break;
14519 case CHSM_ENABLE:
14520 if (off_ch_num < 0) {
14521 send_resp(dut, conn, SIGMA_ERROR,
14522 "ErrorCode,Missing OffChNum argument");
14523 return 0;
14524 }
14525 if (wifi_chip_type == DRIVER_WCN) {
14526 res = tdls_set_offchannel_offset(dut, conn, intf,
14527 off_ch_num, sec_ch);
14528 } else {
14529 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14530 sec_ch);
14531 }
14532 if (res != 1)
14533 return res;
14534 if (wifi_chip_type == DRIVER_WCN)
14535 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
14536 else
14537 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
14538 break;
14539 case CHSM_DISABLE:
14540 if (wifi_chip_type == DRIVER_WCN)
14541 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
14542 else
14543 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
14544 break;
14545 case CHSM_REJREQ:
14546 if (wifi_chip_type == DRIVER_WCN)
14547 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
14548 else
14549 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
14550 break;
14551 case CHSM_UNSOLRESP:
14552 if (off_ch_num < 0) {
14553 send_resp(dut, conn, SIGMA_ERROR,
14554 "ErrorCode,Missing OffChNum argument");
14555 return 0;
14556 }
14557 if (wifi_chip_type == DRIVER_WCN) {
14558 res = tdls_set_offchannel_offset(dut, conn, intf,
14559 off_ch_num, sec_ch);
14560 } else {
14561 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14562 sec_ch);
14563 }
14564 if (res != 1)
14565 return res;
14566 if (wifi_chip_type == DRIVER_WCN)
14567 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
14568 else
14569 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
14570 break;
14571 }
14572
14573 return res;
14574}
14575
14576
14577static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14578 struct sigma_conn *conn,
14579 struct sigma_cmd *cmd)
14580{
14581 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014582 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014583
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070014584 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080014585
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014586 val = get_param(cmd, "nss_mcs_opt");
14587 if (val) {
14588 /* String (nss_operating_mode; mcs_operating_mode) */
14589 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014590 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014591
14592 token = strdup(val);
14593 if (!token)
14594 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014595 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014596 if (!result) {
14597 sigma_dut_print(dut, DUT_MSG_ERROR,
14598 "VHT NSS not specified");
14599 goto failed;
14600 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014601 if (strcasecmp(result, "def") != 0) {
14602 nss = atoi(result);
14603 if (nss == 4)
14604 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014605 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014606 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014607
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014608 }
14609
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014610 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014611 if (!result) {
14612 sigma_dut_print(dut, DUT_MSG_ERROR,
14613 "VHT MCS not specified");
14614 goto failed;
14615 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014616 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014617 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014618 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014619 } else {
14620 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014621 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014622 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014623 }
14624 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014625 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014626 }
14627
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014628 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014629 return 1;
14630failed:
14631 free(token);
14632 return 0;
14633}
14634
14635
14636static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14637 struct sigma_conn *conn,
14638 struct sigma_cmd *cmd)
14639{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014640 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014641 case DRIVER_ATHEROS:
14642 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
14643 default:
14644 send_resp(dut, conn, SIGMA_ERROR,
14645 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
14646 return 0;
14647 }
14648}
14649
14650
Jouni Malinen1702fe32021-06-08 19:08:01 +030014651static enum sigma_cmd_result
14652wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14653 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014654{
14655 const char *val;
14656 char *token = NULL, *result;
14657 char buf[60];
14658
14659 val = get_param(cmd, "nss_mcs_opt");
14660 if (val) {
14661 /* String (nss_operating_mode; mcs_operating_mode) */
14662 int nss, mcs, ratecode;
14663 char *saveptr;
14664
14665 token = strdup(val);
14666 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014667 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014668
14669 result = strtok_r(token, ";", &saveptr);
14670 if (!result) {
14671 sigma_dut_print(dut, DUT_MSG_ERROR,
14672 "HE NSS not specified");
14673 goto failed;
14674 }
14675 nss = 1;
14676 if (strcasecmp(result, "def") != 0)
14677 nss = atoi(result);
14678
14679 result = strtok_r(NULL, ";", &saveptr);
14680 if (!result) {
14681 sigma_dut_print(dut, DUT_MSG_ERROR,
14682 "HE MCS not specified");
14683 goto failed;
14684 }
14685 mcs = 7;
14686 if (strcasecmp(result, "def") != 0)
14687 mcs = atoi(result);
14688
Arif Hussain557bf412018-05-25 17:29:36 -070014689 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014690 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070014691 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014692 } else if (nss > 2) {
14693 sigma_dut_print(dut, DUT_MSG_ERROR,
14694 "HE NSS %d not supported", nss);
14695 goto failed;
14696 }
14697
Arif Hussain557bf412018-05-25 17:29:36 -070014698 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
14699 if (system(buf) != 0) {
14700 sigma_dut_print(dut, DUT_MSG_ERROR,
14701 "nss_mcs_opt: iwpriv %s nss %d failed",
14702 intf, nss);
14703 goto failed;
14704 }
Arif Hussainac6c5112018-05-25 17:34:00 -070014705 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070014706
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014707 /* Add the MCS to the ratecode */
14708 if (mcs >= 0 && mcs <= 11) {
14709 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070014710#ifdef NL80211_SUPPORT
14711 if (dut->device_type == STA_testbed) {
14712 enum he_mcs_config mcs_config;
14713 int ret;
14714
14715 if (mcs <= 7)
14716 mcs_config = HE_80_MCS0_7;
14717 else if (mcs <= 9)
14718 mcs_config = HE_80_MCS0_9;
14719 else
14720 mcs_config = HE_80_MCS0_11;
14721 ret = sta_set_he_mcs(dut, intf, mcs_config);
14722 if (ret) {
14723 sigma_dut_print(dut, DUT_MSG_ERROR,
14724 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
14725 mcs, mcs_config, ret);
14726 goto failed;
14727 }
14728 }
14729#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014730 } else {
14731 sigma_dut_print(dut, DUT_MSG_ERROR,
14732 "HE MCS %d not supported", mcs);
14733 goto failed;
14734 }
14735 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
14736 intf, ratecode);
14737 if (system(buf) != 0) {
14738 sigma_dut_print(dut, DUT_MSG_ERROR,
14739 "iwpriv setting of 11ax rates failed");
14740 goto failed;
14741 }
14742 free(token);
14743 }
14744
14745 val = get_param(cmd, "GI");
14746 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014747 int fix_rate_sgi;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014748 u8 he_gi_val = 0;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014749
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014750 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014751 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014752 fix_rate_sgi = 1;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014753 he_gi_val = NL80211_RATE_INFO_HE_GI_0_8;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014754 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014755 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
14756 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014757 fix_rate_sgi = 2;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014758 he_gi_val = NL80211_RATE_INFO_HE_GI_1_6;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014759 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014760 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
14761 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014762 fix_rate_sgi = 3;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014763 he_gi_val = NL80211_RATE_INFO_HE_GI_3_2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014764 } else {
14765 send_resp(dut, conn, SIGMA_ERROR,
14766 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014767 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014768 }
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014769 if (wcn_set_he_gi(dut, intf, he_gi_val)) {
14770 sigma_dut_print(dut, DUT_MSG_INFO,
14771 "wcn_set_he_gi failed, using iwpriv");
14772 if (system(buf) != 0) {
14773 send_resp(dut, conn, SIGMA_ERROR,
14774 "errorCode,Failed to set shortgi");
14775 return STATUS_SENT_ERROR;
14776 }
14777 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
14778 intf, fix_rate_sgi);
14779 if (system(buf) != 0) {
14780 send_resp(dut, conn, SIGMA_ERROR,
14781 "errorCode,Failed to set fix rate shortgi");
14782 return STATUS_SENT_ERROR;
14783 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014784 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014785 }
14786
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014787 val = get_param(cmd, "LTF");
14788 if (val) {
14789#ifdef NL80211_SUPPORT
14790 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014791 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014792 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014793 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014794 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014795 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014796 } else {
14797 send_resp(dut, conn, SIGMA_ERROR,
14798 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014799 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014800 }
14801#else /* NL80211_SUPPORT */
14802 sigma_dut_print(dut, DUT_MSG_ERROR,
14803 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014804 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014805#endif /* NL80211_SUPPORT */
14806 }
14807
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070014808 val = get_param(cmd, "KeepAlive");
14809 if (val) {
14810 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
14811
14812 if (strcasecmp(val, "Data") == 0)
14813 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
14814 else if (strcasecmp(val, "Mgmt") == 0)
14815 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
14816
14817 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
14818 send_resp(dut, conn, SIGMA_ERROR,
14819 "ErrorCode,Failed to set keep alive type config");
14820 return STATUS_SENT_ERROR;
14821 }
14822 }
14823
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014824 val = get_param(cmd, "TxSUPPDU");
14825 if (val) {
14826 int set_val = 1;
14827
14828 if (strcasecmp(val, "Enable") == 0)
14829 set_val = 1;
14830 else if (strcasecmp(val, "Disable") == 0)
14831 set_val = 0;
14832
14833 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
14834 send_resp(dut, conn, SIGMA_ERROR,
14835 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014836 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014837 }
14838 }
14839
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070014840 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
14841 if (val) {
14842 int set_val = 0;
14843
14844 if (strcasecmp(val, "Enable") == 0)
14845 set_val = 0;
14846 else if (strcasecmp(val, "Disable") == 0)
14847 set_val = 1;
14848
14849 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
14850 send_resp(dut, conn, SIGMA_ERROR,
14851 "ErrorCode,Failed to set mgmt/data Tx disable config");
14852 return STATUS_SENT_ERROR;
14853 }
14854 }
14855
Arif Hussain480d5f42019-03-12 14:40:42 -070014856 val = get_param(cmd, "TWT_Setup");
14857 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014858#ifdef NL80211_SUPPORT
14859 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14860 sigma_dut_print(dut, DUT_MSG_ERROR,
14861 "Failed to open nl80211 event socket");
14862#endif /* NL80211_SUPPORT */
Arif Hussain480d5f42019-03-12 14:40:42 -070014863 if (strcasecmp(val, "Request") == 0) {
Kiran Kumar Lokereafac46a2021-11-29 14:03:20 -080014864 if (set_power_save_wcn(dut, intf, 1) < 0)
14865 sigma_dut_print(dut, DUT_MSG_ERROR,
14866 "Failed to enable power save");
Arif Hussain480d5f42019-03-12 14:40:42 -070014867 if (sta_twt_request(dut, conn, cmd)) {
14868 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014869 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014870 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014871 }
14872 } else if (strcasecmp(val, "Teardown") == 0) {
14873 if (sta_twt_teardown(dut, conn, cmd)) {
14874 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014875 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014876 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014877 }
14878 }
14879 }
14880
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014881 val = get_param(cmd, "TWT_Operation");
14882 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014883#ifdef NL80211_SUPPORT
14884 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14885 sigma_dut_print(dut, DUT_MSG_ERROR,
14886 "Failed to open nl80211 event socket");
14887#endif /* NL80211_SUPPORT */
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014888 if (strcasecmp(val, "Suspend") == 0) {
14889 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
14890 send_resp(dut, conn, SIGMA_ERROR,
14891 "ErrorCode,TWT suspend failed");
14892 return STATUS_SENT_ERROR;
14893 }
14894 } else if (strcasecmp(val, "Resume") == 0) {
14895 if (sta_twt_resume(dut, conn, cmd)) {
14896 send_resp(dut, conn, SIGMA_ERROR,
14897 "ErrorCode,TWT resume failed");
14898 return STATUS_SENT_ERROR;
14899 }
14900 }
14901 }
14902
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080014903 val = get_param(cmd, "transmitOMI");
14904 if (val && sta_transmit_omi(dut, conn, cmd)) {
14905 send_resp(dut, conn, SIGMA_ERROR,
14906 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014907 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070014908 }
14909
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014910 val = get_param(cmd, "Powersave");
14911 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014912 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014913
14914 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014915 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014916 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014917 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014918 } else {
14919 sigma_dut_print(dut, DUT_MSG_ERROR,
14920 "Unsupported Powersave value '%s'",
14921 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014922 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014923 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014924 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014925 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014926 }
14927
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080014928 val = get_param(cmd, "MU_EDCA");
14929 if (val) {
14930 if (strcasecmp(val, "Override") == 0) {
14931 if (sta_set_mu_edca_override(dut, intf, 1)) {
14932 send_resp(dut, conn, SIGMA_ERROR,
14933 "errorCode,MU EDCA override set failed");
14934 return STATUS_SENT;
14935 }
14936 } else if (strcasecmp(val, "Disable") == 0) {
14937 if (sta_set_mu_edca_override(dut, intf, 0)) {
14938 send_resp(dut, conn, SIGMA_ERROR,
14939 "errorCode,MU EDCA override disable failed");
14940 return STATUS_SENT;
14941 }
14942 }
14943 }
14944
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070014945 val = get_param(cmd, "RUAllocTone");
14946 if (val && strcasecmp(val, "242") == 0) {
14947 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
14948 send_resp(dut, conn, SIGMA_ERROR,
14949 "ErrorCode,Failed to set RU 242 tone Tx");
14950 return STATUS_SENT_ERROR;
14951 }
14952 }
14953
14954 val = get_param(cmd, "PPDUTxType");
14955 if (val && strcasecmp(val, "ER-SU") == 0) {
14956 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
14957 send_resp(dut, conn, SIGMA_ERROR,
14958 "ErrorCode,Failed to set ER-SU PPDU type Tx");
14959 return STATUS_SENT_ERROR;
14960 }
14961 }
14962
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070014963 val = get_param(cmd, "Ch_Pref");
14964 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14965 return STATUS_SENT;
14966
14967 val = get_param(cmd, "Cellular_Data_Cap");
14968 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14969 return STATUS_SENT;
14970
Jouni Malinen1702fe32021-06-08 19:08:01 +030014971 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014972
14973failed:
14974 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014975 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014976}
14977
14978
Jouni Malinen1702fe32021-06-08 19:08:01 +030014979static enum sigma_cmd_result
14980cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14981 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014982{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014983 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014984 case DRIVER_WCN:
14985 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
14986 default:
14987 send_resp(dut, conn, SIGMA_ERROR,
14988 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014989 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014990 }
14991}
14992
14993
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014994static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
14995 struct sigma_conn *conn,
14996 struct sigma_cmd *cmd)
14997{
14998 const char *val;
14999
15000 val = get_param(cmd, "powersave");
15001 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015002 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015003
15004 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015005 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015006 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015007 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015008 } else {
15009 sigma_dut_print(dut, DUT_MSG_ERROR,
15010 "Unsupported power save config");
15011 return -1;
15012 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015013 if (set_power_save_wcn(dut, intf, ps) < 0)
15014 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015015 return 1;
15016 }
15017
15018 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
15019
15020 return 0;
15021}
15022
15023
Ashwini Patil5acd7382017-04-13 15:55:04 +053015024static int btm_query_candidate_list(struct sigma_dut *dut,
15025 struct sigma_conn *conn,
15026 struct sigma_cmd *cmd)
15027{
15028 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
15029 int len, ret;
15030 char buf[10];
15031
15032 /*
15033 * Neighbor Report elements format:
15034 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
15035 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
15036 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
15037 */
15038
15039 bssid = get_param(cmd, "Nebor_BSSID");
15040 if (!bssid) {
15041 send_resp(dut, conn, SIGMA_INVALID,
15042 "errorCode,Nebor_BSSID is missing");
15043 return 0;
15044 }
15045
15046 info = get_param(cmd, "Nebor_Bssid_Info");
15047 if (!info) {
15048 sigma_dut_print(dut, DUT_MSG_INFO,
15049 "Using default value for Nebor_Bssid_Info: %s",
15050 DEFAULT_NEIGHBOR_BSSID_INFO);
15051 info = DEFAULT_NEIGHBOR_BSSID_INFO;
15052 }
15053
15054 op_class = get_param(cmd, "Nebor_Op_Class");
15055 if (!op_class) {
15056 send_resp(dut, conn, SIGMA_INVALID,
15057 "errorCode,Nebor_Op_Class is missing");
15058 return 0;
15059 }
15060
15061 ch = get_param(cmd, "Nebor_Op_Ch");
15062 if (!ch) {
15063 send_resp(dut, conn, SIGMA_INVALID,
15064 "errorCode,Nebor_Op_Ch is missing");
15065 return 0;
15066 }
15067
15068 phy_type = get_param(cmd, "Nebor_Phy_Type");
15069 if (!phy_type) {
15070 sigma_dut_print(dut, DUT_MSG_INFO,
15071 "Using default value for Nebor_Phy_Type: %s",
15072 DEFAULT_NEIGHBOR_PHY_TYPE);
15073 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
15074 }
15075
15076 /* Parse optional subelements */
15077 buf[0] = '\0';
15078 pref = get_param(cmd, "Nebor_Pref");
15079 if (pref) {
15080 /* hexdump for preferrence subelement */
15081 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
15082 if (ret < 0 || ret >= (int) sizeof(buf)) {
15083 sigma_dut_print(dut, DUT_MSG_ERROR,
15084 "snprintf failed for optional subelement ret: %d",
15085 ret);
15086 send_resp(dut, conn, SIGMA_ERROR,
15087 "errorCode,snprintf failed for subelement");
15088 return 0;
15089 }
15090 }
15091
15092 if (!dut->btm_query_cand_list) {
15093 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
15094 if (!dut->btm_query_cand_list) {
15095 send_resp(dut, conn, SIGMA_ERROR,
15096 "errorCode,Failed to allocate memory for btm_query_cand_list");
15097 return 0;
15098 }
15099 }
15100
15101 len = strlen(dut->btm_query_cand_list);
15102 ret = snprintf(dut->btm_query_cand_list + len,
15103 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
15104 bssid, info, op_class, ch, phy_type, buf);
15105 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
15106 sigma_dut_print(dut, DUT_MSG_ERROR,
15107 "snprintf failed for neighbor report list ret: %d",
15108 ret);
15109 send_resp(dut, conn, SIGMA_ERROR,
15110 "errorCode,snprintf failed for neighbor report");
15111 free(dut->btm_query_cand_list);
15112 dut->btm_query_cand_list = NULL;
15113 return 0;
15114 }
15115
15116 return 1;
15117}
15118
15119
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015120int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
15121 struct sigma_ese_alloc *allocs, int *allocs_size)
15122{
15123 int max_count = *allocs_size;
15124 int count = 0, i;
15125 const char *val;
15126
15127 do {
15128 val = get_param_indexed(cmd, "AllocID", count);
15129 if (val)
15130 count++;
15131 } while (val);
15132
15133 if (count == 0 || count > max_count) {
15134 sigma_dut_print(dut, DUT_MSG_ERROR,
15135 "Invalid number of allocations(%d)", count);
15136 return -1;
15137 }
15138
15139 for (i = 0; i < count; i++) {
15140 val = get_param_indexed(cmd, "PercentBI", i);
15141 if (!val) {
15142 sigma_dut_print(dut, DUT_MSG_ERROR,
15143 "Missing PercentBI parameter at index %d",
15144 i);
15145 return -1;
15146 }
15147 allocs[i].percent_bi = atoi(val);
15148
15149 val = get_param_indexed(cmd, "SrcAID", i);
15150 if (val)
15151 allocs[i].src_aid = strtol(val, NULL, 0);
15152 else
15153 allocs[i].src_aid = ESE_BCAST_AID;
15154
15155 val = get_param_indexed(cmd, "DestAID", i);
15156 if (val)
15157 allocs[i].dst_aid = strtol(val, NULL, 0);
15158 else
15159 allocs[i].dst_aid = ESE_BCAST_AID;
15160
15161 allocs[i].type = ESE_CBAP;
15162 sigma_dut_print(dut, DUT_MSG_INFO,
15163 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
15164 i, allocs[i].percent_bi, allocs[i].src_aid,
15165 allocs[i].dst_aid);
15166 }
15167
15168 *allocs_size = count;
15169 return 0;
15170}
15171
15172
15173static int sta_set_60g_ese(struct sigma_dut *dut, int count,
15174 struct sigma_ese_alloc *allocs)
15175{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015176 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015177#ifdef __linux__
15178 case DRIVER_WIL6210:
15179 if (wil6210_set_ese(dut, count, allocs))
15180 return -1;
15181 return 1;
15182#endif /* __linux__ */
15183 default:
15184 sigma_dut_print(dut, DUT_MSG_ERROR,
15185 "Unsupported sta_set_60g_ese with the current driver");
15186 return -1;
15187 }
15188}
15189
15190
15191static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
15192 struct sigma_conn *conn,
15193 struct sigma_cmd *cmd)
15194{
15195 const char *val;
15196
15197 val = get_param(cmd, "ExtSchIE");
15198 if (val && !strcasecmp(val, "Enable")) {
15199 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
15200 int count = MAX_ESE_ALLOCS;
15201
15202 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
15203 return -1;
15204 return sta_set_60g_ese(dut, count, allocs);
15205 }
15206
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015207 val = get_param(cmd, "MCS_FixedRate");
15208 if (val) {
15209 int sta_mcs = atoi(val);
15210
15211 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
15212 sta_mcs);
15213 wil6210_set_force_mcs(dut, 1, sta_mcs);
15214
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015215 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015216 }
15217
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015218 send_resp(dut, conn, SIGMA_ERROR,
15219 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015220 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015221}
15222
15223
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015224static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
15225 const char *oci_frametype, uint32_t oci_freq)
15226{
15227#ifdef NL80211_SUPPORT
15228 struct nl_msg *msg;
15229 int ret = 0;
15230 struct nlattr *params;
15231 struct nlattr *attr;
15232 int ifindex;
15233 u8 frame_type;
15234
15235 ifindex = if_nametoindex(intf);
15236 if (ifindex == 0) {
15237 sigma_dut_print(dut, DUT_MSG_ERROR,
15238 "%s: Index for interface %s failed",
15239 __func__, intf);
15240 return -1;
15241 }
15242
15243 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15244 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
15245 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15246 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
15247 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15248 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
15249 } else {
15250 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
15251 __func__, oci_frametype);
15252 return -1;
15253 }
15254
15255
15256 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
15257 NL80211_CMD_VENDOR)) ||
15258 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
15259 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
15260 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
15261 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
15262 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
15263 !(params = nla_nest_start(
15264 msg,
15265 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
15266 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
15267 frame_type) ||
15268 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
15269 oci_freq)) {
15270 sigma_dut_print(dut, DUT_MSG_ERROR,
15271 "%s: err in adding vendor_cmd and vendor_data",
15272 __func__);
15273 nlmsg_free(msg);
15274 return -1;
15275 }
15276 nla_nest_end(msg, params);
15277 nla_nest_end(msg, attr);
15278
15279 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
15280 if (ret) {
15281 sigma_dut_print(dut, DUT_MSG_ERROR,
15282 "%s: err in send_and_recv_msgs, ret=%d",
15283 __func__, ret);
15284 }
15285 return ret;
15286#else /* NL80211_SUPPORT */
15287 sigma_dut_print(dut, DUT_MSG_ERROR,
15288 "OCI override not possible without NL80211_SUPPORT defined");
15289 return -1;
15290#endif /* NL80211_SUPPORT */
15291}
15292
15293
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015294static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
15295 uint8_t ignore_csa)
15296{
15297#ifdef NL80211_SUPPORT
15298 return wcn_wifi_test_config_set_u8(
15299 dut, intf,
15300 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
15301#else /* NL80211_SUPPORT */
15302 sigma_dut_print(dut, DUT_MSG_ERROR,
15303 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
15304 return -1;
15305#endif /* NL80211_SUPPORT */
15306}
15307
15308
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015309static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
15310 uint8_t rsnxe_used)
15311{
15312#ifdef NL80211_SUPPORT
15313 return wcn_wifi_test_config_set_u8(
15314 dut, intf,
15315 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
15316 rsnxe_used);
15317#else /* NL80211_SUPPORT */
15318 sigma_dut_print(dut, DUT_MSG_ERROR,
15319 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
15320 return -1;
15321#endif /* NL80211_SUPPORT */
15322}
15323
15324
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015325static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
15326 const char *intf,
15327 uint8_t ignore_sa_query_timeout)
15328{
15329#ifdef NL80211_SUPPORT
15330 return wcn_wifi_test_config_set_u8(
15331 dut, intf,
15332 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
15333 ignore_sa_query_timeout);
15334#else /* NL80211_SUPPORT */
15335 sigma_dut_print(dut, DUT_MSG_ERROR,
15336 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
15337 return -1;
15338#endif /* NL80211_SUPPORT */
15339}
15340
15341
Jouni Malinen6250cb02020-04-15 13:54:45 +030015342static enum sigma_cmd_result
15343cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
15344 struct sigma_conn *conn,
15345 struct sigma_cmd *cmd)
15346{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015347 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030015348
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053015349 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030015350 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015351 if (wifi_chip_type == DRIVER_WCN) {
15352 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
15353 send_resp(dut, conn, SIGMA_ERROR,
15354 "errorCode,Failed to set ft_rsnxe_used");
15355 return STATUS_SENT_ERROR;
15356 }
15357 return SUCCESS_SEND_STATUS;
15358 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030015359 send_resp(dut, conn, SIGMA_ERROR,
15360 "errorCode,Failed to set ft_rsnxe_used");
15361 return STATUS_SENT_ERROR;
15362 }
15363 return SUCCESS_SEND_STATUS;
15364 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015365
15366 oci_chan = get_param(cmd, "OCIChannel");
15367 oci_frametype = get_param(cmd, "OCIFrameType");
15368 if (oci_chan && oci_frametype) {
15369 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
15370 char buf[100];
15371
15372 if (!oci_freq) {
15373 send_resp(dut, conn, SIGMA_ERROR,
15374 "errorCode,Invalid OCIChannel number");
15375 return STATUS_SENT_ERROR;
15376 }
15377
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015378 if (wifi_chip_type == DRIVER_WCN &&
15379 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
15380 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
15381 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
15382 if (wcn_sta_override_oci(dut, intf, oci_frametype,
15383 oci_freq)) {
15384 send_resp(dut, conn, SIGMA_ERROR,
15385 "errorCode,Failed to override OCI");
15386 return STATUS_SENT_ERROR;
15387 }
15388 return SUCCESS_SEND_STATUS;
15389 }
15390
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015391 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
15392 snprintf(buf, sizeof(buf),
15393 "SET oci_freq_override_eapol %d", oci_freq);
15394 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15395 snprintf(buf, sizeof(buf),
15396 "SET oci_freq_override_saquery_req %d",
15397 oci_freq);
15398 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15399 snprintf(buf, sizeof(buf),
15400 "SET oci_freq_override_saquery_resp %d",
15401 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015402 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
15403 snprintf(buf, sizeof(buf),
15404 "SET oci_freq_override_eapol_g2 %d",
15405 oci_freq);
15406 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15407 snprintf(buf, sizeof(buf),
15408 "SET oci_freq_override_ft_assoc %d",
15409 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015410 } else {
15411 send_resp(dut, conn, SIGMA_ERROR,
15412 "errorCode,Unsupported OCIFrameType");
15413 return STATUS_SENT_ERROR;
15414 }
15415 if (wpa_command(intf, buf) < 0) {
15416 send_resp(dut, conn, SIGMA_ERROR,
15417 "errorCode,Failed to set oci_freq_override");
15418 return STATUS_SENT_ERROR;
15419 }
15420 return SUCCESS_SEND_STATUS;
15421 }
15422
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015423 val = get_param(cmd, "IgnoreCSA");
15424 if (val && atoi(val) == 1) {
15425 if (wifi_chip_type == DRIVER_WCN) {
15426 if (wcn_sta_ignore_csa(dut, intf, 1)) {
15427 send_resp(dut, conn, SIGMA_ERROR,
15428 "errorCode,Failed to set ignore CSA");
15429 return STATUS_SENT_ERROR;
15430 }
15431 return SUCCESS_SEND_STATUS;
15432 }
15433 }
15434
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015435 val = get_param(cmd, "Deauth_Per_SAQueryResp");
15436 if (val && atoi(val) == 0) {
15437 if (wifi_chip_type == DRIVER_WCN) {
15438 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
15439 send_resp(dut, conn, SIGMA_ERROR,
15440 "errorCode,Failed to set ignore SA Query timeout");
15441 return STATUS_SENT_ERROR;
15442 }
15443 return SUCCESS_SEND_STATUS;
15444 }
15445 }
15446
Jouni Malinen6250cb02020-04-15 13:54:45 +030015447 send_resp(dut, conn, SIGMA_ERROR,
15448 "errorCode,Unsupported WPA3 rfeature");
15449 return STATUS_SENT_ERROR;
15450}
15451
15452
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015453static enum sigma_cmd_result
15454cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
15455 struct sigma_conn *conn, struct sigma_cmd *cmd)
15456{
15457 const char *val;
15458
15459 val = get_param(cmd, "DomainName_Domain");
15460 if (val) {
15461 if (strlen(val) >= sizeof(dut->qm_domain_name))
15462 return ERROR_SEND_STATUS;
15463
15464 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
15465 return SUCCESS_SEND_STATUS;
15466 }
15467
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053015468 val = get_param(cmd, "DSCPPolicy_PolicyID");
15469 if (val) {
15470 unsigned int i;
15471 int policy_id = atoi(val);
15472
15473 val = get_param(cmd, "DSCPPolicy_RequestType");
15474
15475 if (!policy_id || !val)
15476 return INVALID_SEND_STATUS;
15477
15478 if (dut->num_dscp_status >= ARRAY_SIZE(dut->dscp_status)) {
15479 send_resp(dut, conn, SIGMA_ERROR,
15480 "errorCode,DSCP status list full");
15481 return STATUS_SENT_ERROR;
15482 }
15483
15484 for (i = 0; i < dut->num_dscp_status; i++)
15485 if (dut->dscp_status[i].id == policy_id)
15486 break;
15487
15488 /* New policy configured */
15489 if (i == dut->num_dscp_status) {
15490 dut->dscp_status[i].id = policy_id;
15491 dut->num_dscp_status++;
15492 }
15493
15494 dut->dscp_status[i].status = strcasecmp(val, "Remove") ?
15495 DSCP_POLICY_SUCCESS : DSCP_POLICY_REJECT;
15496
15497 return SUCCESS_SEND_STATUS;
15498 }
15499
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015500 send_resp(dut, conn, SIGMA_ERROR,
15501 "errorCode,Unsupported QM rfeature");
15502 return STATUS_SENT_ERROR;
15503}
15504
15505
Jouni Malinenf7222712019-06-13 01:50:21 +030015506static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
15507 struct sigma_conn *conn,
15508 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015509{
15510 const char *intf = get_param(cmd, "Interface");
15511 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015512 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015513
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015514 if (!prog)
15515 prog = get_param(cmd, "Program");
15516
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015517 if (intf == NULL || prog == NULL)
15518 return -1;
15519
Ashwini Patil5acd7382017-04-13 15:55:04 +053015520 /* BSS Transition candidate list for BTM query */
15521 val = get_param(cmd, "Nebor_BSSID");
15522 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
15523 return 0;
15524
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015525 if (strcasecmp(prog, "TDLS") == 0)
15526 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
15527
15528 if (strcasecmp(prog, "VHT") == 0)
15529 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
15530
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015531 if (strcasecmp(prog, "HE") == 0)
15532 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
15533
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015534 if (strcasecmp(prog, "MBO") == 0) {
15535 val = get_param(cmd, "Cellular_Data_Cap");
15536 if (val &&
15537 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
15538 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053015539
15540 val = get_param(cmd, "Ch_Pref");
15541 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
15542 return 0;
15543
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015544 return 1;
15545 }
15546
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015547 if (strcasecmp(prog, "60GHz") == 0)
15548 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
15549
Jouni Malinen6250cb02020-04-15 13:54:45 +030015550 if (strcasecmp(prog, "WPA3") == 0)
15551 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015552 if (strcasecmp(prog, "QM") == 0)
15553 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030015554
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015555 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
15556 return 0;
15557}
15558
15559
Jouni Malinenf7222712019-06-13 01:50:21 +030015560static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
15561 struct sigma_conn *conn,
15562 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015563{
15564 const char *intf = get_param(cmd, "Interface");
15565 const char *mode = get_param(cmd, "Mode");
15566 int res;
15567
15568 if (intf == NULL || mode == NULL)
15569 return -1;
15570
15571 if (strcasecmp(mode, "On") == 0)
15572 res = wpa_command(intf, "SET radio_disabled 0");
15573 else if (strcasecmp(mode, "Off") == 0)
15574 res = wpa_command(intf, "SET radio_disabled 1");
15575 else
15576 return -1;
15577
15578 if (res) {
15579 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15580 "radio mode");
15581 return 0;
15582 }
15583
15584 return 1;
15585}
15586
15587
Jouni Malinenf7222712019-06-13 01:50:21 +030015588static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
15589 struct sigma_conn *conn,
15590 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015591{
15592 const char *intf = get_param(cmd, "Interface");
15593 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015594 const char *prog = get_param(cmd, "program");
15595 const char *powersave = get_param(cmd, "powersave");
15596 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015597
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015598 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015599 return -1;
15600
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015601 if (prog && strcasecmp(prog, "60GHz") == 0) {
15602 /*
15603 * The CAPI mode parameter does not exist in 60G
15604 * unscheduled PS.
15605 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080015606 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015607 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015608 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020015609 strcasecmp(prog, "HE") == 0) {
15610 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015611 } else {
15612 if (mode == NULL)
15613 return -1;
15614
15615 if (strcasecmp(mode, "On") == 0)
15616 res = set_ps(intf, dut, 1);
15617 else if (strcasecmp(mode, "Off") == 0)
15618 res = set_ps(intf, dut, 0);
15619 else
15620 return -1;
15621 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015622
15623 if (res) {
15624 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15625 "power save mode");
15626 return 0;
15627 }
15628
15629 return 1;
15630}
15631
15632
Jouni Malinenf7222712019-06-13 01:50:21 +030015633static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
15634 struct sigma_conn *conn,
15635 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015636{
15637 const char *intf = get_param(cmd, "Interface");
15638 const char *val, *bssid;
15639 int res;
15640 char *buf;
15641 size_t buf_len;
15642
15643 val = get_param(cmd, "BSSID_FILTER");
15644 if (val == NULL)
15645 return -1;
15646
15647 bssid = get_param(cmd, "BSSID_List");
15648 if (atoi(val) == 0 || bssid == NULL) {
15649 /* Disable BSSID filter */
15650 if (wpa_command(intf, "SET bssid_filter ")) {
15651 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
15652 "to disable BSSID filter");
15653 return 0;
15654 }
15655
15656 return 1;
15657 }
15658
15659 buf_len = 100 + strlen(bssid);
15660 buf = malloc(buf_len);
15661 if (buf == NULL)
15662 return -1;
15663
15664 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
15665 res = wpa_command(intf, buf);
15666 free(buf);
15667 if (res) {
15668 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
15669 "BSSID filter");
15670 return 0;
15671 }
15672
15673 return 1;
15674}
15675
15676
Jouni Malinenf7222712019-06-13 01:50:21 +030015677static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
15678 struct sigma_conn *conn,
15679 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015680{
15681 const char *intf = get_param(cmd, "Interface");
15682 const char *val;
15683
15684 /* TODO: ARP */
15685
15686 val = get_param(cmd, "HS2_CACHE_PROFILE");
15687 if (val && strcasecmp(val, "All") == 0)
15688 hs2_clear_credentials(intf);
15689
15690 return 1;
15691}
15692
15693
Jouni Malinenf7222712019-06-13 01:50:21 +030015694static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
15695 struct sigma_conn *conn,
15696 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015697{
15698 const char *intf = get_param(cmd, "Interface");
15699 const char *key_type = get_param(cmd, "KeyType");
15700 char buf[100], resp[200];
15701
15702 if (key_type == NULL)
15703 return -1;
15704
15705 if (strcasecmp(key_type, "GTK") == 0) {
15706 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
15707 strncmp(buf, "FAIL", 4) == 0) {
15708 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15709 "not fetch current GTK");
15710 return 0;
15711 }
15712 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
15713 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15714 return 0;
15715 } else {
15716 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
15717 "KeyType");
15718 return 0;
15719 }
15720
15721 return 1;
15722}
15723
15724
15725static int hs2_set_policy(struct sigma_dut *dut)
15726{
15727#ifdef ANDROID
15728 system("ip rule del prio 23000");
15729 if (system("ip rule add from all lookup main prio 23000") != 0) {
15730 sigma_dut_print(dut, DUT_MSG_ERROR,
15731 "Failed to run:ip rule add from all lookup main prio");
15732 return -1;
15733 }
15734 if (system("ip route flush cache") != 0) {
15735 sigma_dut_print(dut, DUT_MSG_ERROR,
15736 "Failed to run ip route flush cache");
15737 return -1;
15738 }
15739 return 1;
15740#else /* ANDROID */
15741 return 0;
15742#endif /* ANDROID */
15743}
15744
15745
Jouni Malinenf7222712019-06-13 01:50:21 +030015746static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
15747 struct sigma_conn *conn,
15748 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015749{
15750 const char *intf = get_param(cmd, "Interface");
15751 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030015752 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015753 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030015754 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015755 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
15756 int tries = 0;
15757 int ignore_blacklist = 0;
15758 const char *events[] = {
15759 "CTRL-EVENT-CONNECTED",
15760 "INTERWORKING-BLACKLISTED",
15761 "INTERWORKING-NO-MATCH",
15762 NULL
15763 };
15764
15765 start_sta_mode(dut);
15766
Jouni Malinen439352d2018-09-13 03:42:23 +030015767 if (band) {
15768 if (strcmp(band, "2.4") == 0) {
15769 wpa_command(intf, "SET setband 2G");
15770 } else if (strcmp(band, "5") == 0) {
15771 wpa_command(intf, "SET setband 5G");
15772 } else {
15773 send_resp(dut, conn, SIGMA_ERROR,
15774 "errorCode,Unsupported band");
15775 return 0;
15776 }
15777 }
15778
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015779 blacklisted[0] = '\0';
15780 if (val && atoi(val))
15781 ignore_blacklist = 1;
15782
15783try_again:
15784 ctrl = open_wpa_mon(intf);
15785 if (ctrl == NULL) {
15786 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15787 "wpa_supplicant monitor connection");
15788 return -2;
15789 }
15790
15791 tries++;
15792 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
15793 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
15794 "Interworking connection");
15795 wpa_ctrl_detach(ctrl);
15796 wpa_ctrl_close(ctrl);
15797 return 0;
15798 }
15799
15800 buf[0] = '\0';
15801 while (1) {
15802 char *pos;
15803 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15804 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
15805 if (!pos)
15806 break;
15807 pos += 25;
15808 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
15809 pos);
15810 if (!blacklisted[0])
15811 memcpy(blacklisted, pos, strlen(pos) + 1);
15812 }
15813
15814 if (ignore_blacklist && blacklisted[0]) {
15815 char *end;
15816 end = strchr(blacklisted, ' ');
15817 if (end)
15818 *end = '\0';
15819 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
15820 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030015821 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
15822 blacklisted);
15823 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015824 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
15825 wpa_ctrl_detach(ctrl);
15826 wpa_ctrl_close(ctrl);
15827 return 0;
15828 }
15829 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15830 buf, sizeof(buf));
15831 }
15832
15833 wpa_ctrl_detach(ctrl);
15834 wpa_ctrl_close(ctrl);
15835
15836 if (res < 0) {
15837 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15838 "connect");
15839 return 0;
15840 }
15841
15842 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
15843 strstr(buf, "INTERWORKING-BLACKLISTED")) {
15844 if (tries < 2) {
15845 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
15846 goto try_again;
15847 }
15848 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
15849 "matching credentials found");
15850 return 0;
15851 }
15852
15853 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15854 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15855 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15856 "get current BSSID/SSID");
15857 return 0;
15858 }
15859
15860 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
15861 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15862 hs2_set_policy(dut);
15863 return 0;
15864}
15865
15866
Jouni Malinenf7222712019-06-13 01:50:21 +030015867static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
15868 struct sigma_conn *conn,
15869 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015870{
15871 const char *intf = get_param(cmd, "Interface");
15872 const char *display = get_param(cmd, "Display");
15873 struct wpa_ctrl *ctrl;
15874 char buf[300], params[400], *pos;
15875 char bssid[20];
15876 int info_avail = 0;
15877 unsigned int old_timeout;
15878 int res;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015879 const char *events[] = { "RX-VENUE-URL", "ANQP-QUERY-DONE", NULL };
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015880
15881 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
15882 send_resp(dut, conn, SIGMA_ERROR,
15883 "ErrorCode,Could not get current BSSID");
15884 return 0;
15885 }
15886 ctrl = open_wpa_mon(intf);
15887 if (!ctrl) {
15888 sigma_dut_print(dut, DUT_MSG_ERROR,
15889 "Failed to open wpa_supplicant monitor connection");
15890 return -2;
15891 }
15892
15893 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
15894 wpa_command(intf, buf);
15895
15896 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
15897 if (res < 0) {
15898 send_resp(dut, conn, SIGMA_ERROR,
15899 "ErrorCode,Could not complete GAS query");
15900 goto fail;
15901 }
15902
15903 old_timeout = dut->default_timeout;
15904 dut->default_timeout = 2;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015905 for (;;) {
15906 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15907 if (res < 0)
15908 break;
15909 if (strstr(buf, "ANQP-QUERY-DONE") != NULL) {
15910 res = -1;
15911 break;
15912 }
15913 pos = strchr(buf, ' ');
15914 if (!pos)
15915 continue;
15916 pos++;
15917 pos = strchr(pos, ' ');
15918 if (!pos)
15919 continue;
15920 pos++;
15921
15922 if (strncmp(pos, "https://", 8) == 0)
15923 break;
15924
15925 sigma_dut_print(dut, DUT_MSG_DEBUG,
15926 "Ignore non-HTTPS venue URL: %s", pos);
15927 }
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015928 dut->default_timeout = old_timeout;
15929 if (res < 0)
15930 goto done;
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015931 info_avail = 1;
15932 snprintf(params, sizeof(params), "browser %s", pos);
15933
15934 if (display && strcasecmp(display, "Yes") == 0) {
15935 pid_t pid;
15936
15937 pid = fork();
15938 if (pid < 0) {
15939 perror("fork");
15940 return -1;
15941 }
15942
15943 if (pid == 0) {
15944 run_hs20_osu(dut, params);
15945 exit(0);
15946 }
15947 }
15948
15949done:
15950 snprintf(buf, sizeof(buf), "Info_available,%s",
15951 info_avail ? "Yes" : "No");
15952 send_resp(dut, conn, SIGMA_COMPLETE, buf);
15953fail:
15954 wpa_ctrl_detach(ctrl);
15955 wpa_ctrl_close(ctrl);
15956 return 0;
15957}
15958
15959
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015960static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
15961 struct sigma_conn *conn,
15962 const char *ifname,
15963 struct sigma_cmd *cmd)
15964{
15965 const char *val;
15966 int id;
15967
15968 id = add_cred(ifname);
15969 if (id < 0)
15970 return -2;
15971 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15972
15973 val = get_param(cmd, "prefer");
15974 if (val && atoi(val) > 0)
15975 set_cred(ifname, id, "priority", "1");
15976
15977 val = get_param(cmd, "REALM");
15978 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
15979 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15980 "realm");
15981 return 0;
15982 }
15983
15984 val = get_param(cmd, "HOME_FQDN");
15985 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
15986 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15987 "home_fqdn");
15988 return 0;
15989 }
15990
15991 val = get_param(cmd, "Username");
15992 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
15993 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15994 "username");
15995 return 0;
15996 }
15997
15998 val = get_param(cmd, "Password");
15999 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
16000 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16001 "password");
16002 return 0;
16003 }
16004
16005 val = get_param(cmd, "ROOT_CA");
16006 if (val) {
16007 char fname[200];
16008 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16009#ifdef __linux__
16010 if (!file_exists(fname)) {
16011 char msg[300];
16012 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16013 "file (%s) not found", fname);
16014 send_resp(dut, conn, SIGMA_ERROR, msg);
16015 return 0;
16016 }
16017#endif /* __linux__ */
16018 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16019 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16020 "not set root CA");
16021 return 0;
16022 }
16023 }
16024
16025 return 1;
16026}
16027
16028
16029static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
16030{
16031 FILE *in, *out;
16032 char buf[500];
16033 int found = 0;
16034
16035 in = fopen("devdetail.xml", "r");
16036 if (in == NULL)
16037 return -1;
16038 out = fopen("devdetail.xml.tmp", "w");
16039 if (out == NULL) {
16040 fclose(in);
16041 return -1;
16042 }
16043
16044 while (fgets(buf, sizeof(buf), in)) {
16045 char *pos = strstr(buf, "<IMSI>");
16046 if (pos) {
16047 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
16048 imsi);
16049 pos += 6;
16050 *pos = '\0';
16051 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
16052 found++;
16053 } else {
16054 fprintf(out, "%s", buf);
16055 }
16056 }
16057
16058 fclose(out);
16059 fclose(in);
16060 if (found)
16061 rename("devdetail.xml.tmp", "devdetail.xml");
16062 else
16063 unlink("devdetail.xml.tmp");
16064
16065 return 0;
16066}
16067
16068
16069static int sta_add_credential_sim(struct sigma_dut *dut,
16070 struct sigma_conn *conn,
16071 const char *ifname, struct sigma_cmd *cmd)
16072{
16073 const char *val, *imsi = NULL;
16074 int id;
16075 char buf[200];
16076 int res;
16077 const char *pos;
16078 size_t mnc_len;
16079 char plmn_mcc[4];
16080 char plmn_mnc[4];
16081
16082 id = add_cred(ifname);
16083 if (id < 0)
16084 return -2;
16085 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16086
16087 val = get_param(cmd, "prefer");
16088 if (val && atoi(val) > 0)
16089 set_cred(ifname, id, "priority", "1");
16090
16091 val = get_param(cmd, "PLMN_MCC");
16092 if (val == NULL) {
16093 send_resp(dut, conn, SIGMA_ERROR,
16094 "errorCode,Missing PLMN_MCC");
16095 return 0;
16096 }
16097 if (strlen(val) != 3) {
16098 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
16099 return 0;
16100 }
16101 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
16102
16103 val = get_param(cmd, "PLMN_MNC");
16104 if (val == NULL) {
16105 send_resp(dut, conn, SIGMA_ERROR,
16106 "errorCode,Missing PLMN_MNC");
16107 return 0;
16108 }
16109 if (strlen(val) != 2 && strlen(val) != 3) {
16110 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
16111 return 0;
16112 }
16113 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
16114
16115 val = get_param(cmd, "IMSI");
16116 if (val == NULL) {
16117 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
16118 "IMSI");
16119 return 0;
16120 }
16121
16122 imsi = pos = val;
16123
16124 if (strncmp(plmn_mcc, pos, 3) != 0) {
16125 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
16126 return 0;
16127 }
16128 pos += 3;
16129
16130 mnc_len = strlen(plmn_mnc);
16131 if (mnc_len < 2) {
16132 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
16133 return 0;
16134 }
16135
16136 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
16137 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
16138 return 0;
16139 }
16140 pos += mnc_len;
16141
16142 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
16143 if (res < 0 || res >= (int) sizeof(buf))
16144 return -1;
16145 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
16146 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16147 "not set IMSI");
16148 return 0;
16149 }
16150
16151 val = get_param(cmd, "Password");
16152 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
16153 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16154 "not set password");
16155 return 0;
16156 }
16157
Jouni Malinen9a742ff2022-01-27 00:43:14 +020016158 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
16159 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016160 /*
16161 * Set provisioning_sp for the test cases where SIM/USIM
16162 * provisioning is used.
16163 */
16164 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
16165 "wi-fi.org") < 0) {
16166 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16167 "not set provisioning_sp");
16168 return 0;
16169 }
16170
16171 update_devdetail_imsi(dut, imsi);
16172 }
16173
16174 return 1;
16175}
16176
16177
16178static int sta_add_credential_cert(struct sigma_dut *dut,
16179 struct sigma_conn *conn,
16180 const char *ifname,
16181 struct sigma_cmd *cmd)
16182{
16183 const char *val;
16184 int id;
16185
16186 id = add_cred(ifname);
16187 if (id < 0)
16188 return -2;
16189 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16190
16191 val = get_param(cmd, "prefer");
16192 if (val && atoi(val) > 0)
16193 set_cred(ifname, id, "priority", "1");
16194
16195 val = get_param(cmd, "REALM");
16196 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
16197 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16198 "realm");
16199 return 0;
16200 }
16201
16202 val = get_param(cmd, "HOME_FQDN");
16203 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
16204 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16205 "home_fqdn");
16206 return 0;
16207 }
16208
16209 val = get_param(cmd, "Username");
16210 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
16211 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16212 "username");
16213 return 0;
16214 }
16215
16216 val = get_param(cmd, "clientCertificate");
16217 if (val) {
16218 char fname[200];
16219 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16220#ifdef __linux__
16221 if (!file_exists(fname)) {
16222 char msg[300];
16223 snprintf(msg, sizeof(msg),
16224 "ErrorCode,clientCertificate "
16225 "file (%s) not found", fname);
16226 send_resp(dut, conn, SIGMA_ERROR, msg);
16227 return 0;
16228 }
16229#endif /* __linux__ */
16230 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
16231 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16232 "not set client_cert");
16233 return 0;
16234 }
16235 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
16236 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16237 "not set private_key");
16238 return 0;
16239 }
16240 }
16241
16242 val = get_param(cmd, "ROOT_CA");
16243 if (val) {
16244 char fname[200];
16245 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16246#ifdef __linux__
16247 if (!file_exists(fname)) {
16248 char msg[300];
16249 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16250 "file (%s) not found", fname);
16251 send_resp(dut, conn, SIGMA_ERROR, msg);
16252 return 0;
16253 }
16254#endif /* __linux__ */
16255 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16256 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16257 "not set root CA");
16258 return 0;
16259 }
16260 }
16261
16262 return 1;
16263}
16264
16265
Jouni Malinenf7222712019-06-13 01:50:21 +030016266static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
16267 struct sigma_conn *conn,
16268 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016269{
16270 const char *intf = get_param(cmd, "Interface");
16271 const char *type;
16272
16273 start_sta_mode(dut);
16274
16275 type = get_param(cmd, "Type");
16276 if (!type)
16277 return -1;
16278
16279 if (strcasecmp(type, "uname_pwd") == 0)
16280 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
16281
16282 if (strcasecmp(type, "sim") == 0)
16283 return sta_add_credential_sim(dut, conn, intf, cmd);
16284
16285 if (strcasecmp(type, "cert") == 0)
16286 return sta_add_credential_cert(dut, conn, intf, cmd);
16287
16288 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
16289 "type");
16290 return 0;
16291}
16292
16293
Jouni Malinenf7222712019-06-13 01:50:21 +030016294static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
16295 struct sigma_conn *conn,
16296 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016297{
16298 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016299 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070016300 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053016301 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016302 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016303 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016304 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016305 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016306
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020016307 start_sta_mode(dut);
16308
Arif Hussain66a4af02019-02-07 15:04:51 -080016309 val = get_param(cmd, "GetParameter");
16310 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016311 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080016312 buf, sizeof(buf)) < 0) {
16313 sigma_dut_print(dut, DUT_MSG_ERROR,
16314 "Could not get ssid bssid");
16315 return ERROR_SEND_STATUS;
16316 }
16317
16318 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
16319 send_resp(dut, conn, SIGMA_COMPLETE, buf);
16320 return STATUS_SENT;
16321 }
16322
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016323 val = get_param(cmd, "HESSID");
16324 if (val) {
16325 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
16326 if (res < 0 || res >= (int) sizeof(buf))
16327 return -1;
16328 wpa_command(intf, buf);
16329 }
16330
16331 val = get_param(cmd, "ACCS_NET_TYPE");
16332 if (val) {
16333 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
16334 val);
16335 if (res < 0 || res >= (int) sizeof(buf))
16336 return -1;
16337 wpa_command(intf, buf);
16338 }
16339
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016340 if (get_param(cmd, "RxMac"))
16341 sta_set_scan_unicast_probe(dut, intf, 1);
16342
vamsi krishna89ad8c62017-09-19 12:51:18 +053016343 bssid = get_param(cmd, "Bssid");
16344 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016345 if (!bssid)
16346 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053016347
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016348 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
16349 dut->device_type == STA_testbed) {
16350 ssid = NULL;
16351 wildcard_ssid = 1;
16352 }
16353
vamsi krishna89ad8c62017-09-19 12:51:18 +053016354 if (ssid) {
16355 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
16356 send_resp(dut, conn, SIGMA_ERROR,
16357 "ErrorCode,Too long SSID");
16358 return 0;
16359 }
16360 ascii2hexstr(ssid, ssid_hex);
16361 }
16362
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016363 short_ssid = get_param(cmd, "ShortSSID");
16364 if (short_ssid) {
16365 uint32_t short_ssid_hex;
16366
16367 short_ssid_hex = strtoul(short_ssid, NULL, 16);
16368 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
16369 (((short_ssid_hex >> 8) & 0xFF) << 16) |
16370 (((short_ssid_hex >> 16) & 0xFF) << 8) |
16371 ((short_ssid_hex >> 24) & 0xFF);
16372
16373 res = snprintf(buf, sizeof(buf),
16374 "VENDOR_ELEM_ADD 14 ff053a%08x",
16375 short_ssid_hex);
16376 if (res < 0 || res >= (int) sizeof(buf) ||
16377 wpa_command(intf, buf)) {
16378 send_resp(dut, conn, SIGMA_ERROR,
16379 "errorCode,Failed to add short SSID");
16380 return STATUS_SENT_ERROR;
16381 }
16382 }
16383
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016384 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053016385 if (scan_freq) {
16386 if (strcasecmp(scan_freq, "2G") == 0)
16387 scan_freq = "2412-2462";
16388 else if (strcasecmp(scan_freq, "5G") == 0)
16389 scan_freq = "5180-5925";
16390 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016391
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016392 val = get_param(cmd, "WaitCompletion");
16393 if (val && atoi(val) == 1) {
16394 ctrl = open_wpa_mon(intf);
16395 if (!ctrl) {
16396 send_resp(dut, conn, SIGMA_ERROR,
16397 "errorCode,Failed to open monitor socket");
16398 return STATUS_SENT_ERROR;
16399 }
16400 }
16401
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016402 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053016403 bssid ? " bssid=": "",
16404 bssid ? bssid : "",
16405 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016406 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016407 wildcard_ssid ? " wildcard_ssid=1" : "",
16408 scan_freq ? " freq=" : "",
16409 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016410 if (res < 0 || res >= (int) sizeof(buf)) {
16411 send_resp(dut, conn, SIGMA_ERROR,
16412 "errorCode,Could not build scan command");
16413 status = STATUS_SENT_ERROR;
16414 goto remove_s_ssid;
16415 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053016416
Veerendranathdc581b52020-08-10 03:29:08 -070016417 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
16418 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
16419 sigma_dut_print(dut, DUT_MSG_DEBUG,
16420 "Scan request rejected with busy status, abort ongoing scan and try again");
16421 wpa_command(intf, "ABORT_SCAN");
16422 res = wpa_command(intf, buf);
16423 }
16424
16425 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016426 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
16427 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016428 status = STATUS_SENT_ERROR;
16429 } else {
16430 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016431 }
16432
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016433remove_s_ssid:
16434 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
16435 sigma_dut_print(dut, DUT_MSG_ERROR,
16436 "Failed to delete vendor element");
16437
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016438 if (ctrl) {
16439 if (status == SUCCESS_SEND_STATUS) {
16440 res = get_wpa_cli_event(dut, ctrl,
16441 "CTRL-EVENT-SCAN-RESULTS",
16442 buf, sizeof(buf));
16443 if (res < 0) {
16444 send_resp(dut, conn, SIGMA_ERROR,
16445 "ErrorCode,scan did not complete");
16446 status = STATUS_SENT_ERROR;
16447 }
16448 }
16449
16450 wpa_ctrl_detach(ctrl);
16451 wpa_ctrl_close(ctrl);
16452 }
16453
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016454 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016455}
16456
16457
Jouni Malinenf7222712019-06-13 01:50:21 +030016458static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
16459 struct sigma_conn *conn,
16460 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016461{
16462 const char *intf = get_param(cmd, "Interface");
16463 const char *bssid;
16464 char buf[4096], *pos;
16465 int freq, chan;
16466 char *ssid;
16467 char resp[100];
16468 int res;
16469 struct wpa_ctrl *ctrl;
16470
16471 bssid = get_param(cmd, "BSSID");
16472 if (!bssid) {
16473 send_resp(dut, conn, SIGMA_INVALID,
16474 "errorCode,BSSID argument is missing");
16475 return 0;
16476 }
16477
16478 ctrl = open_wpa_mon(intf);
16479 if (!ctrl) {
16480 sigma_dut_print(dut, DUT_MSG_ERROR,
16481 "Failed to open wpa_supplicant monitor connection");
16482 return -1;
16483 }
16484
16485 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
16486 send_resp(dut, conn, SIGMA_ERROR,
16487 "errorCode,Could not start scan");
16488 wpa_ctrl_detach(ctrl);
16489 wpa_ctrl_close(ctrl);
16490 return 0;
16491 }
16492
16493 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
16494 buf, sizeof(buf));
16495
16496 wpa_ctrl_detach(ctrl);
16497 wpa_ctrl_close(ctrl);
16498
16499 if (res < 0) {
16500 send_resp(dut, conn, SIGMA_ERROR,
16501 "errorCode,Scan did not complete");
16502 return 0;
16503 }
16504
16505 snprintf(buf, sizeof(buf), "BSS %s", bssid);
16506 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
16507 strncmp(buf, "id=", 3) != 0) {
16508 send_resp(dut, conn, SIGMA_ERROR,
16509 "errorCode,Specified BSSID not found");
16510 return 0;
16511 }
16512
16513 pos = strstr(buf, "\nfreq=");
16514 if (!pos) {
16515 send_resp(dut, conn, SIGMA_ERROR,
16516 "errorCode,Channel not found");
16517 return 0;
16518 }
16519 freq = atoi(pos + 6);
16520 chan = freq_to_channel(freq);
16521
16522 pos = strstr(buf, "\nssid=");
16523 if (!pos) {
16524 send_resp(dut, conn, SIGMA_ERROR,
16525 "errorCode,SSID not found");
16526 return 0;
16527 }
16528 ssid = pos + 6;
16529 pos = strchr(ssid, '\n');
16530 if (pos)
16531 *pos = '\0';
16532 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
16533 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16534 return 0;
16535}
16536
16537
Jouni Malinenf7222712019-06-13 01:50:21 +030016538static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
16539 struct sigma_conn *conn,
16540 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016541{
16542#ifdef __linux__
16543 struct timeval tv;
16544 struct tm tm;
16545 time_t t;
16546 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016547 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016548
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016549 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016550
16551 memset(&tm, 0, sizeof(tm));
16552 val = get_param(cmd, "seconds");
16553 if (val)
16554 tm.tm_sec = atoi(val);
16555 val = get_param(cmd, "minutes");
16556 if (val)
16557 tm.tm_min = atoi(val);
16558 val = get_param(cmd, "hours");
16559 if (val)
16560 tm.tm_hour = atoi(val);
16561 val = get_param(cmd, "date");
16562 if (val)
16563 tm.tm_mday = atoi(val);
16564 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016565 if (val) {
16566 v = atoi(val);
16567 if (v < 1 || v > 12) {
16568 send_resp(dut, conn, SIGMA_INVALID,
16569 "errorCode,Invalid month");
16570 return 0;
16571 }
16572 tm.tm_mon = v - 1;
16573 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016574 val = get_param(cmd, "year");
16575 if (val) {
16576 int year = atoi(val);
16577#ifdef ANDROID
16578 if (year > 2035)
16579 year = 2035; /* years beyond 2035 not supported */
16580#endif /* ANDROID */
16581 tm.tm_year = year - 1900;
16582 }
16583 t = mktime(&tm);
16584 if (t == (time_t) -1) {
16585 send_resp(dut, conn, SIGMA_ERROR,
16586 "errorCode,Invalid date or time");
16587 return 0;
16588 }
16589
16590 memset(&tv, 0, sizeof(tv));
16591 tv.tv_sec = t;
16592
16593 if (settimeofday(&tv, NULL) < 0) {
16594 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
16595 strerror(errno));
16596 send_resp(dut, conn, SIGMA_ERROR,
16597 "errorCode,Failed to set time");
16598 return 0;
16599 }
16600
16601 return 1;
16602#endif /* __linux__ */
16603
16604 return -1;
16605}
16606
16607
Jouni Malinenf7222712019-06-13 01:50:21 +030016608static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
16609 struct sigma_conn *conn,
16610 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016611{
16612 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016613 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016614 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016615 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016616 int res;
16617 struct wpa_ctrl *ctrl;
16618
16619 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016620 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016621
16622 val = get_param(cmd, "ProdESSAssoc");
16623 if (val)
16624 prod_ess_assoc = atoi(val);
16625
16626 kill_dhcp_client(dut, intf);
16627 if (start_dhcp_client(dut, intf) < 0)
16628 return -2;
16629
16630 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
16631 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16632 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016633 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016634 prod_ess_assoc ? "" : "-N",
16635 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016636 name ? "'" : "",
16637 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
16638 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016639
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053016640 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016641 if (run_hs20_osu(dut, buf) < 0) {
16642 FILE *f;
16643
16644 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
16645
16646 f = fopen("hs20-osu-client.res", "r");
16647 if (f) {
16648 char resp[400], res[300], *pos;
16649 if (!fgets(res, sizeof(res), f))
16650 res[0] = '\0';
16651 pos = strchr(res, '\n');
16652 if (pos)
16653 *pos = '\0';
16654 fclose(f);
16655 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
16656 res);
16657 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
16658 if (system(resp) != 0) {
16659 }
16660 snprintf(resp, sizeof(resp),
16661 "SSID,,BSSID,,failureReason,%s", res);
16662 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16663 return 0;
16664 }
16665
16666 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16667 return 0;
16668 }
16669
16670 if (!prod_ess_assoc)
16671 goto report;
16672
16673 ctrl = open_wpa_mon(intf);
16674 if (ctrl == NULL) {
16675 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16676 "wpa_supplicant monitor connection");
16677 return -1;
16678 }
16679
16680 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
16681 buf, sizeof(buf));
16682
16683 wpa_ctrl_detach(ctrl);
16684 wpa_ctrl_close(ctrl);
16685
16686 if (res < 0) {
16687 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
16688 "network after OSU");
16689 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16690 return 0;
16691 }
16692
16693report:
16694 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
16695 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
16696 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
16697 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16698 return 0;
16699 }
16700
16701 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
16702 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016703 return 0;
16704}
16705
16706
Jouni Malinenf7222712019-06-13 01:50:21 +030016707static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
16708 struct sigma_conn *conn,
16709 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016710{
16711 const char *val;
16712 int timeout = 120;
16713
16714 val = get_param(cmd, "PolicyUpdate");
16715 if (val == NULL || atoi(val) == 0)
16716 return 1; /* No operation requested */
16717
16718 val = get_param(cmd, "Timeout");
16719 if (val)
16720 timeout = atoi(val);
16721
16722 if (timeout) {
16723 /* TODO: time out the command and return
16724 * PolicyUpdateStatus,TIMEOUT if needed. */
16725 }
16726
16727 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
16728 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16729 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
16730 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
16731 return 0;
16732 }
16733
16734 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
16735 return 0;
16736}
16737
16738
Jouni Malinenf7222712019-06-13 01:50:21 +030016739static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
16740 struct sigma_conn *conn,
16741 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016742{
16743 struct wpa_ctrl *ctrl;
16744 const char *intf = get_param(cmd, "Interface");
16745 const char *bssid = get_param(cmd, "Bssid");
16746 const char *ssid = get_param(cmd, "SSID");
16747 const char *security = get_param(cmd, "Security");
16748 const char *passphrase = get_param(cmd, "Passphrase");
16749 const char *pin = get_param(cmd, "PIN");
16750 char buf[1000];
16751 char ssid_hex[200], passphrase_hex[200];
16752 const char *keymgmt, *cipher;
16753
16754 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016755 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016756
16757 if (!bssid) {
16758 send_resp(dut, conn, SIGMA_ERROR,
16759 "ErrorCode,Missing Bssid argument");
16760 return 0;
16761 }
16762
16763 if (!ssid) {
16764 send_resp(dut, conn, SIGMA_ERROR,
16765 "ErrorCode,Missing SSID argument");
16766 return 0;
16767 }
16768
16769 if (!security) {
16770 send_resp(dut, conn, SIGMA_ERROR,
16771 "ErrorCode,Missing Security argument");
16772 return 0;
16773 }
16774
16775 if (!passphrase) {
16776 send_resp(dut, conn, SIGMA_ERROR,
16777 "ErrorCode,Missing Passphrase argument");
16778 return 0;
16779 }
16780
16781 if (!pin) {
16782 send_resp(dut, conn, SIGMA_ERROR,
16783 "ErrorCode,Missing PIN argument");
16784 return 0;
16785 }
16786
vamsi krishna8c9c1562017-05-12 15:51:46 +053016787 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
16788 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016789 send_resp(dut, conn, SIGMA_ERROR,
16790 "ErrorCode,Too long SSID/passphrase");
16791 return 0;
16792 }
16793
16794 ctrl = open_wpa_mon(intf);
16795 if (ctrl == NULL) {
16796 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16797 "wpa_supplicant monitor connection");
16798 return -2;
16799 }
16800
16801 if (strcasecmp(security, "wpa2-psk") == 0) {
16802 keymgmt = "WPA2PSK";
16803 cipher = "CCMP";
16804 } else {
16805 wpa_ctrl_detach(ctrl);
16806 wpa_ctrl_close(ctrl);
16807 send_resp(dut, conn, SIGMA_ERROR,
16808 "ErrorCode,Unsupported Security value");
16809 return 0;
16810 }
16811
16812 ascii2hexstr(ssid, ssid_hex);
16813 ascii2hexstr(passphrase, passphrase_hex);
16814 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
16815 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
16816
16817 if (wpa_command(intf, buf) < 0) {
16818 wpa_ctrl_detach(ctrl);
16819 wpa_ctrl_close(ctrl);
16820 send_resp(dut, conn, SIGMA_ERROR,
16821 "ErrorCode,Failed to start registrar");
16822 return 0;
16823 }
16824
16825 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
16826 dut->er_oper_performed = 1;
16827
16828 return wps_connection_event(dut, conn, ctrl, intf, 0);
16829}
16830
16831
Jouni Malinenf7222712019-06-13 01:50:21 +030016832static enum sigma_cmd_result
16833cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
16834 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016835{
16836 struct wpa_ctrl *ctrl;
16837 const char *intf = get_param(cmd, "Interface");
16838 const char *bssid = get_param(cmd, "Bssid");
16839 char buf[100];
16840
16841 if (!bssid) {
16842 send_resp(dut, conn, SIGMA_ERROR,
16843 "ErrorCode,Missing Bssid argument");
16844 return 0;
16845 }
16846
16847 ctrl = open_wpa_mon(intf);
16848 if (ctrl == NULL) {
16849 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16850 "wpa_supplicant monitor connection");
16851 return -2;
16852 }
16853
16854 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
16855
16856 if (wpa_command(intf, buf) < 0) {
16857 wpa_ctrl_detach(ctrl);
16858 wpa_ctrl_close(ctrl);
16859 send_resp(dut, conn, SIGMA_ERROR,
16860 "ErrorCode,Failed to start registrar");
16861 return 0;
16862 }
16863
16864 return wps_connection_event(dut, conn, ctrl, intf, 0);
16865}
16866
16867
Jouni Malinenf7222712019-06-13 01:50:21 +030016868static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
16869 struct sigma_conn *conn,
16870 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053016871{
16872 struct wpa_ctrl *ctrl;
16873 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016874 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016875 const char *config_method = get_param(cmd, "WPSConfigMethod");
16876 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053016877 int res;
16878 char buf[256];
16879 const char *events[] = {
16880 "CTRL-EVENT-CONNECTED",
16881 "WPS-OVERLAP-DETECTED",
16882 "WPS-TIMEOUT",
16883 "WPS-FAIL",
16884 NULL
16885 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016886 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053016887
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016888 /* 60G WPS tests do not pass Interface parameter */
16889 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016890 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016891
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016892 if (dut->mode == SIGMA_MODE_AP)
16893 return ap_wps_registration(dut, conn, cmd);
16894
16895 if (config_method) {
16896 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
16897 * sta_wps_enter_pin before calling start_wps_registration. */
16898 if (strcasecmp(config_method, "PBC") == 0)
16899 dut->wps_method = WFA_CS_WPS_PBC;
16900 }
16901 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
16902 send_resp(dut, conn, SIGMA_ERROR,
16903 "ErrorCode,WPS parameters not yet set");
16904 return STATUS_SENT;
16905 }
16906
16907 /* Make sure WPS is enabled (also for STA mode) */
16908 dut->wps_disable = 0;
16909
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016910 if (dut->band == WPS_BAND_60G && network_mode &&
16911 strcasecmp(network_mode, "PBSS") == 0) {
16912 sigma_dut_print(dut, DUT_MSG_DEBUG,
16913 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016914 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016915 return -2;
16916 }
16917
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016918 if (dut->force_rsn_ie) {
16919 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
16920 dut->force_rsn_ie);
16921 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
16922 sigma_dut_print(dut, DUT_MSG_INFO,
16923 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020016924 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016925 }
16926 }
16927
vamsi krishna9b144002017-09-20 13:28:13 +053016928 ctrl = open_wpa_mon(intf);
16929 if (!ctrl) {
16930 sigma_dut_print(dut, DUT_MSG_ERROR,
16931 "Failed to open wpa_supplicant monitor connection");
16932 return -2;
16933 }
16934
16935 role = get_param(cmd, "WpsRole");
16936 if (!role) {
16937 send_resp(dut, conn, SIGMA_INVALID,
16938 "ErrorCode,WpsRole not provided");
16939 goto fail;
16940 }
16941
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016942 if (strcasecmp(role, "Enrollee") != 0) {
16943 /* Registrar role for STA not supported */
16944 send_resp(dut, conn, SIGMA_ERROR,
16945 "ErrorCode,Unsupported WpsRole value");
16946 goto fail;
16947 }
16948
16949 if (is_60g_sigma_dut(dut)) {
16950 if (dut->wps_method == WFA_CS_WPS_PBC)
16951 snprintf(buf, sizeof(buf), "WPS_PBC");
16952 else /* WFA_CS_WPS_PIN_KEYPAD */
16953 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
16954 dut->wps_pin);
16955 if (wpa_command(intf, buf) < 0) {
16956 send_resp(dut, conn, SIGMA_ERROR,
16957 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053016958 goto fail;
16959 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016960 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16961 if (res < 0) {
16962 send_resp(dut, conn, SIGMA_ERROR,
16963 "ErrorCode,WPS connection did not complete");
16964 goto fail;
16965 }
16966 if (strstr(buf, "WPS-TIMEOUT")) {
16967 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
16968 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16969 send_resp(dut, conn, SIGMA_COMPLETE,
16970 "WpsState,OverlapSession");
16971 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16972 send_resp(dut, conn, SIGMA_COMPLETE,
16973 "WpsState,Successful");
16974 } else {
16975 send_resp(dut, conn, SIGMA_COMPLETE,
16976 "WpsState,Failure");
16977 }
16978 } else {
16979 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053016980 if (wpa_command(intf, "WPS_PBC") < 0) {
16981 send_resp(dut, conn, SIGMA_ERROR,
16982 "ErrorCode,Failed to enable PBC");
16983 goto fail;
16984 }
16985 } else {
16986 /* TODO: PIN method */
16987 send_resp(dut, conn, SIGMA_ERROR,
16988 "ErrorCode,Unsupported WpsConfigMethod value");
16989 goto fail;
16990 }
16991 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16992 if (res < 0) {
16993 send_resp(dut, conn, SIGMA_ERROR,
16994 "ErrorCode,WPS connection did not complete");
16995 goto fail;
16996 }
16997 if (strstr(buf, "WPS-TIMEOUT")) {
16998 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
16999 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
17000 send_resp(dut, conn, SIGMA_ERROR,
17001 "ErrorCode,OverlapSession");
17002 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
17003 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
17004 } else {
17005 send_resp(dut, conn, SIGMA_ERROR,
17006 "ErrorCode,WPS operation failed");
17007 }
vamsi krishna9b144002017-09-20 13:28:13 +053017008 }
17009
17010fail:
17011 wpa_ctrl_detach(ctrl);
17012 wpa_ctrl_close(ctrl);
17013 return 0;
17014}
17015
17016
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017017static int req_intf(struct sigma_cmd *cmd)
17018{
17019 return get_param(cmd, "interface") == NULL ? -1 : 0;
17020}
17021
17022
17023void sta_register_cmds(void)
17024{
17025 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
17026 cmd_sta_get_ip_config);
17027 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
17028 cmd_sta_set_ip_config);
17029 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
17030 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
17031 cmd_sta_get_mac_address);
17032 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
17033 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
17034 cmd_sta_verify_ip_connection);
17035 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
17036 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
17037 cmd_sta_set_encryption);
17038 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
17039 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
17040 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
17041 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
17042 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
17043 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
17044 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
17045 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
17046 cmd_sta_set_eapakaprime);
17047 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
17048 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
17049 /* TODO: sta_set_ibss */
17050 /* TODO: sta_set_mode */
17051 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
17052 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
17053 /* TODO: sta_up_load */
17054 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
17055 cmd_sta_preset_testparameters);
17056 /* TODO: sta_set_system */
17057 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
17058 /* TODO: sta_set_rifs_test */
17059 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
17060 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
17061 /* TODO: sta_send_coexist_mgmt */
17062 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
17063 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
17064 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
17065 sigma_dut_reg_cmd("sta_reset_default", req_intf,
17066 cmd_sta_reset_default);
17067 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
17068 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
17069 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
17070 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
17071 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020017072 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017073 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
17074 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
17075 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
17076 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
17077 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030017078 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
17079 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017080 sigma_dut_reg_cmd("sta_add_credential", req_intf,
17081 cmd_sta_add_credential);
17082 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020017083 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017084 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
17085 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
17086 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
17087 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
17088 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
17089 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030017090 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017091 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
17092 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020017093 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053017094 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017095}