blob: c6d40cffabbaa315013fed3aae55bf156b81d275 [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) {
5969 if (strcasecmp(val, "Enable") == 0) {
5970 dut->sta_ft_ds = 1;
5971 } else if (strcasecmp(val, "Disable") == 0) {
5972 dut->sta_ft_ds = 0;
5973 } else {
5974 send_resp(dut, conn, SIGMA_ERROR,
5975 "errorCode,Unsupported value for FT_DS");
5976 return STATUS_SENT_ERROR;
5977 }
Shivani Baranwal7aa48602021-09-29 10:53:38 +05305978 if (get_driver_type(dut) == DRIVER_WCN &&
5979 sta_config_params(dut, intf, STA_SET_FT_DS,
5980 dut->sta_ft_ds) != 0) {
5981 send_resp(dut, conn, SIGMA_ERROR,
5982 "errorCode,Failed to enable/disable FT_DS");
5983 return STATUS_SENT_ERROR;
5984 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005985 }
5986
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005987 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03005988 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02005989 strcasecmp(val, "HS2-R3") == 0 ||
5990 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005991 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
5992 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005993
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005994 if (val && strcasecmp(val, "LOC") == 0)
5995 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02005996 if (val && strcasecmp(val, "60GHZ") == 0) {
5997 val = get_param(cmd, "WPS");
5998 if (val && strcasecmp(val, "disable") == 0) {
5999 dut->wps_disable = 1;
6000 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
6001 } else {
6002 /* wps_disable can have other value from the previous
6003 * test, so make sure it has the correct value.
6004 */
6005 dut->wps_disable = 0;
6006 }
6007
6008 val = get_param(cmd, "P2P");
6009 if (val && strcasecmp(val, "disable") == 0)
6010 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
6011 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07006012
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006013 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
6014 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
6015
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006016#ifdef ANDROID_NAN
6017 if (val && strcasecmp(val, "NAN") == 0)
6018 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
6019#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006020#ifdef MIRACAST
6021 if (val && (strcasecmp(val, "WFD") == 0 ||
6022 strcasecmp(val, "DisplayR2") == 0))
6023 return miracast_preset_testparameters(dut, conn, cmd);
6024#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006025
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07006026 if (val &&
6027 (strcasecmp(val, "MBO") == 0 || strcasecmp(val, "HE") == 0)) {
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306028 val = get_param(cmd, "Cellular_Data_Cap");
6029 if (val &&
6030 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
6031 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05306032
6033 val = get_param(cmd, "Ch_Pref");
6034 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
6035 return 0;
6036
Ashwini Patilc63161e2017-04-13 16:30:23 +05306037 val = get_param(cmd, "BSS_Transition");
6038 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
6039 return 0;
6040
Ashwini Patila75de5a2017-04-13 16:35:05 +05306041 val = get_param(cmd, "Assoc_Disallow");
6042 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
6043 return 0;
6044
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306045 val = get_param(cmd, "Roaming");
6046 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
6047 return 0;
6048
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306049 return 1;
6050 }
6051
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306052 if (val && strcasecmp(val, "OCE") == 0)
6053 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
6054
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006055#if 0
6056 val = get_param(cmd, "Supplicant");
6057 if (val && strcasecmp(val, "Default") != 0) {
6058 send_resp(dut, conn, SIGMA_ERROR,
6059 "ErrorCode,Only default(Vendor) supplicant "
6060 "supported");
6061 return 0;
6062 }
6063#endif
6064
6065 val = get_param(cmd, "RTS");
6066 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006067 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006068 case DRIVER_ATHEROS:
6069 ath_sta_set_rts(dut, intf, val);
6070 break;
6071 default:
6072#if 0
6073 send_resp(dut, conn, SIGMA_ERROR,
6074 "ErrorCode,Setting RTS not supported");
6075 return 0;
6076#else
6077 sigma_dut_print(dut, DUT_MSG_DEBUG,
6078 "Setting RTS not supported");
6079 break;
6080#endif
6081 }
6082 }
6083
6084#if 0
6085 val = get_param(cmd, "FRGMNT");
6086 if (val) {
6087 /* TODO */
6088 send_resp(dut, conn, SIGMA_ERROR,
6089 "ErrorCode,Setting FRGMNT not supported");
6090 return 0;
6091 }
6092#endif
6093
6094#if 0
6095 val = get_param(cmd, "Preamble");
6096 if (val) {
6097 /* TODO: Long/Short */
6098 send_resp(dut, conn, SIGMA_ERROR,
6099 "ErrorCode,Setting Preamble not supported");
6100 return 0;
6101 }
6102#endif
6103
6104 val = get_param(cmd, "Mode");
6105 if (val) {
6106 if (strcmp(val, "11b") == 0 ||
6107 strcmp(val, "11g") == 0 ||
6108 strcmp(val, "11a") == 0 ||
6109 strcmp(val, "11n") == 0 ||
6110 strcmp(val, "11ng") == 0 ||
6111 strcmp(val, "11nl") == 0 ||
6112 strcmp(val, "11nl(nabg)") == 0 ||
6113 strcmp(val, "AC") == 0 ||
6114 strcmp(val, "11AC") == 0 ||
6115 strcmp(val, "11ac") == 0 ||
6116 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08006117 strcmp(val, "11an") == 0 ||
6118 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006119 /* STA supports all modes by default */
6120 } else {
6121 send_resp(dut, conn, SIGMA_ERROR,
6122 "ErrorCode,Setting Mode not supported");
6123 return 0;
6124 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006125
6126 /* Change the mode only in case of testbed for HE program
6127 * and for 11a and 11g modes only. */
6128 if (dut->program == PROGRAM_HE &&
6129 dut->device_type == STA_testbed) {
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05306130 sta_set_phymode(dut, intf, val);
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006131 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006132 }
6133
6134 val = get_param(cmd, "wmm");
6135 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006136 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006137 case DRIVER_ATHEROS:
6138 ath_sta_set_wmm(dut, intf, val);
6139 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08006140 case DRIVER_WCN:
6141 wcn_sta_set_wmm(dut, intf, val);
6142 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006143 default:
6144 sigma_dut_print(dut, DUT_MSG_DEBUG,
6145 "Setting wmm not supported");
6146 break;
6147 }
6148 }
6149
6150 val = get_param(cmd, "Powersave");
6151 if (val) {
6152 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006153 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306154 if (set_power_save_wcn(dut, intf, 2) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006155 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006156 }
6157
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006158 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006159 "P2P_SET ps 0") < 0)
6160 return -2;
6161 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006162 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6163 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006164 } else if (strcmp(val, "1") == 0 ||
6165 strcasecmp(val, "PSPoll") == 0 ||
6166 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006167 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306168 if (set_power_save_wcn(dut, intf, 1) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006169 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006170 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006171 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006172 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006173 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006174 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006175 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006176 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006177 "P2P_SET ps 99") < 0)
6178 return -2;
6179 } else if (strcmp(val, "2") == 0 ||
6180 strcasecmp(val, "Fast") == 0) {
6181 /* TODO */
6182 send_resp(dut, conn, SIGMA_ERROR,
6183 "ErrorCode,Powersave=Fast not supported");
6184 return 0;
6185 } else if (strcmp(val, "3") == 0 ||
6186 strcasecmp(val, "PSNonPoll") == 0) {
6187 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006188 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6189 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006190
6191 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006192 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006193 "P2P_SET ps 1") < 0)
6194 return -2;
6195 } else
6196 return -1;
6197 }
6198
6199 val = get_param(cmd, "NoAck");
6200 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006201 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006202 case DRIVER_ATHEROS:
6203 ath_sta_set_noack(dut, intf, val);
6204 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08006205#ifdef NL80211_SUPPORT
6206 case DRIVER_WCN:
6207 wcn_sta_set_noack(dut, intf, val);
6208 break;
6209#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006210 default:
6211 send_resp(dut, conn, SIGMA_ERROR,
6212 "ErrorCode,Setting NoAck not supported");
6213 return 0;
6214 }
6215 }
6216
6217 val = get_param(cmd, "IgnoreChswitchProhibit");
6218 if (val) {
6219 /* TODO: Enabled/disabled */
6220 if (strcasecmp(val, "Enabled") == 0) {
6221 send_resp(dut, conn, SIGMA_ERROR,
6222 "ErrorCode,Enabling IgnoreChswitchProhibit "
6223 "not supported");
6224 return 0;
6225 }
6226 }
6227
6228 val = get_param(cmd, "TDLS");
6229 if (val) {
6230 if (strcasecmp(val, "Disabled") == 0) {
6231 if (wpa_command(intf, "SET tdls_disabled 1")) {
6232 send_resp(dut, conn, SIGMA_ERROR,
6233 "ErrorCode,Failed to disable TDLS");
6234 return 0;
6235 }
6236 } else if (strcasecmp(val, "Enabled") == 0) {
6237 if (wpa_command(intf, "SET tdls_disabled 0")) {
6238 send_resp(dut, conn, SIGMA_ERROR,
6239 "ErrorCode,Failed to enable TDLS");
6240 return 0;
6241 }
6242 } else {
6243 send_resp(dut, conn, SIGMA_ERROR,
6244 "ErrorCode,Unsupported TDLS value");
6245 return 0;
6246 }
6247 }
6248
6249 val = get_param(cmd, "TDLSmode");
6250 if (val) {
6251 if (strcasecmp(val, "Default") == 0) {
6252 wpa_command(intf, "SET tdls_testing 0");
6253 } else if (strcasecmp(val, "APProhibit") == 0) {
6254 if (wpa_command(intf, "SET tdls_testing 0x400")) {
6255 send_resp(dut, conn, SIGMA_ERROR,
6256 "ErrorCode,Failed to enable ignore "
6257 "APProhibit TDLS mode");
6258 return 0;
6259 }
6260 } else if (strcasecmp(val, "HiLoMac") == 0) {
6261 /* STA should respond with TDLS setup req for a TDLS
6262 * setup req */
6263 if (wpa_command(intf, "SET tdls_testing 0x80")) {
6264 send_resp(dut, conn, SIGMA_ERROR,
6265 "ErrorCode,Failed to enable HiLoMac "
6266 "TDLS mode");
6267 return 0;
6268 }
6269 } else if (strcasecmp(val, "WeakSecurity") == 0) {
6270 /*
6271 * Since all security modes are enabled by default when
6272 * Sigma control is used, there is no need to do
6273 * anything here.
6274 */
6275 } else if (strcasecmp(val, "ExistLink") == 0) {
6276 /*
6277 * Since we allow new TDLS Setup Request even if there
6278 * is an existing link, nothing needs to be done for
6279 * this.
6280 */
6281 } else {
6282 /* TODO:
6283 * ExistLink: STA should send TDLS setup req even if
6284 * direct link already exists
6285 */
6286 send_resp(dut, conn, SIGMA_ERROR,
6287 "ErrorCode,Unsupported TDLSmode value");
6288 return 0;
6289 }
6290 }
6291
6292 val = get_param(cmd, "FakePubKey");
6293 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
6294 send_resp(dut, conn, SIGMA_ERROR,
6295 "ErrorCode,Failed to enable FakePubKey");
6296 return 0;
6297 }
6298
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08006299#ifdef NL80211_SUPPORT
6300 val = get_param(cmd, "FrgmntSupport");
6301 if (val) {
6302 if (strcasecmp(val, "Enable") == 0) {
6303 if (sta_set_he_fragmentation(dut, intf,
6304 HE_FRAG_LEVEL1)) {
6305 send_resp(dut, conn, SIGMA_ERROR,
6306 "ErrorCode,Failed to enable HE Fragmentation");
6307 return 0;
6308 }
6309 } else if (strcasecmp(val, "Disable") == 0) {
6310 if (sta_set_he_fragmentation(dut, intf,
6311 HE_FRAG_DISABLE)) {
6312 send_resp(dut, conn, SIGMA_ERROR,
6313 "ErrorCode,Failed to disable HE Fragmentation");
6314 return 0;
6315 }
6316 }
6317 }
6318#endif /* NL80211_SUPPORT */
6319
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306320 val = get_param(cmd, "IncludeMSCSDescriptor");
6321 if (val && strcasecmp(val, "1") == 0) {
6322 char buf[128];
6323 int len;
6324
6325 len = snprintf(buf, sizeof(buf),
Veerendranath Jakkam62cde372020-08-19 18:03:06 +05306326 "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=60000 frame_classifier=045F%032x",
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306327 0);
6328
6329 if (len < 0 || len >= sizeof(buf)) {
6330 sigma_dut_print(dut, DUT_MSG_ERROR,
6331 "Failed to build MSCS Descriptor IE");
6332 return ERROR_SEND_STATUS;
6333 }
6334
6335 if (wpa_command(intf, buf) != 0) {
6336 send_resp(dut, conn, SIGMA_ERROR,
6337 "ErrorCode,Failed to include MSCS descriptor");
6338 return STATUS_SENT_ERROR;
6339 }
6340 }
6341
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306342 val = get_param(cmd, "SCSSupport");
6343 if (val) {
6344 char buf[30];
6345 int disable_scs, len;
6346
6347 if (strcasecmp(val, "Enable") == 0) {
6348 disable_scs = 0;
6349 } else if (strcasecmp(val, "Disable") == 0) {
6350 disable_scs = 1;
6351 } else {
6352 sigma_dut_print(dut, DUT_MSG_ERROR,
6353 "Invalid SCSsupport parameter");
6354 return INVALID_SEND_STATUS;
6355 }
6356
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306357 if (disable_scs || dut->prev_disable_scs_support) {
6358 len = snprintf(buf, sizeof(buf),
6359 "SET disable_scs_support %d",
6360 disable_scs);
6361 if (len < 0 || len >= sizeof(buf) ||
6362 wpa_command(intf, buf) != 0) {
6363 send_resp(dut, conn, SIGMA_ERROR,
6364 "ErrorCode,Failed to update SCS support");
6365 return STATUS_SENT_ERROR;
6366 }
6367 dut->prev_disable_scs_support = disable_scs;
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306368 }
6369 }
6370
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306371 val = get_param(cmd, "MSCSSupport");
6372 if (val) {
6373 char buf[30];
6374 int disable_mscs, len;
6375
6376 if (strcasecmp(val, "Enable") == 0) {
6377 disable_mscs = 0;
6378 } else if (strcasecmp(val, "Disable") == 0) {
6379 disable_mscs = 1;
6380 } else {
6381 sigma_dut_print(dut, DUT_MSG_ERROR,
6382 "Invalid MSCSsupport parameter");
6383 return INVALID_SEND_STATUS;
6384 }
6385
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306386 if (disable_mscs || dut->prev_disable_mscs_support) {
6387 len = snprintf(buf, sizeof(buf),
6388 "SET disable_mscs_support %d",
6389 disable_mscs);
6390 if (len < 0 || len >= sizeof(buf) ||
6391 wpa_command(intf, buf) != 0) {
6392 send_resp(dut, conn, SIGMA_ERROR,
6393 "ErrorCode,Failed to update MSCS support");
6394 return STATUS_SENT_ERROR;
6395 }
6396 dut->prev_disable_mscs_support = disable_mscs;
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306397 }
6398 }
6399
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05306400 val = get_param(cmd, "DSCPPolicyCapability");
6401 if (val) {
6402 char buf[35];
6403 int len;
6404
6405 if (strcasecmp(val, "Enable") == 0) {
6406 len = snprintf(buf, sizeof(buf),
6407 "SET enable_dscp_policy_capa 1");
6408 } else if (strcasecmp(val, "Disable") == 0) {
6409 len = snprintf(buf, sizeof(buf),
6410 "SET enable_dscp_policy_capa 0");
6411 } else {
6412 sigma_dut_print(dut, DUT_MSG_ERROR,
6413 "Invalid DSCP policy parameter");
6414 return INVALID_SEND_STATUS;
6415 }
6416
6417 if (len < 0 || len >= sizeof(buf) ||
6418 wpa_command(intf, buf) != 0) {
6419 send_resp(dut, conn, SIGMA_ERROR,
6420 "ErrorCode,Failed to update DSCP policy capability");
6421 return STATUS_SENT_ERROR;
6422 }
6423 }
6424
6425 val = get_param(cmd, "DSCPPolicyRespParams");
6426 if (val) {
6427 if (strcasecmp(val, "RejectAll") == 0) {
6428 dut->reject_dscp_policies = 1;
6429 dut->dscp_reject_resp_code = DSCP_POLICY_REJECT;
6430 } else if (strcasecmp(val, "AcceptAll") == 0) {
6431 dut->reject_dscp_policies = 0;
6432 }
6433 }
6434
6435 val = get_param(cmd, "DSCPPolicyResp_StatusCode");
6436 if (val)
6437 dut->dscp_reject_resp_code = atoi(val);
6438
Veerendranath Jakkamf6c8ab52022-03-10 05:43:02 -08006439 val = get_param(cmd, "Deauth_Reconnect_Policy");
6440 if (val) {
6441 char buf[35];
6442 int len;
6443
6444 if (strcasecmp(val, "0") == 0) {
6445 len = snprintf(buf, sizeof(buf),
6446 "STA_AUTOCONNECT %d",
6447 dut->autoconnect_default);
6448 } else if (strcasecmp(val, "1") == 0) {
6449 len = snprintf(buf, sizeof(buf),
6450 "STA_AUTOCONNECT 0");
6451 } else if (strcasecmp(val, "2") == 0) {
6452 len = snprintf(buf, sizeof(buf),
6453 "STA_AUTOCONNECT 1");
6454 } else {
6455 sigma_dut_print(dut, DUT_MSG_ERROR,
6456 "Invalid Deauth_Reconnect_Policy");
6457 return INVALID_SEND_STATUS;
6458 }
6459
6460 if (len < 0 || len >= sizeof(buf) ||
6461 wpa_command(intf, buf) != 0) {
6462 send_resp(dut, conn, SIGMA_ERROR,
6463 "ErrorCode,Failed to update Deauth_Reconnect_Policy");
6464 return STATUS_SENT_ERROR;
6465 }
6466 }
6467
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006468 return 1;
6469}
6470
6471
6472static const char * ath_get_radio_name(const char *radio_name)
6473{
6474 if (radio_name == NULL)
6475 return "wifi0";
6476 if (strcmp(radio_name, "wifi1") == 0)
6477 return "wifi1";
6478 if (strcmp(radio_name, "wifi2") == 0)
6479 return "wifi2";
6480 return "wifi0";
6481}
6482
6483
6484static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
6485 const char *val)
6486{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006487 unsigned int vht_mcsmap = 0;
6488 int txchainmask = 0;
6489 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6490
6491 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6492 if (dut->testbed_flag_txsp == 1) {
6493 vht_mcsmap = 0xfffc;
6494 dut->testbed_flag_txsp = 0;
6495 } else {
6496 vht_mcsmap = 0xfffe;
6497 }
6498 txchainmask = 1;
6499 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6500 if (dut->testbed_flag_txsp == 1) {
6501 vht_mcsmap = 0xfff0;
6502 dut->testbed_flag_txsp = 0;
6503 } else {
6504 vht_mcsmap = 0xfffa;
6505 }
6506 txchainmask = 3;
6507 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6508 if (dut->testbed_flag_txsp == 1) {
6509 vht_mcsmap = 0xffc0;
6510 dut->testbed_flag_txsp = 0;
6511 } else {
6512 vht_mcsmap = 0xffea;
6513 }
6514 txchainmask = 7;
6515 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6516 if (dut->testbed_flag_txsp == 1) {
6517 vht_mcsmap = 0xff00;
6518 dut->testbed_flag_txsp = 0;
6519 } else {
6520 vht_mcsmap = 0xffaa;
6521 }
6522 txchainmask = 15;
6523 } else {
6524 if (dut->testbed_flag_txsp == 1) {
6525 vht_mcsmap = 0xffc0;
6526 dut->testbed_flag_txsp = 0;
6527 } else {
6528 vht_mcsmap = 0xffea;
6529 }
6530 }
6531
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006532 if (txchainmask)
6533 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006534
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006535 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006536}
6537
6538
6539static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
6540 const char *val)
6541{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006542 unsigned int vht_mcsmap = 0;
6543 int rxchainmask = 0;
6544 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6545
6546 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6547 if (dut->testbed_flag_rxsp == 1) {
6548 vht_mcsmap = 0xfffc;
6549 dut->testbed_flag_rxsp = 0;
6550 } else {
6551 vht_mcsmap = 0xfffe;
6552 }
6553 rxchainmask = 1;
6554 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6555 if (dut->testbed_flag_rxsp == 1) {
6556 vht_mcsmap = 0xfff0;
6557 dut->testbed_flag_rxsp = 0;
6558 } else {
6559 vht_mcsmap = 0xfffa;
6560 }
6561 rxchainmask = 3;
6562 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6563 if (dut->testbed_flag_rxsp == 1) {
6564 vht_mcsmap = 0xffc0;
6565 dut->testbed_flag_rxsp = 0;
6566 } else {
6567 vht_mcsmap = 0xffea;
6568 }
6569 rxchainmask = 7;
6570 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6571 if (dut->testbed_flag_rxsp == 1) {
6572 vht_mcsmap = 0xff00;
6573 dut->testbed_flag_rxsp = 0;
6574 } else {
6575 vht_mcsmap = 0xffaa;
6576 }
6577 rxchainmask = 15;
6578 } else {
6579 if (dut->testbed_flag_rxsp == 1) {
6580 vht_mcsmap = 0xffc0;
6581 dut->testbed_flag_rxsp = 0;
6582 } else {
6583 vht_mcsmap = 0xffea;
6584 }
6585 }
6586
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006587 if (rxchainmask)
6588 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006589
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006590 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006591}
6592
6593
6594void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
6595{
6596 if (strcasecmp(val, "enable") == 0) {
6597 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
6598 != 0) {
6599 sigma_dut_print(dut, DUT_MSG_ERROR,
6600 "Disable BB_VHTSIGB_CRC_CALC failed");
6601 }
6602
6603 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
6604 != 0) {
6605 sigma_dut_print(dut, DUT_MSG_ERROR,
6606 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6607 }
6608 } else {
6609 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
6610 != 0) {
6611 sigma_dut_print(dut, DUT_MSG_ERROR,
6612 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6613 }
6614
6615 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
6616 != 0) {
6617 sigma_dut_print(dut, DUT_MSG_ERROR,
6618 "Enable BB_VHTSIGB_CRC_CALC failed");
6619 }
6620 }
6621}
6622
6623
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006624static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
6625 const char *val)
6626{
6627 char buf[60];
6628
Shivani Baranwal2a572842021-09-16 12:27:15 +05306629#ifdef NL80211_SUPPORT
6630 enum nl80211_chan_width qca_channel_width;
6631
6632 if (strcmp(val, "20") == 0) {
6633 qca_channel_width = NL80211_CHAN_WIDTH_20;
6634 dut->chwidth = 0;
6635 } else if (strcmp(val, "40") == 0) {
6636 qca_channel_width = NL80211_CHAN_WIDTH_40;
6637 dut->chwidth = 1;
6638 } else if (strcmp(val, "80") == 0) {
6639 qca_channel_width = NL80211_CHAN_WIDTH_80;
6640 dut->chwidth = 2;
6641 } else if (strcmp(val, "160") == 0) {
6642 qca_channel_width = NL80211_CHAN_WIDTH_160;
6643 dut->chwidth = 3;
6644 } else if (strcasecmp(val, "Auto") == 0) {
6645 return 0;
6646 } else {
6647 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6648 val);
6649 return -1;
6650 }
6651 if (sta_config_params(dut, intf, STA_SET_CHAN_WIDTH,
6652 qca_channel_width) == 0)
6653 return 0;
6654#endif /* NL80211_SUPPORT */
6655
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006656 if (strcmp(val, "20") == 0) {
6657 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
6658 dut->chwidth = 0;
6659 } else if (strcmp(val, "40") == 0) {
6660 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
6661 dut->chwidth = 1;
6662 } else if (strcmp(val, "80") == 0) {
6663 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
6664 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05306665 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006666 buf[0] = '\0';
6667 } else {
6668 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6669 val);
6670 return -1;
6671 }
6672
6673 if (buf[0] != '\0' && system(buf) != 0) {
6674 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
6675 return -1;
6676 }
6677
6678 return 0;
6679}
6680
6681
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006682static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
6683 const char *intf, int addbareject)
6684{
6685#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306686 return wcn_wifi_test_config_set_u8(
6687 dut, intf,
6688 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
6689 !addbareject);
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006690#else /* NL80211_SUPPORT */
6691 sigma_dut_print(dut, DUT_MSG_ERROR,
6692 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
6693 return -1;
6694#endif /* NL80211_SUPPORT */
6695}
6696
6697
6698static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
6699 int addbareject)
6700{
6701 int ret;
6702
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006703 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006704 case DRIVER_WCN:
6705 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
6706 if (ret) {
6707 sigma_dut_print(dut, DUT_MSG_ERROR,
6708 "nlvendor_sta_set_addba_reject failed, ret:%d",
6709 ret);
6710 return ret;
6711 }
6712 break;
6713 default:
6714 sigma_dut_print(dut, DUT_MSG_ERROR,
6715 "errorCode,Unsupported ADDBA_REJECT with the current driver");
6716 ret = -1;
6717 break;
6718 }
6719
6720 return ret;
6721}
6722
6723
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006724static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
6725 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006726{
6727#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306728 return wcn_wifi_test_config_set_u8(
6729 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
6730 enable);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006731#else /* NL80211_SUPPORT */
6732 sigma_dut_print(dut, DUT_MSG_ERROR,
6733 "Disable addba not possible without NL80211_SUPPORT defined");
6734 return -1;
6735#endif /* NL80211_SUPPORT */
6736}
6737
6738
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306739#ifdef NL80211_SUPPORT
6740static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6741{
6742 struct nl_msg *msg;
6743 int ret = 0;
6744 int ifindex;
6745
6746 ifindex = if_nametoindex(intf);
6747 if (ifindex == 0) {
6748 sigma_dut_print(dut, DUT_MSG_ERROR,
6749 "%s: Index for interface %s failed",
6750 __func__, intf);
6751 return -1;
6752 }
6753
6754 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6755 NL80211_CMD_SET_WIPHY)) ||
6756 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
6757 sigma_dut_print(dut, DUT_MSG_ERROR,
6758 "%s: err in adding RTS threshold",
6759 __func__);
6760 nlmsg_free(msg);
6761 return -1;
6762 }
6763
6764 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6765 if (ret) {
6766 sigma_dut_print(dut, DUT_MSG_ERROR,
6767 "%s: err in send_and_recv_msgs, ret=%d",
6768 __func__, ret);
6769 }
6770 return ret;
6771}
6772#endif /* NL80211_SUPPORT */
6773
6774
6775static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6776{
6777 char buf[100];
6778
6779#ifdef NL80211_SUPPORT
6780 if (nl80211_sta_set_rts(dut, intf, val) == 0)
6781 return 0;
6782 sigma_dut_print(dut, DUT_MSG_DEBUG,
6783 "Fall back to using iwconfig for setting RTS threshold");
6784#endif /* NL80211_SUPPORT */
6785
6786 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
6787 if (system(buf) != 0) {
6788 sigma_dut_print(dut, DUT_MSG_ERROR,
6789 "Failed to set RTS threshold %d", val);
6790 return -1;
6791 }
6792 return 0;
6793}
6794
6795
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006796static enum sigma_cmd_result
6797cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
6798 struct sigma_conn *conn, struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006799{
6800 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006801 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006802 char buf[128];
6803 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006804
6805 val = get_param(cmd, "40_INTOLERANT");
6806 if (val) {
6807 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6808 /* TODO: iwpriv ht40intol through wpa_supplicant */
6809 send_resp(dut, conn, SIGMA_ERROR,
6810 "ErrorCode,40_INTOLERANT not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006811 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006812 }
6813 }
6814
6815 val = get_param(cmd, "ADDBA_REJECT");
6816 if (val) {
6817 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6818 /* reject any ADDBA with status "decline" */
6819 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006820 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006821 } else {
6822 /* accept ADDBA */
6823 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006824 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006825 }
6826 }
6827
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006828 if (addbareject >= 0 &&
6829 sta_set_addba_reject(dut, intf, addbareject) < 0) {
6830 send_resp(dut, conn, SIGMA_ERROR,
6831 "ErrorCode,set addba_reject failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006832 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006833 }
6834
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006835 val = get_param(cmd, "AMPDU");
6836 if (val) {
6837 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6838 /* enable AMPDU Aggregation */
6839 if (ampdu == 0) {
6840 send_resp(dut, conn, SIGMA_ERROR,
6841 "ErrorCode,Mismatch in "
6842 "addba_reject/ampdu - "
6843 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006844 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006845 }
6846 ampdu = 1;
6847 } else {
6848 /* disable AMPDU Aggregation */
6849 if (ampdu == 1) {
6850 send_resp(dut, conn, SIGMA_ERROR,
6851 "ErrorCode,Mismatch in "
6852 "addba_reject/ampdu - "
6853 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006854 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006855 }
6856 ampdu = 0;
6857 }
6858 }
6859
6860 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006861 int ret;
6862
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006863 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
6864 ampdu ? "Enabling" : "Disabling");
6865 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07006866 if (wpa_command(intf, buf) < 0 &&
6867 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006868 send_resp(dut, conn, SIGMA_ERROR,
6869 "ErrorCode,set aggr failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006870 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006871 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006872
6873 if (ampdu == 0) {
6874 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006875 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006876 if (ret) {
6877 sigma_dut_print(dut, DUT_MSG_ERROR,
6878 "Failed to disable addba, ret:%d",
6879 ret);
6880 }
6881 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006882 }
6883
6884 val = get_param(cmd, "AMSDU");
6885 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006886 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006887 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006888 case DRIVER_WCN:
6889 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006890 break;
6891 default:
6892 if (strcmp(val, "1") == 0 ||
6893 strcasecmp(val, "Enable") == 0) {
6894 /* Enable AMSDU Aggregation */
6895 send_resp(dut, conn, SIGMA_ERROR,
6896 "ErrorCode,AMSDU aggregation not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006897 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006898 }
6899 break;
6900 }
6901 }
6902
6903 val = get_param(cmd, "STBC_RX");
6904 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006905 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006906 case DRIVER_ATHEROS:
6907 ath_sta_set_stbc(dut, intf, val);
6908 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05306909 case DRIVER_WCN:
6910 wcn_sta_set_stbc(dut, intf, val);
6911 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006912 default:
6913 send_resp(dut, conn, SIGMA_ERROR,
6914 "ErrorCode,STBC_RX not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006915 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006916 }
6917 }
6918
6919 val = get_param(cmd, "WIDTH");
6920 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006921 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006922 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006923 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006924 send_resp(dut, conn, SIGMA_ERROR,
6925 "ErrorCode,Failed to set WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006926 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006927 }
6928 break;
6929 case DRIVER_ATHEROS:
6930 if (ath_set_width(dut, conn, intf, val) < 0)
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006931 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006932 break;
6933 default:
6934 sigma_dut_print(dut, DUT_MSG_ERROR,
6935 "Setting WIDTH not supported");
6936 break;
6937 }
6938 }
6939
6940 val = get_param(cmd, "SMPS");
6941 if (val) {
6942 /* TODO: Dynamic/0, Static/1, No Limit/2 */
6943 send_resp(dut, conn, SIGMA_ERROR,
6944 "ErrorCode,SMPS not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006945 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006946 }
6947
6948 val = get_param(cmd, "TXSP_STREAM");
6949 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006950 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006951 case DRIVER_WCN:
6952 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6953 send_resp(dut, conn, SIGMA_ERROR,
6954 "ErrorCode,Failed to set TXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006955 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006956 }
6957 break;
6958 case DRIVER_ATHEROS:
6959 ath_sta_set_txsp_stream(dut, intf, val);
6960 break;
6961 default:
6962 sigma_dut_print(dut, DUT_MSG_ERROR,
6963 "Setting TXSP_STREAM not supported");
6964 break;
6965 }
6966 }
6967
6968 val = get_param(cmd, "RXSP_STREAM");
6969 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006970 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006971 case DRIVER_WCN:
6972 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6973 send_resp(dut, conn, SIGMA_ERROR,
6974 "ErrorCode,Failed to set RXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006975 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006976 }
6977 break;
6978 case DRIVER_ATHEROS:
6979 ath_sta_set_rxsp_stream(dut, intf, val);
6980 break;
6981 default:
6982 sigma_dut_print(dut, DUT_MSG_ERROR,
6983 "Setting RXSP_STREAM not supported");
6984 break;
6985 }
6986 }
6987
6988 val = get_param(cmd, "DYN_BW_SGNL");
6989 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006990 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006991 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08006992 if (strcasecmp(val, "enable") == 0) {
6993 snprintf(buf, sizeof(buf),
6994 "iwpriv %s cwmenable 1", intf);
6995 if (system(buf) != 0) {
6996 sigma_dut_print(dut, DUT_MSG_ERROR,
6997 "iwpriv cwmenable 1 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006998 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006999 }
7000 } else if (strcasecmp(val, "disable") == 0) {
7001 snprintf(buf, sizeof(buf),
7002 "iwpriv %s cwmenable 0", intf);
7003 if (system(buf) != 0) {
7004 sigma_dut_print(dut, DUT_MSG_ERROR,
7005 "iwpriv cwmenable 0 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007006 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08007007 }
7008 } else {
7009 sigma_dut_print(dut, DUT_MSG_ERROR,
7010 "Unsupported DYN_BW_SGL");
7011 }
7012
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007013 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
7014 if (system(buf) != 0) {
7015 sigma_dut_print(dut, DUT_MSG_ERROR,
7016 "Failed to set cts_cbw in DYN_BW_SGNL");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007017 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007018 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08007019 break;
7020 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07007021 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08007022 ath_config_dyn_bw_sig(dut, intf, val);
7023 break;
7024 default:
7025 sigma_dut_print(dut, DUT_MSG_ERROR,
7026 "Failed to set DYN_BW_SGNL");
7027 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007028 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007029 }
7030
7031 val = get_param(cmd, "RTS_FORCE");
7032 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07007033 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007034 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307035 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007036 sigma_dut_print(dut, DUT_MSG_ERROR,
7037 "Failed to set RTS_FORCE 64");
7038 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03007039 res = snprintf(buf, sizeof(buf),
7040 "wifitool %s beeliner_fw_test 100 1",
7041 intf);
7042 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08007043 sigma_dut_print(dut, DUT_MSG_ERROR,
7044 "wifitool beeliner_fw_test 100 1 failed");
7045 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007046 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307047 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007048 sigma_dut_print(dut, DUT_MSG_ERROR,
7049 "Failed to set RTS_FORCE 2347");
7050 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007051 } else {
7052 send_resp(dut, conn, SIGMA_ERROR,
7053 "ErrorCode,RTS_FORCE value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007054 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007055 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007056 }
7057
7058 val = get_param(cmd, "CTS_WIDTH");
7059 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007060 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007061 case DRIVER_WCN:
7062 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
7063 send_resp(dut, conn, SIGMA_ERROR,
7064 "ErrorCode,Failed to set CTS_WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007065 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007066 }
7067 break;
7068 case DRIVER_ATHEROS:
7069 ath_set_cts_width(dut, intf, val);
7070 break;
7071 default:
7072 sigma_dut_print(dut, DUT_MSG_ERROR,
7073 "Setting CTS_WIDTH not supported");
7074 break;
7075 }
7076 }
7077
7078 val = get_param(cmd, "BW_SGNL");
7079 if (val) {
7080 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007081 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007082 } else if (strcasecmp(val, "Disable") == 0) {
7083 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007084 } else {
7085 send_resp(dut, conn, SIGMA_ERROR,
7086 "ErrorCode,BW_SGNL value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007087 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007088 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007089 }
7090
7091 val = get_param(cmd, "Band");
7092 if (val) {
7093 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
7094 /* STA supports all bands by default */
7095 } else {
7096 send_resp(dut, conn, SIGMA_ERROR,
7097 "ErrorCode,Unsupported Band");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007098 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007099 }
7100 }
7101
7102 val = get_param(cmd, "zero_crc");
7103 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007104 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007105 case DRIVER_ATHEROS:
7106 ath_set_zero_crc(dut, val);
7107 break;
7108 default:
7109 break;
7110 }
7111 }
7112
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007113 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007114}
7115
7116
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007117static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7118{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007119 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007120#ifdef __linux__
7121 case DRIVER_WIL6210:
7122 return wil6210_set_force_mcs(dut, force, mcs);
7123#endif /* __linux__ */
7124 default:
7125 sigma_dut_print(dut, DUT_MSG_ERROR,
7126 "Unsupported sta_set_force_mcs with the current driver");
7127 return -1;
7128 }
7129}
7130
7131
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007132static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
7133{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007134 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007135#ifdef __linux__
7136 case DRIVER_WIL6210:
7137 return wil6210_force_rsn_ie(dut, state);
7138#endif /* __linux__ */
7139 default:
7140 sigma_dut_print(dut, DUT_MSG_ERROR,
7141 "Unsupported sta_60g_force_rsn_ie with the current driver");
7142 return -1;
7143 }
7144}
7145
7146
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007147static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
7148 struct sigma_cmd *cmd)
7149{
7150 const char *val;
7151 char buf[100];
7152
7153 val = get_param(cmd, "MSDUSize");
7154 if (val) {
7155 int mtu;
7156
7157 dut->amsdu_size = atoi(val);
7158 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
7159 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
7160 sigma_dut_print(dut, DUT_MSG_ERROR,
7161 "MSDUSize %d is above max %d or below min %d",
7162 dut->amsdu_size,
7163 IEEE80211_MAX_DATA_LEN_DMG,
7164 IEEE80211_SNAP_LEN_DMG);
7165 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007166 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007167 }
7168
7169 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
7170 sigma_dut_print(dut, DUT_MSG_DEBUG,
7171 "Setting amsdu_size to %d", mtu);
7172 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007173 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007174
7175 if (system(buf) != 0) {
7176 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7177 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007178 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007179 }
7180 }
7181
7182 val = get_param(cmd, "BAckRcvBuf");
7183 if (val) {
7184 dut->back_rcv_buf = atoi(val);
7185 if (dut->back_rcv_buf == 0) {
7186 sigma_dut_print(dut, DUT_MSG_ERROR,
7187 "Failed to convert %s or value is 0",
7188 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007189 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007190 }
7191
7192 sigma_dut_print(dut, DUT_MSG_DEBUG,
7193 "Setting BAckRcvBuf to %s", val);
7194 }
7195
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007196 val = get_param(cmd, "MCS_FixedRate");
7197 if (val) {
7198 if (sta_set_force_mcs(dut, 1, atoi(val))) {
7199 sigma_dut_print(dut, DUT_MSG_ERROR,
7200 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007201 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007202 }
7203 }
7204
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007205 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007206}
7207
7208
7209static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
7210 struct sigma_cmd *cmd)
7211{
7212 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007213 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007214 const char *val;
7215 char buf[100];
7216
7217 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007218 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007219 if (wpa_command(ifname, "PING") != 0) {
7220 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007221 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007222 }
7223
7224 wpa_command(ifname, "FLUSH");
7225 net_id = add_network_common(dut, conn, ifname, cmd);
7226 if (net_id < 0) {
7227 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
7228 return net_id;
7229 }
7230
7231 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
7232 if (set_network(ifname, net_id, "mode", "2") < 0) {
7233 sigma_dut_print(dut, DUT_MSG_ERROR,
7234 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007235 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007236 }
7237
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02007238 if (set_network(ifname, net_id, "pbss", "1") < 0)
7239 return -2;
7240
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007241 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007242 "Supplicant set network with mode 2. network_id %d",
7243 net_id);
7244
7245 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
7246 sigma_dut_print(dut, DUT_MSG_INFO,
7247 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007248 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007249 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007250
7251 val = get_param(cmd, "Security");
7252 if (val && strcasecmp(val, "OPEN") == 0) {
7253 dut->ap_key_mgmt = AP_OPEN;
7254 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
7255 sigma_dut_print(dut, DUT_MSG_ERROR,
7256 "Failed to set supplicant to %s security",
7257 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007258 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007259 }
7260 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
7261 dut->ap_key_mgmt = AP_WPA2_PSK;
7262 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
7263 sigma_dut_print(dut, DUT_MSG_ERROR,
7264 "Failed to set supplicant to %s security",
7265 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007266 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007267 }
7268
7269 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
7270 sigma_dut_print(dut, DUT_MSG_ERROR,
7271 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007272 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007273 }
7274 } else if (val) {
7275 sigma_dut_print(dut, DUT_MSG_ERROR,
7276 "Requested Security %s is not supported on 60GHz",
7277 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007278 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007279 }
7280
7281 val = get_param(cmd, "Encrypt");
7282 if (val && strcasecmp(val, "AES-GCMP") == 0) {
7283 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
7284 sigma_dut_print(dut, DUT_MSG_ERROR,
7285 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007286 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007287 }
7288 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
7289 sigma_dut_print(dut, DUT_MSG_ERROR,
7290 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007291 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007292 }
7293 } else if (val) {
7294 sigma_dut_print(dut, DUT_MSG_ERROR,
7295 "Requested Encrypt %s is not supported on 60 GHz",
7296 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007297 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007298 }
7299
7300 val = get_param(cmd, "PSK");
7301 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
7302 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
7303 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007304 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007305 }
7306
7307 /* Convert 60G channel to freq */
7308 switch (dut->ap_channel) {
7309 case 1:
7310 val = "58320";
7311 break;
7312 case 2:
7313 val = "60480";
7314 break;
7315 case 3:
7316 val = "62640";
7317 break;
7318 default:
7319 sigma_dut_print(dut, DUT_MSG_ERROR,
7320 "Failed to configure channel %d. Not supported",
7321 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007322 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007323 }
7324
7325 if (set_network(ifname, net_id, "frequency", val) < 0) {
7326 sigma_dut_print(dut, DUT_MSG_ERROR,
7327 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007328 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007329 }
7330
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02007331 if (dut->eap_fragment) {
7332 sigma_dut_print(dut, DUT_MSG_DEBUG,
7333 "Set EAP fragment size to 128 bytes.");
7334 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
7335 return ERROR_SEND_STATUS;
7336 }
7337
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007338 sigma_dut_print(dut, DUT_MSG_DEBUG,
7339 "Supplicant set network with frequency");
7340
7341 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
7342 if (wpa_command(ifname, buf) < 0) {
7343 sigma_dut_print(dut, DUT_MSG_INFO,
7344 "Failed to select network id %d on %s",
7345 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007346 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007347 }
7348
7349 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
7350
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007351 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007352}
7353
7354
Lior David67543f52017-01-03 19:04:22 +02007355static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
7356{
7357 char buf[128], fname[128];
7358 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03007359 int res;
Lior David67543f52017-01-03 19:04:22 +02007360
7361 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
7362 sigma_dut_print(dut, DUT_MSG_ERROR,
7363 "failed to get wil6210 debugfs dir");
7364 return -1;
7365 }
7366
Jouni Malinen3aa72862019-05-29 23:14:51 +03007367 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
7368 if (res < 0 || res >= sizeof(fname))
7369 return -1;
Lior David67543f52017-01-03 19:04:22 +02007370 f = fopen(fname, "w");
7371 if (!f) {
7372 sigma_dut_print(dut, DUT_MSG_ERROR,
7373 "failed to open: %s", fname);
7374 return -1;
7375 }
7376
7377 fprintf(f, "%d\n", abft_len);
7378 fclose(f);
7379
7380 return 0;
7381}
7382
7383
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02007384int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
7385 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02007386{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007387 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02007388 case DRIVER_WIL6210:
7389 return wil6210_set_abft_len(dut, abft_len);
7390 default:
7391 sigma_dut_print(dut, DUT_MSG_ERROR,
7392 "set abft_len not supported");
7393 return -1;
7394 }
7395}
7396
7397
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007398static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
7399 struct sigma_cmd *cmd)
7400{
7401 const char *val;
Lior David67543f52017-01-03 19:04:22 +02007402 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007403
7404 if (dut->dev_role != DEVROLE_PCP) {
7405 send_resp(dut, conn, SIGMA_INVALID,
7406 "ErrorCode,Invalid DevRole");
7407 return 0;
7408 }
7409
7410 val = get_param(cmd, "SSID");
7411 if (val) {
7412 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
7413 send_resp(dut, conn, SIGMA_INVALID,
7414 "ErrorCode,Invalid SSID");
7415 return -1;
7416 }
7417
Peng Xub8fc5cc2017-05-10 17:27:28 -07007418 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007419 }
7420
7421 val = get_param(cmd, "CHANNEL");
7422 if (val) {
7423 const char *pos;
7424
7425 dut->ap_channel = atoi(val);
7426 pos = strchr(val, ';');
7427 if (pos) {
7428 pos++;
7429 dut->ap_channel_1 = atoi(pos);
7430 }
7431 }
7432
7433 switch (dut->ap_channel) {
7434 case 1:
7435 case 2:
7436 case 3:
7437 break;
7438 default:
7439 sigma_dut_print(dut, DUT_MSG_ERROR,
7440 "Channel %d is not supported", dut->ap_channel);
7441 send_resp(dut, conn, SIGMA_ERROR,
7442 "Requested channel is not supported");
7443 return -1;
7444 }
7445
7446 val = get_param(cmd, "BCNINT");
7447 if (val)
7448 dut->ap_bcnint = atoi(val);
7449
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007450 val = get_param(cmd, "AllocType");
7451 if (val) {
7452 send_resp(dut, conn, SIGMA_ERROR,
7453 "ErrorCode,AllocType is not supported yet");
7454 return -1;
7455 }
7456
7457 val = get_param(cmd, "PercentBI");
7458 if (val) {
7459 send_resp(dut, conn, SIGMA_ERROR,
7460 "ErrorCode,PercentBI is not supported yet");
7461 return -1;
7462 }
7463
7464 val = get_param(cmd, "CBAPOnly");
7465 if (val) {
7466 send_resp(dut, conn, SIGMA_ERROR,
7467 "ErrorCode,CBAPOnly is not supported yet");
7468 return -1;
7469 }
7470
7471 val = get_param(cmd, "AMPDU");
7472 if (val) {
7473 if (strcasecmp(val, "Enable") == 0)
7474 dut->ap_ampdu = 1;
7475 else if (strcasecmp(val, "Disable") == 0)
7476 dut->ap_ampdu = 2;
7477 else {
7478 send_resp(dut, conn, SIGMA_ERROR,
7479 "ErrorCode,AMPDU value is not Enable nor Disabled");
7480 return -1;
7481 }
7482 }
7483
7484 val = get_param(cmd, "AMSDU");
7485 if (val) {
7486 if (strcasecmp(val, "Enable") == 0)
7487 dut->ap_amsdu = 1;
7488 else if (strcasecmp(val, "Disable") == 0)
7489 dut->ap_amsdu = 2;
7490 }
7491
7492 val = get_param(cmd, "NumMSDU");
7493 if (val) {
7494 send_resp(dut, conn, SIGMA_ERROR,
7495 "ErrorCode, NumMSDU is not supported yet");
7496 return -1;
7497 }
7498
7499 val = get_param(cmd, "ABFTLRang");
7500 if (val) {
7501 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02007502 "ABFTLRang parameter %s", val);
7503 if (strcmp(val, "Gt1") == 0)
7504 abft_len = 2; /* 2 slots in this case */
7505 }
7506
7507 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
7508 send_resp(dut, conn, SIGMA_ERROR,
7509 "ErrorCode, Can't set ABFT length");
7510 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007511 }
7512
7513 if (sta_pcp_start(dut, conn, cmd) < 0) {
7514 send_resp(dut, conn, SIGMA_ERROR,
7515 "ErrorCode, Can't start PCP role");
7516 return -1;
7517 }
7518
7519 return sta_set_60g_common(dut, conn, cmd);
7520}
7521
7522
7523static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
7524 struct sigma_cmd *cmd)
7525{
7526 const char *val = get_param(cmd, "DiscoveryMode");
7527
7528 if (dut->dev_role != DEVROLE_STA) {
7529 send_resp(dut, conn, SIGMA_INVALID,
7530 "ErrorCode,Invalid DevRole");
7531 return 0;
7532 }
7533
7534 if (val) {
7535 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
7536 /* Ignore Discovery mode till Driver expose API. */
7537#if 0
7538 if (strcasecmp(val, "1") == 0) {
7539 send_resp(dut, conn, SIGMA_INVALID,
7540 "ErrorCode,DiscoveryMode 1 not supported");
7541 return 0;
7542 }
7543
7544 if (strcasecmp(val, "0") == 0) {
7545 /* OK */
7546 } else {
7547 send_resp(dut, conn, SIGMA_INVALID,
7548 "ErrorCode,DiscoveryMode not supported");
7549 return 0;
7550 }
7551#endif
7552 }
7553
7554 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007555 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007556 return sta_set_60g_common(dut, conn, cmd);
7557}
7558
7559
Jouni Malinenf7222712019-06-13 01:50:21 +03007560static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
7561 struct sigma_conn *conn,
7562 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007563{
7564 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02007565 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05307566
Jouni Malinened77e672018-01-10 16:45:13 +02007567 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08007568 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02007569 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05307570 wpa_command(intf, "DISCONNECT");
7571 return 1;
7572 }
7573
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007574 disconnect_station(dut);
7575 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
7576 * due to cached results. */
7577 wpa_command(intf, "SET ignore_old_scan_res 1");
7578 wpa_command(intf, "BSS_FLUSH");
7579 return 1;
7580}
7581
7582
Jouni Malinenf7222712019-06-13 01:50:21 +03007583static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
7584 struct sigma_conn *conn,
7585 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007586{
7587 const char *intf = get_param(cmd, "Interface");
7588 const char *bssid = get_param(cmd, "bssid");
7589 const char *val = get_param(cmd, "CHANNEL");
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007590 const char *freq_val = get_param(cmd, "ChnlFreq");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007591 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307592 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05307593 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007594 int res;
7595 int chan = 0;
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007596 int freq = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007597 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05307598 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007599 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007600
7601 if (bssid == NULL) {
7602 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
7603 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007604 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007605 }
7606
7607 if (val)
7608 chan = atoi(val);
7609
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007610 if (freq_val)
7611 freq = atoi(freq_val);
7612
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007613 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
7614 /* The current network may be from sta_associate or
7615 * sta_hs2_associate
7616 */
7617 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
7618 0 ||
7619 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007620 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007621 }
7622
7623 ctrl = open_wpa_mon(intf);
7624 if (ctrl == NULL) {
7625 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7626 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007627 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007628 }
7629
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007630 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05307631 sizeof(result)) < 0 ||
7632 strncmp(result, "COMPLETED", 9) != 0) {
7633 sigma_dut_print(dut, DUT_MSG_DEBUG,
7634 "sta_reassoc: Not connected");
7635 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007636 } else if (dut->sta_ft_ds) {
7637 sigma_dut_print(dut, DUT_MSG_DEBUG,
7638 "sta_reassoc: Use FT-over-DS");
7639 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05307640 }
7641
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307642 if (dut->rsne_override) {
7643#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007644 if (get_driver_type(dut) == DRIVER_WCN &&
7645 dut->config_rsnie == 0) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05307646 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307647 dut->config_rsnie = 1;
7648 }
7649#endif /* NL80211_SUPPORT */
7650 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
7651 dut->rsne_override);
7652 if (wpa_command(intf, buf) < 0) {
7653 send_resp(dut, conn, SIGMA_ERROR,
7654 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
7655 return 0;
7656 }
7657 }
7658
Shivani Baranwal7aa48602021-09-29 10:53:38 +05307659 if (ft_ds && get_driver_type(dut) != DRIVER_WCN) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007660 if (chan || freq) {
7661 if (!freq)
7662 freq = channel_to_freq(dut, chan);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007663 if (!freq) {
7664 sigma_dut_print(dut, DUT_MSG_ERROR,
7665 "Invalid channel number provided: %d",
7666 chan);
7667 send_resp(dut, conn, SIGMA_INVALID,
7668 "ErrorCode,Invalid channel number");
7669 goto close_mon_conn;
7670 }
7671 res = snprintf(buf, sizeof(buf),
7672 "SCAN TYPE=ONLY freq=%d", freq);
7673 } else {
7674 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7675 }
7676 if (res < 0 || res >= (int) sizeof(buf)) {
7677 send_resp(dut, conn, SIGMA_ERROR,
7678 "ErrorCode,snprintf failed");
7679 goto close_mon_conn;
7680 }
7681 if (wpa_command(intf, buf) < 0) {
7682 sigma_dut_print(dut, DUT_MSG_INFO,
7683 "Failed to start scan");
7684 send_resp(dut, conn, SIGMA_ERROR,
7685 "ErrorCode,scan failed");
7686 goto close_mon_conn;
7687 }
7688
7689 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7690 buf, sizeof(buf));
7691 if (res < 0) {
7692 sigma_dut_print(dut, DUT_MSG_INFO,
7693 "Scan did not complete");
7694 send_resp(dut, conn, SIGMA_ERROR,
7695 "ErrorCode,scan did not complete");
7696 goto close_mon_conn;
7697 }
7698
7699 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
7700 if (res > 0 && res < (int) sizeof(buf))
7701 res = wpa_command(intf, buf);
7702
7703 if (res < 0 || res >= (int) sizeof(buf)) {
7704 send_resp(dut, conn, SIGMA_ERROR,
7705 "errorCode,FT_DS command failed");
7706 status = STATUS_SENT_ERROR;
7707 goto close_mon_conn;
7708 }
7709 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007710 if (chan || freq) {
7711 if (!freq)
7712 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05307713 if (!freq) {
7714 sigma_dut_print(dut, DUT_MSG_ERROR,
7715 "Invalid channel number provided: %d",
7716 chan);
7717 send_resp(dut, conn, SIGMA_INVALID,
7718 "ErrorCode,Invalid channel number");
7719 goto close_mon_conn;
7720 }
7721 res = snprintf(buf, sizeof(buf),
7722 "SCAN TYPE=ONLY freq=%d", freq);
7723 } else {
7724 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7725 }
7726 if (res < 0 || res >= (int) sizeof(buf)) {
7727 send_resp(dut, conn, SIGMA_ERROR,
7728 "ErrorCode,snprintf failed");
7729 goto close_mon_conn;
7730 }
7731 if (wpa_command(intf, buf) < 0) {
7732 sigma_dut_print(dut, DUT_MSG_INFO,
7733 "Failed to start scan");
7734 send_resp(dut, conn, SIGMA_ERROR,
7735 "ErrorCode,scan failed");
7736 goto close_mon_conn;
7737 }
7738
7739 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7740 buf, sizeof(buf));
7741 if (res < 0) {
7742 sigma_dut_print(dut, DUT_MSG_INFO,
7743 "Scan did not complete");
7744 send_resp(dut, conn, SIGMA_ERROR,
7745 "ErrorCode,scan did not complete");
7746 goto close_mon_conn;
7747 }
7748
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007749 if (set_network(intf, dut->infra_network_id, "bssid", "any")
7750 < 0) {
7751 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7752 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007753 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05307754 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007755 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307756 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007757 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307758 if (res < 0 || res >= (int) sizeof(buf) ||
7759 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007760 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307761 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05307762 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007763 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007764 sigma_dut_print(dut, DUT_MSG_INFO,
7765 "sta_reassoc: Run %s successful", buf);
7766 } else if (wpa_command(intf, "REASSOCIATE")) {
7767 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
7768 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05307769 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007770 }
7771
7772 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
7773 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05307774 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007775 send_resp(dut, conn, SIGMA_ERROR,
7776 "errorCode,Connection did not complete");
7777 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05307778 goto close_mon_conn;
7779 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007780 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007781
Ashwini Patil467efef2017-05-25 12:18:27 +05307782close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007783 wpa_ctrl_detach(ctrl);
7784 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05307785 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007786}
7787
7788
7789static void hs2_clear_credentials(const char *intf)
7790{
7791 wpa_command(intf, "REMOVE_CRED all");
7792}
7793
7794
Lior Davidcc88b562017-01-03 18:52:09 +02007795#ifdef __linux__
7796static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
7797 unsigned int *aid)
7798{
Lior David0fe101e2017-03-09 16:09:50 +02007799 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02007800
Lior David0fe101e2017-03-09 16:09:50 +02007801 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02007802}
7803#endif /* __linux__ */
7804
7805
7806static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
7807 unsigned int *aid)
7808{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007809 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02007810#ifdef __linux__
7811 case DRIVER_WIL6210:
7812 return wil6210_get_aid(dut, bssid, aid);
7813#endif /* __linux__ */
7814 default:
7815 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
7816 return -1;
7817 }
7818}
7819
7820
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007821static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7822 struct sigma_cmd *cmd)
7823{
7824 char buf[MAX_CMD_LEN];
7825 char bss_list[MAX_CMD_LEN];
7826 const char *parameter = get_param(cmd, "Parameter");
7827
7828 if (parameter == NULL)
7829 return -1;
7830
Lior Davidcc88b562017-01-03 18:52:09 +02007831 if (strcasecmp(parameter, "AID") == 0) {
7832 unsigned int aid = 0;
7833 char bssid[20];
7834
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007835 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02007836 bssid, sizeof(bssid)) < 0) {
7837 sigma_dut_print(dut, DUT_MSG_ERROR,
7838 "could not get bssid");
7839 return -2;
7840 }
7841
7842 if (sta_get_aid_60g(dut, bssid, &aid))
7843 return -2;
7844
7845 snprintf(buf, sizeof(buf), "aid,%d", aid);
7846 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
7847 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7848 return 0;
7849 }
7850
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007851 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
7852 char *bss_line;
7853 char *bss_id = NULL;
7854 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307855 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007856
7857 if (ifname == NULL) {
7858 sigma_dut_print(dut, DUT_MSG_INFO,
7859 "For get DiscoveredDevList need Interface name.");
7860 return -1;
7861 }
7862
7863 /*
7864 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
7865 * of BSSIDs in "bssid=<BSSID>\n"
7866 */
7867 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
7868 bss_list,
7869 sizeof(bss_list)) < 0) {
7870 sigma_dut_print(dut, DUT_MSG_ERROR,
7871 "Failed to get bss list");
7872 return -1;
7873 }
7874
7875 sigma_dut_print(dut, DUT_MSG_DEBUG,
7876 "bss list for ifname:%s is:%s",
7877 ifname, bss_list);
7878
7879 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307880 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007881 while (bss_line) {
7882 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
7883 bss_id) {
7884 int len;
7885
7886 len = snprintf(buf + strlen(buf),
7887 sizeof(buf) - strlen(buf),
7888 ",%s", bss_id);
7889 free(bss_id);
7890 bss_id = NULL;
7891 if (len < 0) {
7892 sigma_dut_print(dut,
7893 DUT_MSG_ERROR,
7894 "Failed to read BSSID");
7895 send_resp(dut, conn, SIGMA_ERROR,
7896 "ErrorCode,Failed to read BSS ID");
7897 return 0;
7898 }
7899
7900 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
7901 sigma_dut_print(dut,
7902 DUT_MSG_ERROR,
7903 "Response buf too small for list");
7904 send_resp(dut, conn,
7905 SIGMA_ERROR,
7906 "ErrorCode,Response buf too small for list");
7907 return 0;
7908 }
7909 }
7910
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307911 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007912 }
7913
7914 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
7915 buf);
7916 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7917 return 0;
7918 }
7919
7920 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7921 return 0;
7922}
7923
7924
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007925static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
7926 struct sigma_cmd *cmd)
7927{
7928 char buf[MAX_CMD_LEN];
7929 const char *parameter = get_param(cmd, "Parameter");
7930
7931 if (!parameter)
7932 return -1;
7933
7934 if (strcasecmp(parameter, "RSSI") == 0) {
7935 char rssi[10];
7936
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007937 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007938 rssi, sizeof(rssi)) < 0) {
7939 sigma_dut_print(dut, DUT_MSG_ERROR,
7940 "Could not get RSSI");
7941 return -2;
7942 }
7943
7944 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
7945 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
7946 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7947 return 0;
7948 }
7949
7950 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7951 return 0;
7952}
7953
7954
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05307955#ifdef NL80211_SUPPORT
7956
7957struct station_info {
7958 uint64_t filled;
7959 uint32_t beacon_mic_error_count;
7960 uint32_t beacon_replay_count;
7961};
7962
7963
7964static int qca_get_sta_info_handler(struct nl_msg *msg, void *arg)
7965{
7966 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7967 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7968 struct station_info *data = arg;
7969 struct nlattr *info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
7970 static struct nla_policy info_policy[
7971 QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = {
7972 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT] = {
7973 .type = NLA_U32
7974 },
7975 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT] = {
7976 .type = NLA_U32
7977 },
7978 };
7979
7980 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7981 genlmsg_attrlen(gnlh, 0), NULL);
7982
7983 if (!tb[NL80211_ATTR_VENDOR_DATA])
7984 return NL_SKIP;
7985
7986 if (nla_parse_nested(info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
7987 tb[NL80211_ATTR_VENDOR_DATA], info_policy)) {
7988 return NL_SKIP;
7989 }
7990
7991 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]) {
7992 data->filled |=
7993 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT);
7994 data->beacon_mic_error_count =
7995 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]);
7996 }
7997
7998 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]) {
7999 data->filled |=
8000 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT);
8001 data->beacon_replay_count =
8002 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]);
8003 }
8004
8005 return NL_SKIP;
8006}
8007
8008
8009static int qca_nl80211_get_sta_info(struct sigma_dut *dut, const char *intf,
8010 struct station_info *sta_data)
8011{
8012 struct nl_msg *msg;
8013 int ifindex, ret;
8014
8015 ifindex = if_nametoindex(intf);
8016 if (ifindex == 0) {
8017 sigma_dut_print(dut, DUT_MSG_ERROR,
8018 "%s: Index for interface %s not found",
8019 __func__, intf);
8020 return -1;
8021 }
8022
8023 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8024 NL80211_CMD_VENDOR)) ||
8025 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8026 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8027 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8028 QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
8029 sigma_dut_print(dut, DUT_MSG_ERROR,
8030 "%s: err in adding vendor_cmd", __func__);
8031 nlmsg_free(msg);
8032 return -1;
8033 }
8034
8035 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg,
8036 qca_get_sta_info_handler, sta_data);
8037 if (ret) {
8038 sigma_dut_print(dut, DUT_MSG_ERROR,
8039 "%s: err in send_and_recv_msgs, ret=%d",
8040 __func__, ret);
8041 }
8042 return ret;
8043}
8044#endif /* NL80211_SUPPORT */
8045
8046
8047static int get_bip_mic_error_count(struct sigma_dut *dut,
8048 const char *ifname,
8049 unsigned int *count)
8050{
8051#ifdef NL80211_SUPPORT
8052 struct station_info sta_data;
8053#endif /* NL80211_SUPPORT */
8054
8055 if (get_driver_type(dut) != DRIVER_WCN) {
8056 sigma_dut_print(dut, DUT_MSG_ERROR,
8057 "BIP MIC error count not supported");
8058 return -1;
8059 }
8060
8061#ifdef NL80211_SUPPORT
8062 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8063 !(sta_data.filled &
8064 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT))) {
8065 sigma_dut_print(dut, DUT_MSG_ERROR,
8066 "BIP MIC error count fetching failed");
8067 return -1;
8068 }
8069
8070 *count = sta_data.beacon_mic_error_count;
8071 return 0;
8072#else /* NL80211_SUPPORT */
8073 sigma_dut_print(dut, DUT_MSG_ERROR,
8074 "BIP MIC error count cannot be fetched without NL80211_SUPPORT defined");
8075 return -1;
8076#endif /* NL80211_SUPPORT */
8077}
8078
8079
8080static int get_cmac_replay_count(struct sigma_dut *dut, const char *ifname,
8081 unsigned int *count)
8082{
8083#ifdef NL80211_SUPPORT
8084 struct station_info sta_data;
8085#endif /* NL80211_SUPPORT */
8086
8087 if (get_driver_type(dut) != DRIVER_WCN) {
8088 sigma_dut_print(dut, DUT_MSG_ERROR,
8089 "CMAC reply count not supported");
8090 return -1;
8091 }
8092
8093#ifdef NL80211_SUPPORT
8094 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8095 !(sta_data.filled &
8096 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT))) {
8097 sigma_dut_print(dut, DUT_MSG_ERROR,
8098 "CMAC replay count fetching failed");
8099 return -1;
8100 }
8101
8102 *count = sta_data.beacon_replay_count;
8103 return 0;
8104#else /* NL80211_SUPPORT */
8105 sigma_dut_print(dut, DUT_MSG_ERROR,
8106 "CMAC replay count cannot be fetched without NL80211_SUPPORT defined");
8107 return -1;
8108#endif /* NL80211_SUPPORT */
8109}
8110
8111
8112static enum sigma_cmd_result sta_get_parameter_wpa3(struct sigma_dut *dut,
8113 struct sigma_conn *conn,
8114 struct sigma_cmd *cmd)
8115{
8116 char buf[MAX_CMD_LEN];
8117 const char *ifname = get_param(cmd, "interface");
8118 const char *parameter = get_param(cmd, "Parameter");
8119 unsigned int val;
8120
8121 if (!ifname || !parameter)
8122 return INVALID_SEND_STATUS;
8123
8124 if (strcasecmp(parameter, "BIPMICErrors") == 0) {
8125 if (get_bip_mic_error_count(dut, ifname, &val)) {
8126 send_resp(dut, conn, SIGMA_ERROR,
8127 "ErrorCode,Failed to get BIPMICErrors");
8128 return STATUS_SENT_ERROR;
8129 }
8130 snprintf(buf, sizeof(buf), "BIPMICErrors,%d", val);
8131 sigma_dut_print(dut, DUT_MSG_INFO, "BIPMICErrors %s", buf);
8132 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8133 return STATUS_SENT;
8134 }
8135
8136 if (strcasecmp(parameter, "CMACReplays") == 0) {
8137 if (get_cmac_replay_count(dut, ifname, &val)) {
8138 send_resp(dut, conn, SIGMA_ERROR,
8139 "ErrorCode,Failed to get CMACReplays");
8140 return STATUS_SENT_ERROR;
8141 }
8142 snprintf(buf, sizeof(buf), "CMACReplays,%d", val);
8143 sigma_dut_print(dut, DUT_MSG_INFO, "CMACReplays %s", buf);
8144 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8145 return STATUS_SENT;
8146 }
8147
8148 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8149 return STATUS_SENT_ERROR;
8150}
8151
8152
Jouni Malinenca0abd32020-02-09 20:18:10 +02008153static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
8154 struct sigma_conn *conn,
8155 struct sigma_cmd *cmd)
8156{
8157 const char *intf = get_param(cmd, "Interface");
8158 char buf[4096], bssid[20], resp[200], *pos, *tmp;
8159
8160 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
8161 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8162 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
8163 send_resp(dut, conn, SIGMA_ERROR,
8164 "ErrorCode,PMKSA_GET not supported");
8165 return STATUS_SENT_ERROR;
8166 }
8167
8168 if (strncmp(buf, "FAIL", 4) == 0 ||
8169 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
8170 send_resp(dut, conn, SIGMA_ERROR,
8171 "ErrorCode,Could not find current network");
8172 return STATUS_SENT_ERROR;
8173 }
8174
8175 pos = buf;
8176 while (pos) {
8177 if (strncmp(pos, bssid, 17) == 0) {
8178 pos = strchr(pos, ' ');
8179 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308180 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008181 pos++;
8182 pos = strchr(pos, ' ');
8183 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308184 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008185 pos++;
8186 tmp = strchr(pos, ' ');
8187 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308188 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008189 *tmp = '\0';
8190 break;
8191 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02008192 pos = strchr(pos, '\n');
8193 if (pos)
8194 pos++;
8195 }
8196
8197 if (!pos) {
8198 send_resp(dut, conn, SIGMA_ERROR,
8199 "ErrorCode,PMK not available");
8200 return STATUS_SENT_ERROR;
8201 }
8202
8203 snprintf(resp, sizeof(resp), "PMK,%s", pos);
8204 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8205 return STATUS_SENT;
8206}
8207
8208
Jouni Malinenf7222712019-06-13 01:50:21 +03008209static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
8210 struct sigma_conn *conn,
8211 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008212{
8213 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02008214 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008215
Jouni Malinenca0abd32020-02-09 20:18:10 +02008216 if (!parameter)
8217 return INVALID_SEND_STATUS;
8218
8219 if (strcasecmp(parameter, "PMK") == 0)
8220 return sta_get_pmk(dut, conn, cmd);
8221
8222 if (!program)
8223 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008224
8225 if (strcasecmp(program, "P2PNFC") == 0)
8226 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
8227
8228 if (strcasecmp(program, "60ghz") == 0)
8229 return sta_get_parameter_60g(dut, conn, cmd);
8230
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07008231 if (strcasecmp(program, "he") == 0)
8232 return sta_get_parameter_he(dut, conn, cmd);
8233
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008234#ifdef ANDROID_NAN
8235 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07008236 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008237#endif /* ANDROID_NAN */
8238
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008239#ifdef MIRACAST
8240 if (strcasecmp(program, "WFD") == 0 ||
8241 strcasecmp(program, "DisplayR2") == 0)
8242 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
8243#endif /* MIRACAST */
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05308244 if (strcasecmp(program, "WPA3") == 0)
8245 return sta_get_parameter_wpa3(dut, conn, cmd);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008246
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008247 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8248 return 0;
8249}
8250
8251
8252static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
8253 const char *type)
8254{
8255 char buf[100];
8256
8257 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008258 run_iwpriv(dut, intf, "chwidth 2");
8259 run_iwpriv(dut, intf, "mode 11ACVHT80");
8260 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008261 }
8262
8263 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008264 run_iwpriv(dut, intf, "chwidth 0");
8265 run_iwpriv(dut, intf, "mode 11naht40");
8266 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008267 }
8268
8269 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008270 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008271
8272 /* Reset CTS width */
8273 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
8274 intf);
8275 if (system(buf) != 0) {
8276 sigma_dut_print(dut, DUT_MSG_ERROR,
8277 "wifitool %s beeliner_fw_test 54 0 failed",
8278 intf);
8279 }
8280
8281 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008282 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008283
8284 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
8285 if (system(buf) != 0) {
8286 sigma_dut_print(dut, DUT_MSG_ERROR,
8287 "iwpriv rts failed");
8288 }
8289 }
8290
8291 if (type && strcasecmp(type, "Testbed") == 0) {
8292 dut->testbed_flag_txsp = 1;
8293 dut->testbed_flag_rxsp = 1;
8294 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008295 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008296
8297 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008298 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008299
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008300 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008301
8302 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008303 run_iwpriv(dut, intf, "tx_stbc 0");
8304 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008305
8306 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008307 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008308 }
8309
8310 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008311 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07008312 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008313
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008314 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008315 }
8316}
8317
8318
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008319#ifdef NL80211_SUPPORT
8320static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
8321 enum he_mcs_config mcs)
8322{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308323 return wcn_wifi_test_config_set_u8(
8324 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS, mcs);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008325}
8326#endif /* NL80211_SUPPORT */
8327
8328
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008329static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
8330 const char *intf, int enable)
8331{
8332#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308333 return wcn_wifi_test_config_set_u8(
8334 dut, intf,
8335 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
8336 enable);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008337#else /* NL80211_SUPPORT */
8338 sigma_dut_print(dut, DUT_MSG_ERROR,
8339 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
8340 return -1;
8341#endif /* NL80211_SUPPORT */
8342}
8343
8344
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008345static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
8346 const char *intf, int enable)
8347{
8348#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308349 return wcn_wifi_test_config_set_u8(
8350 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
8351 enable);
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008352#else /* NL80211_SUPPORT */
8353 sigma_dut_print(dut, DUT_MSG_ERROR,
8354 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
8355 return -1;
8356#endif /* NL80211_SUPPORT */
8357}
8358
8359
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008360#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008361
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008362static int sta_set_he_testbed_def(struct sigma_dut *dut,
8363 const char *intf, int cfg)
8364{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308365 return wcn_wifi_test_config_set_u8(
8366 dut, intf,
8367 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
8368 cfg);
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008369}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008370
8371
8372static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
8373{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308374 return wcn_wifi_test_config_set_u8(
8375 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
8376 cfg);
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008377}
8378
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008379#endif /* NL80211_SUPPORT */
8380
8381
Qiwei Caib6806972020-01-15 13:52:11 +08008382int sta_set_addba_buf_size(struct sigma_dut *dut,
8383 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008384{
8385#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308386 return wcn_wifi_test_config_set_u16(
8387 dut, intf,
8388 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE, bufsize);
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008389#else /* NL80211_SUPPORT */
8390 sigma_dut_print(dut, DUT_MSG_ERROR,
8391 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
8392 return -1;
8393#endif /* NL80211_SUPPORT */
8394}
8395
8396
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008397static int sta_set_scan_unicast_probe(struct sigma_dut *dut,
8398 const char *intf, int val)
8399{
8400#ifdef NL80211_SUPPORT
8401 return wcn_wifi_test_config_set_u8(
8402 dut, intf,
8403 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA,
8404 val);
8405#else /* NL80211_SUPPORT */
8406 sigma_dut_print(dut, DUT_MSG_ERROR,
8407 "Unicast RA in Probe Request frame cannot be set without NL80211_SUPPORT defined");
8408 return -1;
8409#endif /* NL80211_SUPPORT */
8410}
8411
8412
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07008413static int sta_set_rx_ctrl_multi_bss(struct sigma_dut *dut, const char *intf,
8414 int enable)
8415{
8416#ifdef NL80211_SUPPORT
8417 return wcn_wifi_test_config_set_u8(
8418 dut, intf,
8419 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS,
8420 enable);
8421#else /* NL80211_SUPPORT */
8422 sigma_dut_print(dut, DUT_MSG_ERROR,
8423 "Rx ctrl frame to Multi-BSS cannot be changed without NL80211_SUPPORT defined");
8424 return -1;
8425#endif /* NL80211_SUPPORT */
8426}
8427
8428
8429static int sta_set_bcast_twt_support(struct sigma_dut *dut, const char *intf,
8430 int enable)
8431{
8432#ifdef NL80211_SUPPORT
8433 return wcn_wifi_test_config_set_u8(
8434 dut, intf,
8435 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT,
8436 enable);
8437#else /* NL80211_SUPPORT */
8438 sigma_dut_print(dut, DUT_MSG_ERROR,
8439 "BCAST TWT cannot be changed without NL80211_SUPPORT defined");
8440 return -1;
8441#endif /* NL80211_SUPPORT */
8442}
8443
8444
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008445static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
8446 int enable)
8447{
8448#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308449 return wcn_wifi_test_config_set_u8(
8450 dut, intf,
8451 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
8452 enable);
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008453#else /* NL80211_SUPPORT */
8454 sigma_dut_print(dut, DUT_MSG_ERROR,
8455 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
8456 return -1;
8457#endif /* NL80211_SUPPORT */
8458}
8459
8460
Arif Hussain9765f7d2018-07-03 08:28:26 -07008461static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
8462 int val)
8463{
8464#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308465 return wcn_wifi_test_config_set_u8(
8466 dut, intf,
8467 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
8468 val);
Arif Hussain9765f7d2018-07-03 08:28:26 -07008469#else /* NL80211_SUPPORT */
8470 sigma_dut_print(dut, DUT_MSG_ERROR,
8471 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
8472 return -1;
8473#endif /* NL80211_SUPPORT */
8474}
8475
8476
Arif Hussain68d23f52018-07-11 13:39:08 -07008477#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008478static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
8479 enum qca_wlan_he_mac_padding_dur val)
8480{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308481 return wcn_wifi_test_config_set_u8(
8482 dut, intf,
8483 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR, val);
Arif Hussain68d23f52018-07-11 13:39:08 -07008484}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008485#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008486
8487
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008488static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
8489 int val)
8490{
8491#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308492 return wcn_wifi_test_config_set_u8(
8493 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
8494 val);
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008495#else /* NL80211_SUPPORT */
8496 sigma_dut_print(dut, DUT_MSG_ERROR,
8497 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
8498 return -1;
8499#endif /* NL80211_SUPPORT */
8500}
8501
8502
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008503static int sta_set_mgmt_data_tx_disable_cfg(struct sigma_dut *dut,
8504 const char *intf, int val)
8505{
8506#ifdef NL80211_SUPPORT
8507 return wcn_wifi_test_config_set_u8(
8508 dut, intf,
8509 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX,
8510 val);
8511#else /* NL80211_SUPPORT */
8512 sigma_dut_print(dut, DUT_MSG_ERROR,
8513 "Tx disable config cannot be set without NL80211_SUPPORT defined");
8514 return -1;
8515#endif /* NL80211_SUPPORT */
8516}
8517
8518
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -07008519static int sta_set_keep_alive_data_cfg(struct sigma_dut *dut, const char *intf,
8520 int val)
8521{
8522#ifdef NL80211_SUPPORT
8523 return wcn_wifi_test_config_set_u8(
8524 dut, intf,
8525 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE,
8526 val);
8527#else /* NL80211_SUPPORT */
8528 sigma_dut_print(dut, DUT_MSG_ERROR,
8529 "Keep alive data type cannot be set without NL80211_SUPPORT defined");
8530 return -1;
8531#endif /* NL80211_SUPPORT */
8532}
8533
8534
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008535#ifdef NL80211_SUPPORT
8536static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
8537{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308538 return wcn_wifi_test_config_set_flag(
8539 dut, intf,
8540 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG);
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008541}
8542#endif /* NL80211_SUPPORT */
8543
8544
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008545static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
8546 int val)
8547{
8548#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308549 return wcn_wifi_test_config_set_u8(
8550 dut, intf,
8551 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA, val);
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008552#else /* NL80211_SUPPORT */
8553 sigma_dut_print(dut, DUT_MSG_ERROR,
8554 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
8555 return -1;
8556#endif /* NL80211_SUPPORT */
8557}
8558
8559
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008560static int sta_set_er_su_ppdu_type_tx(struct sigma_dut *dut, const char *intf,
8561 int val)
8562{
8563#ifdef NL80211_SUPPORT
8564 return wcn_wifi_test_config_set_u8(
8565 dut, intf,
8566 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE, val);
8567#else /* NL80211_SUPPORT */
8568 sigma_dut_print(dut, DUT_MSG_ERROR,
8569 "ER-SU PPDU type cannot be set without NL80211_SUPPORT defined");
8570 return -1;
8571#endif /* NL80211_SUPPORT */
8572}
8573
8574
8575static int sta_set_ru_242_tone_tx(struct sigma_dut *dut, const char *intf,
8576 int val)
8577{
8578#ifdef NL80211_SUPPORT
8579 return wcn_wifi_test_config_set_u8(
8580 dut, intf,
8581 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX, val);
8582#else /* NL80211_SUPPORT */
8583 sigma_dut_print(dut, DUT_MSG_ERROR,
8584 "RU 242 tone cannot be set without NL80211_SUPPORT defined");
8585 return -1;
8586#endif /* NL80211_SUPPORT */
8587}
8588
8589
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008590static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
8591 int val)
8592{
8593#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308594 return wcn_wifi_test_config_set_u8(
8595 dut, intf,
8596 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP, val);
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008597#else /* NL80211_SUPPORT */
8598 sigma_dut_print(dut, DUT_MSG_ERROR,
8599 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
8600 return -1;
8601#endif /* NL80211_SUPPORT */
8602}
8603
8604
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008605#ifdef NL80211_SUPPORT
8606
8607struct features_info {
8608 unsigned char flags[8];
8609 size_t flags_len;
8610};
8611
8612static int features_info_handler(struct nl_msg *msg, void *arg)
8613{
8614 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8615 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8616 struct features_info *info = arg;
8617 struct nlattr *nl_vend, *attr;
8618
8619 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8620 genlmsg_attrlen(gnlh, 0), NULL);
8621
8622 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
8623 if (nl_vend) {
8624 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
8625
8626 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
8627 nla_data(nl_vend), nla_len(nl_vend), NULL);
8628
8629 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
8630 if (attr) {
8631 int len = nla_len(attr);
8632
Vamsi Krishna79a91132021-08-16 21:40:22 +05308633 if (info && len <= sizeof(info->flags)) {
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008634 memcpy(info->flags, nla_data(attr), len);
8635 info->flags_len = len;
8636 }
8637 }
8638 }
8639
8640 return NL_SKIP;
8641}
8642
8643
8644static int check_feature(enum qca_wlan_vendor_features feature,
8645 struct features_info *info)
8646{
8647 size_t idx = feature / 8;
8648
Vamsi Krishna79a91132021-08-16 21:40:22 +05308649 if (!info)
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008650 return 0;
8651
8652 return (idx < info->flags_len) &&
8653 (info->flags[idx] & BIT(feature % 8));
8654}
8655
8656#endif /* NL80211_SUPPORT */
8657
8658
8659static void sta_get_twt_feature_async_supp(struct sigma_dut *dut,
8660 const char *intf)
8661{
8662#ifdef NL80211_SUPPORT
8663 struct nl_msg *msg;
8664 struct features_info info = { 0 };
8665 int ifindex, ret;
8666
8667 ifindex = if_nametoindex(intf);
8668 if (ifindex == 0) {
8669 sigma_dut_print(dut, DUT_MSG_ERROR,
8670 "%s: Index for interface %s failed",
8671 __func__, intf);
8672 return;
8673 }
8674
8675 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8676 NL80211_CMD_VENDOR)) ||
8677 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8678 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8679 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8680 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
8681 sigma_dut_print(dut, DUT_MSG_ERROR,
8682 "%s: err in adding vendor_cmd and vendor_data",
8683 __func__);
8684 nlmsg_free(msg);
8685 return;
8686 }
8687
8688 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, features_info_handler,
8689 &info);
8690 if (ret) {
8691 sigma_dut_print(dut, DUT_MSG_ERROR,
8692 "%s: err in send_and_recv_msgs, ret=%d",
8693 __func__, ret);
8694 return;
8695 }
8696
8697 if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info))
8698 dut->sta_async_twt_supp = 1;
8699 else
8700 dut->sta_async_twt_supp = 0;
8701
8702 sigma_dut_print(dut, DUT_MSG_DEBUG,
8703 "%s: sta_async_twt_supp %d",
8704 __func__, dut->sta_async_twt_supp);
8705#else /* NL80211_SUPPORT */
8706 sigma_dut_print(dut, DUT_MSG_INFO,
8707 "TWT async supp get cannot be done without NL80211_SUPPORT defined");
8708 dut->sta_async_twt_supp = 0;
8709#endif /* NL80211_SUPPORT */
8710}
8711
8712
Arif Hussain480d5f42019-03-12 14:40:42 -07008713static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
8714 int val)
8715{
8716#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308717 return wcn_wifi_test_config_set_u8(
8718 dut, intf,
8719 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT, val);
Arif Hussain480d5f42019-03-12 14:40:42 -07008720#else /* NL80211_SUPPORT */
8721 sigma_dut_print(dut, DUT_MSG_ERROR,
8722 "TWT Request cannot be changed without NL80211_SUPPORT defined");
8723 return -1;
8724#endif /* NL80211_SUPPORT */
8725}
8726
8727
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07008728static int sta_set_bss_max_idle_period(struct sigma_dut *dut, const char *intf,
8729 int val)
8730{
8731#ifdef NL80211_SUPPORT
8732 return wcn_wifi_test_config_set_u16(
8733 dut, intf,
8734 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD, val);
8735#else /* NL80211_SUPPORT */
8736 sigma_dut_print(dut, DUT_MSG_ERROR,
8737 "BSS max idle period cannot be set without NL80211_SUPPORT defined");
8738 return -1;
8739#endif /* NL80211_SUPPORT */
8740}
8741
8742
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07008743static int sta_set_bss_max_idle_support(struct sigma_dut *dut, const char *intf,
8744 int val)
8745{
8746#ifdef NL80211_SUPPORT
8747 return wcn_wifi_test_config_set_u8(
8748 dut, intf,
8749 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE,
8750 val);
8751#else /* NL80211_SUPPORT */
8752 sigma_dut_print(dut, DUT_MSG_ERROR,
8753 "BSS max idle support cannot be set without NL80211_SUPPORT defined");
8754 return -1;
8755#endif /* NL80211_SUPPORT */
8756}
8757
8758
Srinivas Girigowda0525e292020-11-12 13:28:21 -08008759static int sta_set_fullbw_ulmumimo(struct sigma_dut *dut, const char *intf,
8760 int val)
8761{
8762#ifdef NL80211_SUPPORT
8763 return wcn_wifi_test_config_set_u8(
8764 dut, intf,
8765 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO, val);
8766#else /* NL80211_SUPPORT */
8767 sigma_dut_print(dut, DUT_MSG_ERROR,
8768 "Full BW UL MU MIMO cannot be changed without NL80211_SUPPORT defined");
8769 return -1;
8770#endif /* NL80211_SUPPORT */
8771}
8772
8773
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07008774static int sta_set_punctured_preamble_rx(struct sigma_dut *dut,
8775 const char *intf, int val)
8776{
8777#ifdef NL80211_SUPPORT
8778 return wcn_wifi_test_config_set_u8(
8779 dut, intf,
8780 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX,
8781 val);
8782#else /* NL80211_SUPPORT */
8783 sigma_dut_print(dut, DUT_MSG_ERROR,
8784 "Punctured preamble Rx cannot be set without NL80211_SUPPORT defined");
8785 return -1;
8786#endif /* NL80211_SUPPORT */
8787}
8788
8789
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -08008790int wcn_set_he_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8791{
8792 #ifdef NL80211_SUPPORT
8793 struct nlattr *attr;
8794 struct nlattr *attr1;
8795 int ifindex, ret;
8796 struct nl_msg *msg;
8797
8798 ifindex = if_nametoindex(intf);
8799 if (ifindex == 0) {
8800 sigma_dut_print(dut, DUT_MSG_ERROR,
8801 "%s: Index for interface %s failed",
8802 __func__, intf);
8803 return -1;
8804 }
8805
8806 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8807 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8808 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8809 sigma_dut_print(dut, DUT_MSG_ERROR,
8810 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8811 __func__);
8812 nlmsg_free(msg);
8813 return -1;
8814 }
8815
8816 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting HE GI %d",
8817 __func__, gi_val);
8818
8819 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8820 if (!attr1) {
8821 sigma_dut_print(dut, DUT_MSG_ERROR,
8822 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8823 __func__);
8824 nlmsg_free(msg);
8825 return -1;
8826 }
8827 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8828 nla_nest_end(msg, attr1);
8829
8830 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8831 if (!attr1) {
8832 sigma_dut_print(dut, DUT_MSG_ERROR,
8833 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8834 __func__);
8835 nlmsg_free(msg);
8836 return -1;
8837 }
8838 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8839 nla_nest_end(msg, attr1);
8840
8841 nla_nest_end(msg, attr);
8842 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8843 if (ret) {
8844 sigma_dut_print(dut, DUT_MSG_ERROR,
8845 "%s: send_and_recv_msgs failed, ret=%d",
8846 __func__, ret);
8847 }
8848 return ret;
8849#else /* NL80211_SUPPORT */
8850 return -1;
8851#endif /* NL80211_SUPPORT */
8852}
8853
8854
8855static int sta_set_vht_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8856{
8857 #ifdef NL80211_SUPPORT
8858 struct nlattr *attr;
8859 struct nlattr *attr1;
8860 int ifindex, ret;
8861 struct nl_msg *msg;
8862
8863 ifindex = if_nametoindex(intf);
8864 if (ifindex == 0) {
8865 sigma_dut_print(dut, DUT_MSG_ERROR,
8866 "%s: Index for interface %s failed",
8867 __func__, intf);
8868 return -1;
8869 }
8870
8871 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8872 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8873 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8874 sigma_dut_print(dut, DUT_MSG_ERROR,
8875 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8876 __func__);
8877 nlmsg_free(msg);
8878 return -1;
8879 }
8880
8881 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting VHT GI %d",
8882 __func__, gi_val);
8883
8884 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8885 if (!attr1) {
8886 sigma_dut_print(dut, DUT_MSG_ERROR,
8887 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8888 __func__);
8889 nlmsg_free(msg);
8890 return -1;
8891 }
8892 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8893 nla_nest_end(msg, attr1);
8894
8895 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8896 if (!attr1) {
8897 sigma_dut_print(dut, DUT_MSG_ERROR,
8898 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8899 __func__);
8900 nlmsg_free(msg);
8901 return -1;
8902 }
8903 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8904 nla_nest_end(msg, attr1);
8905 nla_nest_end(msg, attr);
8906
8907 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8908 if (ret) {
8909 sigma_dut_print(dut, DUT_MSG_ERROR,
8910 "%s: send_and_recv_msgs failed, ret=%d",
8911 __func__, ret);
8912 }
8913 return ret;
8914#else /* NL80211_SUPPORT */
8915 return -1;
8916#endif /* NL80211_SUPPORT */
8917}
8918
8919
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008920static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
8921 const char *type)
8922{
8923 char buf[60];
8924
8925 if (dut->program == PROGRAM_HE) {
8926 /* resetting phymode to auto in case of HE program */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05308927 sta_set_phymode(dut, intf, "auto");
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008928
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07008929 /* reset the rate to Auto rate */
8930 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
8931 intf);
8932 if (system(buf) != 0) {
8933 sigma_dut_print(dut, DUT_MSG_ERROR,
8934 "iwpriv %s set_11ax_rate 0xff failed",
8935 intf);
8936 }
8937
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07008938 /* reset the LDPC setting */
8939 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
8940 if (system(buf) != 0) {
8941 sigma_dut_print(dut, DUT_MSG_ERROR,
8942 "iwpriv %s ldpc 1 failed", intf);
8943 }
8944
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008945 /* reset the power save setting */
Vinita S. Malooa8b62722020-04-23 01:45:41 +05308946 set_power_save_wcn(dut, intf, 2);
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008947
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008948 /* remove all network profiles */
8949 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008950
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008951 /* Configure ADDBA Req/Rsp buffer size to be 64 */
8952 sta_set_addba_buf_size(dut, intf, 64);
8953
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008954 if (dut->sta_async_twt_supp == -1)
8955 sta_get_twt_feature_async_supp(dut, intf);
8956
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008957 sta_set_scan_unicast_probe(dut, intf, 0);
8958
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008959#ifdef NL80211_SUPPORT
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08008960 nl80211_close_event_sock(dut);
8961
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008962 /* Reset the device HE capabilities to its default supported
8963 * configuration. */
8964 sta_set_he_testbed_def(dut, intf, 0);
8965
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008966 /* Disable noackpolicy for all AC */
8967 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
8968 sigma_dut_print(dut, DUT_MSG_ERROR,
8969 "Disable of noackpolicy for all AC failed");
8970 }
8971#endif /* NL80211_SUPPORT */
8972
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08008973 /* Enable WMM by default */
8974 if (wcn_sta_set_wmm(dut, intf, "on")) {
8975 sigma_dut_print(dut, DUT_MSG_ERROR,
8976 "Enable of WMM in sta_reset_default_wcn failed");
8977 }
8978
8979 /* Disable ADDBA_REJECT by default */
8980 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
8981 sigma_dut_print(dut, DUT_MSG_ERROR,
8982 "Disable of addba_reject in sta_reset_default_wcn failed");
8983 }
8984
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08008985 /* Enable sending of ADDBA by default */
8986 if (nlvendor_config_send_addba(dut, intf, 1)) {
8987 sigma_dut_print(dut, DUT_MSG_ERROR,
8988 "Enable sending of ADDBA in sta_reset_default_wcn failed");
8989 }
8990
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08008991 /* Enable AMPDU by default */
8992 iwpriv_sta_set_ampdu(dut, intf, 1);
8993
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008994#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08008995 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008996 sigma_dut_print(dut, DUT_MSG_ERROR,
8997 "Set LTF config to default in sta_reset_default_wcn failed");
8998 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07008999
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009000 /* set the beamformee NSTS(maximum number of
9001 * space-time streams) to default DUT config
9002 */
9003 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07009004 sigma_dut_print(dut, DUT_MSG_ERROR,
9005 "Failed to set BeamformeeSTS");
9006 }
Arif Hussain68d23f52018-07-11 13:39:08 -07009007
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07009008 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, 0)) {
9009 sigma_dut_print(dut, DUT_MSG_ERROR,
9010 "Failed to reset mgmt/data Tx disable config");
9011 }
9012
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07009013 if (sta_set_mac_padding_duration(
9014 dut, intf,
9015 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07009016 sigma_dut_print(dut, DUT_MSG_ERROR,
9017 "Failed to set MAC padding duration");
9018 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07009019
9020 if (sta_set_mu_edca_override(dut, intf, 0)) {
9021 sigma_dut_print(dut, DUT_MSG_ERROR,
9022 "ErrorCode,Failed to set MU EDCA override disable");
9023 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009024
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07009025 if (sta_set_ru_242_tone_tx(dut, intf, 0)) {
9026 sigma_dut_print(dut, DUT_MSG_ERROR,
9027 "Failed to set RU 242 tone Tx");
9028 }
9029
9030 if (sta_set_er_su_ppdu_type_tx(dut, intf, 0)) {
9031 sigma_dut_print(dut, DUT_MSG_ERROR,
9032 "Failed to set ER-SU PPDU type Tx");
9033 }
9034
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009035 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
9036 sigma_dut_print(dut, DUT_MSG_ERROR,
9037 "Failed to set OM ctrl supp");
9038 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07009039
9040 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
9041 sigma_dut_print(dut, DUT_MSG_ERROR,
9042 "Failed to set Tx SU PPDU enable");
9043 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009044
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009045 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
9046 sigma_dut_print(dut, DUT_MSG_ERROR,
9047 "failed to send TB PPDU Tx cfg");
9048 }
9049
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009050 if (sta_set_he_om_ctrl_reset(dut, intf)) {
9051 sigma_dut_print(dut, DUT_MSG_ERROR,
9052 "Failed to set OM ctrl reset");
9053 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009054
9055 /* +HTC-HE support default on */
9056 if (sta_set_he_htc_supp(dut, intf, 1)) {
9057 sigma_dut_print(dut, DUT_MSG_ERROR,
9058 "Setting of +HTC-HE support failed");
9059 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009060#endif /* NL80211_SUPPORT */
9061
Arif Hussain8d5b27b2018-05-14 14:31:03 -07009062 if (sta_set_tx_beamformee(dut, intf, 1)) {
9063 sigma_dut_print(dut, DUT_MSG_ERROR,
9064 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
9065 }
9066
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009067 wpa_command(intf, "SET oce 1");
9068
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009069 /* Set nss to 1 and MCS 0-7 in case of testbed */
9070 if (type && strcasecmp(type, "Testbed") == 0) {
9071#ifdef NL80211_SUPPORT
9072 int ret;
9073#endif /* NL80211_SUPPORT */
9074
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009075 wpa_command(intf, "SET oce 0");
9076
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009077 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
9078 if (system(buf) != 0) {
9079 sigma_dut_print(dut, DUT_MSG_ERROR,
9080 "iwpriv %s nss failed", intf);
9081 }
9082
9083#ifdef NL80211_SUPPORT
9084 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
9085 if (ret) {
9086 sigma_dut_print(dut, DUT_MSG_ERROR,
9087 "Setting of MCS failed, ret:%d",
9088 ret);
9089 }
9090#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08009091
9092 /* Disable STBC as default */
9093 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08009094
9095 /* Disable AMSDU as default */
9096 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009097
9098#ifdef NL80211_SUPPORT
9099 /* HE fragmentation default off */
9100 if (sta_set_he_fragmentation(dut, intf,
9101 HE_FRAG_DISABLE)) {
9102 sigma_dut_print(dut, DUT_MSG_ERROR,
9103 "Setting of HE fragmentation failed");
9104 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009105
9106 /* set the beamformee NSTS(maximum number of
9107 * space-time streams) to default testbed config
9108 */
9109 if (sta_set_beamformee_sts(dut, intf, 3)) {
9110 sigma_dut_print(dut, DUT_MSG_ERROR,
9111 "Failed to set BeamformeeSTS");
9112 }
9113
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07009114 if (sta_set_punctured_preamble_rx(dut, intf, 0)) {
9115 sigma_dut_print(dut, DUT_MSG_ERROR,
9116 "Failed to reset PreamblePunctRx support");
9117 }
9118
Kiran Kumar Lokere727687f2021-06-24 00:35:49 -07009119 if (sta_set_bss_max_idle_period(dut, intf, 0)) {
9120 sigma_dut_print(dut, DUT_MSG_ERROR,
9121 "Failed to reset BSS max idle period");
9122 }
9123
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009124 /* +HTC-HE support default off */
9125 if (sta_set_he_htc_supp(dut, intf, 0)) {
9126 sigma_dut_print(dut, DUT_MSG_ERROR,
9127 "Setting of +HTC-HE support failed");
9128 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08009129
9130 /* Set device HE capabilities to testbed default
9131 * configuration. */
9132 if (sta_set_he_testbed_def(dut, intf, 1)) {
9133 sigma_dut_print(dut, DUT_MSG_DEBUG,
9134 "Failed to set HE defaults");
9135 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08009136
9137 /* Disable VHT support in 2.4 GHz for testbed */
9138 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009139#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08009140
9141 /* Enable WEP/TKIP with HE capability in testbed */
9142 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
9143 sigma_dut_print(dut, DUT_MSG_ERROR,
9144 "Enabling HE config with WEP/TKIP failed");
9145 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009146 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009147
9148 /* Defaults in case of DUT */
9149 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07009150 /* Enable STBC by default */
9151 wcn_sta_set_stbc(dut, intf, "1");
9152
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009153 /* set nss to 2 */
9154 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
9155 if (system(buf) != 0) {
9156 sigma_dut_print(dut, DUT_MSG_ERROR,
9157 "iwpriv %s nss 2 failed", intf);
9158 }
Arif Hussainac6c5112018-05-25 17:34:00 -07009159 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009160
9161#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07009162 /* Set HE_MCS to 0-11 */
9163 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009164 sigma_dut_print(dut, DUT_MSG_ERROR,
9165 "Setting of MCS failed");
9166 }
9167#endif /* NL80211_SUPPORT */
9168
9169 /* Disable WEP/TKIP with HE capability in DUT */
9170 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
9171 sigma_dut_print(dut, DUT_MSG_ERROR,
9172 "Enabling HE config with WEP/TKIP failed");
9173 }
9174 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009175 }
9176}
9177
9178
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309179static int sta_set_client_privacy(struct sigma_dut *dut,
9180 struct sigma_conn *conn, const char *intf,
9181 int enable)
9182{
9183 if (enable &&
9184 (wpa_command(intf, "SET mac_addr 1") < 0 ||
9185 wpa_command(intf, "SET rand_addr_lifetime 1") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309186 (wpa_command(intf, "MAC_RAND_SCAN enable=1 all") < 0 &&
9187 wpa_command(intf, "SET preassoc_mac_addr 1") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309188 wpa_command(intf, "SET gas_rand_mac_addr 1") < 0 ||
9189 wpa_command(intf, "SET gas_rand_addr_lifetime 1") < 0))
9190 return -1;
9191
9192 if (!enable &&
9193 (wpa_command(intf, "SET mac_addr 0") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309194 (wpa_command(intf, "MAC_RAND_SCAN enable=0 all") < 0 &&
9195 wpa_command(intf, "SET preassoc_mac_addr 0") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309196 wpa_command(intf, "SET gas_rand_mac_addr 0") < 0))
9197 return -1;
9198
9199 dut->client_privacy = enable;
9200 return 0;
9201}
9202
9203
Jouni Malinenf7222712019-06-13 01:50:21 +03009204static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
9205 struct sigma_conn *conn,
9206 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009207{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009208 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009209 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009210 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009211 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309212 const char *dev_role = get_param(cmd, "DevRole");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309213 char resp[20];
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309214 char buf[100];
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309215 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009216
Shivani Baranwal31182012021-12-07 21:11:13 +05309217#ifdef ANDROID
9218 kill_pid(dut, concat_sigma_tmpdir(dut, "/sigma_dut-dnsmasq.pid",
9219 buf, sizeof(buf)));
9220#endif /* ANDROID */
9221
Jouni Malinenb21f0542019-11-04 17:53:38 +02009222 if (dut->station_ifname_2g &&
9223 strcmp(dut->station_ifname_2g, intf) == 0)
9224 dut->use_5g = 0;
9225 else if (dut->station_ifname_5g &&
9226 strcmp(dut->station_ifname_5g, intf) == 0)
9227 dut->use_5g = 1;
9228
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009229 if (!program)
9230 program = get_param(cmd, "prog");
9231 dut->program = sigma_program_to_enum(program);
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05309232
9233 if (dut->program == PROGRAM_WFD && dut->user_config_timeout)
9234 dut->default_timeout = dut->user_config_timeout;
9235
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009236 dut->device_type = STA_unknown;
9237 type = get_param(cmd, "type");
9238 if (type && strcasecmp(type, "Testbed") == 0)
9239 dut->device_type = STA_testbed;
9240 if (type && strcasecmp(type, "DUT") == 0)
9241 dut->device_type = STA_dut;
9242
9243 if (dut->program == PROGRAM_TDLS) {
9244 /* Clear TDLS testing mode */
9245 wpa_command(intf, "SET tdls_disabled 0");
9246 wpa_command(intf, "SET tdls_testing 0");
9247 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009248 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05309249 /* Enable the WCN driver in TDLS Explicit trigger mode
9250 */
9251 wpa_command(intf, "SET tdls_external_control 0");
9252 wpa_command(intf, "SET tdls_trigger_control 0");
9253 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009254 }
9255
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009256#ifdef MIRACAST
9257 if (dut->program == PROGRAM_WFD ||
9258 dut->program == PROGRAM_DISPLAYR2)
9259 miracast_sta_reset_default(dut, conn, cmd);
9260#endif /* MIRACAST */
9261
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009262 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009263 case DRIVER_ATHEROS:
9264 sta_reset_default_ath(dut, intf, type);
9265 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009266 case DRIVER_WCN:
9267 sta_reset_default_wcn(dut, intf, type);
9268 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009269 default:
9270 break;
9271 }
9272
9273#ifdef ANDROID_NAN
9274 if (dut->program == PROGRAM_NAN)
9275 nan_cmd_sta_reset_default(dut, conn, cmd);
9276#endif /* ANDROID_NAN */
9277
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05309278 if (dut->program == PROGRAM_LOC &&
9279 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
9280 return ERROR_SEND_STATUS;
9281
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009282 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
9283 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009284 unlink("SP/wi-fi.org/pps.xml");
9285 if (system("rm -r SP/*") != 0) {
9286 }
9287 unlink("next-client-cert.pem");
9288 unlink("next-client-key.pem");
9289 }
9290
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009291 /* For WPS program of the 60 GHz band the band type needs to be saved */
9292 if (dut->program == PROGRAM_WPS) {
9293 if (band && strcasecmp(band, "60GHz") == 0) {
9294 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009295 /* For 60 GHz enable WPS for WPS TCs */
9296 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009297 } else {
9298 dut->band = WPS_BAND_NON_60G;
9299 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009300 } else if (dut->program == PROGRAM_60GHZ) {
9301 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
9302 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009303 }
9304
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02009305 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009306 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009307 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009308
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009309 sigma_dut_print(dut, DUT_MSG_INFO,
9310 "WPS 60 GHz program, wps_disable = %d",
9311 dut->wps_disable);
9312
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009313 if (!dev_role) {
9314 send_resp(dut, conn, SIGMA_ERROR,
9315 "errorCode,Missing DevRole argument");
9316 return 0;
9317 }
9318
9319 if (strcasecmp(dev_role, "STA") == 0)
9320 dut->dev_role = DEVROLE_STA;
9321 else if (strcasecmp(dev_role, "PCP") == 0)
9322 dut->dev_role = DEVROLE_PCP;
9323 else {
9324 send_resp(dut, conn, SIGMA_ERROR,
9325 "errorCode,Unknown DevRole");
9326 return 0;
9327 }
9328
9329 if (dut->device_type == STA_unknown) {
9330 sigma_dut_print(dut, DUT_MSG_ERROR,
9331 "Device type is not STA testbed or DUT");
9332 send_resp(dut, conn, SIGMA_ERROR,
9333 "errorCode,Unknown device type");
9334 return 0;
9335 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009336
9337 sigma_dut_print(dut, DUT_MSG_DEBUG,
9338 "Setting msdu_size to MAX: 7912");
9339 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009340 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009341
9342 if (system(buf) != 0) {
9343 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9344 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009345 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009346 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009347
9348 if (sta_set_force_mcs(dut, 0, 1)) {
9349 sigma_dut_print(dut, DUT_MSG_ERROR,
9350 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009351 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009352 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009353 }
9354
9355 wpa_command(intf, "WPS_ER_STOP");
9356 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05309357 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009358 wpa_command(intf, "SET radio_disabled 0");
9359
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02009360 dut->wps_forced_version = 0;
9361
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009362 if (dut->wsc_fragment) {
9363 dut->wsc_fragment = 0;
9364 wpa_command(intf, "SET device_name Test client");
9365 wpa_command(intf, "SET manufacturer ");
9366 wpa_command(intf, "SET model_name ");
9367 wpa_command(intf, "SET model_number ");
9368 wpa_command(intf, "SET serial_number ");
9369 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02009370 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
9371 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
9372 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
9373 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009374
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009375 if (dut->tmp_mac_addr && dut->set_macaddr) {
9376 dut->tmp_mac_addr = 0;
9377 if (system(dut->set_macaddr) != 0) {
9378 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
9379 "temporary MAC address");
9380 }
9381 }
9382
9383 set_ps(intf, dut, 0);
9384
Jouni Malinenba630452018-06-22 11:49:59 +03009385 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009386 dut->program == PROGRAM_HS2_R3 || dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009387 wpa_command(intf, "SET interworking 1");
9388 wpa_command(intf, "SET hs20 1");
9389 }
9390
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009391 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03009392 dut->program == PROGRAM_HS2_R3 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009393 dut->program == PROGRAM_HS2_R4 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009394 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009395 wpa_command(intf, "SET pmf 1");
9396 } else {
9397 wpa_command(intf, "SET pmf 0");
9398 }
9399
9400 hs2_clear_credentials(intf);
9401 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
9402 wpa_command(intf, "SET access_network_type 15");
9403
9404 static_ip_file(0, NULL, NULL, NULL);
9405 kill_dhcp_client(dut, intf);
9406 clear_ip_addr(dut, intf);
9407
9408 dut->er_oper_performed = 0;
9409 dut->er_oper_bssid[0] = '\0';
9410
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009411 if (dut->program == PROGRAM_LOC) {
9412 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009413 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009414 }
9415
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07009416 if (dut->program == PROGRAM_MBO || dut->program == PROGRAM_HE) {
Ashwini Patil00402582017-04-13 12:29:39 +05309417 free(dut->non_pref_ch_list);
9418 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309419 free(dut->btm_query_cand_list);
9420 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05309421 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05309422 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05309423 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05309424 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05309425 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05309426 }
9427
Jouni Malinen3c367e82017-06-23 17:01:47 +03009428 free(dut->rsne_override);
9429 dut->rsne_override = NULL;
9430
Jouni Malinen68143132017-09-02 02:34:08 +03009431 free(dut->sae_commit_override);
9432 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03009433 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02009434 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03009435
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009436 dut->sta_associate_wait_connect = 0;
9437 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03009438 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009439 dut->sta_tod_policy = 0;
9440
Jouni Malinend86e5822017-08-29 03:55:32 +03009441 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02009442 free(dut->dpp_peer_uri);
9443 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02009444 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02009445 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03009446 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinend86e5822017-08-29 03:55:32 +03009447
Jouni Malinenfac9cad2017-10-10 18:35:55 +03009448 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
9449
vamsi krishnaa2799492017-12-05 14:28:01 +05309450 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309451 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05309452 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05309453 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
9454 dut->fils_hlp = 0;
9455#ifdef ANDROID
9456 hlp_thread_cleanup(dut);
9457#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05309458 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309459
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309460 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309461 wpa_command(intf, "SET interworking 1");
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309462 wpa_command(intf, "SET enable_dscp_policy_capa 1");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05309463 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309464 dut->reject_dscp_policies = 0;
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +05309465 dut->num_dscp_status = 0;
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309466 snprintf(buf, sizeof(buf),
9467 "ip -6 route replace fe80::/64 dev %s table local",
9468 intf);
9469 if (system(buf) != 0)
9470 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
9471 buf);
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05309472
9473 stop_dscp_policy_mon_thread(dut);
9474 clear_all_dscp_policies(dut);
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309475 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309476
Jouni Malinen8179fee2019-03-28 03:19:47 +02009477 dut->akm_values = 0;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05309478
9479#ifdef NL80211_SUPPORT
9480 if (get_driver_type(dut) == DRIVER_WCN)
9481 sta_config_params(dut, intf, STA_SET_FT_DS, 0);
9482#endif /* NL80211_SUPPORT */
9483
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03009484 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02009485
Sunil Dutt076081f2018-02-05 19:45:50 +05309486#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009487 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05309488 dut->config_rsnie == 1) {
9489 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309490 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05309491 }
9492#endif /* NL80211_SUPPORT */
9493
Sunil Duttfebf8a82018-02-09 18:50:13 +05309494 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
9495 dut->dev_role = DEVROLE_STA_CFON;
9496 return sta_cfon_reset_default(dut, conn, cmd);
9497 }
9498
Jouni Malinen439352d2018-09-13 03:42:23 +03009499 wpa_command(intf, "SET setband AUTO");
9500
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309501 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
9502 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
9503
9504 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
9505 sizeof(resp));
9506 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
9507
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309508 if (sta_set_client_privacy(dut, conn, intf,
9509 dut->program == PROGRAM_WPA3 &&
9510 dut->device_type == STA_dut &&
9511 dut->client_privacy_default)) {
9512 sigma_dut_print(dut, DUT_MSG_ERROR,
9513 "Failed to set client privacy functionality");
9514 /* sta_reset_default command is not really supposed to fail,
9515 * so allow this to continue. */
9516 }
9517
Veerendranath Jakkamca239592021-10-11 20:48:00 +05309518 if (get_driver_type(dut) == DRIVER_WCN)
9519 wcn_set_ignore_h2e_rsnxe(dut, intf, 0);
9520
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05309521 dut->saquery_oci_freq = 0;
Shivani Baranwalebde8f62021-10-19 12:26:02 +05309522 dut->prev_disable_scs_support = 0;
9523 dut->prev_disable_mscs_support = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309524
Veerendranath Jakkamf6c8ab52022-03-10 05:43:02 -08009525 if (dut->autoconnect_default)
9526 wpa_command(intf, "STA_AUTOCONNECT 1");
9527 else
9528 wpa_command(intf, "STA_AUTOCONNECT 0");
9529
Sunil Duttfebf8a82018-02-09 18:50:13 +05309530 if (dut->program != PROGRAM_VHT)
9531 return cmd_sta_p2p_reset(dut, conn, cmd);
9532
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08009533 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009534}
9535
9536
Jouni Malinenf7222712019-06-13 01:50:21 +03009537static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
9538 struct sigma_conn *conn,
9539 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009540{
9541 const char *program = get_param(cmd, "Program");
9542
9543 if (program == NULL)
9544 return -1;
9545#ifdef ANDROID_NAN
9546 if (strcasecmp(program, "NAN") == 0)
9547 return nan_cmd_sta_get_events(dut, conn, cmd);
9548#endif /* ANDROID_NAN */
9549 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9550 return 0;
9551}
9552
9553
Jouni Malinen82905202018-04-29 17:20:10 +03009554static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
9555 struct sigma_cmd *cmd)
9556{
9557 const char *url = get_param(cmd, "url");
9558 const char *method = get_param(cmd, "method");
9559 pid_t pid;
9560 int status;
9561
9562 if (!url || !method)
9563 return -1;
9564
9565 /* TODO: Add support for method,post */
9566 if (strcasecmp(method, "get") != 0) {
9567 send_resp(dut, conn, SIGMA_ERROR,
9568 "ErrorCode,Unsupported method");
9569 return 0;
9570 }
9571
9572 pid = fork();
9573 if (pid < 0) {
9574 perror("fork");
9575 return -1;
9576 }
9577
9578 if (pid == 0) {
9579 char * argv[5] = { "wget", "-O", "/dev/null",
9580 (char *) url, NULL };
9581
9582 execv("/usr/bin/wget", argv);
9583 perror("execv");
9584 exit(0);
9585 return -1;
9586 }
9587
9588 if (waitpid(pid, &status, 0) < 0) {
9589 perror("waitpid");
9590 return -1;
9591 }
9592
9593 if (WIFEXITED(status)) {
9594 const char *errmsg;
9595
9596 if (WEXITSTATUS(status) == 0)
9597 return 1;
9598 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
9599 WEXITSTATUS(status));
9600 switch (WEXITSTATUS(status)) {
9601 case 4:
9602 errmsg = "errmsg,Network failure";
9603 break;
9604 case 8:
9605 errmsg = "errmsg,Server issued an error response";
9606 break;
9607 default:
9608 errmsg = "errmsg,Unknown failure from wget";
9609 break;
9610 }
9611 send_resp(dut, conn, SIGMA_ERROR, errmsg);
9612 return 0;
9613 }
9614
9615 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
9616 return 0;
9617}
9618
9619
Jouni Malinenf7222712019-06-13 01:50:21 +03009620static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
9621 struct sigma_conn *conn,
9622 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009623{
9624 const char *program = get_param(cmd, "Prog");
9625
Jouni Malinen82905202018-04-29 17:20:10 +03009626 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009627 return -1;
9628#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03009629 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009630 return nan_cmd_sta_exec_action(dut, conn, cmd);
9631#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03009632
9633 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009634 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03009635
9636 if (get_param(cmd, "url"))
9637 return sta_exec_action_url(dut, conn, cmd);
9638
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009639 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9640 return 0;
9641}
9642
9643
Jouni Malinenf7222712019-06-13 01:50:21 +03009644static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
9645 struct sigma_conn *conn,
9646 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009647{
9648 const char *intf = get_param(cmd, "Interface");
9649 const char *val, *mcs32, *rate;
9650
9651 val = get_param(cmd, "GREENFIELD");
9652 if (val) {
9653 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
9654 /* Enable GD */
9655 send_resp(dut, conn, SIGMA_ERROR,
9656 "ErrorCode,GF not supported");
9657 return 0;
9658 }
9659 }
9660
9661 val = get_param(cmd, "SGI20");
9662 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009663 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009664 case DRIVER_ATHEROS:
9665 ath_sta_set_sgi(dut, intf, val);
9666 break;
9667 default:
9668 send_resp(dut, conn, SIGMA_ERROR,
9669 "ErrorCode,SGI20 not supported");
9670 return 0;
9671 }
9672 }
9673
9674 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
9675 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
9676 if (mcs32 && rate) {
9677 /* TODO */
9678 send_resp(dut, conn, SIGMA_ERROR,
9679 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
9680 return 0;
9681 } else if (mcs32 && !rate) {
9682 /* TODO */
9683 send_resp(dut, conn, SIGMA_ERROR,
9684 "ErrorCode,MCS32 not supported");
9685 return 0;
9686 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009687 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009688 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07009689 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009690 ath_sta_set_11nrates(dut, intf, rate);
9691 break;
9692 default:
9693 send_resp(dut, conn, SIGMA_ERROR,
9694 "ErrorCode,MCS32_FIXEDRATE not supported");
9695 return 0;
9696 }
9697 }
9698
9699 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9700}
9701
9702
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009703static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
9704 int mcs_config)
9705{
9706#ifdef NL80211_SUPPORT
9707 int ret;
9708
9709 switch (mcs_config) {
9710 case HE_80_MCS0_7:
9711 case HE_80_MCS0_9:
9712 case HE_80_MCS0_11:
9713 ret = sta_set_he_mcs(dut, intf, mcs_config);
9714 if (ret) {
9715 sigma_dut_print(dut, DUT_MSG_ERROR,
9716 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
9717 mcs_config, ret);
9718 }
9719 break;
9720 default:
9721 sigma_dut_print(dut, DUT_MSG_ERROR,
9722 "cmd_set_max_he_mcs: Invalid mcs %d",
9723 mcs_config);
9724 break;
9725 }
9726#else /* NL80211_SUPPORT */
9727 sigma_dut_print(dut, DUT_MSG_ERROR,
9728 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
9729#endif /* NL80211_SUPPORT */
9730}
9731
9732
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009733struct wait_event {
9734 struct sigma_dut *dut;
9735 int cmd;
9736 unsigned int twt_op;
9737};
9738
9739#ifdef NL80211_SUPPORT
9740
9741static int twt_event_handler(struct nl_msg *msg, void *arg)
9742{
9743 struct wait_event *wait = arg;
9744 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9745 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9746 uint32_t subcmd;
9747 uint8_t *data = NULL;
9748 size_t len = 0;
9749 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
9750 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
9751 int cmd_id;
9752 unsigned char val;
9753
9754 if (!wait)
9755 return NL_SKIP;
9756
9757 if (gnlh->cmd != NL80211_CMD_VENDOR) {
9758 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9759 "%s: NL cmd is not vendor %d", __func__,
9760 gnlh->cmd);
9761 return NL_SKIP;
9762 }
9763
9764 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9765 genlmsg_attrlen(gnlh, 0), NULL);
9766
9767 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
9768 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9769 "%s: vendor ID not found", __func__);
9770 return NL_SKIP;
9771 }
9772 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
9773
9774 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
9775 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9776 "%s: Not a TWT_cmd %d", __func__, subcmd);
9777 return NL_SKIP;
9778 }
9779 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9780 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
9781 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
9782 } else {
9783 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9784 "%s: vendor data not present", __func__);
9785 return NL_SKIP;
9786 }
9787 if (!data || !len) {
9788 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9789 "Invalid vendor data or len");
9790 return NL_SKIP;
9791 }
9792 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
9793 "event data len %ld", len);
9794 hex_dump(wait->dut, data, len);
9795 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
9796 (struct nlattr *) data, len, NULL)) {
9797 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9798 "vendor data parse error");
9799 return NL_SKIP;
9800 }
9801
9802 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
9803 if (val != wait->twt_op) {
9804 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9805 "Invalid TWT operation, expected %d, rcvd %d",
9806 wait->twt_op, val);
9807 return NL_SKIP;
9808 }
9809 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
9810 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
9811 NULL)) {
9812 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9813 "nla_parse failed for TWT event");
9814 return NL_SKIP;
9815 }
9816
9817 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
9818 if (!twt_status[cmd_id]) {
9819 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9820 "%s TWT resp status missing", __func__);
9821 wait->cmd = -1;
9822 } else {
9823 val = nla_get_u8(twt_status[cmd_id]);
9824 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
9825 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9826 "%s TWT resp status %d", __func__, val);
9827 wait->cmd = -1;
9828 } else {
9829 wait->cmd = 1;
9830 }
9831 }
9832
9833 return NL_SKIP;
9834}
9835
9836
9837static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
9838 unsigned int timeout)
9839{
9840 fd_set read_fd_set;
9841 int retval;
9842 int sock_fd;
9843 struct timeval time_out;
9844
9845 time_out.tv_sec = timeout;
9846 time_out.tv_usec = 0;
9847
9848 FD_ZERO(&read_fd_set);
9849
9850 if (!sock)
9851 return -1;
9852
9853 sock_fd = nl_socket_get_fd(sock);
9854 FD_SET(sock_fd, &read_fd_set);
9855
9856 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
9857
9858 if (retval == 0)
9859 sigma_dut_print(dut, DUT_MSG_ERROR,
9860 "%s: TWT event response timedout", __func__);
9861
9862 if (retval < 0)
9863 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
9864 __func__, retval);
9865
9866 return retval;
9867}
9868
9869
9870#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
9871
9872static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
9873{
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009874 struct nl_cb *cb = NULL;
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009875 int err_code = 0, select_retval = 0;
9876 struct wait_event wait_info;
9877
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009878 if (dut->nl_ctx->event_sock)
9879 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009880 if (!cb) {
9881 sigma_dut_print(dut, DUT_MSG_ERROR,
9882 "event callback not found");
9883 return ERROR_SEND_STATUS;
9884 }
9885
9886 wait_info.cmd = 0;
9887 wait_info.dut = dut;
9888 wait_info.twt_op = twt_op;
9889
9890 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
9891
9892 while (!wait_info.cmd) {
9893 select_retval = wait_on_nl_socket(
9894 dut->nl_ctx->event_sock, dut,
9895 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
9896
9897 if (select_retval > 0) {
9898 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
9899 if (err_code < 0) {
9900 sigma_dut_print(dut, DUT_MSG_ERROR,
9901 "%s: nl rcv failed, err_code %d",
9902 __func__, err_code);
9903 break;
9904 }
9905 } else {
9906 sigma_dut_print(dut, DUT_MSG_ERROR,
9907 "%s: wait on socket failed %d",
9908 __func__, select_retval);
9909 err_code = 1;
9910 break;
9911 }
9912
9913 }
9914 nl_cb_put(cb);
9915
9916 if (wait_info.cmd < 0)
9917 err_code = 1;
9918
9919 sigma_dut_print(dut, DUT_MSG_DEBUG,
9920 "%s: rcvd cmd %d, err_code %d, s_ret %d",
9921 __func__, wait_info.cmd, err_code, select_retval);
9922
9923 return err_code;
9924}
9925
9926#endif /* NL80211_SUPPORT */
9927
9928
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009929static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
9930 struct sigma_cmd *cmd)
9931{
9932#ifdef NL80211_SUPPORT
9933 struct nlattr *attr, *attr1;
9934 struct nl_msg *msg;
9935 int ifindex, ret;
9936 const char *intf = get_param(cmd, "Interface");
9937
9938 ifindex = if_nametoindex(intf);
9939 if (ifindex == 0) {
9940 sigma_dut_print(dut, DUT_MSG_ERROR,
9941 "%s: Index for interface %s failed",
9942 __func__, intf);
9943 return ERROR_SEND_STATUS;
9944 }
9945
9946 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9947 NL80211_CMD_VENDOR)) ||
9948 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9949 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9950 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9951 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9952 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9953 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9954 QCA_WLAN_TWT_SUSPEND) ||
9955 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07009956 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009957 sigma_dut_print(dut, DUT_MSG_ERROR,
9958 "%s: err in adding vendor_cmd and vendor_data",
9959 __func__);
9960 nlmsg_free(msg);
9961 return ERROR_SEND_STATUS;
9962 }
9963 nla_nest_end(msg, attr1);
9964 nla_nest_end(msg, attr);
9965
9966 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9967 if (ret) {
9968 sigma_dut_print(dut, DUT_MSG_ERROR,
9969 "%s: err in send_and_recv_msgs, ret=%d",
9970 __func__, ret);
9971 }
9972
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009973 if (!dut->sta_async_twt_supp)
9974 return ret;
9975
9976 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009977#else /* NL80211_SUPPORT */
9978 sigma_dut_print(dut, DUT_MSG_ERROR,
9979 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9980 return ERROR_SEND_STATUS;
9981#endif /* NL80211_SUPPORT */
9982}
9983
9984
9985static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
9986 struct sigma_cmd *cmd,
9987 unsigned int suspend_duration)
9988{
9989#ifdef NL80211_SUPPORT
9990 struct nlattr *attr, *attr1;
9991 struct nl_msg *msg;
9992 int ifindex, ret;
9993 const char *intf = get_param(cmd, "Interface");
9994 int next_twt_size = 1;
9995
9996 ifindex = if_nametoindex(intf);
9997 if (ifindex == 0) {
9998 sigma_dut_print(dut, DUT_MSG_ERROR,
9999 "%s: Index for interface %s failed",
10000 __func__, intf);
10001 return ERROR_SEND_STATUS;
10002 }
10003
10004 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10005 NL80211_CMD_VENDOR)) ||
10006 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10007 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10008 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10009 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10010 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10011 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10012 QCA_WLAN_TWT_NUDGE) ||
10013 !(attr1 = nla_nest_start(msg,
10014 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10015 (suspend_duration &&
10016 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
10017 suspend_duration)) ||
10018 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010019 next_twt_size) ||
10020 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010021 sigma_dut_print(dut, DUT_MSG_ERROR,
10022 "%s: err in adding vendor_cmd and vendor_data",
10023 __func__);
10024 nlmsg_free(msg);
10025 return ERROR_SEND_STATUS;
10026 }
10027 nla_nest_end(msg, attr1);
10028 nla_nest_end(msg, attr);
10029
10030 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10031 if (ret) {
10032 sigma_dut_print(dut, DUT_MSG_ERROR,
10033 "%s: err in send_and_recv_msgs, ret=%d",
10034 __func__, ret);
10035 }
10036
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010037 if (!dut->sta_async_twt_supp)
10038 return ret;
10039
10040 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010041#else /* NL80211_SUPPORT */
10042 sigma_dut_print(dut, DUT_MSG_ERROR,
10043 "TWT suspend cannot be done without NL80211_SUPPORT defined");
10044 return ERROR_SEND_STATUS;
10045#endif /* NL80211_SUPPORT */
10046}
10047
10048
10049static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
10050 struct sigma_conn *conn,
10051 struct sigma_cmd *cmd)
10052{
10053 const char *val;
10054
10055 val = get_param(cmd, "TWT_SuspendDuration");
10056 if (val) {
10057 unsigned int suspend_duration;
10058
10059 suspend_duration = atoi(val);
10060 suspend_duration = suspend_duration * 1000 * 1000;
10061 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
10062 }
10063
10064 return sta_twt_send_suspend(dut, conn, cmd);
10065}
10066
10067
10068static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
10069 struct sigma_cmd *cmd)
10070{
10071#ifdef NL80211_SUPPORT
10072 struct nlattr *attr, *attr1;
10073 struct nl_msg *msg;
10074 int ifindex, ret;
10075 const char *intf = get_param(cmd, "Interface");
10076 int next2_twt_size = 1;
10077 unsigned int resume_duration = 0;
10078 const char *val;
10079
10080 ifindex = if_nametoindex(intf);
10081 if (ifindex == 0) {
10082 sigma_dut_print(dut, DUT_MSG_ERROR,
10083 "%s: Index for interface %s failed",
10084 __func__, intf);
10085 return ERROR_SEND_STATUS;
10086 }
10087
10088 val = get_param(cmd, "TWT_ResumeDuration");
10089 if (val) {
10090 resume_duration = atoi(val);
10091 resume_duration = resume_duration * 1000 * 1000;
10092 }
10093
10094 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10095 NL80211_CMD_VENDOR)) ||
10096 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10097 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10098 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10099 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10100 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10101 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10102 QCA_WLAN_TWT_RESUME) ||
10103 !(attr1 = nla_nest_start(msg,
10104 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10105 (resume_duration &&
10106 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
10107 resume_duration)) ||
10108 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
10109 next2_twt_size)) {
10110 sigma_dut_print(dut, DUT_MSG_ERROR,
10111 "%s: err in adding vendor_cmd and vendor_data",
10112 __func__);
10113 nlmsg_free(msg);
10114 return ERROR_SEND_STATUS;
10115 }
10116 nla_nest_end(msg, attr1);
10117 nla_nest_end(msg, attr);
10118
10119 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10120 if (ret) {
10121 sigma_dut_print(dut, DUT_MSG_ERROR,
10122 "%s: err in send_and_recv_msgs, ret=%d",
10123 __func__, ret);
10124 }
10125
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010126 if (!dut->sta_async_twt_supp)
10127 return ret;
10128
10129 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010130#else /* NL80211_SUPPORT */
10131 sigma_dut_print(dut, DUT_MSG_ERROR,
10132 "TWT resume cannot be done without NL80211_SUPPORT defined");
10133 return ERROR_SEND_STATUS;
10134#endif /* NL80211_SUPPORT */
10135}
10136
10137
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010138#define TWT_REQUEST_CMD 0
10139#define TWT_SUGGEST_CMD 1
10140#define TWT_DEMAND_CMD 2
10141
Arif Hussain480d5f42019-03-12 14:40:42 -070010142static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
10143 struct sigma_cmd *cmd)
10144{
10145#ifdef NL80211_SUPPORT
10146 struct nlattr *params;
10147 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010148 struct nl_msg *msg;
10149 int ifindex, ret;
10150 const char *val;
10151 const char *intf = get_param(cmd, "Interface");
10152 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
10153 wake_interval_mantissa = 512;
10154 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010155 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010156 int bcast_twt = 0;
10157 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -070010158
10159 ifindex = if_nametoindex(intf);
10160 if (ifindex == 0) {
10161 sigma_dut_print(dut, DUT_MSG_ERROR,
10162 "%s: Index for interface %s failed",
10163 __func__, intf);
10164 return -1;
10165 }
10166
10167 val = get_param(cmd, "FlowType");
10168 if (val) {
10169 flow_type = atoi(val);
10170 if (flow_type != 0 && flow_type != 1) {
10171 sigma_dut_print(dut, DUT_MSG_ERROR,
10172 "TWT: Invalid FlowType %d", flow_type);
10173 return -1;
10174 }
10175 }
10176
10177 val = get_param(cmd, "TWT_Trigger");
10178 if (val) {
10179 twt_trigger = atoi(val);
10180 if (twt_trigger != 0 && twt_trigger != 1) {
10181 sigma_dut_print(dut, DUT_MSG_ERROR,
10182 "TWT: Invalid TWT_Trigger %d",
10183 twt_trigger);
10184 return -1;
10185 }
10186 }
10187
10188 val = get_param(cmd, "Protection");
10189 if (val) {
10190 protection = atoi(val);
10191 if (protection != 0 && protection != 1) {
10192 sigma_dut_print(dut, DUT_MSG_ERROR,
10193 "TWT: Invalid Protection %d",
10194 protection);
10195 return -1;
10196 }
10197 }
10198
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010199 val = get_param(cmd, "SetupCommand");
10200 if (val) {
10201 cmd_type = atoi(val);
10202 if (cmd_type == TWT_REQUEST_CMD)
10203 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
10204 else if (cmd_type == TWT_SUGGEST_CMD)
10205 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
10206 else if (cmd_type == TWT_DEMAND_CMD)
10207 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
10208 else
10209 sigma_dut_print(dut, DUT_MSG_ERROR,
10210 "Default suggest is used for cmd %d",
10211 cmd_type);
10212 }
10213
Arif Hussain480d5f42019-03-12 14:40:42 -070010214 val = get_param(cmd, "TargetWakeTime");
10215 if (val)
10216 target_wake_time = atoi(val);
10217
10218 val = get_param(cmd, "WakeIntervalMantissa");
10219 if (val)
10220 wake_interval_mantissa = atoi(val);
10221
10222 val = get_param(cmd, "WakeIntervalExp");
10223 if (val)
10224 wake_interval_exp = atoi(val);
10225
10226 val = get_param(cmd, "NominalMinWakeDur");
10227 if (val)
10228 nominal_min_wake_dur = atoi(val);
10229
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010230 val = get_param(cmd, "BTWT_ID");
10231 if (val) {
10232 bcast_twt_id = atoi(val);
10233 bcast_twt = 1;
10234 }
10235
10236 val = get_param(cmd, "BTWT_Persistence");
10237 if (val) {
10238 bcast_twt_persis = atoi(val);
10239 bcast_twt = 1;
10240 }
10241
10242 val = get_param(cmd, "BTWT_Recommendation");
10243 if (val) {
10244 bcast_twt_recommdn = atoi(val);
10245 bcast_twt = 1;
10246 }
10247
10248 if (bcast_twt)
10249 sigma_dut_print(dut, DUT_MSG_DEBUG,
10250 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
10251 bcast_twt_id, bcast_twt_recommdn,
10252 bcast_twt_persis);
10253
Arif Hussain480d5f42019-03-12 14:40:42 -070010254 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10255 NL80211_CMD_VENDOR)) ||
10256 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10257 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10258 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010259 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010260 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010261 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10262 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010263 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010264 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010265 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
10266 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010267 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010268 (twt_trigger &&
10269 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010270 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
10271 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010272 (protection &&
10273 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010274 (bcast_twt &&
10275 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10276 (bcast_twt &&
10277 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10278 bcast_twt_id)) ||
10279 (bcast_twt &&
10280 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
10281 bcast_twt_persis)) ||
10282 (bcast_twt &&
10283 nla_put_u8(msg,
10284 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
10285 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010286 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
10287 target_wake_time) ||
10288 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
10289 nominal_min_wake_dur) ||
10290 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
10291 wake_interval_mantissa)) {
10292 sigma_dut_print(dut, DUT_MSG_ERROR,
10293 "%s: err in adding vendor_cmd and vendor_data",
10294 __func__);
10295 nlmsg_free(msg);
10296 return -1;
10297 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010298 nla_nest_end(msg, params);
10299 nla_nest_end(msg, attr);
10300
10301 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10302 if (ret) {
10303 sigma_dut_print(dut, DUT_MSG_ERROR,
10304 "%s: err in send_and_recv_msgs, ret=%d",
10305 __func__, ret);
10306 }
10307
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010308 if (!dut->sta_async_twt_supp)
10309 return ret;
10310
10311 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -070010312#else /* NL80211_SUPPORT */
10313 sigma_dut_print(dut, DUT_MSG_ERROR,
10314 "TWT request cannot be done without NL80211_SUPPORT defined");
10315 return -1;
10316#endif /* NL80211_SUPPORT */
10317}
10318
10319
10320static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
10321 struct sigma_cmd *cmd)
10322{
10323 #ifdef NL80211_SUPPORT
10324 struct nlattr *params;
10325 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010326 int ifindex, ret;
10327 struct nl_msg *msg;
10328 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010329 int bcast_twt = 0;
10330 int bcast_twt_id = 0;
10331 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -070010332
10333 ifindex = if_nametoindex(intf);
10334 if (ifindex == 0) {
10335 sigma_dut_print(dut, DUT_MSG_ERROR,
10336 "%s: Index for interface %s failed",
10337 __func__, intf);
10338 return -1;
10339 }
10340
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010341 val = get_param(cmd, "BTWT_ID");
10342 if (val) {
10343 bcast_twt_id = atoi(val);
10344 bcast_twt = 1;
10345 }
10346
Arif Hussain480d5f42019-03-12 14:40:42 -070010347 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10348 NL80211_CMD_VENDOR)) ||
10349 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10350 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10351 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010352 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010353 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010354 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10355 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010356 !(params = nla_nest_start(
10357 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010358 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010359 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
10360 (bcast_twt &&
10361 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10362 (bcast_twt &&
10363 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10364 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -070010365 sigma_dut_print(dut, DUT_MSG_ERROR,
10366 "%s: err in adding vendor_cmd and vendor_data",
10367 __func__);
10368 nlmsg_free(msg);
10369 return -1;
10370 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010371 nla_nest_end(msg, params);
10372 nla_nest_end(msg, attr);
10373
10374 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10375 if (ret) {
10376 sigma_dut_print(dut, DUT_MSG_ERROR,
10377 "%s: err in send_and_recv_msgs, ret=%d",
10378 __func__, ret);
10379 }
10380
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010381 if (!dut->sta_async_twt_supp)
10382 return ret;
10383
10384 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -070010385#else /* NL80211_SUPPORT */
10386 sigma_dut_print(dut, DUT_MSG_ERROR,
10387 "TWT teardown cannot be done without NL80211_SUPPORT defined");
10388 return -1;
10389#endif /* NL80211_SUPPORT */
10390}
10391
10392
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080010393static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
10394 struct sigma_cmd *cmd)
10395{
10396#ifdef NL80211_SUPPORT
10397 struct nlattr *params;
10398 struct nlattr *attr;
10399 struct nlattr *attr1;
10400 struct nl_msg *msg;
10401 int ifindex, ret;
10402 const char *val;
10403 const char *intf = get_param(cmd, "Interface");
10404 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
10405 ulmu_data_dis = 0;
10406
10407 ifindex = if_nametoindex(intf);
10408 if (ifindex == 0) {
10409 sigma_dut_print(dut, DUT_MSG_ERROR,
10410 "%s: Index for interface %s failed",
10411 __func__, intf);
10412 return -1;
10413 }
10414 val = get_param(cmd, "OMCtrl_RxNSS");
10415 if (val)
10416 rx_nss = atoi(val);
10417
10418 val = get_param(cmd, "OMCtrl_ChnlWidth");
10419 if (val)
10420 ch_bw = atoi(val);
10421
10422 val = get_param(cmd, "OMCtrl_ULMUDisable");
10423 if (val)
10424 ulmu_dis = atoi(val);
10425
10426 val = get_param(cmd, "OMCtrl_TxNSTS");
10427 if (val)
10428 tx_nsts = atoi(val);
10429
10430 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
10431 if (val)
10432 ulmu_data_dis = atoi(val);
10433
10434 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10435 NL80211_CMD_VENDOR)) ||
10436 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10437 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10438 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10439 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10440 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10441 !(params = nla_nest_start(
10442 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
10443 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10444 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
10445 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
10446 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
10447 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
10448 ulmu_data_dis) ||
10449 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
10450 ulmu_dis)) {
10451 sigma_dut_print(dut, DUT_MSG_ERROR,
10452 "%s: err in adding vendor_cmd and vendor_data",
10453 __func__);
10454 nlmsg_free(msg);
10455 return -1;
10456 }
10457 nla_nest_end(msg, attr1);
10458 nla_nest_end(msg, params);
10459 nla_nest_end(msg, attr);
10460
10461 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10462 if (ret) {
10463 sigma_dut_print(dut, DUT_MSG_ERROR,
10464 "%s: err in send_and_recv_msgs, ret=%d",
10465 __func__, ret);
10466 }
10467
10468 return ret;
10469#else /* NL80211_SUPPORT */
10470 sigma_dut_print(dut, DUT_MSG_ERROR,
10471 "OMI TX cannot be processed without NL80211_SUPPORT defined");
10472 return -1;
10473#endif /* NL80211_SUPPORT */
10474}
10475
10476
Jouni Malinen224e3902021-06-09 16:41:27 +030010477static enum sigma_cmd_result
10478cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10479 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010480{
10481 const char *intf = get_param(cmd, "Interface");
10482 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -070010483 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010484 int tkip = -1;
10485 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010486 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010487
Arif Hussaina37e9552018-06-20 17:05:59 -070010488 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010489 val = get_param(cmd, "SGI80");
10490 if (val) {
10491 int sgi80;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010492 enum nl80211_txrate_gi gi_val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010493
10494 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010495 if (sgi80)
10496 gi_val = NL80211_TXRATE_FORCE_LGI;
10497 else
10498 gi_val = NL80211_TXRATE_FORCE_SGI;
10499 if (sta_set_vht_gi(dut, intf, (u8) gi_val)) {
10500 sigma_dut_print(dut, DUT_MSG_INFO,
10501 "sta_set_vht_gi failed, using iwpriv");
10502 run_iwpriv(dut, intf, "shortgi %d", sgi80);
10503 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010504 }
10505
10506 val = get_param(cmd, "TxBF");
10507 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010508 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010509 case DRIVER_WCN:
10510 if (sta_set_tx_beamformee(dut, intf, 1)) {
10511 send_resp(dut, conn, SIGMA_ERROR,
10512 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010513 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010514 }
10515 break;
10516 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010517 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010518 send_resp(dut, conn, SIGMA_ERROR,
10519 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010520 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010521 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010522 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010523 send_resp(dut, conn, SIGMA_ERROR,
10524 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010525 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010526 }
10527 break;
10528 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010529 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010530 "Unsupported driver type");
10531 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010532 }
10533 }
10534
10535 val = get_param(cmd, "MU_TxBF");
10536 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010537 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010538 case DRIVER_ATHEROS:
10539 ath_sta_set_txsp_stream(dut, intf, "1SS");
10540 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010541 run_iwpriv(dut, intf, "vhtmubfee 1");
10542 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +053010543 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010544 case DRIVER_WCN:
10545 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
10546 send_resp(dut, conn, SIGMA_ERROR,
10547 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +030010548 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010549 }
Sunil Duttae9e5d12018-06-29 11:50:47 +053010550 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010551 default:
10552 sigma_dut_print(dut, DUT_MSG_ERROR,
10553 "Setting SP_STREAM not supported");
10554 break;
10555 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010556 }
10557
10558 val = get_param(cmd, "LDPC");
10559 if (val) {
10560 int ldpc;
10561
10562 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010563 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
10564 if (iwpriv_status)
10565 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010566 }
10567
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010568 val = get_param(cmd, "BCC");
10569 if (val) {
10570 int bcc;
10571
10572 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10573 /* use LDPC iwpriv itself to set bcc coding, bcc coding
10574 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010575 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
10576 if (iwpriv_status)
10577 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010578 }
10579
Arif Hussain7b47d2d2018-05-09 10:44:02 -070010580 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
10581 if (val && dut->sta_nss == 1)
10582 cmd_set_max_he_mcs(dut, intf, atoi(val));
10583
10584 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
10585 if (val && dut->sta_nss == 2)
10586 cmd_set_max_he_mcs(dut, intf, atoi(val));
10587
Arif Hussainac6c5112018-05-25 17:34:00 -070010588 val = get_param(cmd, "MCS_FixedRate");
10589 if (val) {
10590#ifdef NL80211_SUPPORT
10591 int mcs, ratecode = 0;
10592 enum he_mcs_config mcs_config;
10593 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +030010594 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -070010595
10596 ratecode = (0x07 & dut->sta_nss) << 5;
10597 mcs = atoi(val);
10598 /* Add the MCS to the ratecode */
10599 if (mcs >= 0 && mcs <= 11) {
10600 ratecode += mcs;
10601 if (dut->device_type == STA_testbed &&
10602 mcs > 7 && mcs <= 11) {
10603 if (mcs <= 9)
10604 mcs_config = HE_80_MCS0_9;
10605 else
10606 mcs_config = HE_80_MCS0_11;
10607 ret = sta_set_he_mcs(dut, intf, mcs_config);
10608 if (ret) {
10609 sigma_dut_print(dut, DUT_MSG_ERROR,
10610 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10611 mcs, mcs_config, ret);
10612 }
10613 }
10614 snprintf(buf, sizeof(buf),
10615 "iwpriv %s set_11ax_rate 0x%03x",
10616 intf, ratecode);
10617 if (system(buf) != 0) {
10618 sigma_dut_print(dut, DUT_MSG_ERROR,
10619 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
10620 ratecode);
10621 }
10622 } else {
10623 sigma_dut_print(dut, DUT_MSG_ERROR,
10624 "MCS_FixedRate: HE MCS %d not supported",
10625 mcs);
10626 }
10627#else /* NL80211_SUPPORT */
10628 sigma_dut_print(dut, DUT_MSG_ERROR,
10629 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
10630#endif /* NL80211_SUPPORT */
10631 }
10632
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010633 val = get_param(cmd, "opt_md_notif_ie");
10634 if (val) {
10635 char *result = NULL;
10636 char delim[] = ";";
10637 char token[30];
10638 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010639 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010640
Peng Xub8fc5cc2017-05-10 17:27:28 -070010641 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010642 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010643
10644 /* Extract the NSS information */
10645 if (result) {
10646 value = atoi(result);
10647 switch (value) {
10648 case 1:
10649 config_val = 1;
10650 break;
10651 case 2:
10652 config_val = 3;
10653 break;
10654 case 3:
10655 config_val = 7;
10656 break;
10657 case 4:
10658 config_val = 15;
10659 break;
10660 default:
10661 config_val = 3;
10662 break;
10663 }
10664
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010665 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
10666 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010667
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010668 }
10669
10670 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010671 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010672 if (result) {
10673 value = atoi(result);
10674 switch (value) {
10675 case 20:
10676 config_val = 0;
10677 break;
10678 case 40:
10679 config_val = 1;
10680 break;
10681 case 80:
10682 config_val = 2;
10683 break;
10684 case 160:
10685 config_val = 3;
10686 break;
10687 default:
10688 config_val = 2;
10689 break;
10690 }
10691
10692 dut->chwidth = config_val;
10693
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010694 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010695 }
10696
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010697 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010698 }
10699
10700 val = get_param(cmd, "nss_mcs_cap");
10701 if (val) {
10702 int nss, mcs;
10703 char token[20];
10704 char *result = NULL;
10705 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010706 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010707
Peng Xub8fc5cc2017-05-10 17:27:28 -070010708 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010709 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010710 if (!result) {
10711 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010712 "NSS not specified");
10713 send_resp(dut, conn, SIGMA_ERROR,
10714 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010715 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010716 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010717 nss = atoi(result);
10718
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010719 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -070010720 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010721
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010722 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010723 if (result == NULL) {
10724 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010725 "MCS not specified");
10726 send_resp(dut, conn, SIGMA_ERROR,
10727 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010728 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010729 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010730 result = strtok_r(result, "-", &saveptr);
10731 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010732 if (!result) {
10733 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010734 "MCS not specified");
10735 send_resp(dut, conn, SIGMA_ERROR,
10736 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010737 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010738 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010739 mcs = atoi(result);
10740
Arif Hussaina37e9552018-06-20 17:05:59 -070010741 if (program && strcasecmp(program, "HE") == 0) {
10742#ifdef NL80211_SUPPORT
10743 enum he_mcs_config mcs_config;
10744 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010745
Arif Hussaina37e9552018-06-20 17:05:59 -070010746 if (mcs >= 0 && mcs <= 7) {
10747 mcs_config = HE_80_MCS0_7;
10748 } else if (mcs > 7 && mcs <= 9) {
10749 mcs_config = HE_80_MCS0_9;
10750 } else if (mcs > 9 && mcs <= 11) {
10751 mcs_config = HE_80_MCS0_11;
10752 } else {
10753 sigma_dut_print(dut, DUT_MSG_ERROR,
10754 "nss_mcs_cap: HE: Invalid mcs: %d",
10755 mcs);
10756 send_resp(dut, conn, SIGMA_ERROR,
10757 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010758 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010759 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010760
10761 ret = sta_set_he_mcs(dut, intf, mcs_config);
10762 if (ret) {
10763 sigma_dut_print(dut, DUT_MSG_ERROR,
10764 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
10765 mcs_config, ret);
10766 send_resp(dut, conn, SIGMA_ERROR,
10767 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010768 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010769 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010770#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010771 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010772 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
10773#endif /* NL80211_SUPPORT */
10774 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010775 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -070010776
10777 switch (nss) {
10778 case 1:
10779 switch (mcs) {
10780 case 7:
10781 vht_mcsmap = 0xfffc;
10782 break;
10783 case 8:
10784 vht_mcsmap = 0xfffd;
10785 break;
10786 case 9:
10787 vht_mcsmap = 0xfffe;
10788 break;
10789 default:
10790 vht_mcsmap = 0xfffe;
10791 break;
10792 }
10793 break;
10794 case 2:
10795 switch (mcs) {
10796 case 7:
10797 vht_mcsmap = 0xfff0;
10798 break;
10799 case 8:
10800 vht_mcsmap = 0xfff5;
10801 break;
10802 case 9:
10803 vht_mcsmap = 0xfffa;
10804 break;
10805 default:
10806 vht_mcsmap = 0xfffa;
10807 break;
10808 }
10809 break;
10810 case 3:
10811 switch (mcs) {
10812 case 7:
10813 vht_mcsmap = 0xffc0;
10814 break;
10815 case 8:
10816 vht_mcsmap = 0xffd5;
10817 break;
10818 case 9:
10819 vht_mcsmap = 0xffea;
10820 break;
10821 default:
10822 vht_mcsmap = 0xffea;
10823 break;
10824 }
10825 break;
10826 default:
10827 vht_mcsmap = 0xffea;
10828 break;
10829 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010830 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010831 }
10832 }
10833
10834 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
10835
10836 val = get_param(cmd, "Vht_tkip");
10837 if (val)
10838 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10839
10840 val = get_param(cmd, "Vht_wep");
10841 if (val)
10842 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10843
10844 if (tkip != -1 || wep != -1) {
10845 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010846 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010847 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010848 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010849 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +030010850 send_resp(dut, conn, SIGMA_ERROR,
10851 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
10852 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010853 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010854 }
10855
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -070010856 val = get_param(cmd, "TWTSchedSTASupport");
10857 if (val) {
10858 int set_val;
10859
10860 switch (get_driver_type(dut)) {
10861 case DRIVER_WCN:
10862 if (strcasecmp(val, "Enable") == 0) {
10863 set_val = 1;
10864 } else if (strcasecmp(val, "Disable") == 0) {
10865 set_val = 0;
10866 } else {
10867 send_resp(dut, conn, SIGMA_ERROR,
10868 "ErrorCode,Invalid TWTSchedSTASupport");
10869 return STATUS_SENT_ERROR;
10870 }
10871
10872 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
10873 send_resp(dut, conn, SIGMA_ERROR,
10874 "ErrorCode,Failed to set TWTSchedSTASupport");
10875 return STATUS_SENT_ERROR;
10876 }
10877 break;
10878 default:
10879 sigma_dut_print(dut, DUT_MSG_ERROR,
10880 "Setting TWTSchedSTASupport not supported");
10881 break;
10882 }
10883 }
10884
10885 val = get_param(cmd, "MBSSID_RxCtrl");
10886 if (val) {
10887 int set_val;
10888
10889 switch (get_driver_type(dut)) {
10890 case DRIVER_WCN:
10891 if (strcasecmp(val, "Enable") == 0) {
10892 set_val = 1;
10893 } else if (strcasecmp(val, "Disable") == 0) {
10894 set_val = 0;
10895 } else {
10896 send_resp(dut, conn, SIGMA_ERROR,
10897 "ErrorCode,Invalid MBSSID_RxCtrl");
10898 return STATUS_SENT_ERROR;
10899 }
10900
10901 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
10902 send_resp(dut, conn, SIGMA_ERROR,
10903 "ErrorCode,Failed to set MBSSID_RxCtrl");
10904 return STATUS_SENT_ERROR;
10905 }
10906 break;
10907 default:
10908 sigma_dut_print(dut, DUT_MSG_ERROR,
10909 "Setting MBSSID_RxCtrl not supported");
10910 break;
10911 }
10912 }
10913
Arif Hussain55f00da2018-07-03 08:28:26 -070010914 val = get_param(cmd, "txBandwidth");
10915 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010916 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -070010917 case DRIVER_WCN:
10918 if (wcn_sta_set_width(dut, intf, val) < 0) {
10919 send_resp(dut, conn, SIGMA_ERROR,
10920 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010921 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010922 }
10923 break;
10924 case DRIVER_ATHEROS:
10925 if (ath_set_width(dut, conn, 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 default:
10932 sigma_dut_print(dut, DUT_MSG_ERROR,
10933 "Setting txBandwidth not supported");
10934 break;
10935 }
10936 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010937
Arif Hussain9765f7d2018-07-03 08:28:26 -070010938 val = get_param(cmd, "BeamformeeSTS");
10939 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010940 if (sta_set_tx_beamformee(dut, intf, 1)) {
10941 send_resp(dut, conn, SIGMA_ERROR,
10942 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010943 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010944 }
10945
Arif Hussain9765f7d2018-07-03 08:28:26 -070010946 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
10947 send_resp(dut, conn, SIGMA_ERROR,
10948 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010949 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -070010950 }
10951 }
10952
Arif Hussain68d23f52018-07-11 13:39:08 -070010953 val = get_param(cmd, "Trig_MAC_Padding_Dur");
10954 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010955#ifdef NL80211_SUPPORT
10956 enum qca_wlan_he_mac_padding_dur set_val;
10957
10958 switch (atoi(val)) {
10959 case 16:
10960 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
10961 break;
10962 case 8:
10963 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
10964 break;
10965 default:
10966 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
10967 break;
10968 }
10969 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -070010970 send_resp(dut, conn, SIGMA_ERROR,
10971 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +030010972 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -070010973 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010974#else /* NL80211_SUPPORT */
10975 sigma_dut_print(dut, DUT_MSG_ERROR,
10976 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
10977#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -070010978 }
10979
Arif Hussain480d5f42019-03-12 14:40:42 -070010980 val = get_param(cmd, "TWT_ReqSupport");
10981 if (val) {
10982 int set_val;
10983
10984 if (strcasecmp(val, "Enable") == 0) {
10985 set_val = 1;
10986 } else if (strcasecmp(val, "Disable") == 0) {
10987 set_val = 0;
10988 } else {
10989 send_resp(dut, conn, SIGMA_ERROR,
10990 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010991 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010992 }
10993
10994 if (sta_set_twt_req_support(dut, intf, set_val)) {
10995 sigma_dut_print(dut, DUT_MSG_ERROR,
10996 "Failed to set TWT req support %d",
10997 set_val);
10998 send_resp(dut, conn, SIGMA_ERROR,
10999 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030011000 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070011001 }
11002 }
11003
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -070011004 val = get_param(cmd, "PreamblePunctRx");
11005 if (val && get_driver_type(dut) == DRIVER_WCN) {
11006 int set_val;
11007
11008 if (strcasecmp(val, "Enable") == 0) {
11009 set_val = 1;
11010 } else if (strcasecmp(val, "Disable") == 0) {
11011 set_val = 0;
11012 } else {
11013 send_resp(dut, conn, SIGMA_ERROR,
11014 "ErrorCode,Invalid PreamblePunctRx");
11015 return STATUS_SENT_ERROR;
11016 }
11017
11018 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
11019 sigma_dut_print(dut, DUT_MSG_ERROR,
11020 "Failed to set PreamblePunctRx support %d",
11021 set_val);
11022 send_resp(dut, conn, SIGMA_ERROR,
11023 "ErrorCode,Failed to set PreamblePunctRx");
11024 return STATUS_SENT_ERROR;
11025 }
11026 }
11027
Srinivas Girigowda0525e292020-11-12 13:28:21 -080011028 val = get_param(cmd, "FullBW_ULMUMIMO");
11029 if (val) {
11030 int set_val;
11031
11032 if (strcasecmp(val, "Enable") == 0) {
11033 set_val = 1;
11034 } else if (strcasecmp(val, "Disable") == 0) {
11035 set_val = 0;
11036 } else {
11037 send_resp(dut, conn, SIGMA_ERROR,
11038 "ErrorCode,Invalid FullBW_ULMUMIMO");
11039 return STATUS_SENT_ERROR;
11040 }
11041
11042 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
11043 sigma_dut_print(dut, DUT_MSG_ERROR,
11044 "Failed to set FullBW_ULMUMIMO %d",
11045 set_val);
11046 send_resp(dut, conn, SIGMA_ERROR,
11047 "ErrorCode,Failed to set FullBW_ULMUMIMO");
11048 return STATUS_SENT_ERROR;
11049 }
11050 }
11051
Srinivas Girigowda6707f032020-10-26 15:24:46 -070011052 val = get_param(cmd, "TWTInfoFrameTx");
11053 if (val) {
11054 if (strcasecmp(val, "Enable") == 0) {
11055 /* No-op */
11056 } else if (strcasecmp(val, "Disable") == 0) {
11057 /* No-op */
11058 } else {
11059 send_resp(dut, conn, SIGMA_ERROR,
11060 "ErrorCode,Invalid TWTInfoFrameTx");
11061 return STATUS_SENT_ERROR;
11062 }
11063 }
11064
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011065 val = get_param(cmd, "MU_EDCA");
11066 if (val && (strcasecmp(val, "Override") == 0)) {
11067 if (sta_set_mu_edca_override(dut, intf, 1)) {
11068 send_resp(dut, conn, SIGMA_ERROR,
11069 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +030011070 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011071 }
11072 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011073
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070011074 val = get_param(cmd, "PPDUTxType");
11075 if (val && strcasecmp(val, "ER-SU") == 0) {
11076 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
11077 send_resp(dut, conn, SIGMA_ERROR,
11078 "ErrorCode,Failed to set ER-SU PPDU type Tx");
11079 return STATUS_SENT_ERROR;
11080 }
11081 }
11082
11083 val = get_param(cmd, "RUAllocTone");
11084 if (val && strcasecmp(val, "242") == 0) {
11085 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
11086 send_resp(dut, conn, SIGMA_ERROR,
11087 "ErrorCode,Failed to set RU 242 tone Tx");
11088 return STATUS_SENT_ERROR;
11089 }
11090 }
11091
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011092 val = get_param(cmd, "OMControl");
11093 if (val) {
11094 int set_val = 1;
11095
11096 if (strcasecmp(val, "Enable") == 0)
11097 set_val = 1;
11098 else if (strcasecmp(val, "Disable") == 0)
11099 set_val = 0;
11100
11101 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
11102 send_resp(dut, conn, SIGMA_ERROR,
11103 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +030011104 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011105 }
11106 }
11107
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -070011108 val = get_param(cmd, "BSSMaxIdlePeriod");
11109 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
11110 send_resp(dut, conn, SIGMA_ERROR,
11111 "ErrorCode,Failed to set BSS max idle period");
11112 return STATUS_SENT_ERROR;
11113 }
11114
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -070011115 val = get_param(cmd, "BSS_max_idle");
11116 if (val) {
11117 int set_val = 0;
11118
11119 if (strcasecmp(val, "Enable") == 0)
11120 set_val = 1;
11121 else if (strcasecmp(val, "Disable") == 0)
11122 set_val = 0;
11123 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
11124 send_resp(dut, conn, SIGMA_ERROR,
11125 "ErrorCode,Failed to set BSS max idle support");
11126 return STATUS_SENT_ERROR;
11127 }
11128 }
11129
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011130 val = get_param(cmd, "ADDBAResp_BufSize");
11131 if (val) {
11132 int buf_size;
11133
11134 if (strcasecmp(val, "gt64") == 0)
11135 buf_size = 256;
11136 else
11137 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011138 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011139 sta_set_addba_buf_size(dut, intf, buf_size)) {
11140 send_resp(dut, conn, SIGMA_ERROR,
11141 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011142 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011143 }
11144 }
11145
11146 val = get_param(cmd, "ADDBAReq_BufSize");
11147 if (val) {
11148 int buf_size;
11149
11150 if (strcasecmp(val, "gt64") == 0)
11151 buf_size = 256;
11152 else
11153 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011154 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011155 sta_set_addba_buf_size(dut, intf, buf_size)) {
11156 send_resp(dut, conn, SIGMA_ERROR,
11157 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011158 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011159 }
11160 }
11161
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011162 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11163}
11164
11165
11166static int sta_set_wireless_60g(struct sigma_dut *dut,
11167 struct sigma_conn *conn,
11168 struct sigma_cmd *cmd)
11169{
11170 const char *dev_role = get_param(cmd, "DevRole");
11171
11172 if (!dev_role) {
11173 send_resp(dut, conn, SIGMA_INVALID,
11174 "ErrorCode,DevRole not specified");
11175 return 0;
11176 }
11177
11178 if (strcasecmp(dev_role, "PCP") == 0)
11179 return sta_set_60g_pcp(dut, conn, cmd);
11180 if (strcasecmp(dev_role, "STA") == 0)
11181 return sta_set_60g_sta(dut, conn, cmd);
11182 send_resp(dut, conn, SIGMA_INVALID,
11183 "ErrorCode,DevRole not supported");
11184 return 0;
11185}
11186
11187
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011188static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
11189 struct sigma_cmd *cmd)
11190{
11191 int status;
11192 const char *intf = get_param(cmd, "Interface");
11193 const char *val = get_param(cmd, "DevRole");
11194
11195 if (val && strcasecmp(val, "STA-CFON") == 0) {
11196 status = sta_cfon_set_wireless(dut, conn, cmd);
11197 if (status)
11198 return status;
11199 }
11200 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11201}
11202
11203
Jouni Malinen67433fc2020-06-26 22:50:33 +030011204static enum sigma_cmd_result
11205sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
11206 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011207{
11208 const char *intf = get_param(cmd, "Interface");
11209 const char *val;
11210
11211 val = get_param(cmd, "ocvc");
11212 if (val)
11213 dut->ocvc = atoi(val);
11214
Jouni Malinen67433fc2020-06-26 22:50:33 +030011215 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +053011216 if (val && dut->client_privacy != atoi(val) &&
11217 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
11218 send_resp(dut, conn, SIGMA_ERROR,
11219 "errorCode,Failed to configure random MAC address use");
11220 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +030011221 }
11222
Veerendranath Jakkam9ce2b642022-02-28 18:49:25 +053011223 val = get_param(cmd, "GKH_G2_Tx");
11224 if (val) {
11225 char buf[50];
11226
11227 snprintf(buf, sizeof(buf), "SET disable_eapol_g2_tx %d",
11228 strcasecmp(val, "disable") == 0);
11229
11230 if (wpa_command(intf, buf) < 0) {
11231 send_resp(dut, conn, SIGMA_ERROR,
11232 "errorCode,Failed to enable/disable G2 transmit");
11233 return STATUS_SENT_ERROR;
11234 }
11235 }
11236
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011237 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11238}
11239
11240
Jouni Malinenf7222712019-06-13 01:50:21 +030011241static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
11242 struct sigma_conn *conn,
11243 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011244{
11245 const char *val;
11246
11247 val = get_param(cmd, "Program");
Veerendranath Jakkam9ce2b642022-02-28 18:49:25 +053011248 if (!val)
11249 val = get_param(cmd, "Prog");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011250 if (val) {
11251 if (strcasecmp(val, "11n") == 0)
11252 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080011253 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011254 return cmd_sta_set_wireless_vht(dut, conn, cmd);
11255 if (strcasecmp(val, "60ghz") == 0)
11256 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011257 if (strcasecmp(val, "OCE") == 0)
11258 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020011259 /* sta_set_wireless in WPS program is only used for 60G */
11260 if (is_60g_sigma_dut(dut))
11261 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011262 if (strcasecmp(val, "WPA3") == 0)
11263 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011264 send_resp(dut, conn, SIGMA_ERROR,
11265 "ErrorCode,Program value not supported");
11266 } else {
11267 send_resp(dut, conn, SIGMA_ERROR,
11268 "ErrorCode,Program argument not available");
11269 }
11270
11271 return 0;
11272}
11273
11274
11275static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
11276 int tid)
11277{
11278 char buf[100];
11279 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
11280
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053011281 if (tid < 0 ||
11282 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
11283 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
11284 return;
11285 }
11286
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011287 /*
11288 * Two ways to ensure that addba request with a
11289 * non zero TID could be sent out. EV 117296
11290 */
11291 snprintf(buf, sizeof(buf),
11292 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
11293 tid);
11294 if (system(buf) != 0) {
11295 sigma_dut_print(dut, DUT_MSG_ERROR,
11296 "Ping did not send out");
11297 }
11298
11299 snprintf(buf, sizeof(buf),
11300 "iwconfig %s | grep Access | awk '{print $6}' > %s",
11301 intf, VI_QOS_TMP_FILE);
11302 if (system(buf) != 0)
11303 return;
11304
11305 snprintf(buf, sizeof(buf),
11306 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
11307 intf, VI_QOS_TMP_FILE);
11308 if (system(buf) != 0)
11309 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
11310
11311 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
11312 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
11313 if (system(buf) != 0) {
11314 sigma_dut_print(dut, DUT_MSG_ERROR,
11315 "VI_QOS_TEMP_FILE generation error failed");
11316 }
11317 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11318 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11319 if (system(buf) != 0) {
11320 sigma_dut_print(dut, DUT_MSG_ERROR,
11321 "VI_QOS_FILE generation failed");
11322 }
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), "ethinject %s %s", intf, VI_QOS_FILE);
11332 if (system(buf) != 0) {
11333 }
11334}
11335
11336
11337static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11338 struct sigma_cmd *cmd)
11339{
11340 const char *intf = get_param(cmd, "Interface");
11341 const char *val;
11342 int tid = 0;
11343 char buf[100];
11344
11345 val = get_param(cmd, "TID");
11346 if (val) {
11347 tid = atoi(val);
11348 if (tid)
11349 ath_sta_inject_frame(dut, intf, tid);
11350 }
11351
11352 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011353 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011354
11355 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
11356 if (system(buf) != 0) {
11357 sigma_dut_print(dut, DUT_MSG_ERROR,
11358 "wifitool senddelba failed");
11359 }
11360
11361 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
11362 if (system(buf) != 0) {
11363 sigma_dut_print(dut, DUT_MSG_ERROR,
11364 "wifitool sendaddba failed");
11365 }
11366
11367 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11368
11369 return 1;
11370}
11371
11372
Lior David9981b512017-01-20 13:16:40 +020011373#ifdef __linux__
11374
11375static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
11376 int agg_size)
11377{
11378 char dir[128], buf[128];
11379 FILE *f;
11380 regex_t re;
11381 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030011382 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020011383
11384 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
11385 sigma_dut_print(dut, DUT_MSG_ERROR,
11386 "failed to get wil6210 debugfs dir");
11387 return -1;
11388 }
11389
Jouni Malinen3aa72862019-05-29 23:14:51 +030011390 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
11391 if (res < 0 || res >= sizeof(buf))
11392 return -1;
Lior David9981b512017-01-20 13:16:40 +020011393 f = fopen(buf, "r");
11394 if (!f) {
11395 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011396 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030011397 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
11398 if (res < 0 || res >= sizeof(buf))
11399 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011400 f = fopen(buf, "r");
11401 if (!f) {
11402 sigma_dut_print(dut, DUT_MSG_ERROR,
11403 "failed to open: %s", buf);
11404 return -1;
11405 }
Lior David9981b512017-01-20 13:16:40 +020011406 }
11407
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011408 /* can be either VRING tx... or RING... */
11409 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020011410 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
11411 goto out;
11412 }
11413
11414 /* find TX VRING for the mac address */
11415 found = 0;
11416 while (fgets(buf, sizeof(buf), f)) {
11417 if (strcasestr(buf, dest_mac)) {
11418 found = 1;
11419 break;
11420 }
11421 }
11422
11423 if (!found) {
11424 sigma_dut_print(dut, DUT_MSG_ERROR,
11425 "no TX VRING for %s", dest_mac);
11426 goto out;
11427 }
11428
11429 /* extract VRING ID, "VRING tx_<id> = {" */
11430 if (!fgets(buf, sizeof(buf), f)) {
11431 sigma_dut_print(dut, DUT_MSG_ERROR,
11432 "no VRING start line for %s", dest_mac);
11433 goto out;
11434 }
11435
11436 rc = regexec(&re, buf, 2, m, 0);
11437 regfree(&re);
11438 if (rc || m[1].rm_so < 0) {
11439 sigma_dut_print(dut, DUT_MSG_ERROR,
11440 "no VRING TX ID for %s", dest_mac);
11441 goto out;
11442 }
11443 buf[m[1].rm_eo] = 0;
11444 vring_id = atoi(&buf[m[1].rm_so]);
11445
11446 /* send the addba command */
11447 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011448 res = snprintf(buf, sizeof(buf), "%s/back", dir);
11449 if (res < 0 || res >= sizeof(buf))
11450 return -1;
Lior David9981b512017-01-20 13:16:40 +020011451 f = fopen(buf, "w");
11452 if (!f) {
11453 sigma_dut_print(dut, DUT_MSG_ERROR,
11454 "failed to open: %s", buf);
11455 return -1;
11456 }
11457
11458 fprintf(f, "add %d %d\n", vring_id, agg_size);
11459
11460 ret = 0;
11461
11462out:
11463 fclose(f);
11464
11465 return ret;
11466}
11467
11468
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011469int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11470 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011471{
11472 const char *val;
11473 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011474
11475 val = get_param(cmd, "TID");
11476 if (val) {
11477 tid = atoi(val);
11478 if (tid != 0) {
11479 sigma_dut_print(dut, DUT_MSG_ERROR,
11480 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
11481 tid);
11482 }
11483 }
11484
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011485 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011486 if (!val) {
11487 sigma_dut_print(dut, DUT_MSG_ERROR,
11488 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011489 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011490 }
11491
Lior David9981b512017-01-20 13:16:40 +020011492 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011493 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011494
11495 return 1;
11496}
11497
Lior David9981b512017-01-20 13:16:40 +020011498#endif /* __linux__ */
11499
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011500
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011501static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11502 struct sigma_cmd *cmd)
11503{
11504#ifdef NL80211_SUPPORT
11505 const char *intf = get_param(cmd, "Interface");
11506 const char *val;
11507 int tid = -1;
11508 int bufsize = 64;
11509 struct nl_msg *msg;
11510 int ret = 0;
11511 struct nlattr *params;
11512 int ifindex;
11513
11514 val = get_param(cmd, "TID");
11515 if (val)
11516 tid = atoi(val);
11517
11518 if (tid == -1) {
11519 send_resp(dut, conn, SIGMA_ERROR,
11520 "ErrorCode,sta_send_addba tid invalid");
11521 return 0;
11522 }
11523
11524 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11525
11526 ifindex = if_nametoindex(intf);
11527 if (ifindex == 0) {
11528 sigma_dut_print(dut, DUT_MSG_ERROR,
11529 "%s: Index for interface %s failed",
11530 __func__, intf);
11531 send_resp(dut, conn, SIGMA_ERROR,
11532 "ErrorCode,sta_send_addba interface invalid");
11533 return 0;
11534 }
11535
11536 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11537 NL80211_CMD_VENDOR)) ||
11538 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
11539 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
11540 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
11541 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
11542 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
11543 nla_put_u8(msg,
11544 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
11545 QCA_WLAN_ADD_BA) ||
11546 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
11547 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070011548 nla_put_u16(msg,
11549 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
11550 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011551 sigma_dut_print(dut, DUT_MSG_ERROR,
11552 "%s: err in adding vendor_cmd and vendor_data",
11553 __func__);
11554 nlmsg_free(msg);
11555 send_resp(dut, conn, SIGMA_ERROR,
11556 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
11557 return 0;
11558 }
11559 nla_nest_end(msg, params);
11560
11561 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11562 if (ret) {
11563 sigma_dut_print(dut, DUT_MSG_ERROR,
11564 "%s: err in send_and_recv_msgs, ret=%d",
11565 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053011566 if (ret == -EOPNOTSUPP)
11567 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011568 send_resp(dut, conn, SIGMA_ERROR,
11569 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
11570 return 0;
11571 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011572#else /* NL80211_SUPPORT */
11573 sigma_dut_print(dut, DUT_MSG_ERROR,
11574 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011575#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053011576
11577 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011578}
11579
11580
Jouni Malinenf7222712019-06-13 01:50:21 +030011581static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
11582 struct sigma_conn *conn,
11583 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011584{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011585 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011586 case DRIVER_ATHEROS:
11587 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011588 case DRIVER_WCN:
11589 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020011590#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011591 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011592 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020011593#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011594 default:
11595 /*
11596 * There is no driver specific implementation for other drivers.
11597 * Ignore the command and report COMPLETE since the following
11598 * throughput test operation will end up sending ADDBA anyway.
11599 */
11600 return 1;
11601 }
11602}
11603
11604
11605int inject_eth_frame(int s, const void *data, size_t len,
11606 unsigned short ethtype, char *dst, char *src)
11607{
11608 struct iovec iov[4] = {
11609 {
11610 .iov_base = dst,
11611 .iov_len = ETH_ALEN,
11612 },
11613 {
11614 .iov_base = src,
11615 .iov_len = ETH_ALEN,
11616 },
11617 {
11618 .iov_base = &ethtype,
11619 .iov_len = sizeof(unsigned short),
11620 },
11621 {
11622 .iov_base = (void *) data,
11623 .iov_len = len,
11624 }
11625 };
11626 struct msghdr msg = {
11627 .msg_name = NULL,
11628 .msg_namelen = 0,
11629 .msg_iov = iov,
11630 .msg_iovlen = 4,
11631 .msg_control = NULL,
11632 .msg_controllen = 0,
11633 .msg_flags = 0,
11634 };
11635
11636 return sendmsg(s, &msg, 0);
11637}
11638
11639#if defined(__linux__) || defined(__QNXNTO__)
11640
11641int inject_frame(int s, const void *data, size_t len, int encrypt)
11642{
11643#define IEEE80211_RADIOTAP_F_WEP 0x04
11644#define IEEE80211_RADIOTAP_F_FRAG 0x08
11645 unsigned char rtap_hdr[] = {
11646 0x00, 0x00, /* radiotap version */
11647 0x0e, 0x00, /* radiotap length */
11648 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
11649 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
11650 0x00, /* padding */
11651 0x00, 0x00, /* RX and TX flags to indicate that */
11652 0x00, 0x00, /* this is the injected frame directly */
11653 };
11654 struct iovec iov[2] = {
11655 {
11656 .iov_base = &rtap_hdr,
11657 .iov_len = sizeof(rtap_hdr),
11658 },
11659 {
11660 .iov_base = (void *) data,
11661 .iov_len = len,
11662 }
11663 };
11664 struct msghdr msg = {
11665 .msg_name = NULL,
11666 .msg_namelen = 0,
11667 .msg_iov = iov,
11668 .msg_iovlen = 2,
11669 .msg_control = NULL,
11670 .msg_controllen = 0,
11671 .msg_flags = 0,
11672 };
11673
11674 if (encrypt)
11675 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
11676
11677 return sendmsg(s, &msg, 0);
11678}
11679
11680
11681int open_monitor(const char *ifname)
11682{
11683#ifdef __QNXNTO__
11684 struct sockaddr_dl ll;
11685 int s;
11686
11687 memset(&ll, 0, sizeof(ll));
11688 ll.sdl_family = AF_LINK;
11689 ll.sdl_index = if_nametoindex(ifname);
11690 if (ll.sdl_index == 0) {
11691 perror("if_nametoindex");
11692 return -1;
11693 }
11694 s = socket(PF_INET, SOCK_RAW, 0);
11695#else /* __QNXNTO__ */
11696 struct sockaddr_ll ll;
11697 int s;
11698
11699 memset(&ll, 0, sizeof(ll));
11700 ll.sll_family = AF_PACKET;
11701 ll.sll_ifindex = if_nametoindex(ifname);
11702 if (ll.sll_ifindex == 0) {
11703 perror("if_nametoindex");
11704 return -1;
11705 }
11706 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
11707#endif /* __QNXNTO__ */
11708 if (s < 0) {
11709 perror("socket[PF_PACKET,SOCK_RAW]");
11710 return -1;
11711 }
11712
11713 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
11714 perror("monitor socket bind");
11715 close(s);
11716 return -1;
11717 }
11718
11719 return s;
11720}
11721
11722
11723static int hex2num(char c)
11724{
11725 if (c >= '0' && c <= '9')
11726 return c - '0';
11727 if (c >= 'a' && c <= 'f')
11728 return c - 'a' + 10;
11729 if (c >= 'A' && c <= 'F')
11730 return c - 'A' + 10;
11731 return -1;
11732}
11733
11734
11735int hwaddr_aton(const char *txt, unsigned char *addr)
11736{
11737 int i;
11738
11739 for (i = 0; i < 6; i++) {
11740 int a, b;
11741
11742 a = hex2num(*txt++);
11743 if (a < 0)
11744 return -1;
11745 b = hex2num(*txt++);
11746 if (b < 0)
11747 return -1;
11748 *addr++ = (a << 4) | b;
11749 if (i < 5 && *txt++ != ':')
11750 return -1;
11751 }
11752
11753 return 0;
11754}
11755
11756#endif /* defined(__linux__) || defined(__QNXNTO__) */
11757
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011758
11759#ifdef NL80211_SUPPORT
11760static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
11761 const u8 *data, size_t data_len, int freq)
11762{
11763 struct nl_msg *msg;
11764 int ret = 0;
11765 int ifindex;
11766
11767 ifindex = if_nametoindex(intf);
11768 if (ifindex == 0) {
11769 sigma_dut_print(dut, DUT_MSG_ERROR,
11770 "%s: Index for interface %s failed",
11771 __func__, intf);
11772 return -1;
11773 }
11774
11775 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11776 NL80211_CMD_FRAME)) ||
11777 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11778 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
11779 sigma_dut_print(dut, DUT_MSG_ERROR,
11780 "%s: Error in adding NL80211_CMD_FRAME",
11781 __func__);
11782 nlmsg_free(msg);
11783 return -1;
11784 }
11785
11786 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11787 if (ret) {
11788 sigma_dut_print(dut, DUT_MSG_ERROR,
11789 "nl80211: Frame command failed: ret=%d (%s) req=%u",
11790 ret, strerror(-ret), freq);
11791 return -1;
11792 }
11793
11794 return 0;
11795}
11796#endif /* NL80211_SUPPORT */
11797
11798
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011799enum send_frame_type {
11800 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
11801};
11802enum send_frame_protection {
11803 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
11804};
11805
11806
11807static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011808 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011809 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011810 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011811{
11812#ifdef __linux__
11813 unsigned char buf[1000], *pos;
11814 int s, res;
11815 char bssid[20], addr[20];
11816 char result[32], ssid[100];
11817 size_t ssid_len;
11818
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011819 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011820 sizeof(result)) < 0 ||
11821 strncmp(result, "COMPLETED", 9) != 0) {
11822 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
11823 return 0;
11824 }
11825
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011826 if (get_wpa_status(get_station_ifname(dut), "bssid",
11827 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011828 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11829 "current BSSID");
11830 return 0;
11831 }
11832
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011833 if (get_wpa_status(get_station_ifname(dut), "address",
11834 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011835 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11836 "own MAC address");
11837 return 0;
11838 }
11839
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011840 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011841 < 0) {
11842 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11843 "current SSID");
11844 return 0;
11845 }
11846 ssid_len = strlen(ssid);
11847
11848 pos = buf;
11849
11850 /* Frame Control */
11851 switch (frame) {
11852 case DISASSOC:
11853 *pos++ = 0xa0;
11854 break;
11855 case DEAUTH:
11856 *pos++ = 0xc0;
11857 break;
11858 case SAQUERY:
11859 *pos++ = 0xd0;
11860 break;
11861 case AUTH:
11862 *pos++ = 0xb0;
11863 break;
11864 case ASSOCREQ:
11865 *pos++ = 0x00;
11866 break;
11867 case REASSOCREQ:
11868 *pos++ = 0x20;
11869 break;
11870 case DLS_REQ:
11871 *pos++ = 0xd0;
11872 break;
11873 }
11874
11875 if (protected == INCORRECT_KEY)
11876 *pos++ = 0x40; /* Set Protected field to 1 */
11877 else
11878 *pos++ = 0x00;
11879
11880 /* Duration */
11881 *pos++ = 0x00;
11882 *pos++ = 0x00;
11883
11884 /* addr1 = DA (current AP) */
11885 hwaddr_aton(bssid, pos);
11886 pos += 6;
11887 /* addr2 = SA (own address) */
11888 hwaddr_aton(addr, pos);
11889 pos += 6;
11890 /* addr3 = BSSID (current AP) */
11891 hwaddr_aton(bssid, pos);
11892 pos += 6;
11893
11894 /* Seq# (to be filled by driver/mac80211) */
11895 *pos++ = 0x00;
11896 *pos++ = 0x00;
11897
11898 if (protected == INCORRECT_KEY) {
11899 /* CCMP parameters */
11900 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
11901 pos += 8;
11902 }
11903
11904 if (protected == INCORRECT_KEY) {
11905 switch (frame) {
11906 case DEAUTH:
11907 /* Reason code (encrypted) */
11908 memcpy(pos, "\xa7\x39", 2);
11909 pos += 2;
11910 break;
11911 case DISASSOC:
11912 /* Reason code (encrypted) */
11913 memcpy(pos, "\xa7\x39", 2);
11914 pos += 2;
11915 break;
11916 case SAQUERY:
11917 /* Category|Action|TransID (encrypted) */
11918 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
11919 pos += 4;
11920 break;
11921 default:
11922 return -1;
11923 }
11924
11925 /* CCMP MIC */
11926 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
11927 pos += 8;
11928 } else {
11929 switch (frame) {
11930 case DEAUTH:
11931 /* reason code = 8 */
11932 *pos++ = 0x08;
11933 *pos++ = 0x00;
11934 break;
11935 case DISASSOC:
11936 /* reason code = 8 */
11937 *pos++ = 0x08;
11938 *pos++ = 0x00;
11939 break;
11940 case SAQUERY:
11941 /* Category - SA Query */
11942 *pos++ = 0x08;
11943 /* SA query Action - Request */
11944 *pos++ = 0x00;
11945 /* Transaction ID */
11946 *pos++ = 0x12;
11947 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011948 if (dut->saquery_oci_freq) {
11949 /* OCI IE - Extended ID */
11950 *pos++ = 0xFF;
11951 *pos++ = 0x04;
11952 *pos++ = 0x36;
11953 /* Operating Class */
11954 *pos++ = 0x74;
11955 /* Primary Channel */
11956 *pos++ = freq_to_channel(dut->saquery_oci_freq);
11957 /* Frequency Segment 1 Channel Number */
11958 *pos++ = 0x00;
11959 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011960 break;
11961 case AUTH:
11962 /* Auth Alg (Open) */
11963 *pos++ = 0x00;
11964 *pos++ = 0x00;
11965 /* Seq# */
11966 *pos++ = 0x01;
11967 *pos++ = 0x00;
11968 /* Status code */
11969 *pos++ = 0x00;
11970 *pos++ = 0x00;
11971 break;
11972 case ASSOCREQ:
11973 /* Capability Information */
11974 *pos++ = 0x31;
11975 *pos++ = 0x04;
11976 /* Listen Interval */
11977 *pos++ = 0x0a;
11978 *pos++ = 0x00;
11979 /* SSID */
11980 *pos++ = 0x00;
11981 *pos++ = ssid_len;
11982 memcpy(pos, ssid, ssid_len);
11983 pos += ssid_len;
11984 /* Supported Rates */
11985 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11986 10);
11987 pos += 10;
11988 /* Extended Supported Rates */
11989 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11990 pos += 6;
11991 /* RSN */
11992 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
11993 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
11994 "\x00\x00\x00\x00\x0f\xac\x06", 28);
11995 pos += 28;
11996 break;
11997 case REASSOCREQ:
11998 /* Capability Information */
11999 *pos++ = 0x31;
12000 *pos++ = 0x04;
12001 /* Listen Interval */
12002 *pos++ = 0x0a;
12003 *pos++ = 0x00;
12004 /* Current AP */
12005 hwaddr_aton(bssid, pos);
12006 pos += 6;
12007 /* SSID */
12008 *pos++ = 0x00;
12009 *pos++ = ssid_len;
12010 memcpy(pos, ssid, ssid_len);
12011 pos += ssid_len;
12012 /* Supported Rates */
12013 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
12014 10);
12015 pos += 10;
12016 /* Extended Supported Rates */
12017 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
12018 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053012019 /* RSNE - Group and Pairwise ciphers */
12020 memcpy(pos,
12021 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
12022 14);
12023 pos += 14;
12024 /* RSNE - AKM Suite count */
12025 *pos++ = 0x01;
12026 *pos++ = 0x00;
12027 /* RSNE - AKM Suites */
12028 if (dut->program == PROGRAM_WPA3)
12029 memcpy(pos, "\x00\x0f\xac\x08", 4);
12030 else
12031 memcpy(pos, "\x00\x0f\xac\x02", 4);
12032 pos += 4;
12033 /* RSNE - Capabilities */
12034 *pos++ = 0xc0;
12035 if (dut->ocvc)
12036 *pos++ = 0x40;
12037 else
12038 *pos++ = 0x00;
12039 /* RSNE - PMKID list and Group Management Ciphers */
12040 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
12041 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012042 break;
12043 case DLS_REQ:
12044 /* Category - DLS */
12045 *pos++ = 0x02;
12046 /* DLS Action - Request */
12047 *pos++ = 0x00;
12048 /* Destination MACAddress */
12049 if (dest)
12050 hwaddr_aton(dest, pos);
12051 else
12052 memset(pos, 0, 6);
12053 pos += 6;
12054 /* Source MACAddress */
12055 hwaddr_aton(addr, pos);
12056 pos += 6;
12057 /* Capability Information */
12058 *pos++ = 0x10; /* Privacy */
12059 *pos++ = 0x06; /* QoS */
12060 /* DLS Timeout Value */
12061 *pos++ = 0x00;
12062 *pos++ = 0x01;
12063 /* Supported rates */
12064 *pos++ = 0x01;
12065 *pos++ = 0x08;
12066 *pos++ = 0x0c; /* 6 Mbps */
12067 *pos++ = 0x12; /* 9 Mbps */
12068 *pos++ = 0x18; /* 12 Mbps */
12069 *pos++ = 0x24; /* 18 Mbps */
12070 *pos++ = 0x30; /* 24 Mbps */
12071 *pos++ = 0x48; /* 36 Mbps */
12072 *pos++ = 0x60; /* 48 Mbps */
12073 *pos++ = 0x6c; /* 54 Mbps */
12074 /* TODO: Extended Supported Rates */
12075 /* TODO: HT Capabilities */
12076 break;
12077 }
12078 }
12079
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012080 if (use_monitor) {
12081 s = open_monitor("sigmadut");
12082 if (s < 0) {
12083 send_resp(dut, conn, SIGMA_ERROR,
12084 "errorCode,Failed to open monitor socket");
12085 return 0;
12086 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012087
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012088 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
12089 if (res < 0) {
12090 send_resp(dut, conn, SIGMA_ERROR,
12091 "errorCode,Failed to inject frame");
12092 close(s);
12093 return 0;
12094 }
12095 if (res < pos - buf) {
12096 send_resp(dut, conn, SIGMA_ERROR,
12097 "errorCode,Only partial frame sent");
12098 close(s);
12099 return 0;
12100 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012101
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012102 close(s);
12103 } else {
12104#ifdef NL80211_SUPPORT
12105 int freq;
12106 char freq_str[10];
12107
12108 if (get_wpa_status(get_station_ifname(dut), "freq",
12109 freq_str, sizeof(freq_str)) < 0) {
12110 send_resp(dut, conn, SIGMA_ERROR,
12111 "errorCode,Could not get current operating frequency");
12112 return 0;
12113 }
12114 freq = atoi(freq_str);
12115
12116 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
12117 send_resp(dut, conn, SIGMA_ERROR,
12118 "errorCode,Failed to inject frame");
12119 return 0;
12120 }
12121#else /* NL80211_SUPPORT */
12122 send_resp(dut, conn, SIGMA_ERROR,
12123 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
12124 return 0;
12125#endif /* NL80211_SUPPORT */
12126 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012127
12128 return 1;
12129#else /* __linux__ */
12130 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
12131 "yet supported");
12132 return 0;
12133#endif /* __linux__ */
12134}
12135
12136
12137static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
12138 struct sigma_conn *conn,
12139 struct sigma_cmd *cmd)
12140{
12141 const char *intf = get_param(cmd, "Interface");
12142 const char *sta, *val;
12143 unsigned char addr[ETH_ALEN];
12144 char buf[100];
12145
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012146 if (!intf)
12147 return -1;
12148
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012149 sta = get_param(cmd, "peer");
12150 if (sta == NULL)
12151 sta = get_param(cmd, "station");
12152 if (sta == NULL) {
12153 send_resp(dut, conn, SIGMA_ERROR,
12154 "ErrorCode,Missing peer address");
12155 return 0;
12156 }
12157 if (hwaddr_aton(sta, addr) < 0) {
12158 send_resp(dut, conn, SIGMA_ERROR,
12159 "ErrorCode,Invalid peer address");
12160 return 0;
12161 }
12162
12163 val = get_param(cmd, "type");
12164 if (val == NULL)
12165 return -1;
12166
12167 if (strcasecmp(val, "DISCOVERY") == 0) {
12168 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
12169 if (wpa_command(intf, buf) < 0) {
12170 send_resp(dut, conn, SIGMA_ERROR,
12171 "ErrorCode,Failed to send TDLS discovery");
12172 return 0;
12173 }
12174 return 1;
12175 }
12176
12177 if (strcasecmp(val, "SETUP") == 0) {
12178 int status = 0, timeout = 0;
12179
12180 val = get_param(cmd, "Status");
12181 if (val)
12182 status = atoi(val);
12183
12184 val = get_param(cmd, "Timeout");
12185 if (val)
12186 timeout = atoi(val);
12187
12188 if (status != 0 && status != 37) {
12189 send_resp(dut, conn, SIGMA_ERROR,
12190 "ErrorCode,Unsupported status value");
12191 return 0;
12192 }
12193
12194 if (timeout != 0 && timeout != 301) {
12195 send_resp(dut, conn, SIGMA_ERROR,
12196 "ErrorCode,Unsupported timeout value");
12197 return 0;
12198 }
12199
12200 if (status && timeout) {
12201 send_resp(dut, conn, SIGMA_ERROR,
12202 "ErrorCode,Unsupported timeout+status "
12203 "combination");
12204 return 0;
12205 }
12206
12207 if (status == 37 &&
12208 wpa_command(intf, "SET tdls_testing 0x200")) {
12209 send_resp(dut, conn, SIGMA_ERROR,
12210 "ErrorCode,Failed to enable "
12211 "decline setup response test mode");
12212 return 0;
12213 }
12214
12215 if (timeout == 301) {
12216 int res;
12217 if (dut->no_tpk_expiration)
12218 res = wpa_command(intf,
12219 "SET tdls_testing 0x108");
12220 else
12221 res = wpa_command(intf,
12222 "SET tdls_testing 0x8");
12223 if (res) {
12224 send_resp(dut, conn, SIGMA_ERROR,
12225 "ErrorCode,Failed to set short TPK "
12226 "lifetime");
12227 return 0;
12228 }
12229 }
12230
12231 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
12232 if (wpa_command(intf, buf) < 0) {
12233 send_resp(dut, conn, SIGMA_ERROR,
12234 "ErrorCode,Failed to send TDLS setup");
12235 return 0;
12236 }
12237 return 1;
12238 }
12239
12240 if (strcasecmp(val, "TEARDOWN") == 0) {
12241 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
12242 if (wpa_command(intf, buf) < 0) {
12243 send_resp(dut, conn, SIGMA_ERROR,
12244 "ErrorCode,Failed to send TDLS teardown");
12245 return 0;
12246 }
12247 return 1;
12248 }
12249
12250 send_resp(dut, conn, SIGMA_ERROR,
12251 "ErrorCode,Unsupported TDLS frame");
12252 return 0;
12253}
12254
12255
12256static int sta_ap_known(const char *ifname, const char *bssid)
12257{
12258 char buf[4096];
12259
Jouni Malinendd32f192018-09-15 02:55:19 +030012260 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012261 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
12262 return 0;
12263 if (strncmp(buf, "id=", 3) != 0)
12264 return 0;
12265 return 1;
12266}
12267
12268
12269static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
12270 const char *bssid)
12271{
12272 int res;
12273 struct wpa_ctrl *ctrl;
12274 char buf[256];
12275
12276 if (sta_ap_known(ifname, bssid))
12277 return 0;
12278 sigma_dut_print(dut, DUT_MSG_DEBUG,
12279 "AP not in BSS table - start scan");
12280
12281 ctrl = open_wpa_mon(ifname);
12282 if (ctrl == NULL) {
12283 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12284 "wpa_supplicant monitor connection");
12285 return -1;
12286 }
12287
12288 if (wpa_command(ifname, "SCAN") < 0) {
12289 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
12290 wpa_ctrl_detach(ctrl);
12291 wpa_ctrl_close(ctrl);
12292 return -1;
12293 }
12294
12295 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12296 buf, sizeof(buf));
12297
12298 wpa_ctrl_detach(ctrl);
12299 wpa_ctrl_close(ctrl);
12300
12301 if (res < 0) {
12302 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
12303 return -1;
12304 }
12305
12306 if (sta_ap_known(ifname, bssid))
12307 return 0;
12308 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
12309 return -1;
12310}
12311
12312
12313static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
12314 struct sigma_conn *conn,
12315 struct sigma_cmd *cmd,
12316 const char *intf)
12317{
12318 char buf[200];
12319
12320 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
12321 if (system(buf) != 0) {
12322 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
12323 "ndsend");
12324 return 0;
12325 }
12326
12327 return 1;
12328}
12329
12330
12331static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
12332 struct sigma_conn *conn,
12333 struct sigma_cmd *cmd,
12334 const char *intf)
12335{
12336 char buf[200];
12337 const char *ip = get_param(cmd, "SenderIP");
12338
Peng Xu26b356d2017-10-04 17:58:16 -070012339 if (!ip)
12340 return 0;
12341
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012342 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
12343 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12344 if (system(buf) == 0) {
12345 sigma_dut_print(dut, DUT_MSG_INFO,
12346 "Neighbor Solicitation got a response "
12347 "for %s@%s", ip, intf);
12348 }
12349
12350 return 1;
12351}
12352
12353
12354static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
12355 struct sigma_conn *conn,
12356 struct sigma_cmd *cmd,
12357 const char *ifname)
12358{
12359 char buf[200];
12360 const char *ip = get_param(cmd, "SenderIP");
12361
12362 if (ip == NULL) {
12363 send_resp(dut, conn, SIGMA_ERROR,
12364 "ErrorCode,Missing SenderIP parameter");
12365 return 0;
12366 }
12367 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
12368 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12369 if (system(buf) != 0) {
12370 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
12371 "for %s@%s", ip, ifname);
12372 }
12373
12374 return 1;
12375}
12376
12377
12378static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
12379 struct sigma_conn *conn,
12380 struct sigma_cmd *cmd,
12381 const char *ifname)
12382{
12383 char buf[200];
12384 char ip[16];
12385 int s;
Peng Xub3756882017-10-04 14:39:09 -070012386 struct ifreq ifr;
12387 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012388
12389 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070012390 if (s < 0) {
12391 perror("socket");
12392 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012393 }
12394
Peng Xub3756882017-10-04 14:39:09 -070012395 memset(&ifr, 0, sizeof(ifr));
12396 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
12397 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
12398 sigma_dut_print(dut, DUT_MSG_INFO,
12399 "Failed to get %s IP address: %s",
12400 ifname, strerror(errno));
12401 close(s);
12402 return -1;
12403 }
12404 close(s);
12405
12406 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
12407 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
12408
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012409 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
12410 ip);
12411 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12412 if (system(buf) != 0) {
12413 }
12414
12415 return 1;
12416}
12417
12418
12419static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
12420 struct sigma_conn *conn,
12421 struct sigma_cmd *cmd,
12422 const char *ifname)
12423{
12424 char buf[200], addr[20];
12425 char dst[ETH_ALEN], src[ETH_ALEN];
12426 short ethtype = htons(ETH_P_ARP);
12427 char *pos;
12428 int s, res;
12429 const char *val;
12430 struct sockaddr_in taddr;
12431
12432 val = get_param(cmd, "dest");
12433 if (val)
12434 hwaddr_aton(val, (unsigned char *) dst);
12435
12436 val = get_param(cmd, "DestIP");
12437 if (val)
12438 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070012439 else
12440 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012441
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012442 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012443 sizeof(addr)) < 0)
12444 return -2;
12445 hwaddr_aton(addr, (unsigned char *) src);
12446
12447 pos = buf;
12448 *pos++ = 0x00;
12449 *pos++ = 0x01;
12450 *pos++ = 0x08;
12451 *pos++ = 0x00;
12452 *pos++ = 0x06;
12453 *pos++ = 0x04;
12454 *pos++ = 0x00;
12455 *pos++ = 0x02;
12456 memcpy(pos, src, ETH_ALEN);
12457 pos += ETH_ALEN;
12458 memcpy(pos, &taddr.sin_addr, 4);
12459 pos += 4;
12460 memcpy(pos, dst, ETH_ALEN);
12461 pos += ETH_ALEN;
12462 memcpy(pos, &taddr.sin_addr, 4);
12463 pos += 4;
12464
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012465 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012466 if (s < 0) {
12467 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
12468 "monitor socket");
12469 return 0;
12470 }
12471
12472 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
12473 if (res < 0) {
12474 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
12475 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053012476 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012477 return 0;
12478 }
12479
12480 close(s);
12481
12482 return 1;
12483}
12484
12485
12486static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
12487 struct sigma_conn *conn,
12488 struct sigma_cmd *cmd,
12489 const char *intf, const char *dest)
12490{
12491 char buf[100];
12492
12493 if (if_nametoindex("sigmadut") == 0) {
12494 snprintf(buf, sizeof(buf),
12495 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012496 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012497 if (system(buf) != 0 ||
12498 if_nametoindex("sigmadut") == 0) {
12499 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12500 "monitor interface with '%s'", buf);
12501 return -2;
12502 }
12503 }
12504
12505 if (system("ifconfig sigmadut up") != 0) {
12506 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12507 "monitor interface up");
12508 return -2;
12509 }
12510
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012511 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012512}
12513
12514
12515static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
12516 struct sigma_conn *conn,
12517 struct sigma_cmd *cmd)
12518{
12519 const char *intf = get_param(cmd, "Interface");
12520 const char *dest = get_param(cmd, "Dest");
12521 const char *type = get_param(cmd, "FrameName");
12522 const char *val;
12523 char buf[200], *pos, *end;
12524 int count, count2;
12525
12526 if (type == NULL)
12527 type = get_param(cmd, "Type");
12528
12529 if (intf == NULL || dest == NULL || type == NULL)
12530 return -1;
12531
12532 if (strcasecmp(type, "NeighAdv") == 0)
12533 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
12534
12535 if (strcasecmp(type, "NeighSolicitReq") == 0)
12536 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
12537
12538 if (strcasecmp(type, "ARPProbe") == 0)
12539 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
12540
12541 if (strcasecmp(type, "ARPAnnounce") == 0)
12542 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
12543
12544 if (strcasecmp(type, "ARPReply") == 0)
12545 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
12546
12547 if (strcasecmp(type, "DLS-request") == 0 ||
12548 strcasecmp(type, "DLSrequest") == 0)
12549 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
12550 dest);
12551
12552 if (strcasecmp(type, "ANQPQuery") != 0 &&
12553 strcasecmp(type, "Query") != 0) {
12554 send_resp(dut, conn, SIGMA_ERROR,
12555 "ErrorCode,Unsupported HS 2.0 send frame type");
12556 return 0;
12557 }
12558
12559 if (sta_scan_ap(dut, intf, dest) < 0) {
12560 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
12561 "the requested AP");
12562 return 0;
12563 }
12564
12565 pos = buf;
12566 end = buf + sizeof(buf);
12567 count = 0;
12568 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
12569
12570 val = get_param(cmd, "ANQP_CAP_LIST");
12571 if (val && atoi(val)) {
12572 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
12573 count++;
12574 }
12575
12576 val = get_param(cmd, "VENUE_NAME");
12577 if (val && atoi(val)) {
12578 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
12579 count++;
12580 }
12581
12582 val = get_param(cmd, "NETWORK_AUTH_TYPE");
12583 if (val && atoi(val)) {
12584 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
12585 count++;
12586 }
12587
12588 val = get_param(cmd, "ROAMING_CONS");
12589 if (val && atoi(val)) {
12590 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
12591 count++;
12592 }
12593
12594 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
12595 if (val && atoi(val)) {
12596 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
12597 count++;
12598 }
12599
12600 val = get_param(cmd, "NAI_REALM_LIST");
12601 if (val && atoi(val)) {
12602 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
12603 count++;
12604 }
12605
12606 val = get_param(cmd, "3GPP_INFO");
12607 if (val && atoi(val)) {
12608 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
12609 count++;
12610 }
12611
12612 val = get_param(cmd, "DOMAIN_LIST");
12613 if (val && atoi(val)) {
12614 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
12615 count++;
12616 }
12617
Jouni Malinen34cf9532018-04-29 19:26:33 +030012618 val = get_param(cmd, "Venue_URL");
12619 if (val && atoi(val)) {
12620 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
12621 count++;
12622 }
12623
Jouni Malinend3bca5d2018-04-29 17:25:23 +030012624 val = get_param(cmd, "Advice_Of_Charge");
12625 if (val && atoi(val)) {
12626 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
12627 count++;
12628 }
12629
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012630 if (count && wpa_command(intf, buf)) {
12631 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
12632 return 0;
12633 }
12634
12635 pos = buf;
12636 end = buf + sizeof(buf);
12637 count2 = 0;
12638 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
12639
12640 val = get_param(cmd, "HS_CAP_LIST");
12641 if (val && atoi(val)) {
12642 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
12643 count2++;
12644 }
12645
12646 val = get_param(cmd, "OPER_NAME");
12647 if (val && atoi(val)) {
12648 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
12649 count2++;
12650 }
12651
12652 val = get_param(cmd, "WAN_METRICS");
12653 if (!val)
12654 val = get_param(cmd, "WAN_MAT");
12655 if (!val)
12656 val = get_param(cmd, "WAN_MET");
12657 if (val && atoi(val)) {
12658 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
12659 count2++;
12660 }
12661
12662 val = get_param(cmd, "CONNECTION_CAPABILITY");
12663 if (val && atoi(val)) {
12664 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
12665 count2++;
12666 }
12667
12668 val = get_param(cmd, "OP_CLASS");
12669 if (val && atoi(val)) {
12670 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
12671 count2++;
12672 }
12673
12674 val = get_param(cmd, "OSU_PROVIDER_LIST");
12675 if (val && atoi(val)) {
12676 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
12677 count2++;
12678 }
12679
Jouni Malinenf67afec2018-04-29 19:24:58 +030012680 val = get_param(cmd, "OPER_ICON_METADATA");
12681 if (!val)
12682 val = get_param(cmd, "OPERATOR_ICON_METADATA");
12683 if (val && atoi(val)) {
12684 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
12685 count2++;
12686 }
12687
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012688 if (count && count2) {
12689 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
12690 "second query");
12691 sleep(1);
12692 }
12693
12694 if (count2 && wpa_command(intf, buf)) {
12695 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
12696 "failed");
12697 return 0;
12698 }
12699
12700 val = get_param(cmd, "NAI_HOME_REALM_LIST");
12701 if (val) {
12702 if (count || count2) {
12703 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12704 "sending out second query");
12705 sleep(1);
12706 }
12707
12708 if (strcmp(val, "1") == 0)
12709 val = "mail.example.com";
12710 snprintf(buf, end - pos,
12711 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
12712 dest, val);
12713 if (wpa_command(intf, buf)) {
12714 send_resp(dut, conn, SIGMA_ERROR,
12715 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
12716 "failed");
12717 return 0;
12718 }
12719 }
12720
12721 val = get_param(cmd, "ICON_REQUEST");
12722 if (val) {
12723 if (count || count2) {
12724 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12725 "sending out second query");
12726 sleep(1);
12727 }
12728
12729 snprintf(buf, end - pos,
12730 "HS20_ICON_REQUEST %s %s", dest, val);
12731 if (wpa_command(intf, buf)) {
12732 send_resp(dut, conn, SIGMA_ERROR,
12733 "ErrorCode,HS20_ICON_REQUEST failed");
12734 return 0;
12735 }
12736 }
12737
12738 return 1;
12739}
12740
12741
12742static int ath_sta_send_frame_vht(struct sigma_dut *dut,
12743 struct sigma_conn *conn,
12744 struct sigma_cmd *cmd)
12745{
12746 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012747 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012748 int chwidth, nss;
12749
12750 val = get_param(cmd, "framename");
12751 if (!val)
12752 return -1;
12753 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12754
12755 /* Command sequence to generate Op mode notification */
12756 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012757 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012758
12759 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012760 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012761
12762 /* Extract Channel width */
12763 val = get_param(cmd, "Channel_width");
12764 if (val) {
12765 switch (atoi(val)) {
12766 case 20:
12767 chwidth = 0;
12768 break;
12769 case 40:
12770 chwidth = 1;
12771 break;
12772 case 80:
12773 chwidth = 2;
12774 break;
12775 case 160:
12776 chwidth = 3;
12777 break;
12778 default:
12779 chwidth = 2;
12780 break;
12781 }
12782
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012783 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012784 }
12785
12786 /* Extract NSS */
12787 val = get_param(cmd, "NSS");
12788 if (val) {
12789 switch (atoi(val)) {
12790 case 1:
12791 nss = 1;
12792 break;
12793 case 2:
12794 nss = 3;
12795 break;
12796 case 3:
12797 nss = 7;
12798 break;
12799 default:
12800 /* We do not support NSS > 3 */
12801 nss = 3;
12802 break;
12803 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012804 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012805 }
12806
12807 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012808 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012809 }
12810
12811 return 1;
12812}
12813
12814
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012815static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
12816 enum send_frame_protection protected)
12817{
12818#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012819 return wcn_wifi_test_config_set_u8(
12820 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
12821 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012822#else /* NL80211_SUPPORT */
12823 sigma_dut_print(dut, DUT_MSG_ERROR,
12824 "PMF config cannot be set without NL80211_SUPPORT defined");
12825 return -1;
12826#endif /* NL80211_SUPPORT */
12827}
12828
12829
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012830static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
12831 struct sigma_conn *conn,
12832 struct sigma_cmd *cmd)
12833{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012834 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012835 case DRIVER_ATHEROS:
12836 return ath_sta_send_frame_vht(dut, conn, cmd);
12837 default:
12838 send_resp(dut, conn, SIGMA_ERROR,
12839 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
12840 return 0;
12841 }
12842}
12843
12844
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012845static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
12846{
12847#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012848 return wcn_wifi_test_config_set_flag(
12849 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012850#else /* NL80211_SUPPORT */
12851 sigma_dut_print(dut, DUT_MSG_ERROR,
12852 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
12853 return -1;
12854#endif /* NL80211_SUPPORT */
12855}
12856
12857
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012858static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
12859 struct sigma_cmd *cmd)
12860{
12861 const char *val;
12862 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012863 enum send_frame_protection protected;
12864 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012865
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012866 if (!intf)
12867 return -1;
12868
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012869 val = get_param(cmd, "framename");
12870 if (!val)
12871 return -1;
12872 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12873
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012874 pmf = get_param(cmd, "PMFProtected");
12875 if (!pmf)
12876 pmf = get_param(cmd, "Protected");
12877 if (pmf) {
12878 if (strcasecmp(pmf, "Correct-key") == 0 ||
12879 strcasecmp(pmf, "CorrectKey") == 0) {
12880 protected = CORRECT_KEY;
12881 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
12882 protected = INCORRECT_KEY;
12883 } else if (strcasecmp(pmf, "Unprotected") == 0) {
12884 protected = UNPROTECTED;
12885 } else {
12886 send_resp(dut, conn, SIGMA_ERROR,
12887 "errorCode,Unsupported PMFProtected");
12888 return STATUS_SENT_ERROR;
12889 }
12890 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
12891 protected);
12892 wcn_sta_set_pmf_config(dut, intf, protected);
12893 }
12894
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012895 /* Command sequence to generate Op mode notification */
12896 if (val && strcasecmp(val, "action") == 0) {
12897 val = get_param(cmd, "PPDUTxType");
12898 if (val && strcasecmp(val, "TB") == 0) {
12899 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
12900 sigma_dut_print(dut, DUT_MSG_ERROR,
12901 "failed to send TB PPDU Tx cfg");
12902 send_resp(dut, conn, SIGMA_ERROR,
12903 "ErrorCode,set TB PPDU Tx cfg failed");
12904 return 0;
12905 }
12906 return 1;
12907 }
12908
12909 sigma_dut_print(dut, DUT_MSG_ERROR,
12910 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012911
12912 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012913 }
12914
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012915 if (strcasecmp(val, "disassoc") == 0)
12916 wcn_sta_send_disassoc(dut, intf);
12917
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012918 return 1;
12919}
12920
12921
12922static int cmd_sta_send_frame_he(struct sigma_dut *dut,
12923 struct sigma_conn *conn,
12924 struct sigma_cmd *cmd)
12925{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012926 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012927 case DRIVER_WCN:
12928 return wcn_sta_send_frame_he(dut, conn, cmd);
12929 default:
12930 send_resp(dut, conn, SIGMA_ERROR,
12931 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
12932 return 0;
12933 }
12934}
12935
12936
Lior David0fe101e2017-03-09 16:09:50 +020012937#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012938
12939static int
12940wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
12941 const char *frame_name, const char *dest_mac)
12942{
12943 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
12944 const char *ssid = get_param(cmd, "ssid");
12945 const char *countstr = get_param(cmd, "count");
12946 const char *channelstr = get_param(cmd, "channel");
12947 const char *group_id = get_param(cmd, "groupid");
12948 const char *client_id = get_param(cmd, "clientmac");
12949 int count, channel, freq, i;
12950 const char *fname;
12951 char frame[1024], src_mac[20], group_id_attr[25],
12952 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
12953 const char *group_ssid;
12954 const int group_ssid_prefix_len = 9;
12955 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
12956 size_t framelen = sizeof(frame);
12957 struct template_frame_tag tags[2];
12958 size_t tags_total = ARRAY_SIZE(tags);
12959 int tag_index, len, dst_len;
12960
12961 if (!countstr || !channelstr) {
12962 sigma_dut_print(dut, DUT_MSG_ERROR,
12963 "Missing argument: count, channel");
12964 return -1;
12965 }
12966 if (isprobereq && !ssid) {
12967 sigma_dut_print(dut, DUT_MSG_ERROR,
12968 "Missing argument: ssid");
12969 return -1;
12970 }
12971 if (!isprobereq && (!group_id || !client_id)) {
12972 sigma_dut_print(dut, DUT_MSG_ERROR,
12973 "Missing argument: group_id, client_id");
12974 return -1;
12975 }
12976
12977 count = atoi(countstr);
12978 channel = atoi(channelstr);
12979 freq = channel_to_freq(dut, channel);
12980
12981 if (!freq) {
12982 sigma_dut_print(dut, DUT_MSG_ERROR,
12983 "invalid channel: %s", channelstr);
12984 return -1;
12985 }
12986
12987 if (isprobereq) {
12988 if (strcasecmp(ssid, "wildcard") == 0) {
12989 fname = "probe_req_wildcard.txt";
12990 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
12991 fname = "probe_req_P2P_Wildcard.txt";
12992 } else {
12993 sigma_dut_print(dut, DUT_MSG_ERROR,
12994 "invalid probe request type");
12995 return -1;
12996 }
12997 } else {
12998 fname = "P2P_device_discovery_req.txt";
12999 }
13000
13001 if (parse_template_frame_file(dut, fname, frame, &framelen,
13002 tags, &tags_total)) {
13003 sigma_dut_print(dut, DUT_MSG_ERROR,
13004 "invalid frame template: %s", fname);
13005 return -1;
13006 }
13007
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013008 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013009 src_mac, sizeof(src_mac)) < 0 ||
13010 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
13011 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
13012 return -1;
13013 /* Use wildcard BSSID, since we are in PBSS */
13014 memset(&hdr->addr3, 0xFF, ETH_ALEN);
13015
13016 if (!isprobereq) {
13017 tag_index = find_template_frame_tag(tags, tags_total, 1);
13018 if (tag_index < 0) {
13019 sigma_dut_print(dut, DUT_MSG_ERROR,
13020 "can't find device id attribute");
13021 return -1;
13022 }
13023 if (parse_mac_address(dut, client_id,
13024 (unsigned char *) client_mac)) {
13025 sigma_dut_print(dut, DUT_MSG_ERROR,
13026 "invalid client_id: %s", client_id);
13027 return -1;
13028 }
13029 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13030 framelen - tags[tag_index].offset,
13031 IEEE80211_P2P_ATTR_DEVICE_ID,
13032 client_mac, ETH_ALEN)) {
13033 sigma_dut_print(dut, DUT_MSG_ERROR,
13034 "fail to replace device id attribute");
13035 return -1;
13036 }
13037
13038 /*
13039 * group_id arg contains device MAC address followed by
13040 * space and SSID (DIRECT-somessid).
13041 * group id attribute contains device address (6 bytes)
13042 * followed by SSID prefix DIRECT-XX (9 bytes)
13043 */
13044 if (strlen(group_id) < sizeof(device_macstr)) {
13045 sigma_dut_print(dut, DUT_MSG_ERROR,
13046 "group_id arg too short");
13047 return -1;
13048 }
13049 memcpy(device_macstr, group_id, sizeof(device_macstr));
13050 device_macstr[sizeof(device_macstr) - 1] = '\0';
13051 if (parse_mac_address(dut, device_macstr,
13052 (unsigned char *) group_id_attr)) {
13053 sigma_dut_print(dut, DUT_MSG_ERROR,
13054 "fail to parse device address from group_id");
13055 return -1;
13056 }
13057 group_ssid = strchr(group_id, ' ');
13058 if (!group_ssid) {
13059 sigma_dut_print(dut, DUT_MSG_ERROR,
13060 "invalid group_id arg, no ssid");
13061 return -1;
13062 }
13063 group_ssid++;
13064 len = strlen(group_ssid);
13065 if (len < group_ssid_prefix_len) {
13066 sigma_dut_print(dut, DUT_MSG_ERROR,
13067 "group_id SSID too short");
13068 return -1;
13069 }
13070 dst_len = sizeof(group_id_attr) - ETH_ALEN;
13071 if (len > dst_len) {
13072 sigma_dut_print(dut, DUT_MSG_ERROR,
13073 "group_id SSID (%s) too long",
13074 group_ssid);
13075 return -1;
13076 }
13077
13078 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
13079 tag_index = find_template_frame_tag(tags, tags_total, 2);
13080 if (tag_index < 0) {
13081 sigma_dut_print(dut, DUT_MSG_ERROR,
13082 "can't find group id attribute");
13083 return -1;
13084 }
13085 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13086 framelen - tags[tag_index].offset,
13087 IEEE80211_P2P_ATTR_GROUP_ID,
13088 group_id_attr,
13089 sizeof(group_id_attr))) {
13090 sigma_dut_print(dut, DUT_MSG_ERROR,
13091 "fail to replace group id attribute");
13092 return -1;
13093 }
13094 }
13095
13096 for (i = 0; i < count; i++) {
13097 if (wil6210_transmit_frame(dut, freq,
13098 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
13099 frame, framelen)) {
13100 sigma_dut_print(dut, DUT_MSG_ERROR,
13101 "fail to transmit probe request frame");
13102 return -1;
13103 }
13104 }
13105
13106 return 0;
13107}
13108
13109
Lior David0fe101e2017-03-09 16:09:50 +020013110int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
13111 struct sigma_cmd *cmd)
13112{
13113 const char *frame_name = get_param(cmd, "framename");
13114 const char *mac = get_param(cmd, "dest_mac");
13115
13116 if (!frame_name || !mac) {
13117 sigma_dut_print(dut, DUT_MSG_ERROR,
13118 "framename and dest_mac must be provided");
13119 return -1;
13120 }
13121
13122 if (strcasecmp(frame_name, "brp") == 0) {
13123 const char *l_rx = get_param(cmd, "L-RX");
13124 int l_rx_i;
13125
13126 if (!l_rx) {
13127 sigma_dut_print(dut, DUT_MSG_ERROR,
13128 "L-RX must be provided");
13129 return -1;
13130 }
13131 l_rx_i = atoi(l_rx);
13132
13133 sigma_dut_print(dut, DUT_MSG_INFO,
13134 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
13135 mac, l_rx);
13136 if (l_rx_i != 16) {
13137 sigma_dut_print(dut, DUT_MSG_ERROR,
13138 "unsupported L-RX: %s", l_rx);
13139 return -1;
13140 }
13141
13142 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
13143 return -1;
13144 } else if (strcasecmp(frame_name, "ssw") == 0) {
13145 sigma_dut_print(dut, DUT_MSG_INFO,
13146 "dev_send_frame: SLS, dest_mac %s", mac);
13147 if (wil6210_send_sls(dut, mac))
13148 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013149 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
13150 (strcasecmp(frame_name, "devdiscreq") == 0)) {
13151 sigma_dut_print(dut, DUT_MSG_INFO,
13152 "dev_send_frame: %s, dest_mac %s", frame_name,
13153 mac);
13154 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
13155 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020013156 } else {
13157 sigma_dut_print(dut, DUT_MSG_ERROR,
13158 "unsupported frame type: %s", frame_name);
13159 return -1;
13160 }
13161
13162 return 1;
13163}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013164
Lior David0fe101e2017-03-09 16:09:50 +020013165#endif /* __linux__ */
13166
13167
13168static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
13169 struct sigma_conn *conn,
13170 struct sigma_cmd *cmd)
13171{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013172 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020013173#ifdef __linux__
13174 case DRIVER_WIL6210:
13175 return wil6210_send_frame_60g(dut, conn, cmd);
13176#endif /* __linux__ */
13177 default:
13178 send_resp(dut, conn, SIGMA_ERROR,
13179 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
13180 return 0;
13181 }
13182}
13183
13184
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013185static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13186 const char *intf, struct sigma_cmd *cmd)
13187{
13188 const char *val, *addr;
13189 char buf[100];
13190
13191 addr = get_param(cmd, "DestMac");
13192 if (!addr) {
13193 send_resp(dut, conn, SIGMA_INVALID,
13194 "ErrorCode,AP MAC address is missing");
13195 return 0;
13196 }
13197
13198 val = get_param(cmd, "ANQPQuery_ID");
13199 if (!val) {
13200 send_resp(dut, conn, SIGMA_INVALID,
13201 "ErrorCode,Missing ANQPQuery_ID");
13202 return 0;
13203 }
13204
13205 if (strcasecmp(val, "NeighborReportReq") == 0) {
13206 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
13207 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
13208 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
13209 } else {
13210 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
13211 val);
13212 send_resp(dut, conn, SIGMA_INVALID,
13213 "ErrorCode,Invalid ANQPQuery_ID");
13214 return 0;
13215 }
13216
Ashwini Patild174f2c2017-04-13 16:49:46 +053013217 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
13218 * (Address3 = Wildcard BSSID when sent to not-associated AP;
13219 * if associated, AP BSSID).
13220 */
13221 if (wpa_command(intf, "SET gas_address3 1") < 0) {
13222 send_resp(dut, conn, SIGMA_ERROR,
13223 "ErrorCode,Failed to set gas_address3");
13224 return 0;
13225 }
13226
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013227 if (wpa_command(intf, buf) < 0) {
13228 send_resp(dut, conn, SIGMA_ERROR,
13229 "ErrorCode,Failed to send ANQP query");
13230 return 0;
13231 }
13232
13233 return 1;
13234}
13235
13236
13237static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
13238 struct sigma_conn *conn,
13239 const char *intf,
13240 struct sigma_cmd *cmd)
13241{
13242 const char *val = get_param(cmd, "FrameName");
13243
13244 if (val && strcasecmp(val, "ANQPQuery") == 0)
13245 return mbo_send_anqp_query(dut, conn, intf, cmd);
13246
13247 return 2;
13248}
13249
13250
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013251static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
13252 struct sigma_conn *conn,
13253 const char *intf,
13254 struct sigma_cmd *cmd)
13255{
13256 const char *val = get_param(cmd, "framename");
13257
13258 if (!val)
13259 return INVALID_SEND_STATUS;
13260
13261 if (strcasecmp(val, "SAQueryReq") == 0) {
13262 val = get_param(cmd, "OCIChannel");
13263
13264 if (!val) {
13265 send_resp(dut, conn, SIGMA_ERROR,
13266 "errorCode,OCIChannel not present");
13267 return STATUS_SENT_ERROR;
13268 }
13269
13270 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
13271 if (!dut->saquery_oci_freq) {
13272 send_resp(dut, conn, SIGMA_ERROR,
13273 "errorCode,Invalid OCIChannel number");
13274 return STATUS_SENT_ERROR;
13275 }
13276
13277 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
13278 NULL, 0);
13279 }
13280
13281 if (strcasecmp(val, "reassocreq") == 0)
13282 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
13283 CORRECT_KEY, NULL, 0);
13284
Veerendranath9f81dfb2020-08-10 01:21:29 -070013285 if (strcasecmp(val, "ANQPQuery") == 0) {
13286 char buf[50];
13287 const char *dest = get_param(cmd, "DestMac");
13288 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013289 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070013290 int len, freq;
13291
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013292 if (freq_str)
13293 freq = atoi(freq_str);
13294 else
13295 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
13296
Veerendranath9f81dfb2020-08-10 01:21:29 -070013297 if (!dest || !freq)
13298 return INVALID_SEND_STATUS;
13299
13300 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
13301 dest, freq);
13302 if (len < 0 || len >= sizeof(buf)) {
13303 sigma_dut_print(dut, DUT_MSG_ERROR,
13304 "Failed to allocate buf");
13305 return ERROR_SEND_STATUS;
13306 }
13307
13308 if (wpa_command(intf, buf) != 0) {
13309 send_resp(dut, conn, SIGMA_ERROR,
13310 "ErrorCode,Failed to send ANQP Query frame");
13311 return STATUS_SENT_ERROR;
13312 }
13313
13314 sigma_dut_print(dut, DUT_MSG_DEBUG,
13315 "ANQP Query sent: %s", buf);
13316
13317 return SUCCESS_SEND_STATUS;
13318 }
13319
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013320 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
13321 return STATUS_SENT_ERROR;
13322}
13323
13324
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013325static int
13326get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13327 char *pos, int rem_len, int num_of_scs_desc,
13328 int num_of_tclas_elem)
13329{
13330 const char *val;
13331 int ipv6;
13332 int len, total_len = 0;
13333
13334 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
13335 num_of_tclas_elem);
13336 if (!val) {
13337 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
13338 __func__);
13339 return -1;
13340 }
13341
13342 if (strcmp(val, "6") == 0) {
13343 ipv6 = 1;
13344 } else if (strcmp(val, "4") == 0) {
13345 ipv6 = 0;
13346 } else {
13347 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
13348 __func__);
13349 return -1;
13350 }
13351
13352 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
13353 if (len < 0 || len >= rem_len)
13354 return -1;
13355
13356 pos += len;
13357 rem_len -= len;
13358 total_len += len;
13359
13360 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
13361 num_of_scs_desc, num_of_tclas_elem);
13362 if (val) {
13363 len = snprintf(pos, rem_len, " src_ip=%s", val);
13364 if (len < 0 || len >= rem_len)
13365 return -1;
13366
13367 pos += len;
13368 rem_len -= len;
13369 total_len += len;
13370 }
13371
13372 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
13373 num_of_scs_desc, num_of_tclas_elem);
13374 if (val) {
13375 len = snprintf(pos, rem_len, " dst_ip=%s", val);
13376 if (len < 0 || len >= rem_len)
13377 return -1;
13378
13379 pos += len;
13380 rem_len -= len;
13381 total_len += len;
13382 }
13383
13384 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
13385 num_of_tclas_elem);
13386 if (val) {
13387 len = snprintf(pos, rem_len, " src_port=%s", val);
13388 if (len < 0 || len >= rem_len)
13389 return -1;
13390
13391 pos += len;
13392 rem_len -= len;
13393 total_len += len;
13394 }
13395
13396 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
13397 num_of_scs_desc, num_of_tclas_elem);
13398 if (val) {
13399 len = snprintf(pos, rem_len, " dst_port=%s", val);
13400 if (len < 0 || len >= rem_len)
13401 return -1;
13402
13403 pos += len;
13404 rem_len -= len;
13405 total_len += len;
13406 }
13407
13408 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
13409 num_of_tclas_elem);
13410 if (val) {
13411 len = snprintf(pos, rem_len, " dscp=%s", val);
13412 if (len < 0 || len >= rem_len)
13413 return -1;
13414
13415 pos += len;
13416 rem_len -= len;
13417 total_len += len;
13418 }
13419
13420 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
13421 num_of_scs_desc, num_of_tclas_elem);
13422 if (val) {
13423 char *prot;
13424
13425 switch (atoi(val)) {
13426 case 17:
13427 prot = "udp";
13428 break;
13429 case 6:
13430 prot = "tcp";
13431 break;
13432 case 50:
13433 prot = "esp";
13434 break;
13435 default:
13436 sigma_dut_print(dut, DUT_MSG_ERROR,
13437 "Invalid protocol %d", atoi(val));
13438 return -1;
13439 }
13440
13441 if (ipv6)
13442 len = snprintf(pos, rem_len, " next_header=%s", prot);
13443 else
13444 len = snprintf(pos, rem_len, " protocol=%s", prot);
13445 if (len < 0 || len >= rem_len)
13446 return -1;
13447
13448 pos += len;
13449 rem_len -= len;
13450 total_len += len;
13451 }
13452
13453 return total_len;
13454}
13455
13456
13457static int
13458get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13459 char *pos, int rem_len, int num_of_scs_desc,
13460 int num_of_tclas_elem)
13461{
13462 const char *val;
13463 int len, total_len = 0;
13464
13465 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
13466 num_of_scs_desc, num_of_tclas_elem);
13467 if (val) {
13468 len = snprintf(pos, rem_len, " prot_instance=%s",
13469 val);
13470 if (len < 0 || len >= rem_len)
13471 return -1;
13472
13473 pos += len;
13474 rem_len -= len;
13475 total_len += len;
13476 }
13477
13478 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
13479 num_of_scs_desc, num_of_tclas_elem);
13480 if (val) {
13481 char *prot;
13482
13483 switch (atoi(val)) {
13484 case 17:
13485 prot = "udp";
13486 break;
13487 case 6:
13488 prot = "tcp";
13489 break;
13490 case 50:
13491 prot = "esp";
13492 break;
13493 default:
13494 sigma_dut_print(dut, DUT_MSG_ERROR,
13495 "Invalid protocol %d",
13496 atoi(val));
13497 return -1;
13498 }
13499
13500 len = snprintf(pos, rem_len, " prot_number=%s", prot);
13501 if (len < 0 || len >= rem_len)
13502 return -1;
13503
13504 pos += len;
13505 rem_len -= len;
13506 total_len += len;
13507 }
13508
13509 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
13510 num_of_scs_desc, num_of_tclas_elem);
13511 if (val) {
13512 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
13513 if (len < 0 || len >= rem_len)
13514 return -1;
13515
13516 pos += len;
13517 rem_len -= len;
13518 total_len += len;
13519 }
13520
13521 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
13522 num_of_tclas_elem);
13523 if (val && strlen(val) >= 2) {
13524 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
13525 if (len < 0 || len >= rem_len)
13526 return -1;
13527
13528 pos += len;
13529 rem_len -= len;
13530 total_len += len;
13531 }
13532
13533 return total_len;
13534}
13535
13536
13537static enum sigma_cmd_result
13538cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
13539 const char *intf, struct sigma_cmd *cmd)
13540{
13541 char buf[4096], *pos;
13542 const char *val, *scs_id, *classifier_type;
13543 int len, rem_len, total_bytes;
13544 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
13545
13546 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
13547 if (!scs_id) {
13548 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
13549 return INVALID_SEND_STATUS;
13550 }
13551
13552 rem_len = sizeof(buf);
13553 pos = buf;
13554
13555 len = snprintf(buf, sizeof(buf), "SCS");
13556 if (len < 0 || len > rem_len)
13557 goto fail;
13558
13559 pos += len;
13560 rem_len -= len;
13561
13562 while (scs_id) {
13563 num_of_scs_desc++;
13564
13565 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
13566 num_of_scs_desc);
13567 if (!val)
13568 return INVALID_SEND_STATUS;
13569
13570 if (strcasecmp(val, "Add") == 0) {
13571 len = snprintf(pos, rem_len, " scs_id=%s add",
13572 scs_id);
13573 } else if (strcasecmp(val, "Change") == 0) {
13574 len = snprintf(pos, rem_len, " scs_id=%s change",
13575 scs_id);
13576 } else if (strcasecmp(val, "Remove") == 0) {
13577 len = snprintf(pos, rem_len, " scs_id=%s remove",
13578 scs_id);
13579 if (len < 0 || len >= rem_len)
13580 goto fail;
13581
13582 pos += len;
13583 rem_len -= len;
13584 goto scs_desc_end;
13585 } else {
13586 sigma_dut_print(dut, DUT_MSG_ERROR,
13587 "%s: request type - %s is invalid",
13588 __func__, val);
13589 return INVALID_SEND_STATUS;
13590 }
13591
13592 if (len < 0 || len >= rem_len)
13593 goto fail;
13594
13595 pos += len;
13596 rem_len -= len;
13597
13598 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
13599 num_of_scs_desc);
13600 if (!val) {
13601 sigma_dut_print(dut, DUT_MSG_ERROR,
13602 "IntraAccess Priority empty");
13603 return INVALID_SEND_STATUS;
13604 }
13605
13606 len = snprintf(pos, rem_len, " scs_up=%s", val);
13607 if (len < 0 || len >= rem_len)
13608 goto fail;
13609
13610 pos += len;
13611 rem_len -= len;
13612
13613 classifier_type = get_param_fmt(cmd,
13614 "TCLASElem_ClassifierType_%d_1",
13615 num_of_scs_desc);
13616 if (!classifier_type) {
13617 sigma_dut_print(dut, DUT_MSG_ERROR,
13618 "classifier type missing");
13619 return INVALID_SEND_STATUS;
13620 }
13621
13622 while (classifier_type) {
13623 num_of_tclas_elem++;
13624
13625 len = snprintf(pos, rem_len, " classifier_type=%s",
13626 classifier_type);
13627 if (len < 0 || len >= rem_len)
13628 goto fail;
13629
13630 pos += len;
13631 rem_len -= len;
13632
13633 if (strcmp(classifier_type, "10") == 0) {
13634 total_bytes = get_type10_frame_classifier(
13635 dut, cmd, pos, rem_len,
13636 num_of_scs_desc,
13637 num_of_tclas_elem);
13638 } else if (strcmp(classifier_type, "4") == 0) {
13639 total_bytes = get_type4_frame_classifier(
13640 dut, cmd, pos, rem_len,
13641 num_of_scs_desc,
13642 num_of_tclas_elem);
13643 } else {
13644 sigma_dut_print(dut, DUT_MSG_ERROR,
13645 "classifier_type invalid");
13646 goto fail;
13647 }
13648
13649 if (total_bytes < 0)
13650 goto fail;
13651
13652 pos += total_bytes;
13653 rem_len -= total_bytes;
13654
13655 classifier_type = get_param_fmt(
13656 cmd, "TCLASElem_ClassifierType_%d_%d",
13657 num_of_scs_desc, num_of_tclas_elem + 1);
13658 }
13659
13660 if (num_of_tclas_elem > 1) {
13661 val = get_param_fmt(cmd,
13662 "TCLASProcessingElem_Processing_%d",
13663 num_of_scs_desc);
13664 if (!val) {
13665 sigma_dut_print(dut, DUT_MSG_ERROR,
13666 "Tclas_processing element %d empty",
13667 num_of_scs_desc);
13668 goto fail;
13669 }
13670
13671 len = snprintf(pos, rem_len,
13672 " tclas_processing=%s", val);
13673 if (len < 0 || len >= rem_len)
13674 goto fail;
13675
13676 pos += len;
13677 rem_len -= len;
13678 }
13679scs_desc_end:
13680 num_of_tclas_elem = 0;
13681 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
13682 num_of_scs_desc + 1);
13683 }
13684
13685 if (wpa_command(intf, buf) != 0) {
13686 send_resp(dut, conn, SIGMA_ERROR,
13687 "ErrorCode,Failed to send SCS frame request");
13688 return STATUS_SENT_ERROR;
13689 }
13690
13691 sigma_dut_print(dut, DUT_MSG_DEBUG,
13692 "SCS frame request sent: %s", buf);
13693
13694 return SUCCESS_SEND_STATUS;
13695fail:
13696 sigma_dut_print(dut, DUT_MSG_ERROR,
13697 "Failed to create SCS frame request");
13698 return ERROR_SEND_STATUS;
13699}
13700
13701
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013702static enum sigma_cmd_result
13703cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
13704 const char *intf, struct sigma_cmd *cmd)
13705{
13706 char buf[128], *pos;
13707 const char *val, *classifier_type = "04", *type;
13708 int len, rem_len;
13709 u8 up_bitmap;
13710
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013711 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013712 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013713 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013714 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013715 return INVALID_SEND_STATUS;
13716 }
13717
13718 rem_len = sizeof(buf);
13719 pos = buf;
13720 if (strcasecmp(type, "add") == 0) {
13721 len = snprintf(pos, rem_len, "MSCS add");
13722 } else if (strcasecmp(type, "update") == 0) {
13723 len = snprintf(pos, rem_len, "MSCS change");
13724 } else if (strcasecmp(type, "remove") == 0) {
13725 if (wpa_command(intf, "MSCS remove") != 0) {
13726 send_resp(dut, conn, SIGMA_ERROR,
13727 "ErrorCode,Failed to send MSCS frame req");
13728 return STATUS_SENT_ERROR;
13729 }
13730 return SUCCESS_SEND_STATUS;
13731 } else {
13732 sigma_dut_print(dut, DUT_MSG_ERROR,
13733 "%s: request type invalid", __func__);
13734 return INVALID_SEND_STATUS;
13735 }
13736
13737 if (len < 0 || len >= rem_len)
13738 goto fail;
13739
13740 pos += len;
13741 rem_len -= len;
13742
13743 val = get_param(cmd, "User_Priority_Bitmap");
13744 if (!val) {
13745 sigma_dut_print(dut, DUT_MSG_ERROR,
13746 "%s: user priority bitmap empty", __func__);
13747 return INVALID_SEND_STATUS;
13748 }
13749
13750 switch (atoi(val)) {
13751 case 0:
13752 up_bitmap = 0x00;
13753 break;
13754 case 1:
13755 up_bitmap = 0xF0;
13756 break;
13757 case 2:
13758 up_bitmap = 0xF6;
13759 break;
13760 default:
13761 sigma_dut_print(dut, DUT_MSG_ERROR,
13762 "%s: Unknown User_Priority_Bitmap value %d",
13763 __func__, atoi(val));
13764 return INVALID_SEND_STATUS;
13765 }
13766
13767 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
13768 if (len < 0 || len >= rem_len)
13769 goto fail;
13770
13771 pos += len;
13772 rem_len -= len;
13773
13774 val = get_param(cmd, "User_Priority_Limit");
13775 if (!val) {
13776 sigma_dut_print(dut, DUT_MSG_ERROR,
13777 "%s: invalid user priority limit", __func__);
13778 return INVALID_SEND_STATUS;
13779 }
13780
13781 len = snprintf(pos, rem_len, " up_limit=%s", val);
13782 if (len < 0 || len >= rem_len)
13783 goto fail;
13784
13785 pos += len;
13786 rem_len -= len;
13787
13788 val = get_param(cmd, "Stream_Timeout");
13789 if (!val)
13790 val = get_param(cmd, "Stream_Timtout");
13791 if (!val) {
13792 sigma_dut_print(dut, DUT_MSG_ERROR,
13793 "%s: invalid stream timeout", __func__);
13794 return INVALID_SEND_STATUS;
13795 }
13796
13797 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
13798 if (len < 0 || len >= rem_len)
13799 goto fail;
13800
13801 pos += len;
13802 rem_len -= len;
13803
13804 val = get_param(cmd, "TCLAS_Mask");
13805 if (!val) {
13806 sigma_dut_print(dut, DUT_MSG_ERROR,
13807 "%s: invalid tclas mask", __func__);
13808 return INVALID_SEND_STATUS;
13809 }
13810
13811 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
13812 classifier_type, strtol(val, NULL, 2), 0);
13813 if (len < 0 || len >= rem_len)
13814 goto fail;
13815
13816 if (wpa_command(intf, buf) != 0) {
13817 send_resp(dut, conn, SIGMA_ERROR,
13818 "ErrorCode,Failed to send MSCS frame req");
13819 return STATUS_SENT_ERROR;
13820 }
13821
13822 sigma_dut_print(dut, DUT_MSG_DEBUG,
13823 "MSCS frame request sent: %s", buf);
13824
13825 return SUCCESS_SEND_STATUS;
13826fail:
13827 sigma_dut_print(dut, DUT_MSG_ERROR,
13828 "Failed to create MSCS frame req");
13829 return ERROR_SEND_STATUS;
13830}
13831
13832
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013833static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013834cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13835 const char *intf, struct sigma_cmd *cmd)
13836{
13837 char buf[150], *pos;
13838 const char *val;
13839 int len, rem_len;
13840
13841 rem_len = sizeof(buf);
13842 pos = buf;
13843
13844 len = snprintf(pos, rem_len, "DSCP_QUERY");
13845 if (len < 0 || len >= rem_len)
13846 goto fail;
13847
13848 pos += len;
13849 rem_len -= len;
13850
13851 val = get_param(cmd, "Wildcard");
13852 if (val && strcasecmp(val, "Yes") == 0) {
13853 len = snprintf(pos, rem_len, " wildcard");
13854 if (len < 0 || len >= rem_len)
13855 goto fail;
13856 } else if (strlen(dut->qm_domain_name)) {
13857 len = snprintf(pos, rem_len, " domain_name=%s",
13858 dut->qm_domain_name);
13859 if (len < 0 || len >= rem_len)
13860 goto fail;
13861 } else {
13862 sigma_dut_print(dut, DUT_MSG_ERROR,
13863 "Invalid DSCP Query configuration");
13864 return INVALID_SEND_STATUS;
13865 }
13866
13867 if (wpa_command(intf, buf) != 0) {
13868 send_resp(dut, conn, SIGMA_ERROR,
13869 "ErrorCode,Failed to send DSCP policy query frame");
13870 return STATUS_SENT_ERROR;
13871 }
13872
13873 sigma_dut_print(dut, DUT_MSG_DEBUG,
13874 "DSCP policy query frame sent: %s", buf);
13875 return SUCCESS_SEND_STATUS;
13876fail:
13877 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
13878 return ERROR_SEND_STATUS;
13879}
13880
13881
13882static enum sigma_cmd_result
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013883cmd_sta_send_frame_dscp_response(struct sigma_dut *dut, struct sigma_conn *conn,
13884 const char *intf, struct sigma_cmd *cmd)
13885{
13886 char buf[256], *pos, *item, *list, *saveptr;
13887 const char *val;
13888 int len, rem_len;
13889
13890 pos = buf;
13891 rem_len = sizeof(buf);
13892
13893 len = snprintf(pos, rem_len, "DSCP_RESP");
13894 if (snprintf_error(rem_len, len)) {
13895 sigma_dut_print(dut, DUT_MSG_ERROR,
13896 "Failed to create DSCP Policy Response command");
13897 return ERROR_SEND_STATUS;
13898 }
13899
13900 pos += len;
13901 rem_len -= len;
13902
13903 val = get_param(cmd, "PolicyID_List");
13904 if (!val) {
13905 sigma_dut_print(dut, DUT_MSG_ERROR,
13906 "DSCP policy ID list missing");
13907 return INVALID_SEND_STATUS;
13908 }
13909
13910 list = strdup(val);
13911 if (!list)
13912 return ERROR_SEND_STATUS;
13913
13914 item = strtok_r(list, "_", &saveptr);
13915 while (item) {
13916 unsigned int i;
13917 int policy_id = atoi(item);
13918
13919 for (i = 0; i < dut->num_dscp_status; i++)
13920 if (dut->dscp_status[i].id == policy_id)
13921 break;
13922
13923 if (i == dut->num_dscp_status) {
13924 free(list);
13925 send_resp(dut, conn, SIGMA_ERROR,
13926 "ErrorCode,DSCP policy id not found in status list");
13927 return STATUS_SENT_ERROR;
13928 }
13929
13930 len = snprintf(pos, rem_len, " policy_id=%d status=%d",
13931 policy_id, dut->dscp_status[i].status);
13932 if (snprintf_error(rem_len, len)) {
13933 free(list);
13934 sigma_dut_print(dut, DUT_MSG_ERROR,
13935 "Failed to write DSCP policy list");
13936 return ERROR_SEND_STATUS;
13937 }
13938
13939 pos += len;
13940 rem_len -= len;
13941
13942 if (dut->dscp_status[i].status)
13943 remove_dscp_policy(dut, policy_id);
13944
13945 item = strtok_r(NULL, "_", &saveptr);
13946 }
13947
13948 free(list);
13949
13950 if (wpa_command(intf, buf) != 0) {
13951 send_resp(dut, conn, SIGMA_ERROR,
13952 "ErrorCode,Failed to send DSCP Policy Response frame");
13953 return STATUS_SENT_ERROR;
13954 }
13955
13956 sigma_dut_print(dut, DUT_MSG_DEBUG,
13957 "DSCP Policy Response frame sent: %s", buf);
13958 return SUCCESS_SEND_STATUS;
13959}
13960
13961
13962static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013963cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
13964 const char *intf, struct sigma_cmd *cmd)
13965{
13966 const char *val;
13967
13968 val = get_param(cmd, "FrameName");
13969 if (val) {
13970 if (strcasecmp(val, "MSCSReq") == 0)
13971 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
13972 if (strcasecmp(val, "SCSReq") == 0)
13973 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013974 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
13975 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
13976 cmd);
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013977 if (strcasecmp(val, "DSCPPolicyResponse") == 0)
13978 return cmd_sta_send_frame_dscp_response(dut, conn, intf,
13979 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013980
13981 sigma_dut_print(dut, DUT_MSG_ERROR,
13982 "%s: frame name - %s is invalid",
13983 __func__, val);
13984 }
13985
13986 return INVALID_SEND_STATUS;
13987}
13988
13989
Jouni Malinenf7222712019-06-13 01:50:21 +030013990enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
13991 struct sigma_conn *conn,
13992 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013993{
13994 const char *intf = get_param(cmd, "Interface");
13995 const char *val;
13996 enum send_frame_type frame;
13997 enum send_frame_protection protected;
13998 char buf[100];
13999 unsigned char addr[ETH_ALEN];
14000 int res;
14001
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030014002 if (!intf)
14003 return -1;
14004
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014005 val = get_param(cmd, "program");
14006 if (val == NULL)
14007 val = get_param(cmd, "frame");
14008 if (val && strcasecmp(val, "TDLS") == 0)
14009 return cmd_sta_send_frame_tdls(dut, conn, cmd);
14010 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014011 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014012 strcasecmp(val, "HS2-R3") == 0 ||
14013 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014014 return cmd_sta_send_frame_hs2(dut, conn, cmd);
14015 if (val && strcasecmp(val, "VHT") == 0)
14016 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070014017 if (val && strcasecmp(val, "HE") == 0)
14018 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070014019 if (val && strcasecmp(val, "LOC") == 0)
14020 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020014021 if (val && strcasecmp(val, "60GHz") == 0)
14022 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053014023 if (val && strcasecmp(val, "MBO") == 0) {
14024 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
14025 if (res != 2)
14026 return res;
14027 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053014028 if (val && strcasecmp(val, "WPA3") == 0)
14029 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053014030 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053014031 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014032
14033 val = get_param(cmd, "TD_DISC");
14034 if (val) {
14035 if (hwaddr_aton(val, addr) < 0)
14036 return -1;
14037 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
14038 if (wpa_command(intf, buf) < 0) {
14039 send_resp(dut, conn, SIGMA_ERROR,
14040 "ErrorCode,Failed to send TDLS discovery");
14041 return 0;
14042 }
14043 return 1;
14044 }
14045
14046 val = get_param(cmd, "TD_Setup");
14047 if (val) {
14048 if (hwaddr_aton(val, addr) < 0)
14049 return -1;
14050 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
14051 if (wpa_command(intf, buf) < 0) {
14052 send_resp(dut, conn, SIGMA_ERROR,
14053 "ErrorCode,Failed to start TDLS setup");
14054 return 0;
14055 }
14056 return 1;
14057 }
14058
14059 val = get_param(cmd, "TD_TearDown");
14060 if (val) {
14061 if (hwaddr_aton(val, addr) < 0)
14062 return -1;
14063 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
14064 if (wpa_command(intf, buf) < 0) {
14065 send_resp(dut, conn, SIGMA_ERROR,
14066 "ErrorCode,Failed to tear down TDLS link");
14067 return 0;
14068 }
14069 return 1;
14070 }
14071
14072 val = get_param(cmd, "TD_ChannelSwitch");
14073 if (val) {
14074 /* TODO */
14075 send_resp(dut, conn, SIGMA_ERROR,
14076 "ErrorCode,TD_ChannelSwitch not yet supported");
14077 return 0;
14078 }
14079
14080 val = get_param(cmd, "TD_NF");
14081 if (val) {
14082 /* TODO */
14083 send_resp(dut, conn, SIGMA_ERROR,
14084 "ErrorCode,TD_NF not yet supported");
14085 return 0;
14086 }
14087
14088 val = get_param(cmd, "PMFFrameType");
14089 if (val == NULL)
14090 val = get_param(cmd, "FrameName");
14091 if (val == NULL)
14092 val = get_param(cmd, "Type");
14093 if (val == NULL)
14094 return -1;
14095 if (strcasecmp(val, "disassoc") == 0)
14096 frame = DISASSOC;
14097 else if (strcasecmp(val, "deauth") == 0)
14098 frame = DEAUTH;
14099 else if (strcasecmp(val, "saquery") == 0)
14100 frame = SAQUERY;
14101 else if (strcasecmp(val, "auth") == 0)
14102 frame = AUTH;
14103 else if (strcasecmp(val, "assocreq") == 0)
14104 frame = ASSOCREQ;
14105 else if (strcasecmp(val, "reassocreq") == 0)
14106 frame = REASSOCREQ;
14107 else if (strcasecmp(val, "neigreq") == 0) {
14108 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
14109
14110 val = get_param(cmd, "ssid");
14111 if (val == NULL)
14112 return -1;
14113
14114 res = send_neighbor_request(dut, intf, val);
14115 if (res) {
14116 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14117 "Failed to send neighbor report request");
14118 return 0;
14119 }
14120
14121 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053014122 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
14123 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014124 sigma_dut_print(dut, DUT_MSG_DEBUG,
14125 "Got Transition Management Query");
14126
Ashwini Patil5acd7382017-04-13 15:55:04 +053014127 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014128 if (res) {
14129 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14130 "Failed to send Transition Management Query");
14131 return 0;
14132 }
14133
14134 return 1;
14135 } else {
14136 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14137 "PMFFrameType");
14138 return 0;
14139 }
14140
14141 val = get_param(cmd, "PMFProtected");
14142 if (val == NULL)
14143 val = get_param(cmd, "Protected");
14144 if (val == NULL)
14145 return -1;
14146 if (strcasecmp(val, "Correct-key") == 0 ||
14147 strcasecmp(val, "CorrectKey") == 0)
14148 protected = CORRECT_KEY;
14149 else if (strcasecmp(val, "IncorrectKey") == 0)
14150 protected = INCORRECT_KEY;
14151 else if (strcasecmp(val, "Unprotected") == 0)
14152 protected = UNPROTECTED;
14153 else {
14154 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14155 "PMFProtected");
14156 return 0;
14157 }
14158
14159 if (protected != UNPROTECTED &&
14160 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
14161 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
14162 "PMFProtected for auth/assocreq/reassocreq");
14163 return 0;
14164 }
14165
14166 if (if_nametoindex("sigmadut") == 0) {
14167 snprintf(buf, sizeof(buf),
14168 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014169 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014170 if (system(buf) != 0 ||
14171 if_nametoindex("sigmadut") == 0) {
14172 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
14173 "monitor interface with '%s'", buf);
14174 return -2;
14175 }
14176 }
14177
14178 if (system("ifconfig sigmadut up") != 0) {
14179 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
14180 "monitor interface up");
14181 return -2;
14182 }
14183
Veerendranath Jakkam49774122020-07-05 09:52:18 +053014184 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014185}
14186
14187
14188static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
14189 struct sigma_conn *conn,
14190 struct sigma_cmd *cmd,
14191 const char *ifname)
14192{
14193 char buf[200];
14194 const char *val;
14195
14196 val = get_param(cmd, "ClearARP");
14197 if (val && atoi(val) == 1) {
14198 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
14199 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14200 if (system(buf) != 0) {
14201 send_resp(dut, conn, SIGMA_ERROR,
14202 "errorCode,Failed to clear ARP cache");
14203 return 0;
14204 }
14205 }
14206
14207 return 1;
14208}
14209
14210
14211int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
14212 struct sigma_cmd *cmd)
14213{
14214 const char *intf = get_param(cmd, "Interface");
14215 const char *val;
14216
14217 if (intf == NULL)
14218 return -1;
14219
14220 val = get_param(cmd, "program");
14221 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014222 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014223 strcasecmp(val, "HS2-R3") == 0 ||
14224 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014225 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
14226
14227 return -1;
14228}
14229
14230
Jouni Malinenf7222712019-06-13 01:50:21 +030014231static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
14232 struct sigma_conn *conn,
14233 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014234{
14235 const char *intf = get_param(cmd, "Interface");
14236 const char *mac = get_param(cmd, "MAC");
14237
14238 if (intf == NULL || mac == NULL)
14239 return -1;
14240
14241 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
14242 "interface %s to %s", intf, mac);
14243
14244 if (dut->set_macaddr) {
14245 char buf[128];
14246 int res;
14247 if (strcasecmp(mac, "default") == 0) {
14248 res = snprintf(buf, sizeof(buf), "%s",
14249 dut->set_macaddr);
14250 dut->tmp_mac_addr = 0;
14251 } else {
14252 res = snprintf(buf, sizeof(buf), "%s %s",
14253 dut->set_macaddr, mac);
14254 dut->tmp_mac_addr = 1;
14255 }
14256 if (res < 0 || res >= (int) sizeof(buf))
14257 return -1;
14258 if (system(buf) != 0) {
14259 send_resp(dut, conn, SIGMA_ERROR,
14260 "errorCode,Failed to set MAC "
14261 "address");
14262 return 0;
14263 }
14264 return 1;
14265 }
14266
14267 if (strcasecmp(mac, "default") == 0)
14268 return 1;
14269
14270 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14271 "command");
14272 return 0;
14273}
14274
14275
14276static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
14277 struct sigma_conn *conn, const char *intf,
14278 int val)
14279{
14280 char buf[200];
14281 int res;
14282
14283 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
14284 intf, val);
14285 if (res < 0 || res >= (int) sizeof(buf))
14286 return -1;
14287 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14288 if (system(buf) != 0) {
14289 send_resp(dut, conn, SIGMA_ERROR,
14290 "errorCode,Failed to configure offchannel mode");
14291 return 0;
14292 }
14293
14294 return 1;
14295}
14296
14297
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014298static int off_chan_val(enum sec_ch_offset off)
14299{
14300 switch (off) {
14301 case SEC_CH_NO:
14302 return 0;
14303 case SEC_CH_40ABOVE:
14304 return 40;
14305 case SEC_CH_40BELOW:
14306 return -40;
14307 }
14308
14309 return 0;
14310}
14311
14312
14313static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
14314 const char *intf, int off_ch_num,
14315 enum sec_ch_offset sec)
14316{
14317 char buf[200];
14318 int res;
14319
14320 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
14321 intf, off_ch_num);
14322 if (res < 0 || res >= (int) sizeof(buf))
14323 return -1;
14324 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14325 if (system(buf) != 0) {
14326 send_resp(dut, conn, SIGMA_ERROR,
14327 "errorCode,Failed to set offchan");
14328 return 0;
14329 }
14330
14331 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
14332 intf, off_chan_val(sec));
14333 if (res < 0 || res >= (int) sizeof(buf))
14334 return -1;
14335 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14336 if (system(buf) != 0) {
14337 send_resp(dut, conn, SIGMA_ERROR,
14338 "errorCode,Failed to set sec chan offset");
14339 return 0;
14340 }
14341
14342 return 1;
14343}
14344
14345
14346static int tdls_set_offchannel_offset(struct sigma_dut *dut,
14347 struct sigma_conn *conn,
14348 const char *intf, int off_ch_num,
14349 enum sec_ch_offset sec)
14350{
14351 char buf[200];
14352 int res;
14353
14354 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
14355 off_ch_num);
14356 if (res < 0 || res >= (int) sizeof(buf))
14357 return -1;
14358 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14359
14360 if (wpa_command(intf, buf) < 0) {
14361 send_resp(dut, conn, SIGMA_ERROR,
14362 "ErrorCode,Failed to set offchan");
14363 return 0;
14364 }
14365 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
14366 off_chan_val(sec));
14367 if (res < 0 || res >= (int) sizeof(buf))
14368 return -1;
14369
14370 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14371
14372 if (wpa_command(intf, buf) < 0) {
14373 send_resp(dut, conn, SIGMA_ERROR,
14374 "ErrorCode,Failed to set sec chan offset");
14375 return 0;
14376 }
14377
14378 return 1;
14379}
14380
14381
14382static int tdls_set_offchannel_mode(struct sigma_dut *dut,
14383 struct sigma_conn *conn,
14384 const char *intf, int val)
14385{
14386 char buf[200];
14387 int res;
14388
14389 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
14390 val);
14391 if (res < 0 || res >= (int) sizeof(buf))
14392 return -1;
14393 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14394
14395 if (wpa_command(intf, buf) < 0) {
14396 send_resp(dut, conn, SIGMA_ERROR,
14397 "ErrorCode,Failed to configure offchannel mode");
14398 return 0;
14399 }
14400
14401 return 1;
14402}
14403
14404
14405static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
14406 struct sigma_conn *conn,
14407 struct sigma_cmd *cmd)
14408{
14409 const char *val;
14410 enum {
14411 CHSM_NOT_SET,
14412 CHSM_ENABLE,
14413 CHSM_DISABLE,
14414 CHSM_REJREQ,
14415 CHSM_UNSOLRESP
14416 } chsm = CHSM_NOT_SET;
14417 int off_ch_num = -1;
14418 enum sec_ch_offset sec_ch = SEC_CH_NO;
14419 int res;
14420
14421 val = get_param(cmd, "Uapsd");
14422 if (val) {
14423 char buf[100];
14424 if (strcasecmp(val, "Enable") == 0)
14425 snprintf(buf, sizeof(buf), "SET ps 99");
14426 else if (strcasecmp(val, "Disable") == 0)
14427 snprintf(buf, sizeof(buf), "SET ps 98");
14428 else {
14429 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14430 "Unsupported uapsd parameter value");
14431 return 0;
14432 }
14433 if (wpa_command(intf, buf)) {
14434 send_resp(dut, conn, SIGMA_ERROR,
14435 "ErrorCode,Failed to change U-APSD "
14436 "powersave mode");
14437 return 0;
14438 }
14439 }
14440
14441 val = get_param(cmd, "TPKTIMER");
14442 if (val && strcasecmp(val, "DISABLE") == 0) {
14443 if (wpa_command(intf, "SET tdls_testing 0x100")) {
14444 send_resp(dut, conn, SIGMA_ERROR,
14445 "ErrorCode,Failed to enable no TPK "
14446 "expiration test mode");
14447 return 0;
14448 }
14449 dut->no_tpk_expiration = 1;
14450 }
14451
14452 val = get_param(cmd, "ChSwitchMode");
14453 if (val) {
14454 if (strcasecmp(val, "Enable") == 0 ||
14455 strcasecmp(val, "Initiate") == 0)
14456 chsm = CHSM_ENABLE;
14457 else if (strcasecmp(val, "Disable") == 0 ||
14458 strcasecmp(val, "passive") == 0)
14459 chsm = CHSM_DISABLE;
14460 else if (strcasecmp(val, "RejReq") == 0)
14461 chsm = CHSM_REJREQ;
14462 else if (strcasecmp(val, "UnSolResp") == 0)
14463 chsm = CHSM_UNSOLRESP;
14464 else {
14465 send_resp(dut, conn, SIGMA_ERROR,
14466 "ErrorCode,Unknown ChSwitchMode value");
14467 return 0;
14468 }
14469 }
14470
14471 val = get_param(cmd, "OffChNum");
14472 if (val) {
14473 off_ch_num = atoi(val);
14474 if (off_ch_num == 0) {
14475 send_resp(dut, conn, SIGMA_ERROR,
14476 "ErrorCode,Invalid OffChNum");
14477 return 0;
14478 }
14479 }
14480
14481 val = get_param(cmd, "SecChOffset");
14482 if (val) {
14483 if (strcmp(val, "20") == 0)
14484 sec_ch = SEC_CH_NO;
14485 else if (strcasecmp(val, "40above") == 0)
14486 sec_ch = SEC_CH_40ABOVE;
14487 else if (strcasecmp(val, "40below") == 0)
14488 sec_ch = SEC_CH_40BELOW;
14489 else {
14490 send_resp(dut, conn, SIGMA_ERROR,
14491 "ErrorCode,Unknown SecChOffset value");
14492 return 0;
14493 }
14494 }
14495
14496 if (chsm == CHSM_NOT_SET) {
14497 /* no offchannel changes requested */
14498 return 1;
14499 }
14500
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014501 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
14502 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014503 send_resp(dut, conn, SIGMA_ERROR,
14504 "ErrorCode,Unknown interface");
14505 return 0;
14506 }
14507
14508 switch (chsm) {
14509 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030014510 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014511 break;
14512 case CHSM_ENABLE:
14513 if (off_ch_num < 0) {
14514 send_resp(dut, conn, SIGMA_ERROR,
14515 "ErrorCode,Missing OffChNum argument");
14516 return 0;
14517 }
14518 if (wifi_chip_type == DRIVER_WCN) {
14519 res = tdls_set_offchannel_offset(dut, conn, intf,
14520 off_ch_num, sec_ch);
14521 } else {
14522 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14523 sec_ch);
14524 }
14525 if (res != 1)
14526 return res;
14527 if (wifi_chip_type == DRIVER_WCN)
14528 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
14529 else
14530 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
14531 break;
14532 case CHSM_DISABLE:
14533 if (wifi_chip_type == DRIVER_WCN)
14534 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
14535 else
14536 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
14537 break;
14538 case CHSM_REJREQ:
14539 if (wifi_chip_type == DRIVER_WCN)
14540 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
14541 else
14542 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
14543 break;
14544 case CHSM_UNSOLRESP:
14545 if (off_ch_num < 0) {
14546 send_resp(dut, conn, SIGMA_ERROR,
14547 "ErrorCode,Missing OffChNum argument");
14548 return 0;
14549 }
14550 if (wifi_chip_type == DRIVER_WCN) {
14551 res = tdls_set_offchannel_offset(dut, conn, intf,
14552 off_ch_num, sec_ch);
14553 } else {
14554 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14555 sec_ch);
14556 }
14557 if (res != 1)
14558 return res;
14559 if (wifi_chip_type == DRIVER_WCN)
14560 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
14561 else
14562 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
14563 break;
14564 }
14565
14566 return res;
14567}
14568
14569
14570static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14571 struct sigma_conn *conn,
14572 struct sigma_cmd *cmd)
14573{
14574 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014575 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014576
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070014577 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080014578
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014579 val = get_param(cmd, "nss_mcs_opt");
14580 if (val) {
14581 /* String (nss_operating_mode; mcs_operating_mode) */
14582 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014583 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014584
14585 token = strdup(val);
14586 if (!token)
14587 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014588 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014589 if (!result) {
14590 sigma_dut_print(dut, DUT_MSG_ERROR,
14591 "VHT NSS not specified");
14592 goto failed;
14593 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014594 if (strcasecmp(result, "def") != 0) {
14595 nss = atoi(result);
14596 if (nss == 4)
14597 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014598 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014599 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014600
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014601 }
14602
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014603 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014604 if (!result) {
14605 sigma_dut_print(dut, DUT_MSG_ERROR,
14606 "VHT MCS not specified");
14607 goto failed;
14608 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014609 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014610 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014611 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014612 } else {
14613 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014614 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014615 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014616 }
14617 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014618 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014619 }
14620
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014621 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014622 return 1;
14623failed:
14624 free(token);
14625 return 0;
14626}
14627
14628
14629static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14630 struct sigma_conn *conn,
14631 struct sigma_cmd *cmd)
14632{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014633 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014634 case DRIVER_ATHEROS:
14635 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
14636 default:
14637 send_resp(dut, conn, SIGMA_ERROR,
14638 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
14639 return 0;
14640 }
14641}
14642
14643
Jouni Malinen1702fe32021-06-08 19:08:01 +030014644static enum sigma_cmd_result
14645wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14646 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014647{
14648 const char *val;
14649 char *token = NULL, *result;
14650 char buf[60];
14651
14652 val = get_param(cmd, "nss_mcs_opt");
14653 if (val) {
14654 /* String (nss_operating_mode; mcs_operating_mode) */
14655 int nss, mcs, ratecode;
14656 char *saveptr;
14657
14658 token = strdup(val);
14659 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014660 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014661
14662 result = strtok_r(token, ";", &saveptr);
14663 if (!result) {
14664 sigma_dut_print(dut, DUT_MSG_ERROR,
14665 "HE NSS not specified");
14666 goto failed;
14667 }
14668 nss = 1;
14669 if (strcasecmp(result, "def") != 0)
14670 nss = atoi(result);
14671
14672 result = strtok_r(NULL, ";", &saveptr);
14673 if (!result) {
14674 sigma_dut_print(dut, DUT_MSG_ERROR,
14675 "HE MCS not specified");
14676 goto failed;
14677 }
14678 mcs = 7;
14679 if (strcasecmp(result, "def") != 0)
14680 mcs = atoi(result);
14681
Arif Hussain557bf412018-05-25 17:29:36 -070014682 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014683 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070014684 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014685 } else if (nss > 2) {
14686 sigma_dut_print(dut, DUT_MSG_ERROR,
14687 "HE NSS %d not supported", nss);
14688 goto failed;
14689 }
14690
Arif Hussain557bf412018-05-25 17:29:36 -070014691 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
14692 if (system(buf) != 0) {
14693 sigma_dut_print(dut, DUT_MSG_ERROR,
14694 "nss_mcs_opt: iwpriv %s nss %d failed",
14695 intf, nss);
14696 goto failed;
14697 }
Arif Hussainac6c5112018-05-25 17:34:00 -070014698 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070014699
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014700 /* Add the MCS to the ratecode */
14701 if (mcs >= 0 && mcs <= 11) {
14702 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070014703#ifdef NL80211_SUPPORT
14704 if (dut->device_type == STA_testbed) {
14705 enum he_mcs_config mcs_config;
14706 int ret;
14707
14708 if (mcs <= 7)
14709 mcs_config = HE_80_MCS0_7;
14710 else if (mcs <= 9)
14711 mcs_config = HE_80_MCS0_9;
14712 else
14713 mcs_config = HE_80_MCS0_11;
14714 ret = sta_set_he_mcs(dut, intf, mcs_config);
14715 if (ret) {
14716 sigma_dut_print(dut, DUT_MSG_ERROR,
14717 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
14718 mcs, mcs_config, ret);
14719 goto failed;
14720 }
14721 }
14722#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014723 } else {
14724 sigma_dut_print(dut, DUT_MSG_ERROR,
14725 "HE MCS %d not supported", mcs);
14726 goto failed;
14727 }
14728 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
14729 intf, ratecode);
14730 if (system(buf) != 0) {
14731 sigma_dut_print(dut, DUT_MSG_ERROR,
14732 "iwpriv setting of 11ax rates failed");
14733 goto failed;
14734 }
14735 free(token);
14736 }
14737
14738 val = get_param(cmd, "GI");
14739 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014740 int fix_rate_sgi;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014741 u8 he_gi_val = 0;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014742
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014743 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014744 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014745 fix_rate_sgi = 1;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014746 he_gi_val = NL80211_RATE_INFO_HE_GI_0_8;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014747 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014748 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
14749 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014750 fix_rate_sgi = 2;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014751 he_gi_val = NL80211_RATE_INFO_HE_GI_1_6;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014752 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014753 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
14754 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014755 fix_rate_sgi = 3;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014756 he_gi_val = NL80211_RATE_INFO_HE_GI_3_2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014757 } else {
14758 send_resp(dut, conn, SIGMA_ERROR,
14759 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014760 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014761 }
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014762 if (wcn_set_he_gi(dut, intf, he_gi_val)) {
14763 sigma_dut_print(dut, DUT_MSG_INFO,
14764 "wcn_set_he_gi failed, using iwpriv");
14765 if (system(buf) != 0) {
14766 send_resp(dut, conn, SIGMA_ERROR,
14767 "errorCode,Failed to set shortgi");
14768 return STATUS_SENT_ERROR;
14769 }
14770 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
14771 intf, fix_rate_sgi);
14772 if (system(buf) != 0) {
14773 send_resp(dut, conn, SIGMA_ERROR,
14774 "errorCode,Failed to set fix rate shortgi");
14775 return STATUS_SENT_ERROR;
14776 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014777 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014778 }
14779
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014780 val = get_param(cmd, "LTF");
14781 if (val) {
14782#ifdef NL80211_SUPPORT
14783 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014784 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014785 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014786 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014787 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014788 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014789 } else {
14790 send_resp(dut, conn, SIGMA_ERROR,
14791 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014792 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014793 }
14794#else /* NL80211_SUPPORT */
14795 sigma_dut_print(dut, DUT_MSG_ERROR,
14796 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014797 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014798#endif /* NL80211_SUPPORT */
14799 }
14800
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070014801 val = get_param(cmd, "KeepAlive");
14802 if (val) {
14803 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
14804
14805 if (strcasecmp(val, "Data") == 0)
14806 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
14807 else if (strcasecmp(val, "Mgmt") == 0)
14808 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
14809
14810 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
14811 send_resp(dut, conn, SIGMA_ERROR,
14812 "ErrorCode,Failed to set keep alive type config");
14813 return STATUS_SENT_ERROR;
14814 }
14815 }
14816
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014817 val = get_param(cmd, "TxSUPPDU");
14818 if (val) {
14819 int set_val = 1;
14820
14821 if (strcasecmp(val, "Enable") == 0)
14822 set_val = 1;
14823 else if (strcasecmp(val, "Disable") == 0)
14824 set_val = 0;
14825
14826 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
14827 send_resp(dut, conn, SIGMA_ERROR,
14828 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014829 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014830 }
14831 }
14832
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070014833 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
14834 if (val) {
14835 int set_val = 0;
14836
14837 if (strcasecmp(val, "Enable") == 0)
14838 set_val = 0;
14839 else if (strcasecmp(val, "Disable") == 0)
14840 set_val = 1;
14841
14842 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
14843 send_resp(dut, conn, SIGMA_ERROR,
14844 "ErrorCode,Failed to set mgmt/data Tx disable config");
14845 return STATUS_SENT_ERROR;
14846 }
14847 }
14848
Arif Hussain480d5f42019-03-12 14:40:42 -070014849 val = get_param(cmd, "TWT_Setup");
14850 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014851#ifdef NL80211_SUPPORT
14852 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14853 sigma_dut_print(dut, DUT_MSG_ERROR,
14854 "Failed to open nl80211 event socket");
14855#endif /* NL80211_SUPPORT */
Arif Hussain480d5f42019-03-12 14:40:42 -070014856 if (strcasecmp(val, "Request") == 0) {
Kiran Kumar Lokereafac46a2021-11-29 14:03:20 -080014857 if (set_power_save_wcn(dut, intf, 1) < 0)
14858 sigma_dut_print(dut, DUT_MSG_ERROR,
14859 "Failed to enable power save");
Arif Hussain480d5f42019-03-12 14:40:42 -070014860 if (sta_twt_request(dut, conn, cmd)) {
14861 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014862 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014863 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014864 }
14865 } else if (strcasecmp(val, "Teardown") == 0) {
14866 if (sta_twt_teardown(dut, conn, cmd)) {
14867 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014868 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014869 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014870 }
14871 }
14872 }
14873
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014874 val = get_param(cmd, "TWT_Operation");
14875 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014876#ifdef NL80211_SUPPORT
14877 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14878 sigma_dut_print(dut, DUT_MSG_ERROR,
14879 "Failed to open nl80211 event socket");
14880#endif /* NL80211_SUPPORT */
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014881 if (strcasecmp(val, "Suspend") == 0) {
14882 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
14883 send_resp(dut, conn, SIGMA_ERROR,
14884 "ErrorCode,TWT suspend failed");
14885 return STATUS_SENT_ERROR;
14886 }
14887 } else if (strcasecmp(val, "Resume") == 0) {
14888 if (sta_twt_resume(dut, conn, cmd)) {
14889 send_resp(dut, conn, SIGMA_ERROR,
14890 "ErrorCode,TWT resume failed");
14891 return STATUS_SENT_ERROR;
14892 }
14893 }
14894 }
14895
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080014896 val = get_param(cmd, "transmitOMI");
14897 if (val && sta_transmit_omi(dut, conn, cmd)) {
14898 send_resp(dut, conn, SIGMA_ERROR,
14899 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014900 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070014901 }
14902
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014903 val = get_param(cmd, "Powersave");
14904 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014905 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014906
14907 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014908 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014909 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014910 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014911 } else {
14912 sigma_dut_print(dut, DUT_MSG_ERROR,
14913 "Unsupported Powersave value '%s'",
14914 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014915 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014916 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014917 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014918 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014919 }
14920
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080014921 val = get_param(cmd, "MU_EDCA");
14922 if (val) {
14923 if (strcasecmp(val, "Override") == 0) {
14924 if (sta_set_mu_edca_override(dut, intf, 1)) {
14925 send_resp(dut, conn, SIGMA_ERROR,
14926 "errorCode,MU EDCA override set failed");
14927 return STATUS_SENT;
14928 }
14929 } else if (strcasecmp(val, "Disable") == 0) {
14930 if (sta_set_mu_edca_override(dut, intf, 0)) {
14931 send_resp(dut, conn, SIGMA_ERROR,
14932 "errorCode,MU EDCA override disable failed");
14933 return STATUS_SENT;
14934 }
14935 }
14936 }
14937
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070014938 val = get_param(cmd, "RUAllocTone");
14939 if (val && strcasecmp(val, "242") == 0) {
14940 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
14941 send_resp(dut, conn, SIGMA_ERROR,
14942 "ErrorCode,Failed to set RU 242 tone Tx");
14943 return STATUS_SENT_ERROR;
14944 }
14945 }
14946
14947 val = get_param(cmd, "PPDUTxType");
14948 if (val && strcasecmp(val, "ER-SU") == 0) {
14949 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
14950 send_resp(dut, conn, SIGMA_ERROR,
14951 "ErrorCode,Failed to set ER-SU PPDU type Tx");
14952 return STATUS_SENT_ERROR;
14953 }
14954 }
14955
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070014956 val = get_param(cmd, "Ch_Pref");
14957 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14958 return STATUS_SENT;
14959
14960 val = get_param(cmd, "Cellular_Data_Cap");
14961 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14962 return STATUS_SENT;
14963
Jouni Malinen1702fe32021-06-08 19:08:01 +030014964 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014965
14966failed:
14967 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014968 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014969}
14970
14971
Jouni Malinen1702fe32021-06-08 19:08:01 +030014972static enum sigma_cmd_result
14973cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14974 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014975{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014976 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014977 case DRIVER_WCN:
14978 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
14979 default:
14980 send_resp(dut, conn, SIGMA_ERROR,
14981 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014982 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014983 }
14984}
14985
14986
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014987static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
14988 struct sigma_conn *conn,
14989 struct sigma_cmd *cmd)
14990{
14991 const char *val;
14992
14993 val = get_param(cmd, "powersave");
14994 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014995 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014996
14997 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014998 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014999 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015000 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015001 } else {
15002 sigma_dut_print(dut, DUT_MSG_ERROR,
15003 "Unsupported power save config");
15004 return -1;
15005 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015006 if (set_power_save_wcn(dut, intf, ps) < 0)
15007 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015008 return 1;
15009 }
15010
15011 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
15012
15013 return 0;
15014}
15015
15016
Ashwini Patil5acd7382017-04-13 15:55:04 +053015017static int btm_query_candidate_list(struct sigma_dut *dut,
15018 struct sigma_conn *conn,
15019 struct sigma_cmd *cmd)
15020{
15021 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
15022 int len, ret;
15023 char buf[10];
15024
15025 /*
15026 * Neighbor Report elements format:
15027 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
15028 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
15029 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
15030 */
15031
15032 bssid = get_param(cmd, "Nebor_BSSID");
15033 if (!bssid) {
15034 send_resp(dut, conn, SIGMA_INVALID,
15035 "errorCode,Nebor_BSSID is missing");
15036 return 0;
15037 }
15038
15039 info = get_param(cmd, "Nebor_Bssid_Info");
15040 if (!info) {
15041 sigma_dut_print(dut, DUT_MSG_INFO,
15042 "Using default value for Nebor_Bssid_Info: %s",
15043 DEFAULT_NEIGHBOR_BSSID_INFO);
15044 info = DEFAULT_NEIGHBOR_BSSID_INFO;
15045 }
15046
15047 op_class = get_param(cmd, "Nebor_Op_Class");
15048 if (!op_class) {
15049 send_resp(dut, conn, SIGMA_INVALID,
15050 "errorCode,Nebor_Op_Class is missing");
15051 return 0;
15052 }
15053
15054 ch = get_param(cmd, "Nebor_Op_Ch");
15055 if (!ch) {
15056 send_resp(dut, conn, SIGMA_INVALID,
15057 "errorCode,Nebor_Op_Ch is missing");
15058 return 0;
15059 }
15060
15061 phy_type = get_param(cmd, "Nebor_Phy_Type");
15062 if (!phy_type) {
15063 sigma_dut_print(dut, DUT_MSG_INFO,
15064 "Using default value for Nebor_Phy_Type: %s",
15065 DEFAULT_NEIGHBOR_PHY_TYPE);
15066 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
15067 }
15068
15069 /* Parse optional subelements */
15070 buf[0] = '\0';
15071 pref = get_param(cmd, "Nebor_Pref");
15072 if (pref) {
15073 /* hexdump for preferrence subelement */
15074 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
15075 if (ret < 0 || ret >= (int) sizeof(buf)) {
15076 sigma_dut_print(dut, DUT_MSG_ERROR,
15077 "snprintf failed for optional subelement ret: %d",
15078 ret);
15079 send_resp(dut, conn, SIGMA_ERROR,
15080 "errorCode,snprintf failed for subelement");
15081 return 0;
15082 }
15083 }
15084
15085 if (!dut->btm_query_cand_list) {
15086 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
15087 if (!dut->btm_query_cand_list) {
15088 send_resp(dut, conn, SIGMA_ERROR,
15089 "errorCode,Failed to allocate memory for btm_query_cand_list");
15090 return 0;
15091 }
15092 }
15093
15094 len = strlen(dut->btm_query_cand_list);
15095 ret = snprintf(dut->btm_query_cand_list + len,
15096 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
15097 bssid, info, op_class, ch, phy_type, buf);
15098 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
15099 sigma_dut_print(dut, DUT_MSG_ERROR,
15100 "snprintf failed for neighbor report list ret: %d",
15101 ret);
15102 send_resp(dut, conn, SIGMA_ERROR,
15103 "errorCode,snprintf failed for neighbor report");
15104 free(dut->btm_query_cand_list);
15105 dut->btm_query_cand_list = NULL;
15106 return 0;
15107 }
15108
15109 return 1;
15110}
15111
15112
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015113int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
15114 struct sigma_ese_alloc *allocs, int *allocs_size)
15115{
15116 int max_count = *allocs_size;
15117 int count = 0, i;
15118 const char *val;
15119
15120 do {
15121 val = get_param_indexed(cmd, "AllocID", count);
15122 if (val)
15123 count++;
15124 } while (val);
15125
15126 if (count == 0 || count > max_count) {
15127 sigma_dut_print(dut, DUT_MSG_ERROR,
15128 "Invalid number of allocations(%d)", count);
15129 return -1;
15130 }
15131
15132 for (i = 0; i < count; i++) {
15133 val = get_param_indexed(cmd, "PercentBI", i);
15134 if (!val) {
15135 sigma_dut_print(dut, DUT_MSG_ERROR,
15136 "Missing PercentBI parameter at index %d",
15137 i);
15138 return -1;
15139 }
15140 allocs[i].percent_bi = atoi(val);
15141
15142 val = get_param_indexed(cmd, "SrcAID", i);
15143 if (val)
15144 allocs[i].src_aid = strtol(val, NULL, 0);
15145 else
15146 allocs[i].src_aid = ESE_BCAST_AID;
15147
15148 val = get_param_indexed(cmd, "DestAID", i);
15149 if (val)
15150 allocs[i].dst_aid = strtol(val, NULL, 0);
15151 else
15152 allocs[i].dst_aid = ESE_BCAST_AID;
15153
15154 allocs[i].type = ESE_CBAP;
15155 sigma_dut_print(dut, DUT_MSG_INFO,
15156 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
15157 i, allocs[i].percent_bi, allocs[i].src_aid,
15158 allocs[i].dst_aid);
15159 }
15160
15161 *allocs_size = count;
15162 return 0;
15163}
15164
15165
15166static int sta_set_60g_ese(struct sigma_dut *dut, int count,
15167 struct sigma_ese_alloc *allocs)
15168{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015169 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015170#ifdef __linux__
15171 case DRIVER_WIL6210:
15172 if (wil6210_set_ese(dut, count, allocs))
15173 return -1;
15174 return 1;
15175#endif /* __linux__ */
15176 default:
15177 sigma_dut_print(dut, DUT_MSG_ERROR,
15178 "Unsupported sta_set_60g_ese with the current driver");
15179 return -1;
15180 }
15181}
15182
15183
15184static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
15185 struct sigma_conn *conn,
15186 struct sigma_cmd *cmd)
15187{
15188 const char *val;
15189
15190 val = get_param(cmd, "ExtSchIE");
15191 if (val && !strcasecmp(val, "Enable")) {
15192 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
15193 int count = MAX_ESE_ALLOCS;
15194
15195 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
15196 return -1;
15197 return sta_set_60g_ese(dut, count, allocs);
15198 }
15199
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015200 val = get_param(cmd, "MCS_FixedRate");
15201 if (val) {
15202 int sta_mcs = atoi(val);
15203
15204 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
15205 sta_mcs);
15206 wil6210_set_force_mcs(dut, 1, sta_mcs);
15207
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015208 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015209 }
15210
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015211 send_resp(dut, conn, SIGMA_ERROR,
15212 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015213 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015214}
15215
15216
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015217static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
15218 const char *oci_frametype, uint32_t oci_freq)
15219{
15220#ifdef NL80211_SUPPORT
15221 struct nl_msg *msg;
15222 int ret = 0;
15223 struct nlattr *params;
15224 struct nlattr *attr;
15225 int ifindex;
15226 u8 frame_type;
15227
15228 ifindex = if_nametoindex(intf);
15229 if (ifindex == 0) {
15230 sigma_dut_print(dut, DUT_MSG_ERROR,
15231 "%s: Index for interface %s failed",
15232 __func__, intf);
15233 return -1;
15234 }
15235
15236 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15237 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
15238 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15239 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
15240 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15241 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
15242 } else {
15243 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
15244 __func__, oci_frametype);
15245 return -1;
15246 }
15247
15248
15249 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
15250 NL80211_CMD_VENDOR)) ||
15251 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
15252 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
15253 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
15254 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
15255 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
15256 !(params = nla_nest_start(
15257 msg,
15258 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
15259 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
15260 frame_type) ||
15261 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
15262 oci_freq)) {
15263 sigma_dut_print(dut, DUT_MSG_ERROR,
15264 "%s: err in adding vendor_cmd and vendor_data",
15265 __func__);
15266 nlmsg_free(msg);
15267 return -1;
15268 }
15269 nla_nest_end(msg, params);
15270 nla_nest_end(msg, attr);
15271
15272 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
15273 if (ret) {
15274 sigma_dut_print(dut, DUT_MSG_ERROR,
15275 "%s: err in send_and_recv_msgs, ret=%d",
15276 __func__, ret);
15277 }
15278 return ret;
15279#else /* NL80211_SUPPORT */
15280 sigma_dut_print(dut, DUT_MSG_ERROR,
15281 "OCI override not possible without NL80211_SUPPORT defined");
15282 return -1;
15283#endif /* NL80211_SUPPORT */
15284}
15285
15286
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015287static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
15288 uint8_t ignore_csa)
15289{
15290#ifdef NL80211_SUPPORT
15291 return wcn_wifi_test_config_set_u8(
15292 dut, intf,
15293 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
15294#else /* NL80211_SUPPORT */
15295 sigma_dut_print(dut, DUT_MSG_ERROR,
15296 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
15297 return -1;
15298#endif /* NL80211_SUPPORT */
15299}
15300
15301
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015302static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
15303 uint8_t rsnxe_used)
15304{
15305#ifdef NL80211_SUPPORT
15306 return wcn_wifi_test_config_set_u8(
15307 dut, intf,
15308 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
15309 rsnxe_used);
15310#else /* NL80211_SUPPORT */
15311 sigma_dut_print(dut, DUT_MSG_ERROR,
15312 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
15313 return -1;
15314#endif /* NL80211_SUPPORT */
15315}
15316
15317
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015318static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
15319 const char *intf,
15320 uint8_t ignore_sa_query_timeout)
15321{
15322#ifdef NL80211_SUPPORT
15323 return wcn_wifi_test_config_set_u8(
15324 dut, intf,
15325 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
15326 ignore_sa_query_timeout);
15327#else /* NL80211_SUPPORT */
15328 sigma_dut_print(dut, DUT_MSG_ERROR,
15329 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
15330 return -1;
15331#endif /* NL80211_SUPPORT */
15332}
15333
15334
Jouni Malinen6250cb02020-04-15 13:54:45 +030015335static enum sigma_cmd_result
15336cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
15337 struct sigma_conn *conn,
15338 struct sigma_cmd *cmd)
15339{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015340 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030015341
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053015342 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030015343 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015344 if (wifi_chip_type == DRIVER_WCN) {
15345 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
15346 send_resp(dut, conn, SIGMA_ERROR,
15347 "errorCode,Failed to set ft_rsnxe_used");
15348 return STATUS_SENT_ERROR;
15349 }
15350 return SUCCESS_SEND_STATUS;
15351 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030015352 send_resp(dut, conn, SIGMA_ERROR,
15353 "errorCode,Failed to set ft_rsnxe_used");
15354 return STATUS_SENT_ERROR;
15355 }
15356 return SUCCESS_SEND_STATUS;
15357 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015358
15359 oci_chan = get_param(cmd, "OCIChannel");
15360 oci_frametype = get_param(cmd, "OCIFrameType");
15361 if (oci_chan && oci_frametype) {
15362 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
15363 char buf[100];
15364
15365 if (!oci_freq) {
15366 send_resp(dut, conn, SIGMA_ERROR,
15367 "errorCode,Invalid OCIChannel number");
15368 return STATUS_SENT_ERROR;
15369 }
15370
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015371 if (wifi_chip_type == DRIVER_WCN &&
15372 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
15373 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
15374 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
15375 if (wcn_sta_override_oci(dut, intf, oci_frametype,
15376 oci_freq)) {
15377 send_resp(dut, conn, SIGMA_ERROR,
15378 "errorCode,Failed to override OCI");
15379 return STATUS_SENT_ERROR;
15380 }
15381 return SUCCESS_SEND_STATUS;
15382 }
15383
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015384 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
15385 snprintf(buf, sizeof(buf),
15386 "SET oci_freq_override_eapol %d", oci_freq);
15387 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15388 snprintf(buf, sizeof(buf),
15389 "SET oci_freq_override_saquery_req %d",
15390 oci_freq);
15391 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15392 snprintf(buf, sizeof(buf),
15393 "SET oci_freq_override_saquery_resp %d",
15394 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015395 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
15396 snprintf(buf, sizeof(buf),
15397 "SET oci_freq_override_eapol_g2 %d",
15398 oci_freq);
15399 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15400 snprintf(buf, sizeof(buf),
15401 "SET oci_freq_override_ft_assoc %d",
15402 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015403 } else {
15404 send_resp(dut, conn, SIGMA_ERROR,
15405 "errorCode,Unsupported OCIFrameType");
15406 return STATUS_SENT_ERROR;
15407 }
15408 if (wpa_command(intf, buf) < 0) {
15409 send_resp(dut, conn, SIGMA_ERROR,
15410 "errorCode,Failed to set oci_freq_override");
15411 return STATUS_SENT_ERROR;
15412 }
15413 return SUCCESS_SEND_STATUS;
15414 }
15415
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015416 val = get_param(cmd, "IgnoreCSA");
15417 if (val && atoi(val) == 1) {
15418 if (wifi_chip_type == DRIVER_WCN) {
15419 if (wcn_sta_ignore_csa(dut, intf, 1)) {
15420 send_resp(dut, conn, SIGMA_ERROR,
15421 "errorCode,Failed to set ignore CSA");
15422 return STATUS_SENT_ERROR;
15423 }
15424 return SUCCESS_SEND_STATUS;
15425 }
15426 }
15427
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015428 val = get_param(cmd, "Deauth_Per_SAQueryResp");
15429 if (val && atoi(val) == 0) {
15430 if (wifi_chip_type == DRIVER_WCN) {
15431 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
15432 send_resp(dut, conn, SIGMA_ERROR,
15433 "errorCode,Failed to set ignore SA Query timeout");
15434 return STATUS_SENT_ERROR;
15435 }
15436 return SUCCESS_SEND_STATUS;
15437 }
15438 }
15439
Jouni Malinen6250cb02020-04-15 13:54:45 +030015440 send_resp(dut, conn, SIGMA_ERROR,
15441 "errorCode,Unsupported WPA3 rfeature");
15442 return STATUS_SENT_ERROR;
15443}
15444
15445
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015446static enum sigma_cmd_result
15447cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
15448 struct sigma_conn *conn, struct sigma_cmd *cmd)
15449{
15450 const char *val;
15451
15452 val = get_param(cmd, "DomainName_Domain");
15453 if (val) {
15454 if (strlen(val) >= sizeof(dut->qm_domain_name))
15455 return ERROR_SEND_STATUS;
15456
15457 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
15458 return SUCCESS_SEND_STATUS;
15459 }
15460
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053015461 val = get_param(cmd, "DSCPPolicy_PolicyID");
15462 if (val) {
15463 unsigned int i;
15464 int policy_id = atoi(val);
15465
15466 val = get_param(cmd, "DSCPPolicy_RequestType");
15467
15468 if (!policy_id || !val)
15469 return INVALID_SEND_STATUS;
15470
15471 if (dut->num_dscp_status >= ARRAY_SIZE(dut->dscp_status)) {
15472 send_resp(dut, conn, SIGMA_ERROR,
15473 "errorCode,DSCP status list full");
15474 return STATUS_SENT_ERROR;
15475 }
15476
15477 for (i = 0; i < dut->num_dscp_status; i++)
15478 if (dut->dscp_status[i].id == policy_id)
15479 break;
15480
15481 /* New policy configured */
15482 if (i == dut->num_dscp_status) {
15483 dut->dscp_status[i].id = policy_id;
15484 dut->num_dscp_status++;
15485 }
15486
15487 dut->dscp_status[i].status = strcasecmp(val, "Remove") ?
15488 DSCP_POLICY_SUCCESS : DSCP_POLICY_REJECT;
15489
15490 return SUCCESS_SEND_STATUS;
15491 }
15492
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015493 send_resp(dut, conn, SIGMA_ERROR,
15494 "errorCode,Unsupported QM rfeature");
15495 return STATUS_SENT_ERROR;
15496}
15497
15498
Jouni Malinenf7222712019-06-13 01:50:21 +030015499static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
15500 struct sigma_conn *conn,
15501 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015502{
15503 const char *intf = get_param(cmd, "Interface");
15504 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015505 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015506
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015507 if (!prog)
15508 prog = get_param(cmd, "Program");
15509
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015510 if (intf == NULL || prog == NULL)
15511 return -1;
15512
Ashwini Patil5acd7382017-04-13 15:55:04 +053015513 /* BSS Transition candidate list for BTM query */
15514 val = get_param(cmd, "Nebor_BSSID");
15515 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
15516 return 0;
15517
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015518 if (strcasecmp(prog, "TDLS") == 0)
15519 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
15520
15521 if (strcasecmp(prog, "VHT") == 0)
15522 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
15523
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015524 if (strcasecmp(prog, "HE") == 0)
15525 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
15526
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015527 if (strcasecmp(prog, "MBO") == 0) {
15528 val = get_param(cmd, "Cellular_Data_Cap");
15529 if (val &&
15530 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
15531 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053015532
15533 val = get_param(cmd, "Ch_Pref");
15534 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
15535 return 0;
15536
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015537 return 1;
15538 }
15539
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015540 if (strcasecmp(prog, "60GHz") == 0)
15541 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
15542
Jouni Malinen6250cb02020-04-15 13:54:45 +030015543 if (strcasecmp(prog, "WPA3") == 0)
15544 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015545 if (strcasecmp(prog, "QM") == 0)
15546 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030015547
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015548 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
15549 return 0;
15550}
15551
15552
Jouni Malinenf7222712019-06-13 01:50:21 +030015553static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
15554 struct sigma_conn *conn,
15555 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015556{
15557 const char *intf = get_param(cmd, "Interface");
15558 const char *mode = get_param(cmd, "Mode");
15559 int res;
15560
15561 if (intf == NULL || mode == NULL)
15562 return -1;
15563
15564 if (strcasecmp(mode, "On") == 0)
15565 res = wpa_command(intf, "SET radio_disabled 0");
15566 else if (strcasecmp(mode, "Off") == 0)
15567 res = wpa_command(intf, "SET radio_disabled 1");
15568 else
15569 return -1;
15570
15571 if (res) {
15572 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15573 "radio mode");
15574 return 0;
15575 }
15576
15577 return 1;
15578}
15579
15580
Jouni Malinenf7222712019-06-13 01:50:21 +030015581static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
15582 struct sigma_conn *conn,
15583 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015584{
15585 const char *intf = get_param(cmd, "Interface");
15586 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015587 const char *prog = get_param(cmd, "program");
15588 const char *powersave = get_param(cmd, "powersave");
15589 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015590
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015591 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015592 return -1;
15593
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015594 if (prog && strcasecmp(prog, "60GHz") == 0) {
15595 /*
15596 * The CAPI mode parameter does not exist in 60G
15597 * unscheduled PS.
15598 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080015599 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015600 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015601 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020015602 strcasecmp(prog, "HE") == 0) {
15603 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015604 } else {
15605 if (mode == NULL)
15606 return -1;
15607
15608 if (strcasecmp(mode, "On") == 0)
15609 res = set_ps(intf, dut, 1);
15610 else if (strcasecmp(mode, "Off") == 0)
15611 res = set_ps(intf, dut, 0);
15612 else
15613 return -1;
15614 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015615
15616 if (res) {
15617 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15618 "power save mode");
15619 return 0;
15620 }
15621
15622 return 1;
15623}
15624
15625
Jouni Malinenf7222712019-06-13 01:50:21 +030015626static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
15627 struct sigma_conn *conn,
15628 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015629{
15630 const char *intf = get_param(cmd, "Interface");
15631 const char *val, *bssid;
15632 int res;
15633 char *buf;
15634 size_t buf_len;
15635
15636 val = get_param(cmd, "BSSID_FILTER");
15637 if (val == NULL)
15638 return -1;
15639
15640 bssid = get_param(cmd, "BSSID_List");
15641 if (atoi(val) == 0 || bssid == NULL) {
15642 /* Disable BSSID filter */
15643 if (wpa_command(intf, "SET bssid_filter ")) {
15644 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
15645 "to disable BSSID filter");
15646 return 0;
15647 }
15648
15649 return 1;
15650 }
15651
15652 buf_len = 100 + strlen(bssid);
15653 buf = malloc(buf_len);
15654 if (buf == NULL)
15655 return -1;
15656
15657 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
15658 res = wpa_command(intf, buf);
15659 free(buf);
15660 if (res) {
15661 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
15662 "BSSID filter");
15663 return 0;
15664 }
15665
15666 return 1;
15667}
15668
15669
Jouni Malinenf7222712019-06-13 01:50:21 +030015670static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
15671 struct sigma_conn *conn,
15672 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015673{
15674 const char *intf = get_param(cmd, "Interface");
15675 const char *val;
15676
15677 /* TODO: ARP */
15678
15679 val = get_param(cmd, "HS2_CACHE_PROFILE");
15680 if (val && strcasecmp(val, "All") == 0)
15681 hs2_clear_credentials(intf);
15682
15683 return 1;
15684}
15685
15686
Jouni Malinenf7222712019-06-13 01:50:21 +030015687static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
15688 struct sigma_conn *conn,
15689 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015690{
15691 const char *intf = get_param(cmd, "Interface");
15692 const char *key_type = get_param(cmd, "KeyType");
15693 char buf[100], resp[200];
15694
15695 if (key_type == NULL)
15696 return -1;
15697
15698 if (strcasecmp(key_type, "GTK") == 0) {
15699 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
15700 strncmp(buf, "FAIL", 4) == 0) {
15701 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15702 "not fetch current GTK");
15703 return 0;
15704 }
15705 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
15706 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15707 return 0;
15708 } else {
15709 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
15710 "KeyType");
15711 return 0;
15712 }
15713
15714 return 1;
15715}
15716
15717
15718static int hs2_set_policy(struct sigma_dut *dut)
15719{
15720#ifdef ANDROID
15721 system("ip rule del prio 23000");
15722 if (system("ip rule add from all lookup main prio 23000") != 0) {
15723 sigma_dut_print(dut, DUT_MSG_ERROR,
15724 "Failed to run:ip rule add from all lookup main prio");
15725 return -1;
15726 }
15727 if (system("ip route flush cache") != 0) {
15728 sigma_dut_print(dut, DUT_MSG_ERROR,
15729 "Failed to run ip route flush cache");
15730 return -1;
15731 }
15732 return 1;
15733#else /* ANDROID */
15734 return 0;
15735#endif /* ANDROID */
15736}
15737
15738
Jouni Malinenf7222712019-06-13 01:50:21 +030015739static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
15740 struct sigma_conn *conn,
15741 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015742{
15743 const char *intf = get_param(cmd, "Interface");
15744 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030015745 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015746 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030015747 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015748 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
15749 int tries = 0;
15750 int ignore_blacklist = 0;
15751 const char *events[] = {
15752 "CTRL-EVENT-CONNECTED",
15753 "INTERWORKING-BLACKLISTED",
15754 "INTERWORKING-NO-MATCH",
15755 NULL
15756 };
15757
15758 start_sta_mode(dut);
15759
Jouni Malinen439352d2018-09-13 03:42:23 +030015760 if (band) {
15761 if (strcmp(band, "2.4") == 0) {
15762 wpa_command(intf, "SET setband 2G");
15763 } else if (strcmp(band, "5") == 0) {
15764 wpa_command(intf, "SET setband 5G");
15765 } else {
15766 send_resp(dut, conn, SIGMA_ERROR,
15767 "errorCode,Unsupported band");
15768 return 0;
15769 }
15770 }
15771
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015772 blacklisted[0] = '\0';
15773 if (val && atoi(val))
15774 ignore_blacklist = 1;
15775
15776try_again:
15777 ctrl = open_wpa_mon(intf);
15778 if (ctrl == NULL) {
15779 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15780 "wpa_supplicant monitor connection");
15781 return -2;
15782 }
15783
15784 tries++;
15785 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
15786 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
15787 "Interworking connection");
15788 wpa_ctrl_detach(ctrl);
15789 wpa_ctrl_close(ctrl);
15790 return 0;
15791 }
15792
15793 buf[0] = '\0';
15794 while (1) {
15795 char *pos;
15796 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15797 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
15798 if (!pos)
15799 break;
15800 pos += 25;
15801 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
15802 pos);
15803 if (!blacklisted[0])
15804 memcpy(blacklisted, pos, strlen(pos) + 1);
15805 }
15806
15807 if (ignore_blacklist && blacklisted[0]) {
15808 char *end;
15809 end = strchr(blacklisted, ' ');
15810 if (end)
15811 *end = '\0';
15812 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
15813 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030015814 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
15815 blacklisted);
15816 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015817 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
15818 wpa_ctrl_detach(ctrl);
15819 wpa_ctrl_close(ctrl);
15820 return 0;
15821 }
15822 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15823 buf, sizeof(buf));
15824 }
15825
15826 wpa_ctrl_detach(ctrl);
15827 wpa_ctrl_close(ctrl);
15828
15829 if (res < 0) {
15830 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15831 "connect");
15832 return 0;
15833 }
15834
15835 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
15836 strstr(buf, "INTERWORKING-BLACKLISTED")) {
15837 if (tries < 2) {
15838 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
15839 goto try_again;
15840 }
15841 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
15842 "matching credentials found");
15843 return 0;
15844 }
15845
15846 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15847 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15848 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15849 "get current BSSID/SSID");
15850 return 0;
15851 }
15852
15853 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
15854 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15855 hs2_set_policy(dut);
15856 return 0;
15857}
15858
15859
Jouni Malinenf7222712019-06-13 01:50:21 +030015860static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
15861 struct sigma_conn *conn,
15862 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015863{
15864 const char *intf = get_param(cmd, "Interface");
15865 const char *display = get_param(cmd, "Display");
15866 struct wpa_ctrl *ctrl;
15867 char buf[300], params[400], *pos;
15868 char bssid[20];
15869 int info_avail = 0;
15870 unsigned int old_timeout;
15871 int res;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015872 const char *events[] = { "RX-VENUE-URL", "ANQP-QUERY-DONE", NULL };
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015873
15874 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
15875 send_resp(dut, conn, SIGMA_ERROR,
15876 "ErrorCode,Could not get current BSSID");
15877 return 0;
15878 }
15879 ctrl = open_wpa_mon(intf);
15880 if (!ctrl) {
15881 sigma_dut_print(dut, DUT_MSG_ERROR,
15882 "Failed to open wpa_supplicant monitor connection");
15883 return -2;
15884 }
15885
15886 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
15887 wpa_command(intf, buf);
15888
15889 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
15890 if (res < 0) {
15891 send_resp(dut, conn, SIGMA_ERROR,
15892 "ErrorCode,Could not complete GAS query");
15893 goto fail;
15894 }
15895
15896 old_timeout = dut->default_timeout;
15897 dut->default_timeout = 2;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015898 for (;;) {
15899 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15900 if (res < 0)
15901 break;
15902 if (strstr(buf, "ANQP-QUERY-DONE") != NULL) {
15903 res = -1;
15904 break;
15905 }
15906 pos = strchr(buf, ' ');
15907 if (!pos)
15908 continue;
15909 pos++;
15910 pos = strchr(pos, ' ');
15911 if (!pos)
15912 continue;
15913 pos++;
15914
15915 if (strncmp(pos, "https://", 8) == 0)
15916 break;
15917
15918 sigma_dut_print(dut, DUT_MSG_DEBUG,
15919 "Ignore non-HTTPS venue URL: %s", pos);
15920 }
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015921 dut->default_timeout = old_timeout;
15922 if (res < 0)
15923 goto done;
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015924 info_avail = 1;
15925 snprintf(params, sizeof(params), "browser %s", pos);
15926
15927 if (display && strcasecmp(display, "Yes") == 0) {
15928 pid_t pid;
15929
15930 pid = fork();
15931 if (pid < 0) {
15932 perror("fork");
15933 return -1;
15934 }
15935
15936 if (pid == 0) {
15937 run_hs20_osu(dut, params);
15938 exit(0);
15939 }
15940 }
15941
15942done:
15943 snprintf(buf, sizeof(buf), "Info_available,%s",
15944 info_avail ? "Yes" : "No");
15945 send_resp(dut, conn, SIGMA_COMPLETE, buf);
15946fail:
15947 wpa_ctrl_detach(ctrl);
15948 wpa_ctrl_close(ctrl);
15949 return 0;
15950}
15951
15952
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015953static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
15954 struct sigma_conn *conn,
15955 const char *ifname,
15956 struct sigma_cmd *cmd)
15957{
15958 const char *val;
15959 int id;
15960
15961 id = add_cred(ifname);
15962 if (id < 0)
15963 return -2;
15964 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15965
15966 val = get_param(cmd, "prefer");
15967 if (val && atoi(val) > 0)
15968 set_cred(ifname, id, "priority", "1");
15969
15970 val = get_param(cmd, "REALM");
15971 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
15972 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15973 "realm");
15974 return 0;
15975 }
15976
15977 val = get_param(cmd, "HOME_FQDN");
15978 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
15979 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15980 "home_fqdn");
15981 return 0;
15982 }
15983
15984 val = get_param(cmd, "Username");
15985 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
15986 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15987 "username");
15988 return 0;
15989 }
15990
15991 val = get_param(cmd, "Password");
15992 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
15993 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15994 "password");
15995 return 0;
15996 }
15997
15998 val = get_param(cmd, "ROOT_CA");
15999 if (val) {
16000 char fname[200];
16001 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16002#ifdef __linux__
16003 if (!file_exists(fname)) {
16004 char msg[300];
16005 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16006 "file (%s) not found", fname);
16007 send_resp(dut, conn, SIGMA_ERROR, msg);
16008 return 0;
16009 }
16010#endif /* __linux__ */
16011 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16012 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16013 "not set root CA");
16014 return 0;
16015 }
16016 }
16017
16018 return 1;
16019}
16020
16021
16022static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
16023{
16024 FILE *in, *out;
16025 char buf[500];
16026 int found = 0;
16027
16028 in = fopen("devdetail.xml", "r");
16029 if (in == NULL)
16030 return -1;
16031 out = fopen("devdetail.xml.tmp", "w");
16032 if (out == NULL) {
16033 fclose(in);
16034 return -1;
16035 }
16036
16037 while (fgets(buf, sizeof(buf), in)) {
16038 char *pos = strstr(buf, "<IMSI>");
16039 if (pos) {
16040 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
16041 imsi);
16042 pos += 6;
16043 *pos = '\0';
16044 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
16045 found++;
16046 } else {
16047 fprintf(out, "%s", buf);
16048 }
16049 }
16050
16051 fclose(out);
16052 fclose(in);
16053 if (found)
16054 rename("devdetail.xml.tmp", "devdetail.xml");
16055 else
16056 unlink("devdetail.xml.tmp");
16057
16058 return 0;
16059}
16060
16061
16062static int sta_add_credential_sim(struct sigma_dut *dut,
16063 struct sigma_conn *conn,
16064 const char *ifname, struct sigma_cmd *cmd)
16065{
16066 const char *val, *imsi = NULL;
16067 int id;
16068 char buf[200];
16069 int res;
16070 const char *pos;
16071 size_t mnc_len;
16072 char plmn_mcc[4];
16073 char plmn_mnc[4];
16074
16075 id = add_cred(ifname);
16076 if (id < 0)
16077 return -2;
16078 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16079
16080 val = get_param(cmd, "prefer");
16081 if (val && atoi(val) > 0)
16082 set_cred(ifname, id, "priority", "1");
16083
16084 val = get_param(cmd, "PLMN_MCC");
16085 if (val == NULL) {
16086 send_resp(dut, conn, SIGMA_ERROR,
16087 "errorCode,Missing PLMN_MCC");
16088 return 0;
16089 }
16090 if (strlen(val) != 3) {
16091 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
16092 return 0;
16093 }
16094 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
16095
16096 val = get_param(cmd, "PLMN_MNC");
16097 if (val == NULL) {
16098 send_resp(dut, conn, SIGMA_ERROR,
16099 "errorCode,Missing PLMN_MNC");
16100 return 0;
16101 }
16102 if (strlen(val) != 2 && strlen(val) != 3) {
16103 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
16104 return 0;
16105 }
16106 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
16107
16108 val = get_param(cmd, "IMSI");
16109 if (val == NULL) {
16110 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
16111 "IMSI");
16112 return 0;
16113 }
16114
16115 imsi = pos = val;
16116
16117 if (strncmp(plmn_mcc, pos, 3) != 0) {
16118 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
16119 return 0;
16120 }
16121 pos += 3;
16122
16123 mnc_len = strlen(plmn_mnc);
16124 if (mnc_len < 2) {
16125 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
16126 return 0;
16127 }
16128
16129 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
16130 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
16131 return 0;
16132 }
16133 pos += mnc_len;
16134
16135 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
16136 if (res < 0 || res >= (int) sizeof(buf))
16137 return -1;
16138 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
16139 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16140 "not set IMSI");
16141 return 0;
16142 }
16143
16144 val = get_param(cmd, "Password");
16145 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
16146 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16147 "not set password");
16148 return 0;
16149 }
16150
Jouni Malinen9a742ff2022-01-27 00:43:14 +020016151 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
16152 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016153 /*
16154 * Set provisioning_sp for the test cases where SIM/USIM
16155 * provisioning is used.
16156 */
16157 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
16158 "wi-fi.org") < 0) {
16159 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16160 "not set provisioning_sp");
16161 return 0;
16162 }
16163
16164 update_devdetail_imsi(dut, imsi);
16165 }
16166
16167 return 1;
16168}
16169
16170
16171static int sta_add_credential_cert(struct sigma_dut *dut,
16172 struct sigma_conn *conn,
16173 const char *ifname,
16174 struct sigma_cmd *cmd)
16175{
16176 const char *val;
16177 int id;
16178
16179 id = add_cred(ifname);
16180 if (id < 0)
16181 return -2;
16182 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16183
16184 val = get_param(cmd, "prefer");
16185 if (val && atoi(val) > 0)
16186 set_cred(ifname, id, "priority", "1");
16187
16188 val = get_param(cmd, "REALM");
16189 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
16190 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16191 "realm");
16192 return 0;
16193 }
16194
16195 val = get_param(cmd, "HOME_FQDN");
16196 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
16197 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16198 "home_fqdn");
16199 return 0;
16200 }
16201
16202 val = get_param(cmd, "Username");
16203 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
16204 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16205 "username");
16206 return 0;
16207 }
16208
16209 val = get_param(cmd, "clientCertificate");
16210 if (val) {
16211 char fname[200];
16212 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16213#ifdef __linux__
16214 if (!file_exists(fname)) {
16215 char msg[300];
16216 snprintf(msg, sizeof(msg),
16217 "ErrorCode,clientCertificate "
16218 "file (%s) not found", fname);
16219 send_resp(dut, conn, SIGMA_ERROR, msg);
16220 return 0;
16221 }
16222#endif /* __linux__ */
16223 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
16224 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16225 "not set client_cert");
16226 return 0;
16227 }
16228 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
16229 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16230 "not set private_key");
16231 return 0;
16232 }
16233 }
16234
16235 val = get_param(cmd, "ROOT_CA");
16236 if (val) {
16237 char fname[200];
16238 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16239#ifdef __linux__
16240 if (!file_exists(fname)) {
16241 char msg[300];
16242 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16243 "file (%s) not found", fname);
16244 send_resp(dut, conn, SIGMA_ERROR, msg);
16245 return 0;
16246 }
16247#endif /* __linux__ */
16248 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16249 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16250 "not set root CA");
16251 return 0;
16252 }
16253 }
16254
16255 return 1;
16256}
16257
16258
Jouni Malinenf7222712019-06-13 01:50:21 +030016259static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
16260 struct sigma_conn *conn,
16261 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016262{
16263 const char *intf = get_param(cmd, "Interface");
16264 const char *type;
16265
16266 start_sta_mode(dut);
16267
16268 type = get_param(cmd, "Type");
16269 if (!type)
16270 return -1;
16271
16272 if (strcasecmp(type, "uname_pwd") == 0)
16273 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
16274
16275 if (strcasecmp(type, "sim") == 0)
16276 return sta_add_credential_sim(dut, conn, intf, cmd);
16277
16278 if (strcasecmp(type, "cert") == 0)
16279 return sta_add_credential_cert(dut, conn, intf, cmd);
16280
16281 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
16282 "type");
16283 return 0;
16284}
16285
16286
Jouni Malinenf7222712019-06-13 01:50:21 +030016287static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
16288 struct sigma_conn *conn,
16289 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016290{
16291 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016292 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070016293 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053016294 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016295 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016296 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016297 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016298 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016299
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020016300 start_sta_mode(dut);
16301
Arif Hussain66a4af02019-02-07 15:04:51 -080016302 val = get_param(cmd, "GetParameter");
16303 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016304 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080016305 buf, sizeof(buf)) < 0) {
16306 sigma_dut_print(dut, DUT_MSG_ERROR,
16307 "Could not get ssid bssid");
16308 return ERROR_SEND_STATUS;
16309 }
16310
16311 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
16312 send_resp(dut, conn, SIGMA_COMPLETE, buf);
16313 return STATUS_SENT;
16314 }
16315
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016316 val = get_param(cmd, "HESSID");
16317 if (val) {
16318 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
16319 if (res < 0 || res >= (int) sizeof(buf))
16320 return -1;
16321 wpa_command(intf, buf);
16322 }
16323
16324 val = get_param(cmd, "ACCS_NET_TYPE");
16325 if (val) {
16326 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
16327 val);
16328 if (res < 0 || res >= (int) sizeof(buf))
16329 return -1;
16330 wpa_command(intf, buf);
16331 }
16332
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016333 if (get_param(cmd, "RxMac"))
16334 sta_set_scan_unicast_probe(dut, intf, 1);
16335
vamsi krishna89ad8c62017-09-19 12:51:18 +053016336 bssid = get_param(cmd, "Bssid");
16337 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016338 if (!bssid)
16339 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053016340
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016341 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
16342 dut->device_type == STA_testbed) {
16343 ssid = NULL;
16344 wildcard_ssid = 1;
16345 }
16346
vamsi krishna89ad8c62017-09-19 12:51:18 +053016347 if (ssid) {
16348 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
16349 send_resp(dut, conn, SIGMA_ERROR,
16350 "ErrorCode,Too long SSID");
16351 return 0;
16352 }
16353 ascii2hexstr(ssid, ssid_hex);
16354 }
16355
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016356 short_ssid = get_param(cmd, "ShortSSID");
16357 if (short_ssid) {
16358 uint32_t short_ssid_hex;
16359
16360 short_ssid_hex = strtoul(short_ssid, NULL, 16);
16361 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
16362 (((short_ssid_hex >> 8) & 0xFF) << 16) |
16363 (((short_ssid_hex >> 16) & 0xFF) << 8) |
16364 ((short_ssid_hex >> 24) & 0xFF);
16365
16366 res = snprintf(buf, sizeof(buf),
16367 "VENDOR_ELEM_ADD 14 ff053a%08x",
16368 short_ssid_hex);
16369 if (res < 0 || res >= (int) sizeof(buf) ||
16370 wpa_command(intf, buf)) {
16371 send_resp(dut, conn, SIGMA_ERROR,
16372 "errorCode,Failed to add short SSID");
16373 return STATUS_SENT_ERROR;
16374 }
16375 }
16376
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016377 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053016378 if (scan_freq) {
16379 if (strcasecmp(scan_freq, "2G") == 0)
16380 scan_freq = "2412-2462";
16381 else if (strcasecmp(scan_freq, "5G") == 0)
16382 scan_freq = "5180-5925";
16383 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016384
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016385 val = get_param(cmd, "WaitCompletion");
16386 if (val && atoi(val) == 1) {
16387 ctrl = open_wpa_mon(intf);
16388 if (!ctrl) {
16389 send_resp(dut, conn, SIGMA_ERROR,
16390 "errorCode,Failed to open monitor socket");
16391 return STATUS_SENT_ERROR;
16392 }
16393 }
16394
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016395 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053016396 bssid ? " bssid=": "",
16397 bssid ? bssid : "",
16398 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016399 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016400 wildcard_ssid ? " wildcard_ssid=1" : "",
16401 scan_freq ? " freq=" : "",
16402 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016403 if (res < 0 || res >= (int) sizeof(buf)) {
16404 send_resp(dut, conn, SIGMA_ERROR,
16405 "errorCode,Could not build scan command");
16406 status = STATUS_SENT_ERROR;
16407 goto remove_s_ssid;
16408 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053016409
Veerendranathdc581b52020-08-10 03:29:08 -070016410 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
16411 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
16412 sigma_dut_print(dut, DUT_MSG_DEBUG,
16413 "Scan request rejected with busy status, abort ongoing scan and try again");
16414 wpa_command(intf, "ABORT_SCAN");
16415 res = wpa_command(intf, buf);
16416 }
16417
16418 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016419 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
16420 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016421 status = STATUS_SENT_ERROR;
16422 } else {
16423 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016424 }
16425
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016426remove_s_ssid:
16427 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
16428 sigma_dut_print(dut, DUT_MSG_ERROR,
16429 "Failed to delete vendor element");
16430
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016431 if (ctrl) {
16432 if (status == SUCCESS_SEND_STATUS) {
16433 res = get_wpa_cli_event(dut, ctrl,
16434 "CTRL-EVENT-SCAN-RESULTS",
16435 buf, sizeof(buf));
16436 if (res < 0) {
16437 send_resp(dut, conn, SIGMA_ERROR,
16438 "ErrorCode,scan did not complete");
16439 status = STATUS_SENT_ERROR;
16440 }
16441 }
16442
16443 wpa_ctrl_detach(ctrl);
16444 wpa_ctrl_close(ctrl);
16445 }
16446
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016447 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016448}
16449
16450
Jouni Malinenf7222712019-06-13 01:50:21 +030016451static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
16452 struct sigma_conn *conn,
16453 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016454{
16455 const char *intf = get_param(cmd, "Interface");
16456 const char *bssid;
16457 char buf[4096], *pos;
16458 int freq, chan;
16459 char *ssid;
16460 char resp[100];
16461 int res;
16462 struct wpa_ctrl *ctrl;
16463
16464 bssid = get_param(cmd, "BSSID");
16465 if (!bssid) {
16466 send_resp(dut, conn, SIGMA_INVALID,
16467 "errorCode,BSSID argument is missing");
16468 return 0;
16469 }
16470
16471 ctrl = open_wpa_mon(intf);
16472 if (!ctrl) {
16473 sigma_dut_print(dut, DUT_MSG_ERROR,
16474 "Failed to open wpa_supplicant monitor connection");
16475 return -1;
16476 }
16477
16478 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
16479 send_resp(dut, conn, SIGMA_ERROR,
16480 "errorCode,Could not start scan");
16481 wpa_ctrl_detach(ctrl);
16482 wpa_ctrl_close(ctrl);
16483 return 0;
16484 }
16485
16486 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
16487 buf, sizeof(buf));
16488
16489 wpa_ctrl_detach(ctrl);
16490 wpa_ctrl_close(ctrl);
16491
16492 if (res < 0) {
16493 send_resp(dut, conn, SIGMA_ERROR,
16494 "errorCode,Scan did not complete");
16495 return 0;
16496 }
16497
16498 snprintf(buf, sizeof(buf), "BSS %s", bssid);
16499 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
16500 strncmp(buf, "id=", 3) != 0) {
16501 send_resp(dut, conn, SIGMA_ERROR,
16502 "errorCode,Specified BSSID not found");
16503 return 0;
16504 }
16505
16506 pos = strstr(buf, "\nfreq=");
16507 if (!pos) {
16508 send_resp(dut, conn, SIGMA_ERROR,
16509 "errorCode,Channel not found");
16510 return 0;
16511 }
16512 freq = atoi(pos + 6);
16513 chan = freq_to_channel(freq);
16514
16515 pos = strstr(buf, "\nssid=");
16516 if (!pos) {
16517 send_resp(dut, conn, SIGMA_ERROR,
16518 "errorCode,SSID not found");
16519 return 0;
16520 }
16521 ssid = pos + 6;
16522 pos = strchr(ssid, '\n');
16523 if (pos)
16524 *pos = '\0';
16525 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
16526 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16527 return 0;
16528}
16529
16530
Jouni Malinenf7222712019-06-13 01:50:21 +030016531static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
16532 struct sigma_conn *conn,
16533 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016534{
16535#ifdef __linux__
16536 struct timeval tv;
16537 struct tm tm;
16538 time_t t;
16539 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016540 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016541
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016542 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016543
16544 memset(&tm, 0, sizeof(tm));
16545 val = get_param(cmd, "seconds");
16546 if (val)
16547 tm.tm_sec = atoi(val);
16548 val = get_param(cmd, "minutes");
16549 if (val)
16550 tm.tm_min = atoi(val);
16551 val = get_param(cmd, "hours");
16552 if (val)
16553 tm.tm_hour = atoi(val);
16554 val = get_param(cmd, "date");
16555 if (val)
16556 tm.tm_mday = atoi(val);
16557 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016558 if (val) {
16559 v = atoi(val);
16560 if (v < 1 || v > 12) {
16561 send_resp(dut, conn, SIGMA_INVALID,
16562 "errorCode,Invalid month");
16563 return 0;
16564 }
16565 tm.tm_mon = v - 1;
16566 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016567 val = get_param(cmd, "year");
16568 if (val) {
16569 int year = atoi(val);
16570#ifdef ANDROID
16571 if (year > 2035)
16572 year = 2035; /* years beyond 2035 not supported */
16573#endif /* ANDROID */
16574 tm.tm_year = year - 1900;
16575 }
16576 t = mktime(&tm);
16577 if (t == (time_t) -1) {
16578 send_resp(dut, conn, SIGMA_ERROR,
16579 "errorCode,Invalid date or time");
16580 return 0;
16581 }
16582
16583 memset(&tv, 0, sizeof(tv));
16584 tv.tv_sec = t;
16585
16586 if (settimeofday(&tv, NULL) < 0) {
16587 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
16588 strerror(errno));
16589 send_resp(dut, conn, SIGMA_ERROR,
16590 "errorCode,Failed to set time");
16591 return 0;
16592 }
16593
16594 return 1;
16595#endif /* __linux__ */
16596
16597 return -1;
16598}
16599
16600
Jouni Malinenf7222712019-06-13 01:50:21 +030016601static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
16602 struct sigma_conn *conn,
16603 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016604{
16605 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016606 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016607 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016608 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016609 int res;
16610 struct wpa_ctrl *ctrl;
16611
16612 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016613 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016614
16615 val = get_param(cmd, "ProdESSAssoc");
16616 if (val)
16617 prod_ess_assoc = atoi(val);
16618
16619 kill_dhcp_client(dut, intf);
16620 if (start_dhcp_client(dut, intf) < 0)
16621 return -2;
16622
16623 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
16624 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16625 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016626 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016627 prod_ess_assoc ? "" : "-N",
16628 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016629 name ? "'" : "",
16630 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
16631 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016632
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053016633 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016634 if (run_hs20_osu(dut, buf) < 0) {
16635 FILE *f;
16636
16637 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
16638
16639 f = fopen("hs20-osu-client.res", "r");
16640 if (f) {
16641 char resp[400], res[300], *pos;
16642 if (!fgets(res, sizeof(res), f))
16643 res[0] = '\0';
16644 pos = strchr(res, '\n');
16645 if (pos)
16646 *pos = '\0';
16647 fclose(f);
16648 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
16649 res);
16650 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
16651 if (system(resp) != 0) {
16652 }
16653 snprintf(resp, sizeof(resp),
16654 "SSID,,BSSID,,failureReason,%s", res);
16655 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16656 return 0;
16657 }
16658
16659 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16660 return 0;
16661 }
16662
16663 if (!prod_ess_assoc)
16664 goto report;
16665
16666 ctrl = open_wpa_mon(intf);
16667 if (ctrl == NULL) {
16668 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16669 "wpa_supplicant monitor connection");
16670 return -1;
16671 }
16672
16673 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
16674 buf, sizeof(buf));
16675
16676 wpa_ctrl_detach(ctrl);
16677 wpa_ctrl_close(ctrl);
16678
16679 if (res < 0) {
16680 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
16681 "network after OSU");
16682 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16683 return 0;
16684 }
16685
16686report:
16687 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
16688 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
16689 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
16690 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16691 return 0;
16692 }
16693
16694 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
16695 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016696 return 0;
16697}
16698
16699
Jouni Malinenf7222712019-06-13 01:50:21 +030016700static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
16701 struct sigma_conn *conn,
16702 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016703{
16704 const char *val;
16705 int timeout = 120;
16706
16707 val = get_param(cmd, "PolicyUpdate");
16708 if (val == NULL || atoi(val) == 0)
16709 return 1; /* No operation requested */
16710
16711 val = get_param(cmd, "Timeout");
16712 if (val)
16713 timeout = atoi(val);
16714
16715 if (timeout) {
16716 /* TODO: time out the command and return
16717 * PolicyUpdateStatus,TIMEOUT if needed. */
16718 }
16719
16720 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
16721 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16722 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
16723 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
16724 return 0;
16725 }
16726
16727 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
16728 return 0;
16729}
16730
16731
Jouni Malinenf7222712019-06-13 01:50:21 +030016732static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
16733 struct sigma_conn *conn,
16734 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016735{
16736 struct wpa_ctrl *ctrl;
16737 const char *intf = get_param(cmd, "Interface");
16738 const char *bssid = get_param(cmd, "Bssid");
16739 const char *ssid = get_param(cmd, "SSID");
16740 const char *security = get_param(cmd, "Security");
16741 const char *passphrase = get_param(cmd, "Passphrase");
16742 const char *pin = get_param(cmd, "PIN");
16743 char buf[1000];
16744 char ssid_hex[200], passphrase_hex[200];
16745 const char *keymgmt, *cipher;
16746
16747 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016748 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016749
16750 if (!bssid) {
16751 send_resp(dut, conn, SIGMA_ERROR,
16752 "ErrorCode,Missing Bssid argument");
16753 return 0;
16754 }
16755
16756 if (!ssid) {
16757 send_resp(dut, conn, SIGMA_ERROR,
16758 "ErrorCode,Missing SSID argument");
16759 return 0;
16760 }
16761
16762 if (!security) {
16763 send_resp(dut, conn, SIGMA_ERROR,
16764 "ErrorCode,Missing Security argument");
16765 return 0;
16766 }
16767
16768 if (!passphrase) {
16769 send_resp(dut, conn, SIGMA_ERROR,
16770 "ErrorCode,Missing Passphrase argument");
16771 return 0;
16772 }
16773
16774 if (!pin) {
16775 send_resp(dut, conn, SIGMA_ERROR,
16776 "ErrorCode,Missing PIN argument");
16777 return 0;
16778 }
16779
vamsi krishna8c9c1562017-05-12 15:51:46 +053016780 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
16781 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016782 send_resp(dut, conn, SIGMA_ERROR,
16783 "ErrorCode,Too long SSID/passphrase");
16784 return 0;
16785 }
16786
16787 ctrl = open_wpa_mon(intf);
16788 if (ctrl == NULL) {
16789 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16790 "wpa_supplicant monitor connection");
16791 return -2;
16792 }
16793
16794 if (strcasecmp(security, "wpa2-psk") == 0) {
16795 keymgmt = "WPA2PSK";
16796 cipher = "CCMP";
16797 } else {
16798 wpa_ctrl_detach(ctrl);
16799 wpa_ctrl_close(ctrl);
16800 send_resp(dut, conn, SIGMA_ERROR,
16801 "ErrorCode,Unsupported Security value");
16802 return 0;
16803 }
16804
16805 ascii2hexstr(ssid, ssid_hex);
16806 ascii2hexstr(passphrase, passphrase_hex);
16807 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
16808 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
16809
16810 if (wpa_command(intf, buf) < 0) {
16811 wpa_ctrl_detach(ctrl);
16812 wpa_ctrl_close(ctrl);
16813 send_resp(dut, conn, SIGMA_ERROR,
16814 "ErrorCode,Failed to start registrar");
16815 return 0;
16816 }
16817
16818 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
16819 dut->er_oper_performed = 1;
16820
16821 return wps_connection_event(dut, conn, ctrl, intf, 0);
16822}
16823
16824
Jouni Malinenf7222712019-06-13 01:50:21 +030016825static enum sigma_cmd_result
16826cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
16827 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016828{
16829 struct wpa_ctrl *ctrl;
16830 const char *intf = get_param(cmd, "Interface");
16831 const char *bssid = get_param(cmd, "Bssid");
16832 char buf[100];
16833
16834 if (!bssid) {
16835 send_resp(dut, conn, SIGMA_ERROR,
16836 "ErrorCode,Missing Bssid argument");
16837 return 0;
16838 }
16839
16840 ctrl = open_wpa_mon(intf);
16841 if (ctrl == NULL) {
16842 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16843 "wpa_supplicant monitor connection");
16844 return -2;
16845 }
16846
16847 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
16848
16849 if (wpa_command(intf, buf) < 0) {
16850 wpa_ctrl_detach(ctrl);
16851 wpa_ctrl_close(ctrl);
16852 send_resp(dut, conn, SIGMA_ERROR,
16853 "ErrorCode,Failed to start registrar");
16854 return 0;
16855 }
16856
16857 return wps_connection_event(dut, conn, ctrl, intf, 0);
16858}
16859
16860
Jouni Malinenf7222712019-06-13 01:50:21 +030016861static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
16862 struct sigma_conn *conn,
16863 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053016864{
16865 struct wpa_ctrl *ctrl;
16866 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016867 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016868 const char *config_method = get_param(cmd, "WPSConfigMethod");
16869 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053016870 int res;
16871 char buf[256];
16872 const char *events[] = {
16873 "CTRL-EVENT-CONNECTED",
16874 "WPS-OVERLAP-DETECTED",
16875 "WPS-TIMEOUT",
16876 "WPS-FAIL",
16877 NULL
16878 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016879 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053016880
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016881 /* 60G WPS tests do not pass Interface parameter */
16882 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016883 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016884
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016885 if (dut->mode == SIGMA_MODE_AP)
16886 return ap_wps_registration(dut, conn, cmd);
16887
16888 if (config_method) {
16889 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
16890 * sta_wps_enter_pin before calling start_wps_registration. */
16891 if (strcasecmp(config_method, "PBC") == 0)
16892 dut->wps_method = WFA_CS_WPS_PBC;
16893 }
16894 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
16895 send_resp(dut, conn, SIGMA_ERROR,
16896 "ErrorCode,WPS parameters not yet set");
16897 return STATUS_SENT;
16898 }
16899
16900 /* Make sure WPS is enabled (also for STA mode) */
16901 dut->wps_disable = 0;
16902
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016903 if (dut->band == WPS_BAND_60G && network_mode &&
16904 strcasecmp(network_mode, "PBSS") == 0) {
16905 sigma_dut_print(dut, DUT_MSG_DEBUG,
16906 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016907 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016908 return -2;
16909 }
16910
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016911 if (dut->force_rsn_ie) {
16912 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
16913 dut->force_rsn_ie);
16914 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
16915 sigma_dut_print(dut, DUT_MSG_INFO,
16916 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020016917 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016918 }
16919 }
16920
vamsi krishna9b144002017-09-20 13:28:13 +053016921 ctrl = open_wpa_mon(intf);
16922 if (!ctrl) {
16923 sigma_dut_print(dut, DUT_MSG_ERROR,
16924 "Failed to open wpa_supplicant monitor connection");
16925 return -2;
16926 }
16927
16928 role = get_param(cmd, "WpsRole");
16929 if (!role) {
16930 send_resp(dut, conn, SIGMA_INVALID,
16931 "ErrorCode,WpsRole not provided");
16932 goto fail;
16933 }
16934
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016935 if (strcasecmp(role, "Enrollee") != 0) {
16936 /* Registrar role for STA not supported */
16937 send_resp(dut, conn, SIGMA_ERROR,
16938 "ErrorCode,Unsupported WpsRole value");
16939 goto fail;
16940 }
16941
16942 if (is_60g_sigma_dut(dut)) {
16943 if (dut->wps_method == WFA_CS_WPS_PBC)
16944 snprintf(buf, sizeof(buf), "WPS_PBC");
16945 else /* WFA_CS_WPS_PIN_KEYPAD */
16946 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
16947 dut->wps_pin);
16948 if (wpa_command(intf, buf) < 0) {
16949 send_resp(dut, conn, SIGMA_ERROR,
16950 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053016951 goto fail;
16952 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016953 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16954 if (res < 0) {
16955 send_resp(dut, conn, SIGMA_ERROR,
16956 "ErrorCode,WPS connection did not complete");
16957 goto fail;
16958 }
16959 if (strstr(buf, "WPS-TIMEOUT")) {
16960 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
16961 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16962 send_resp(dut, conn, SIGMA_COMPLETE,
16963 "WpsState,OverlapSession");
16964 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16965 send_resp(dut, conn, SIGMA_COMPLETE,
16966 "WpsState,Successful");
16967 } else {
16968 send_resp(dut, conn, SIGMA_COMPLETE,
16969 "WpsState,Failure");
16970 }
16971 } else {
16972 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053016973 if (wpa_command(intf, "WPS_PBC") < 0) {
16974 send_resp(dut, conn, SIGMA_ERROR,
16975 "ErrorCode,Failed to enable PBC");
16976 goto fail;
16977 }
16978 } else {
16979 /* TODO: PIN method */
16980 send_resp(dut, conn, SIGMA_ERROR,
16981 "ErrorCode,Unsupported WpsConfigMethod value");
16982 goto fail;
16983 }
16984 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16985 if (res < 0) {
16986 send_resp(dut, conn, SIGMA_ERROR,
16987 "ErrorCode,WPS connection did not complete");
16988 goto fail;
16989 }
16990 if (strstr(buf, "WPS-TIMEOUT")) {
16991 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
16992 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16993 send_resp(dut, conn, SIGMA_ERROR,
16994 "ErrorCode,OverlapSession");
16995 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16996 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
16997 } else {
16998 send_resp(dut, conn, SIGMA_ERROR,
16999 "ErrorCode,WPS operation failed");
17000 }
vamsi krishna9b144002017-09-20 13:28:13 +053017001 }
17002
17003fail:
17004 wpa_ctrl_detach(ctrl);
17005 wpa_ctrl_close(ctrl);
17006 return 0;
17007}
17008
17009
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017010static int req_intf(struct sigma_cmd *cmd)
17011{
17012 return get_param(cmd, "interface") == NULL ? -1 : 0;
17013}
17014
17015
17016void sta_register_cmds(void)
17017{
17018 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
17019 cmd_sta_get_ip_config);
17020 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
17021 cmd_sta_set_ip_config);
17022 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
17023 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
17024 cmd_sta_get_mac_address);
17025 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
17026 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
17027 cmd_sta_verify_ip_connection);
17028 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
17029 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
17030 cmd_sta_set_encryption);
17031 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
17032 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
17033 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
17034 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
17035 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
17036 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
17037 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
17038 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
17039 cmd_sta_set_eapakaprime);
17040 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
17041 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
17042 /* TODO: sta_set_ibss */
17043 /* TODO: sta_set_mode */
17044 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
17045 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
17046 /* TODO: sta_up_load */
17047 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
17048 cmd_sta_preset_testparameters);
17049 /* TODO: sta_set_system */
17050 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
17051 /* TODO: sta_set_rifs_test */
17052 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
17053 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
17054 /* TODO: sta_send_coexist_mgmt */
17055 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
17056 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
17057 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
17058 sigma_dut_reg_cmd("sta_reset_default", req_intf,
17059 cmd_sta_reset_default);
17060 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
17061 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
17062 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
17063 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
17064 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020017065 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017066 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
17067 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
17068 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
17069 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
17070 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030017071 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
17072 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017073 sigma_dut_reg_cmd("sta_add_credential", req_intf,
17074 cmd_sta_add_credential);
17075 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020017076 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017077 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
17078 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
17079 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
17080 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
17081 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
17082 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030017083 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017084 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
17085 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020017086 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053017087 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017088}