blob: bb1f570dd21518bb490b4c781e54d0e509a5b4b4 [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 Malinen29a63f42022-04-13 22:08:47 +03009447 dpp_mdns_stop(dut);
Jouni Malinend86e5822017-08-29 03:55:32 +03009448
Jouni Malinenfac9cad2017-10-10 18:35:55 +03009449 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
9450
vamsi krishnaa2799492017-12-05 14:28:01 +05309451 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309452 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05309453 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05309454 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
9455 dut->fils_hlp = 0;
9456#ifdef ANDROID
9457 hlp_thread_cleanup(dut);
9458#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05309459 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309460
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309461 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309462 wpa_command(intf, "SET interworking 1");
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309463 wpa_command(intf, "SET enable_dscp_policy_capa 1");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05309464 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309465 dut->reject_dscp_policies = 0;
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +05309466 dut->num_dscp_status = 0;
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309467 snprintf(buf, sizeof(buf),
9468 "ip -6 route replace fe80::/64 dev %s table local",
9469 intf);
9470 if (system(buf) != 0)
9471 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
9472 buf);
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05309473
9474 stop_dscp_policy_mon_thread(dut);
9475 clear_all_dscp_policies(dut);
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309476 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309477
Jouni Malinen8179fee2019-03-28 03:19:47 +02009478 dut->akm_values = 0;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05309479
9480#ifdef NL80211_SUPPORT
9481 if (get_driver_type(dut) == DRIVER_WCN)
9482 sta_config_params(dut, intf, STA_SET_FT_DS, 0);
9483#endif /* NL80211_SUPPORT */
9484
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03009485 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02009486
Sunil Dutt076081f2018-02-05 19:45:50 +05309487#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009488 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05309489 dut->config_rsnie == 1) {
9490 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309491 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05309492 }
9493#endif /* NL80211_SUPPORT */
9494
Sunil Duttfebf8a82018-02-09 18:50:13 +05309495 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
9496 dut->dev_role = DEVROLE_STA_CFON;
9497 return sta_cfon_reset_default(dut, conn, cmd);
9498 }
9499
Jouni Malinen439352d2018-09-13 03:42:23 +03009500 wpa_command(intf, "SET setband AUTO");
9501
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309502 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
9503 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
9504
9505 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
9506 sizeof(resp));
9507 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
9508
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309509 if (sta_set_client_privacy(dut, conn, intf,
9510 dut->program == PROGRAM_WPA3 &&
9511 dut->device_type == STA_dut &&
9512 dut->client_privacy_default)) {
9513 sigma_dut_print(dut, DUT_MSG_ERROR,
9514 "Failed to set client privacy functionality");
9515 /* sta_reset_default command is not really supposed to fail,
9516 * so allow this to continue. */
9517 }
9518
Veerendranath Jakkamca239592021-10-11 20:48:00 +05309519 if (get_driver_type(dut) == DRIVER_WCN)
9520 wcn_set_ignore_h2e_rsnxe(dut, intf, 0);
9521
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05309522 dut->saquery_oci_freq = 0;
Shivani Baranwalebde8f62021-10-19 12:26:02 +05309523 dut->prev_disable_scs_support = 0;
9524 dut->prev_disable_mscs_support = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309525
Veerendranath Jakkamf6c8ab52022-03-10 05:43:02 -08009526 if (dut->autoconnect_default)
9527 wpa_command(intf, "STA_AUTOCONNECT 1");
9528 else
9529 wpa_command(intf, "STA_AUTOCONNECT 0");
9530
Sunil Duttfebf8a82018-02-09 18:50:13 +05309531 if (dut->program != PROGRAM_VHT)
9532 return cmd_sta_p2p_reset(dut, conn, cmd);
9533
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08009534 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009535}
9536
9537
Jouni Malinenf7222712019-06-13 01:50:21 +03009538static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
9539 struct sigma_conn *conn,
9540 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009541{
9542 const char *program = get_param(cmd, "Program");
9543
9544 if (program == NULL)
9545 return -1;
9546#ifdef ANDROID_NAN
9547 if (strcasecmp(program, "NAN") == 0)
9548 return nan_cmd_sta_get_events(dut, conn, cmd);
9549#endif /* ANDROID_NAN */
9550 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9551 return 0;
9552}
9553
9554
Jouni Malinen82905202018-04-29 17:20:10 +03009555static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
9556 struct sigma_cmd *cmd)
9557{
9558 const char *url = get_param(cmd, "url");
9559 const char *method = get_param(cmd, "method");
9560 pid_t pid;
9561 int status;
9562
9563 if (!url || !method)
9564 return -1;
9565
9566 /* TODO: Add support for method,post */
9567 if (strcasecmp(method, "get") != 0) {
9568 send_resp(dut, conn, SIGMA_ERROR,
9569 "ErrorCode,Unsupported method");
9570 return 0;
9571 }
9572
9573 pid = fork();
9574 if (pid < 0) {
9575 perror("fork");
9576 return -1;
9577 }
9578
9579 if (pid == 0) {
9580 char * argv[5] = { "wget", "-O", "/dev/null",
9581 (char *) url, NULL };
9582
9583 execv("/usr/bin/wget", argv);
9584 perror("execv");
9585 exit(0);
9586 return -1;
9587 }
9588
9589 if (waitpid(pid, &status, 0) < 0) {
9590 perror("waitpid");
9591 return -1;
9592 }
9593
9594 if (WIFEXITED(status)) {
9595 const char *errmsg;
9596
9597 if (WEXITSTATUS(status) == 0)
9598 return 1;
9599 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
9600 WEXITSTATUS(status));
9601 switch (WEXITSTATUS(status)) {
9602 case 4:
9603 errmsg = "errmsg,Network failure";
9604 break;
9605 case 8:
9606 errmsg = "errmsg,Server issued an error response";
9607 break;
9608 default:
9609 errmsg = "errmsg,Unknown failure from wget";
9610 break;
9611 }
9612 send_resp(dut, conn, SIGMA_ERROR, errmsg);
9613 return 0;
9614 }
9615
9616 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
9617 return 0;
9618}
9619
9620
Jouni Malinenf7222712019-06-13 01:50:21 +03009621static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
9622 struct sigma_conn *conn,
9623 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009624{
9625 const char *program = get_param(cmd, "Prog");
9626
Jouni Malinen82905202018-04-29 17:20:10 +03009627 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009628 return -1;
9629#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03009630 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009631 return nan_cmd_sta_exec_action(dut, conn, cmd);
9632#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03009633
9634 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009635 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03009636
9637 if (get_param(cmd, "url"))
9638 return sta_exec_action_url(dut, conn, cmd);
9639
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009640 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9641 return 0;
9642}
9643
9644
Jouni Malinenf7222712019-06-13 01:50:21 +03009645static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
9646 struct sigma_conn *conn,
9647 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009648{
9649 const char *intf = get_param(cmd, "Interface");
9650 const char *val, *mcs32, *rate;
9651
9652 val = get_param(cmd, "GREENFIELD");
9653 if (val) {
9654 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
9655 /* Enable GD */
9656 send_resp(dut, conn, SIGMA_ERROR,
9657 "ErrorCode,GF not supported");
9658 return 0;
9659 }
9660 }
9661
9662 val = get_param(cmd, "SGI20");
9663 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009664 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009665 case DRIVER_ATHEROS:
9666 ath_sta_set_sgi(dut, intf, val);
9667 break;
9668 default:
9669 send_resp(dut, conn, SIGMA_ERROR,
9670 "ErrorCode,SGI20 not supported");
9671 return 0;
9672 }
9673 }
9674
9675 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
9676 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
9677 if (mcs32 && rate) {
9678 /* TODO */
9679 send_resp(dut, conn, SIGMA_ERROR,
9680 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
9681 return 0;
9682 } else if (mcs32 && !rate) {
9683 /* TODO */
9684 send_resp(dut, conn, SIGMA_ERROR,
9685 "ErrorCode,MCS32 not supported");
9686 return 0;
9687 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009688 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009689 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07009690 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009691 ath_sta_set_11nrates(dut, intf, rate);
9692 break;
9693 default:
9694 send_resp(dut, conn, SIGMA_ERROR,
9695 "ErrorCode,MCS32_FIXEDRATE not supported");
9696 return 0;
9697 }
9698 }
9699
9700 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9701}
9702
9703
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009704static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
9705 int mcs_config)
9706{
9707#ifdef NL80211_SUPPORT
9708 int ret;
9709
9710 switch (mcs_config) {
9711 case HE_80_MCS0_7:
9712 case HE_80_MCS0_9:
9713 case HE_80_MCS0_11:
9714 ret = sta_set_he_mcs(dut, intf, mcs_config);
9715 if (ret) {
9716 sigma_dut_print(dut, DUT_MSG_ERROR,
9717 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
9718 mcs_config, ret);
9719 }
9720 break;
9721 default:
9722 sigma_dut_print(dut, DUT_MSG_ERROR,
9723 "cmd_set_max_he_mcs: Invalid mcs %d",
9724 mcs_config);
9725 break;
9726 }
9727#else /* NL80211_SUPPORT */
9728 sigma_dut_print(dut, DUT_MSG_ERROR,
9729 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
9730#endif /* NL80211_SUPPORT */
9731}
9732
9733
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009734struct wait_event {
9735 struct sigma_dut *dut;
9736 int cmd;
9737 unsigned int twt_op;
9738};
9739
9740#ifdef NL80211_SUPPORT
9741
9742static int twt_event_handler(struct nl_msg *msg, void *arg)
9743{
9744 struct wait_event *wait = arg;
9745 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9746 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9747 uint32_t subcmd;
9748 uint8_t *data = NULL;
9749 size_t len = 0;
9750 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
9751 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
9752 int cmd_id;
9753 unsigned char val;
9754
9755 if (!wait)
9756 return NL_SKIP;
9757
9758 if (gnlh->cmd != NL80211_CMD_VENDOR) {
9759 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9760 "%s: NL cmd is not vendor %d", __func__,
9761 gnlh->cmd);
9762 return NL_SKIP;
9763 }
9764
9765 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9766 genlmsg_attrlen(gnlh, 0), NULL);
9767
9768 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
9769 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9770 "%s: vendor ID not found", __func__);
9771 return NL_SKIP;
9772 }
9773 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
9774
9775 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
9776 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9777 "%s: Not a TWT_cmd %d", __func__, subcmd);
9778 return NL_SKIP;
9779 }
9780 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9781 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
9782 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
9783 } else {
9784 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9785 "%s: vendor data not present", __func__);
9786 return NL_SKIP;
9787 }
9788 if (!data || !len) {
9789 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9790 "Invalid vendor data or len");
9791 return NL_SKIP;
9792 }
9793 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
9794 "event data len %ld", len);
9795 hex_dump(wait->dut, data, len);
9796 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
9797 (struct nlattr *) data, len, NULL)) {
9798 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9799 "vendor data parse error");
9800 return NL_SKIP;
9801 }
9802
9803 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
9804 if (val != wait->twt_op) {
9805 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9806 "Invalid TWT operation, expected %d, rcvd %d",
9807 wait->twt_op, val);
9808 return NL_SKIP;
9809 }
9810 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
9811 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
9812 NULL)) {
9813 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9814 "nla_parse failed for TWT event");
9815 return NL_SKIP;
9816 }
9817
9818 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
9819 if (!twt_status[cmd_id]) {
9820 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9821 "%s TWT resp status missing", __func__);
9822 wait->cmd = -1;
9823 } else {
9824 val = nla_get_u8(twt_status[cmd_id]);
9825 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
9826 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9827 "%s TWT resp status %d", __func__, val);
9828 wait->cmd = -1;
9829 } else {
9830 wait->cmd = 1;
9831 }
9832 }
9833
9834 return NL_SKIP;
9835}
9836
9837
9838static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
9839 unsigned int timeout)
9840{
9841 fd_set read_fd_set;
9842 int retval;
9843 int sock_fd;
9844 struct timeval time_out;
9845
9846 time_out.tv_sec = timeout;
9847 time_out.tv_usec = 0;
9848
9849 FD_ZERO(&read_fd_set);
9850
9851 if (!sock)
9852 return -1;
9853
9854 sock_fd = nl_socket_get_fd(sock);
9855 FD_SET(sock_fd, &read_fd_set);
9856
9857 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
9858
9859 if (retval == 0)
9860 sigma_dut_print(dut, DUT_MSG_ERROR,
9861 "%s: TWT event response timedout", __func__);
9862
9863 if (retval < 0)
9864 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
9865 __func__, retval);
9866
9867 return retval;
9868}
9869
9870
9871#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
9872
9873static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
9874{
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009875 struct nl_cb *cb = NULL;
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009876 int err_code = 0, select_retval = 0;
9877 struct wait_event wait_info;
9878
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009879 if (dut->nl_ctx->event_sock)
9880 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009881 if (!cb) {
9882 sigma_dut_print(dut, DUT_MSG_ERROR,
9883 "event callback not found");
9884 return ERROR_SEND_STATUS;
9885 }
9886
9887 wait_info.cmd = 0;
9888 wait_info.dut = dut;
9889 wait_info.twt_op = twt_op;
9890
9891 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
9892
9893 while (!wait_info.cmd) {
9894 select_retval = wait_on_nl_socket(
9895 dut->nl_ctx->event_sock, dut,
9896 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
9897
9898 if (select_retval > 0) {
9899 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
9900 if (err_code < 0) {
9901 sigma_dut_print(dut, DUT_MSG_ERROR,
9902 "%s: nl rcv failed, err_code %d",
9903 __func__, err_code);
9904 break;
9905 }
9906 } else {
9907 sigma_dut_print(dut, DUT_MSG_ERROR,
9908 "%s: wait on socket failed %d",
9909 __func__, select_retval);
9910 err_code = 1;
9911 break;
9912 }
9913
9914 }
9915 nl_cb_put(cb);
9916
9917 if (wait_info.cmd < 0)
9918 err_code = 1;
9919
9920 sigma_dut_print(dut, DUT_MSG_DEBUG,
9921 "%s: rcvd cmd %d, err_code %d, s_ret %d",
9922 __func__, wait_info.cmd, err_code, select_retval);
9923
9924 return err_code;
9925}
9926
9927#endif /* NL80211_SUPPORT */
9928
9929
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009930static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
9931 struct sigma_cmd *cmd)
9932{
9933#ifdef NL80211_SUPPORT
9934 struct nlattr *attr, *attr1;
9935 struct nl_msg *msg;
9936 int ifindex, ret;
9937 const char *intf = get_param(cmd, "Interface");
9938
9939 ifindex = if_nametoindex(intf);
9940 if (ifindex == 0) {
9941 sigma_dut_print(dut, DUT_MSG_ERROR,
9942 "%s: Index for interface %s failed",
9943 __func__, intf);
9944 return ERROR_SEND_STATUS;
9945 }
9946
9947 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9948 NL80211_CMD_VENDOR)) ||
9949 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9950 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9951 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9952 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9953 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9954 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9955 QCA_WLAN_TWT_SUSPEND) ||
9956 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07009957 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009958 sigma_dut_print(dut, DUT_MSG_ERROR,
9959 "%s: err in adding vendor_cmd and vendor_data",
9960 __func__);
9961 nlmsg_free(msg);
9962 return ERROR_SEND_STATUS;
9963 }
9964 nla_nest_end(msg, attr1);
9965 nla_nest_end(msg, attr);
9966
9967 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9968 if (ret) {
9969 sigma_dut_print(dut, DUT_MSG_ERROR,
9970 "%s: err in send_and_recv_msgs, ret=%d",
9971 __func__, ret);
9972 }
9973
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009974 if (!dut->sta_async_twt_supp)
9975 return ret;
9976
9977 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009978#else /* NL80211_SUPPORT */
9979 sigma_dut_print(dut, DUT_MSG_ERROR,
9980 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9981 return ERROR_SEND_STATUS;
9982#endif /* NL80211_SUPPORT */
9983}
9984
9985
9986static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
9987 struct sigma_cmd *cmd,
9988 unsigned int suspend_duration)
9989{
9990#ifdef NL80211_SUPPORT
9991 struct nlattr *attr, *attr1;
9992 struct nl_msg *msg;
9993 int ifindex, ret;
9994 const char *intf = get_param(cmd, "Interface");
9995 int next_twt_size = 1;
9996
9997 ifindex = if_nametoindex(intf);
9998 if (ifindex == 0) {
9999 sigma_dut_print(dut, DUT_MSG_ERROR,
10000 "%s: Index for interface %s failed",
10001 __func__, intf);
10002 return ERROR_SEND_STATUS;
10003 }
10004
10005 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10006 NL80211_CMD_VENDOR)) ||
10007 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10008 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10009 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10010 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10011 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10012 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10013 QCA_WLAN_TWT_NUDGE) ||
10014 !(attr1 = nla_nest_start(msg,
10015 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10016 (suspend_duration &&
10017 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
10018 suspend_duration)) ||
10019 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010020 next_twt_size) ||
10021 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010022 sigma_dut_print(dut, DUT_MSG_ERROR,
10023 "%s: err in adding vendor_cmd and vendor_data",
10024 __func__);
10025 nlmsg_free(msg);
10026 return ERROR_SEND_STATUS;
10027 }
10028 nla_nest_end(msg, attr1);
10029 nla_nest_end(msg, attr);
10030
10031 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10032 if (ret) {
10033 sigma_dut_print(dut, DUT_MSG_ERROR,
10034 "%s: err in send_and_recv_msgs, ret=%d",
10035 __func__, ret);
10036 }
10037
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010038 if (!dut->sta_async_twt_supp)
10039 return ret;
10040
10041 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010042#else /* NL80211_SUPPORT */
10043 sigma_dut_print(dut, DUT_MSG_ERROR,
10044 "TWT suspend cannot be done without NL80211_SUPPORT defined");
10045 return ERROR_SEND_STATUS;
10046#endif /* NL80211_SUPPORT */
10047}
10048
10049
10050static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
10051 struct sigma_conn *conn,
10052 struct sigma_cmd *cmd)
10053{
10054 const char *val;
10055
10056 val = get_param(cmd, "TWT_SuspendDuration");
10057 if (val) {
10058 unsigned int suspend_duration;
10059
10060 suspend_duration = atoi(val);
10061 suspend_duration = suspend_duration * 1000 * 1000;
10062 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
10063 }
10064
10065 return sta_twt_send_suspend(dut, conn, cmd);
10066}
10067
10068
10069static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
10070 struct sigma_cmd *cmd)
10071{
10072#ifdef NL80211_SUPPORT
10073 struct nlattr *attr, *attr1;
10074 struct nl_msg *msg;
10075 int ifindex, ret;
10076 const char *intf = get_param(cmd, "Interface");
10077 int next2_twt_size = 1;
10078 unsigned int resume_duration = 0;
10079 const char *val;
10080
10081 ifindex = if_nametoindex(intf);
10082 if (ifindex == 0) {
10083 sigma_dut_print(dut, DUT_MSG_ERROR,
10084 "%s: Index for interface %s failed",
10085 __func__, intf);
10086 return ERROR_SEND_STATUS;
10087 }
10088
10089 val = get_param(cmd, "TWT_ResumeDuration");
10090 if (val) {
10091 resume_duration = atoi(val);
10092 resume_duration = resume_duration * 1000 * 1000;
10093 }
10094
10095 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10096 NL80211_CMD_VENDOR)) ||
10097 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10098 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10099 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10100 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10101 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10102 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10103 QCA_WLAN_TWT_RESUME) ||
10104 !(attr1 = nla_nest_start(msg,
10105 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10106 (resume_duration &&
10107 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
10108 resume_duration)) ||
10109 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
10110 next2_twt_size)) {
10111 sigma_dut_print(dut, DUT_MSG_ERROR,
10112 "%s: err in adding vendor_cmd and vendor_data",
10113 __func__);
10114 nlmsg_free(msg);
10115 return ERROR_SEND_STATUS;
10116 }
10117 nla_nest_end(msg, attr1);
10118 nla_nest_end(msg, attr);
10119
10120 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10121 if (ret) {
10122 sigma_dut_print(dut, DUT_MSG_ERROR,
10123 "%s: err in send_and_recv_msgs, ret=%d",
10124 __func__, ret);
10125 }
10126
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010127 if (!dut->sta_async_twt_supp)
10128 return ret;
10129
10130 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010131#else /* NL80211_SUPPORT */
10132 sigma_dut_print(dut, DUT_MSG_ERROR,
10133 "TWT resume cannot be done without NL80211_SUPPORT defined");
10134 return ERROR_SEND_STATUS;
10135#endif /* NL80211_SUPPORT */
10136}
10137
10138
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010139#define TWT_REQUEST_CMD 0
10140#define TWT_SUGGEST_CMD 1
10141#define TWT_DEMAND_CMD 2
10142
Arif Hussain480d5f42019-03-12 14:40:42 -070010143static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
10144 struct sigma_cmd *cmd)
10145{
10146#ifdef NL80211_SUPPORT
10147 struct nlattr *params;
10148 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010149 struct nl_msg *msg;
10150 int ifindex, ret;
10151 const char *val;
10152 const char *intf = get_param(cmd, "Interface");
10153 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
10154 wake_interval_mantissa = 512;
10155 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010156 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010157 int bcast_twt = 0;
10158 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -070010159
10160 ifindex = if_nametoindex(intf);
10161 if (ifindex == 0) {
10162 sigma_dut_print(dut, DUT_MSG_ERROR,
10163 "%s: Index for interface %s failed",
10164 __func__, intf);
10165 return -1;
10166 }
10167
10168 val = get_param(cmd, "FlowType");
10169 if (val) {
10170 flow_type = atoi(val);
10171 if (flow_type != 0 && flow_type != 1) {
10172 sigma_dut_print(dut, DUT_MSG_ERROR,
10173 "TWT: Invalid FlowType %d", flow_type);
10174 return -1;
10175 }
10176 }
10177
10178 val = get_param(cmd, "TWT_Trigger");
10179 if (val) {
10180 twt_trigger = atoi(val);
10181 if (twt_trigger != 0 && twt_trigger != 1) {
10182 sigma_dut_print(dut, DUT_MSG_ERROR,
10183 "TWT: Invalid TWT_Trigger %d",
10184 twt_trigger);
10185 return -1;
10186 }
10187 }
10188
10189 val = get_param(cmd, "Protection");
10190 if (val) {
10191 protection = atoi(val);
10192 if (protection != 0 && protection != 1) {
10193 sigma_dut_print(dut, DUT_MSG_ERROR,
10194 "TWT: Invalid Protection %d",
10195 protection);
10196 return -1;
10197 }
10198 }
10199
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010200 val = get_param(cmd, "SetupCommand");
10201 if (val) {
10202 cmd_type = atoi(val);
10203 if (cmd_type == TWT_REQUEST_CMD)
10204 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
10205 else if (cmd_type == TWT_SUGGEST_CMD)
10206 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
10207 else if (cmd_type == TWT_DEMAND_CMD)
10208 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
10209 else
10210 sigma_dut_print(dut, DUT_MSG_ERROR,
10211 "Default suggest is used for cmd %d",
10212 cmd_type);
10213 }
10214
Arif Hussain480d5f42019-03-12 14:40:42 -070010215 val = get_param(cmd, "TargetWakeTime");
10216 if (val)
10217 target_wake_time = atoi(val);
10218
10219 val = get_param(cmd, "WakeIntervalMantissa");
10220 if (val)
10221 wake_interval_mantissa = atoi(val);
10222
10223 val = get_param(cmd, "WakeIntervalExp");
10224 if (val)
10225 wake_interval_exp = atoi(val);
10226
10227 val = get_param(cmd, "NominalMinWakeDur");
10228 if (val)
10229 nominal_min_wake_dur = atoi(val);
10230
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010231 val = get_param(cmd, "BTWT_ID");
10232 if (val) {
10233 bcast_twt_id = atoi(val);
10234 bcast_twt = 1;
10235 }
10236
10237 val = get_param(cmd, "BTWT_Persistence");
10238 if (val) {
10239 bcast_twt_persis = atoi(val);
10240 bcast_twt = 1;
10241 }
10242
10243 val = get_param(cmd, "BTWT_Recommendation");
10244 if (val) {
10245 bcast_twt_recommdn = atoi(val);
10246 bcast_twt = 1;
10247 }
10248
10249 if (bcast_twt)
10250 sigma_dut_print(dut, DUT_MSG_DEBUG,
10251 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
10252 bcast_twt_id, bcast_twt_recommdn,
10253 bcast_twt_persis);
10254
Arif Hussain480d5f42019-03-12 14:40:42 -070010255 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10256 NL80211_CMD_VENDOR)) ||
10257 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10258 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10259 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010260 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010261 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010262 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10263 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010264 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010265 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010266 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
10267 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010268 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010269 (twt_trigger &&
10270 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010271 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
10272 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010273 (protection &&
10274 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010275 (bcast_twt &&
10276 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10277 (bcast_twt &&
10278 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10279 bcast_twt_id)) ||
10280 (bcast_twt &&
10281 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
10282 bcast_twt_persis)) ||
10283 (bcast_twt &&
10284 nla_put_u8(msg,
10285 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
10286 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010287 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
10288 target_wake_time) ||
10289 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
10290 nominal_min_wake_dur) ||
10291 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
10292 wake_interval_mantissa)) {
10293 sigma_dut_print(dut, DUT_MSG_ERROR,
10294 "%s: err in adding vendor_cmd and vendor_data",
10295 __func__);
10296 nlmsg_free(msg);
10297 return -1;
10298 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010299 nla_nest_end(msg, params);
10300 nla_nest_end(msg, attr);
10301
10302 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10303 if (ret) {
10304 sigma_dut_print(dut, DUT_MSG_ERROR,
10305 "%s: err in send_and_recv_msgs, ret=%d",
10306 __func__, ret);
10307 }
10308
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010309 if (!dut->sta_async_twt_supp)
10310 return ret;
10311
10312 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -070010313#else /* NL80211_SUPPORT */
10314 sigma_dut_print(dut, DUT_MSG_ERROR,
10315 "TWT request cannot be done without NL80211_SUPPORT defined");
10316 return -1;
10317#endif /* NL80211_SUPPORT */
10318}
10319
10320
10321static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
10322 struct sigma_cmd *cmd)
10323{
10324 #ifdef NL80211_SUPPORT
10325 struct nlattr *params;
10326 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010327 int ifindex, ret;
10328 struct nl_msg *msg;
10329 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010330 int bcast_twt = 0;
10331 int bcast_twt_id = 0;
10332 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -070010333
10334 ifindex = if_nametoindex(intf);
10335 if (ifindex == 0) {
10336 sigma_dut_print(dut, DUT_MSG_ERROR,
10337 "%s: Index for interface %s failed",
10338 __func__, intf);
10339 return -1;
10340 }
10341
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010342 val = get_param(cmd, "BTWT_ID");
10343 if (val) {
10344 bcast_twt_id = atoi(val);
10345 bcast_twt = 1;
10346 }
10347
Arif Hussain480d5f42019-03-12 14:40:42 -070010348 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10349 NL80211_CMD_VENDOR)) ||
10350 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10351 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10352 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010353 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010354 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010355 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10356 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010357 !(params = nla_nest_start(
10358 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010359 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010360 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
10361 (bcast_twt &&
10362 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10363 (bcast_twt &&
10364 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10365 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -070010366 sigma_dut_print(dut, DUT_MSG_ERROR,
10367 "%s: err in adding vendor_cmd and vendor_data",
10368 __func__);
10369 nlmsg_free(msg);
10370 return -1;
10371 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010372 nla_nest_end(msg, params);
10373 nla_nest_end(msg, attr);
10374
10375 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10376 if (ret) {
10377 sigma_dut_print(dut, DUT_MSG_ERROR,
10378 "%s: err in send_and_recv_msgs, ret=%d",
10379 __func__, ret);
10380 }
10381
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010382 if (!dut->sta_async_twt_supp)
10383 return ret;
10384
10385 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -070010386#else /* NL80211_SUPPORT */
10387 sigma_dut_print(dut, DUT_MSG_ERROR,
10388 "TWT teardown cannot be done without NL80211_SUPPORT defined");
10389 return -1;
10390#endif /* NL80211_SUPPORT */
10391}
10392
10393
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080010394static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
10395 struct sigma_cmd *cmd)
10396{
10397#ifdef NL80211_SUPPORT
10398 struct nlattr *params;
10399 struct nlattr *attr;
10400 struct nlattr *attr1;
10401 struct nl_msg *msg;
10402 int ifindex, ret;
10403 const char *val;
10404 const char *intf = get_param(cmd, "Interface");
10405 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
10406 ulmu_data_dis = 0;
10407
10408 ifindex = if_nametoindex(intf);
10409 if (ifindex == 0) {
10410 sigma_dut_print(dut, DUT_MSG_ERROR,
10411 "%s: Index for interface %s failed",
10412 __func__, intf);
10413 return -1;
10414 }
10415 val = get_param(cmd, "OMCtrl_RxNSS");
10416 if (val)
10417 rx_nss = atoi(val);
10418
10419 val = get_param(cmd, "OMCtrl_ChnlWidth");
10420 if (val)
10421 ch_bw = atoi(val);
10422
10423 val = get_param(cmd, "OMCtrl_ULMUDisable");
10424 if (val)
10425 ulmu_dis = atoi(val);
10426
10427 val = get_param(cmd, "OMCtrl_TxNSTS");
10428 if (val)
10429 tx_nsts = atoi(val);
10430
10431 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
10432 if (val)
10433 ulmu_data_dis = atoi(val);
10434
10435 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10436 NL80211_CMD_VENDOR)) ||
10437 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10438 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10439 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10440 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10441 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10442 !(params = nla_nest_start(
10443 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
10444 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10445 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
10446 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
10447 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
10448 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
10449 ulmu_data_dis) ||
10450 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
10451 ulmu_dis)) {
10452 sigma_dut_print(dut, DUT_MSG_ERROR,
10453 "%s: err in adding vendor_cmd and vendor_data",
10454 __func__);
10455 nlmsg_free(msg);
10456 return -1;
10457 }
10458 nla_nest_end(msg, attr1);
10459 nla_nest_end(msg, params);
10460 nla_nest_end(msg, attr);
10461
10462 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10463 if (ret) {
10464 sigma_dut_print(dut, DUT_MSG_ERROR,
10465 "%s: err in send_and_recv_msgs, ret=%d",
10466 __func__, ret);
10467 }
10468
10469 return ret;
10470#else /* NL80211_SUPPORT */
10471 sigma_dut_print(dut, DUT_MSG_ERROR,
10472 "OMI TX cannot be processed without NL80211_SUPPORT defined");
10473 return -1;
10474#endif /* NL80211_SUPPORT */
10475}
10476
10477
Jouni Malinen224e3902021-06-09 16:41:27 +030010478static enum sigma_cmd_result
10479cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10480 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010481{
10482 const char *intf = get_param(cmd, "Interface");
10483 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -070010484 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010485 int tkip = -1;
10486 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010487 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010488
Arif Hussaina37e9552018-06-20 17:05:59 -070010489 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010490 val = get_param(cmd, "SGI80");
10491 if (val) {
10492 int sgi80;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010493 enum nl80211_txrate_gi gi_val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010494
10495 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010496 if (sgi80)
10497 gi_val = NL80211_TXRATE_FORCE_LGI;
10498 else
10499 gi_val = NL80211_TXRATE_FORCE_SGI;
10500 if (sta_set_vht_gi(dut, intf, (u8) gi_val)) {
10501 sigma_dut_print(dut, DUT_MSG_INFO,
10502 "sta_set_vht_gi failed, using iwpriv");
10503 run_iwpriv(dut, intf, "shortgi %d", sgi80);
10504 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010505 }
10506
10507 val = get_param(cmd, "TxBF");
10508 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010509 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010510 case DRIVER_WCN:
10511 if (sta_set_tx_beamformee(dut, intf, 1)) {
10512 send_resp(dut, conn, SIGMA_ERROR,
10513 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010514 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010515 }
10516 break;
10517 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010518 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010519 send_resp(dut, conn, SIGMA_ERROR,
10520 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010521 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010522 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010523 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010524 send_resp(dut, conn, SIGMA_ERROR,
10525 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010526 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010527 }
10528 break;
10529 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010530 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010531 "Unsupported driver type");
10532 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010533 }
10534 }
10535
10536 val = get_param(cmd, "MU_TxBF");
10537 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010538 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010539 case DRIVER_ATHEROS:
10540 ath_sta_set_txsp_stream(dut, intf, "1SS");
10541 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010542 run_iwpriv(dut, intf, "vhtmubfee 1");
10543 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +053010544 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010545 case DRIVER_WCN:
10546 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
10547 send_resp(dut, conn, SIGMA_ERROR,
10548 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +030010549 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010550 }
Sunil Duttae9e5d12018-06-29 11:50:47 +053010551 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010552 default:
10553 sigma_dut_print(dut, DUT_MSG_ERROR,
10554 "Setting SP_STREAM not supported");
10555 break;
10556 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010557 }
10558
10559 val = get_param(cmd, "LDPC");
10560 if (val) {
10561 int ldpc;
10562
10563 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010564 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
10565 if (iwpriv_status)
10566 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010567 }
10568
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010569 val = get_param(cmd, "BCC");
10570 if (val) {
10571 int bcc;
10572
10573 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10574 /* use LDPC iwpriv itself to set bcc coding, bcc coding
10575 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010576 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
10577 if (iwpriv_status)
10578 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010579 }
10580
Arif Hussain7b47d2d2018-05-09 10:44:02 -070010581 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
10582 if (val && dut->sta_nss == 1)
10583 cmd_set_max_he_mcs(dut, intf, atoi(val));
10584
10585 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
10586 if (val && dut->sta_nss == 2)
10587 cmd_set_max_he_mcs(dut, intf, atoi(val));
10588
Arif Hussainac6c5112018-05-25 17:34:00 -070010589 val = get_param(cmd, "MCS_FixedRate");
10590 if (val) {
10591#ifdef NL80211_SUPPORT
10592 int mcs, ratecode = 0;
10593 enum he_mcs_config mcs_config;
10594 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +030010595 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -070010596
10597 ratecode = (0x07 & dut->sta_nss) << 5;
10598 mcs = atoi(val);
10599 /* Add the MCS to the ratecode */
10600 if (mcs >= 0 && mcs <= 11) {
10601 ratecode += mcs;
10602 if (dut->device_type == STA_testbed &&
10603 mcs > 7 && mcs <= 11) {
10604 if (mcs <= 9)
10605 mcs_config = HE_80_MCS0_9;
10606 else
10607 mcs_config = HE_80_MCS0_11;
10608 ret = sta_set_he_mcs(dut, intf, mcs_config);
10609 if (ret) {
10610 sigma_dut_print(dut, DUT_MSG_ERROR,
10611 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10612 mcs, mcs_config, ret);
10613 }
10614 }
10615 snprintf(buf, sizeof(buf),
10616 "iwpriv %s set_11ax_rate 0x%03x",
10617 intf, ratecode);
10618 if (system(buf) != 0) {
10619 sigma_dut_print(dut, DUT_MSG_ERROR,
10620 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
10621 ratecode);
10622 }
10623 } else {
10624 sigma_dut_print(dut, DUT_MSG_ERROR,
10625 "MCS_FixedRate: HE MCS %d not supported",
10626 mcs);
10627 }
10628#else /* NL80211_SUPPORT */
10629 sigma_dut_print(dut, DUT_MSG_ERROR,
10630 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
10631#endif /* NL80211_SUPPORT */
10632 }
10633
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010634 val = get_param(cmd, "opt_md_notif_ie");
10635 if (val) {
10636 char *result = NULL;
10637 char delim[] = ";";
10638 char token[30];
10639 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010640 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010641
Peng Xub8fc5cc2017-05-10 17:27:28 -070010642 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010643 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010644
10645 /* Extract the NSS information */
10646 if (result) {
10647 value = atoi(result);
10648 switch (value) {
10649 case 1:
10650 config_val = 1;
10651 break;
10652 case 2:
10653 config_val = 3;
10654 break;
10655 case 3:
10656 config_val = 7;
10657 break;
10658 case 4:
10659 config_val = 15;
10660 break;
10661 default:
10662 config_val = 3;
10663 break;
10664 }
10665
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010666 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
10667 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010668
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010669 }
10670
10671 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010672 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010673 if (result) {
10674 value = atoi(result);
10675 switch (value) {
10676 case 20:
10677 config_val = 0;
10678 break;
10679 case 40:
10680 config_val = 1;
10681 break;
10682 case 80:
10683 config_val = 2;
10684 break;
10685 case 160:
10686 config_val = 3;
10687 break;
10688 default:
10689 config_val = 2;
10690 break;
10691 }
10692
10693 dut->chwidth = config_val;
10694
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010695 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010696 }
10697
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010698 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010699 }
10700
10701 val = get_param(cmd, "nss_mcs_cap");
10702 if (val) {
10703 int nss, mcs;
10704 char token[20];
10705 char *result = NULL;
10706 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010707 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010708
Peng Xub8fc5cc2017-05-10 17:27:28 -070010709 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010710 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010711 if (!result) {
10712 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010713 "NSS not specified");
10714 send_resp(dut, conn, SIGMA_ERROR,
10715 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010716 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010717 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010718 nss = atoi(result);
10719
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010720 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -070010721 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010722
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010723 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010724 if (result == NULL) {
10725 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010726 "MCS not specified");
10727 send_resp(dut, conn, SIGMA_ERROR,
10728 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010729 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010730 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010731 result = strtok_r(result, "-", &saveptr);
10732 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010733 if (!result) {
10734 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010735 "MCS not specified");
10736 send_resp(dut, conn, SIGMA_ERROR,
10737 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010738 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010739 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010740 mcs = atoi(result);
10741
Arif Hussaina37e9552018-06-20 17:05:59 -070010742 if (program && strcasecmp(program, "HE") == 0) {
10743#ifdef NL80211_SUPPORT
10744 enum he_mcs_config mcs_config;
10745 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010746
Arif Hussaina37e9552018-06-20 17:05:59 -070010747 if (mcs >= 0 && mcs <= 7) {
10748 mcs_config = HE_80_MCS0_7;
10749 } else if (mcs > 7 && mcs <= 9) {
10750 mcs_config = HE_80_MCS0_9;
10751 } else if (mcs > 9 && mcs <= 11) {
10752 mcs_config = HE_80_MCS0_11;
10753 } else {
10754 sigma_dut_print(dut, DUT_MSG_ERROR,
10755 "nss_mcs_cap: HE: Invalid mcs: %d",
10756 mcs);
10757 send_resp(dut, conn, SIGMA_ERROR,
10758 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010759 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010760 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010761
10762 ret = sta_set_he_mcs(dut, intf, mcs_config);
10763 if (ret) {
10764 sigma_dut_print(dut, DUT_MSG_ERROR,
10765 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
10766 mcs_config, ret);
10767 send_resp(dut, conn, SIGMA_ERROR,
10768 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010769 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010770 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010771#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010772 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010773 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
10774#endif /* NL80211_SUPPORT */
10775 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010776 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -070010777
10778 switch (nss) {
10779 case 1:
10780 switch (mcs) {
10781 case 7:
10782 vht_mcsmap = 0xfffc;
10783 break;
10784 case 8:
10785 vht_mcsmap = 0xfffd;
10786 break;
10787 case 9:
10788 vht_mcsmap = 0xfffe;
10789 break;
10790 default:
10791 vht_mcsmap = 0xfffe;
10792 break;
10793 }
10794 break;
10795 case 2:
10796 switch (mcs) {
10797 case 7:
10798 vht_mcsmap = 0xfff0;
10799 break;
10800 case 8:
10801 vht_mcsmap = 0xfff5;
10802 break;
10803 case 9:
10804 vht_mcsmap = 0xfffa;
10805 break;
10806 default:
10807 vht_mcsmap = 0xfffa;
10808 break;
10809 }
10810 break;
10811 case 3:
10812 switch (mcs) {
10813 case 7:
10814 vht_mcsmap = 0xffc0;
10815 break;
10816 case 8:
10817 vht_mcsmap = 0xffd5;
10818 break;
10819 case 9:
10820 vht_mcsmap = 0xffea;
10821 break;
10822 default:
10823 vht_mcsmap = 0xffea;
10824 break;
10825 }
10826 break;
10827 default:
10828 vht_mcsmap = 0xffea;
10829 break;
10830 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010831 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010832 }
10833 }
10834
10835 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
10836
10837 val = get_param(cmd, "Vht_tkip");
10838 if (val)
10839 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10840
10841 val = get_param(cmd, "Vht_wep");
10842 if (val)
10843 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10844
10845 if (tkip != -1 || wep != -1) {
10846 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010847 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010848 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010849 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010850 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +030010851 send_resp(dut, conn, SIGMA_ERROR,
10852 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
10853 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010854 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010855 }
10856
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -070010857 val = get_param(cmd, "TWTSchedSTASupport");
10858 if (val) {
10859 int set_val;
10860
10861 switch (get_driver_type(dut)) {
10862 case DRIVER_WCN:
10863 if (strcasecmp(val, "Enable") == 0) {
10864 set_val = 1;
10865 } else if (strcasecmp(val, "Disable") == 0) {
10866 set_val = 0;
10867 } else {
10868 send_resp(dut, conn, SIGMA_ERROR,
10869 "ErrorCode,Invalid TWTSchedSTASupport");
10870 return STATUS_SENT_ERROR;
10871 }
10872
10873 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
10874 send_resp(dut, conn, SIGMA_ERROR,
10875 "ErrorCode,Failed to set TWTSchedSTASupport");
10876 return STATUS_SENT_ERROR;
10877 }
10878 break;
10879 default:
10880 sigma_dut_print(dut, DUT_MSG_ERROR,
10881 "Setting TWTSchedSTASupport not supported");
10882 break;
10883 }
10884 }
10885
10886 val = get_param(cmd, "MBSSID_RxCtrl");
10887 if (val) {
10888 int set_val;
10889
10890 switch (get_driver_type(dut)) {
10891 case DRIVER_WCN:
10892 if (strcasecmp(val, "Enable") == 0) {
10893 set_val = 1;
10894 } else if (strcasecmp(val, "Disable") == 0) {
10895 set_val = 0;
10896 } else {
10897 send_resp(dut, conn, SIGMA_ERROR,
10898 "ErrorCode,Invalid MBSSID_RxCtrl");
10899 return STATUS_SENT_ERROR;
10900 }
10901
10902 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
10903 send_resp(dut, conn, SIGMA_ERROR,
10904 "ErrorCode,Failed to set MBSSID_RxCtrl");
10905 return STATUS_SENT_ERROR;
10906 }
10907 break;
10908 default:
10909 sigma_dut_print(dut, DUT_MSG_ERROR,
10910 "Setting MBSSID_RxCtrl not supported");
10911 break;
10912 }
10913 }
10914
Arif Hussain55f00da2018-07-03 08:28:26 -070010915 val = get_param(cmd, "txBandwidth");
10916 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010917 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -070010918 case DRIVER_WCN:
10919 if (wcn_sta_set_width(dut, intf, val) < 0) {
10920 send_resp(dut, conn, SIGMA_ERROR,
10921 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010922 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010923 }
10924 break;
10925 case DRIVER_ATHEROS:
10926 if (ath_set_width(dut, conn, intf, val) < 0) {
10927 send_resp(dut, conn, SIGMA_ERROR,
10928 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010929 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010930 }
10931 break;
10932 default:
10933 sigma_dut_print(dut, DUT_MSG_ERROR,
10934 "Setting txBandwidth not supported");
10935 break;
10936 }
10937 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010938
Arif Hussain9765f7d2018-07-03 08:28:26 -070010939 val = get_param(cmd, "BeamformeeSTS");
10940 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010941 if (sta_set_tx_beamformee(dut, intf, 1)) {
10942 send_resp(dut, conn, SIGMA_ERROR,
10943 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010944 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010945 }
10946
Arif Hussain9765f7d2018-07-03 08:28:26 -070010947 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
10948 send_resp(dut, conn, SIGMA_ERROR,
10949 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010950 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -070010951 }
10952 }
10953
Arif Hussain68d23f52018-07-11 13:39:08 -070010954 val = get_param(cmd, "Trig_MAC_Padding_Dur");
10955 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010956#ifdef NL80211_SUPPORT
10957 enum qca_wlan_he_mac_padding_dur set_val;
10958
10959 switch (atoi(val)) {
10960 case 16:
10961 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
10962 break;
10963 case 8:
10964 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
10965 break;
10966 default:
10967 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
10968 break;
10969 }
10970 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -070010971 send_resp(dut, conn, SIGMA_ERROR,
10972 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +030010973 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -070010974 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010975#else /* NL80211_SUPPORT */
10976 sigma_dut_print(dut, DUT_MSG_ERROR,
10977 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
10978#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -070010979 }
10980
Arif Hussain480d5f42019-03-12 14:40:42 -070010981 val = get_param(cmd, "TWT_ReqSupport");
10982 if (val) {
10983 int set_val;
10984
10985 if (strcasecmp(val, "Enable") == 0) {
10986 set_val = 1;
10987 } else if (strcasecmp(val, "Disable") == 0) {
10988 set_val = 0;
10989 } else {
10990 send_resp(dut, conn, SIGMA_ERROR,
10991 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010992 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010993 }
10994
10995 if (sta_set_twt_req_support(dut, intf, set_val)) {
10996 sigma_dut_print(dut, DUT_MSG_ERROR,
10997 "Failed to set TWT req support %d",
10998 set_val);
10999 send_resp(dut, conn, SIGMA_ERROR,
11000 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030011001 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070011002 }
11003 }
11004
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -070011005 val = get_param(cmd, "PreamblePunctRx");
11006 if (val && get_driver_type(dut) == DRIVER_WCN) {
11007 int set_val;
11008
11009 if (strcasecmp(val, "Enable") == 0) {
11010 set_val = 1;
11011 } else if (strcasecmp(val, "Disable") == 0) {
11012 set_val = 0;
11013 } else {
11014 send_resp(dut, conn, SIGMA_ERROR,
11015 "ErrorCode,Invalid PreamblePunctRx");
11016 return STATUS_SENT_ERROR;
11017 }
11018
11019 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
11020 sigma_dut_print(dut, DUT_MSG_ERROR,
11021 "Failed to set PreamblePunctRx support %d",
11022 set_val);
11023 send_resp(dut, conn, SIGMA_ERROR,
11024 "ErrorCode,Failed to set PreamblePunctRx");
11025 return STATUS_SENT_ERROR;
11026 }
11027 }
11028
Srinivas Girigowda0525e292020-11-12 13:28:21 -080011029 val = get_param(cmd, "FullBW_ULMUMIMO");
11030 if (val) {
11031 int set_val;
11032
11033 if (strcasecmp(val, "Enable") == 0) {
11034 set_val = 1;
11035 } else if (strcasecmp(val, "Disable") == 0) {
11036 set_val = 0;
11037 } else {
11038 send_resp(dut, conn, SIGMA_ERROR,
11039 "ErrorCode,Invalid FullBW_ULMUMIMO");
11040 return STATUS_SENT_ERROR;
11041 }
11042
11043 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
11044 sigma_dut_print(dut, DUT_MSG_ERROR,
11045 "Failed to set FullBW_ULMUMIMO %d",
11046 set_val);
11047 send_resp(dut, conn, SIGMA_ERROR,
11048 "ErrorCode,Failed to set FullBW_ULMUMIMO");
11049 return STATUS_SENT_ERROR;
11050 }
11051 }
11052
Srinivas Girigowda6707f032020-10-26 15:24:46 -070011053 val = get_param(cmd, "TWTInfoFrameTx");
11054 if (val) {
11055 if (strcasecmp(val, "Enable") == 0) {
11056 /* No-op */
11057 } else if (strcasecmp(val, "Disable") == 0) {
11058 /* No-op */
11059 } else {
11060 send_resp(dut, conn, SIGMA_ERROR,
11061 "ErrorCode,Invalid TWTInfoFrameTx");
11062 return STATUS_SENT_ERROR;
11063 }
11064 }
11065
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011066 val = get_param(cmd, "MU_EDCA");
11067 if (val && (strcasecmp(val, "Override") == 0)) {
11068 if (sta_set_mu_edca_override(dut, intf, 1)) {
11069 send_resp(dut, conn, SIGMA_ERROR,
11070 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +030011071 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011072 }
11073 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011074
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070011075 val = get_param(cmd, "PPDUTxType");
11076 if (val && strcasecmp(val, "ER-SU") == 0) {
11077 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
11078 send_resp(dut, conn, SIGMA_ERROR,
11079 "ErrorCode,Failed to set ER-SU PPDU type Tx");
11080 return STATUS_SENT_ERROR;
11081 }
11082 }
11083
11084 val = get_param(cmd, "RUAllocTone");
11085 if (val && strcasecmp(val, "242") == 0) {
11086 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
11087 send_resp(dut, conn, SIGMA_ERROR,
11088 "ErrorCode,Failed to set RU 242 tone Tx");
11089 return STATUS_SENT_ERROR;
11090 }
11091 }
11092
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011093 val = get_param(cmd, "OMControl");
11094 if (val) {
11095 int set_val = 1;
11096
11097 if (strcasecmp(val, "Enable") == 0)
11098 set_val = 1;
11099 else if (strcasecmp(val, "Disable") == 0)
11100 set_val = 0;
11101
11102 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
11103 send_resp(dut, conn, SIGMA_ERROR,
11104 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +030011105 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011106 }
11107 }
11108
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -070011109 val = get_param(cmd, "BSSMaxIdlePeriod");
11110 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
11111 send_resp(dut, conn, SIGMA_ERROR,
11112 "ErrorCode,Failed to set BSS max idle period");
11113 return STATUS_SENT_ERROR;
11114 }
11115
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -070011116 val = get_param(cmd, "BSS_max_idle");
11117 if (val) {
11118 int set_val = 0;
11119
11120 if (strcasecmp(val, "Enable") == 0)
11121 set_val = 1;
11122 else if (strcasecmp(val, "Disable") == 0)
11123 set_val = 0;
11124 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
11125 send_resp(dut, conn, SIGMA_ERROR,
11126 "ErrorCode,Failed to set BSS max idle support");
11127 return STATUS_SENT_ERROR;
11128 }
11129 }
11130
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011131 val = get_param(cmd, "ADDBAResp_BufSize");
11132 if (val) {
11133 int buf_size;
11134
11135 if (strcasecmp(val, "gt64") == 0)
11136 buf_size = 256;
11137 else
11138 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011139 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011140 sta_set_addba_buf_size(dut, intf, buf_size)) {
11141 send_resp(dut, conn, SIGMA_ERROR,
11142 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011143 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011144 }
11145 }
11146
11147 val = get_param(cmd, "ADDBAReq_BufSize");
11148 if (val) {
11149 int buf_size;
11150
11151 if (strcasecmp(val, "gt64") == 0)
11152 buf_size = 256;
11153 else
11154 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011155 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011156 sta_set_addba_buf_size(dut, intf, buf_size)) {
11157 send_resp(dut, conn, SIGMA_ERROR,
11158 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011159 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011160 }
11161 }
11162
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011163 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11164}
11165
11166
11167static int sta_set_wireless_60g(struct sigma_dut *dut,
11168 struct sigma_conn *conn,
11169 struct sigma_cmd *cmd)
11170{
11171 const char *dev_role = get_param(cmd, "DevRole");
11172
11173 if (!dev_role) {
11174 send_resp(dut, conn, SIGMA_INVALID,
11175 "ErrorCode,DevRole not specified");
11176 return 0;
11177 }
11178
11179 if (strcasecmp(dev_role, "PCP") == 0)
11180 return sta_set_60g_pcp(dut, conn, cmd);
11181 if (strcasecmp(dev_role, "STA") == 0)
11182 return sta_set_60g_sta(dut, conn, cmd);
11183 send_resp(dut, conn, SIGMA_INVALID,
11184 "ErrorCode,DevRole not supported");
11185 return 0;
11186}
11187
11188
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011189static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
11190 struct sigma_cmd *cmd)
11191{
11192 int status;
11193 const char *intf = get_param(cmd, "Interface");
11194 const char *val = get_param(cmd, "DevRole");
11195
11196 if (val && strcasecmp(val, "STA-CFON") == 0) {
11197 status = sta_cfon_set_wireless(dut, conn, cmd);
11198 if (status)
11199 return status;
11200 }
11201 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11202}
11203
11204
Jouni Malinen67433fc2020-06-26 22:50:33 +030011205static enum sigma_cmd_result
11206sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
11207 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011208{
11209 const char *intf = get_param(cmd, "Interface");
11210 const char *val;
11211
11212 val = get_param(cmd, "ocvc");
11213 if (val)
11214 dut->ocvc = atoi(val);
11215
Jouni Malinen67433fc2020-06-26 22:50:33 +030011216 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +053011217 if (val && dut->client_privacy != atoi(val) &&
11218 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
11219 send_resp(dut, conn, SIGMA_ERROR,
11220 "errorCode,Failed to configure random MAC address use");
11221 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +030011222 }
11223
Veerendranath Jakkam9ce2b642022-02-28 18:49:25 +053011224 val = get_param(cmd, "GKH_G2_Tx");
11225 if (val) {
11226 char buf[50];
11227
11228 snprintf(buf, sizeof(buf), "SET disable_eapol_g2_tx %d",
11229 strcasecmp(val, "disable") == 0);
11230
11231 if (wpa_command(intf, buf) < 0) {
11232 send_resp(dut, conn, SIGMA_ERROR,
11233 "errorCode,Failed to enable/disable G2 transmit");
11234 return STATUS_SENT_ERROR;
11235 }
11236 }
11237
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011238 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11239}
11240
11241
Jouni Malinenf7222712019-06-13 01:50:21 +030011242static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
11243 struct sigma_conn *conn,
11244 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011245{
11246 const char *val;
11247
11248 val = get_param(cmd, "Program");
Veerendranath Jakkam9ce2b642022-02-28 18:49:25 +053011249 if (!val)
11250 val = get_param(cmd, "Prog");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011251 if (val) {
11252 if (strcasecmp(val, "11n") == 0)
11253 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080011254 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011255 return cmd_sta_set_wireless_vht(dut, conn, cmd);
11256 if (strcasecmp(val, "60ghz") == 0)
11257 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011258 if (strcasecmp(val, "OCE") == 0)
11259 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020011260 /* sta_set_wireless in WPS program is only used for 60G */
11261 if (is_60g_sigma_dut(dut))
11262 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011263 if (strcasecmp(val, "WPA3") == 0)
11264 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011265 send_resp(dut, conn, SIGMA_ERROR,
11266 "ErrorCode,Program value not supported");
11267 } else {
11268 send_resp(dut, conn, SIGMA_ERROR,
11269 "ErrorCode,Program argument not available");
11270 }
11271
11272 return 0;
11273}
11274
11275
11276static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
11277 int tid)
11278{
11279 char buf[100];
11280 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
11281
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053011282 if (tid < 0 ||
11283 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
11284 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
11285 return;
11286 }
11287
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011288 /*
11289 * Two ways to ensure that addba request with a
11290 * non zero TID could be sent out. EV 117296
11291 */
11292 snprintf(buf, sizeof(buf),
11293 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
11294 tid);
11295 if (system(buf) != 0) {
11296 sigma_dut_print(dut, DUT_MSG_ERROR,
11297 "Ping did not send out");
11298 }
11299
11300 snprintf(buf, sizeof(buf),
11301 "iwconfig %s | grep Access | awk '{print $6}' > %s",
11302 intf, VI_QOS_TMP_FILE);
11303 if (system(buf) != 0)
11304 return;
11305
11306 snprintf(buf, sizeof(buf),
11307 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
11308 intf, VI_QOS_TMP_FILE);
11309 if (system(buf) != 0)
11310 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
11311
11312 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
11313 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
11314 if (system(buf) != 0) {
11315 sigma_dut_print(dut, DUT_MSG_ERROR,
11316 "VI_QOS_TEMP_FILE generation error failed");
11317 }
11318 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11319 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11320 if (system(buf) != 0) {
11321 sigma_dut_print(dut, DUT_MSG_ERROR,
11322 "VI_QOS_FILE generation failed");
11323 }
11324
11325 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11326 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11327 if (system(buf) != 0) {
11328 sigma_dut_print(dut, DUT_MSG_ERROR,
11329 "VI_QOS_FILE generation failed");
11330 }
11331
11332 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
11333 if (system(buf) != 0) {
11334 }
11335}
11336
11337
11338static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11339 struct sigma_cmd *cmd)
11340{
11341 const char *intf = get_param(cmd, "Interface");
11342 const char *val;
11343 int tid = 0;
11344 char buf[100];
11345
11346 val = get_param(cmd, "TID");
11347 if (val) {
11348 tid = atoi(val);
11349 if (tid)
11350 ath_sta_inject_frame(dut, intf, tid);
11351 }
11352
11353 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011354 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011355
11356 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
11357 if (system(buf) != 0) {
11358 sigma_dut_print(dut, DUT_MSG_ERROR,
11359 "wifitool senddelba failed");
11360 }
11361
11362 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
11363 if (system(buf) != 0) {
11364 sigma_dut_print(dut, DUT_MSG_ERROR,
11365 "wifitool sendaddba failed");
11366 }
11367
11368 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11369
11370 return 1;
11371}
11372
11373
Lior David9981b512017-01-20 13:16:40 +020011374#ifdef __linux__
11375
11376static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
11377 int agg_size)
11378{
11379 char dir[128], buf[128];
11380 FILE *f;
11381 regex_t re;
11382 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030011383 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020011384
11385 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
11386 sigma_dut_print(dut, DUT_MSG_ERROR,
11387 "failed to get wil6210 debugfs dir");
11388 return -1;
11389 }
11390
Jouni Malinen3aa72862019-05-29 23:14:51 +030011391 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
11392 if (res < 0 || res >= sizeof(buf))
11393 return -1;
Lior David9981b512017-01-20 13:16:40 +020011394 f = fopen(buf, "r");
11395 if (!f) {
11396 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011397 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030011398 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
11399 if (res < 0 || res >= sizeof(buf))
11400 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011401 f = fopen(buf, "r");
11402 if (!f) {
11403 sigma_dut_print(dut, DUT_MSG_ERROR,
11404 "failed to open: %s", buf);
11405 return -1;
11406 }
Lior David9981b512017-01-20 13:16:40 +020011407 }
11408
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011409 /* can be either VRING tx... or RING... */
11410 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020011411 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
11412 goto out;
11413 }
11414
11415 /* find TX VRING for the mac address */
11416 found = 0;
11417 while (fgets(buf, sizeof(buf), f)) {
11418 if (strcasestr(buf, dest_mac)) {
11419 found = 1;
11420 break;
11421 }
11422 }
11423
11424 if (!found) {
11425 sigma_dut_print(dut, DUT_MSG_ERROR,
11426 "no TX VRING for %s", dest_mac);
11427 goto out;
11428 }
11429
11430 /* extract VRING ID, "VRING tx_<id> = {" */
11431 if (!fgets(buf, sizeof(buf), f)) {
11432 sigma_dut_print(dut, DUT_MSG_ERROR,
11433 "no VRING start line for %s", dest_mac);
11434 goto out;
11435 }
11436
11437 rc = regexec(&re, buf, 2, m, 0);
11438 regfree(&re);
11439 if (rc || m[1].rm_so < 0) {
11440 sigma_dut_print(dut, DUT_MSG_ERROR,
11441 "no VRING TX ID for %s", dest_mac);
11442 goto out;
11443 }
11444 buf[m[1].rm_eo] = 0;
11445 vring_id = atoi(&buf[m[1].rm_so]);
11446
11447 /* send the addba command */
11448 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011449 res = snprintf(buf, sizeof(buf), "%s/back", dir);
11450 if (res < 0 || res >= sizeof(buf))
11451 return -1;
Lior David9981b512017-01-20 13:16:40 +020011452 f = fopen(buf, "w");
11453 if (!f) {
11454 sigma_dut_print(dut, DUT_MSG_ERROR,
11455 "failed to open: %s", buf);
11456 return -1;
11457 }
11458
11459 fprintf(f, "add %d %d\n", vring_id, agg_size);
11460
11461 ret = 0;
11462
11463out:
11464 fclose(f);
11465
11466 return ret;
11467}
11468
11469
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011470int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11471 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011472{
11473 const char *val;
11474 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011475
11476 val = get_param(cmd, "TID");
11477 if (val) {
11478 tid = atoi(val);
11479 if (tid != 0) {
11480 sigma_dut_print(dut, DUT_MSG_ERROR,
11481 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
11482 tid);
11483 }
11484 }
11485
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011486 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011487 if (!val) {
11488 sigma_dut_print(dut, DUT_MSG_ERROR,
11489 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011490 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011491 }
11492
Lior David9981b512017-01-20 13:16:40 +020011493 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011494 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011495
11496 return 1;
11497}
11498
Lior David9981b512017-01-20 13:16:40 +020011499#endif /* __linux__ */
11500
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011501
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011502static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11503 struct sigma_cmd *cmd)
11504{
11505#ifdef NL80211_SUPPORT
11506 const char *intf = get_param(cmd, "Interface");
11507 const char *val;
11508 int tid = -1;
11509 int bufsize = 64;
11510 struct nl_msg *msg;
11511 int ret = 0;
11512 struct nlattr *params;
11513 int ifindex;
11514
11515 val = get_param(cmd, "TID");
11516 if (val)
11517 tid = atoi(val);
11518
11519 if (tid == -1) {
11520 send_resp(dut, conn, SIGMA_ERROR,
11521 "ErrorCode,sta_send_addba tid invalid");
11522 return 0;
11523 }
11524
11525 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11526
11527 ifindex = if_nametoindex(intf);
11528 if (ifindex == 0) {
11529 sigma_dut_print(dut, DUT_MSG_ERROR,
11530 "%s: Index for interface %s failed",
11531 __func__, intf);
11532 send_resp(dut, conn, SIGMA_ERROR,
11533 "ErrorCode,sta_send_addba interface invalid");
11534 return 0;
11535 }
11536
11537 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11538 NL80211_CMD_VENDOR)) ||
11539 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
11540 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
11541 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
11542 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
11543 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
11544 nla_put_u8(msg,
11545 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
11546 QCA_WLAN_ADD_BA) ||
11547 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
11548 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070011549 nla_put_u16(msg,
11550 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
11551 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011552 sigma_dut_print(dut, DUT_MSG_ERROR,
11553 "%s: err in adding vendor_cmd and vendor_data",
11554 __func__);
11555 nlmsg_free(msg);
11556 send_resp(dut, conn, SIGMA_ERROR,
11557 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
11558 return 0;
11559 }
11560 nla_nest_end(msg, params);
11561
11562 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11563 if (ret) {
11564 sigma_dut_print(dut, DUT_MSG_ERROR,
11565 "%s: err in send_and_recv_msgs, ret=%d",
11566 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053011567 if (ret == -EOPNOTSUPP)
11568 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011569 send_resp(dut, conn, SIGMA_ERROR,
11570 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
11571 return 0;
11572 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011573#else /* NL80211_SUPPORT */
11574 sigma_dut_print(dut, DUT_MSG_ERROR,
11575 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011576#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053011577
11578 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011579}
11580
11581
Jouni Malinenf7222712019-06-13 01:50:21 +030011582static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
11583 struct sigma_conn *conn,
11584 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011585{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011586 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011587 case DRIVER_ATHEROS:
11588 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011589 case DRIVER_WCN:
11590 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020011591#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011592 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011593 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020011594#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011595 default:
11596 /*
11597 * There is no driver specific implementation for other drivers.
11598 * Ignore the command and report COMPLETE since the following
11599 * throughput test operation will end up sending ADDBA anyway.
11600 */
11601 return 1;
11602 }
11603}
11604
11605
11606int inject_eth_frame(int s, const void *data, size_t len,
11607 unsigned short ethtype, char *dst, char *src)
11608{
11609 struct iovec iov[4] = {
11610 {
11611 .iov_base = dst,
11612 .iov_len = ETH_ALEN,
11613 },
11614 {
11615 .iov_base = src,
11616 .iov_len = ETH_ALEN,
11617 },
11618 {
11619 .iov_base = &ethtype,
11620 .iov_len = sizeof(unsigned short),
11621 },
11622 {
11623 .iov_base = (void *) data,
11624 .iov_len = len,
11625 }
11626 };
11627 struct msghdr msg = {
11628 .msg_name = NULL,
11629 .msg_namelen = 0,
11630 .msg_iov = iov,
11631 .msg_iovlen = 4,
11632 .msg_control = NULL,
11633 .msg_controllen = 0,
11634 .msg_flags = 0,
11635 };
11636
11637 return sendmsg(s, &msg, 0);
11638}
11639
11640#if defined(__linux__) || defined(__QNXNTO__)
11641
11642int inject_frame(int s, const void *data, size_t len, int encrypt)
11643{
11644#define IEEE80211_RADIOTAP_F_WEP 0x04
11645#define IEEE80211_RADIOTAP_F_FRAG 0x08
11646 unsigned char rtap_hdr[] = {
11647 0x00, 0x00, /* radiotap version */
11648 0x0e, 0x00, /* radiotap length */
11649 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
11650 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
11651 0x00, /* padding */
11652 0x00, 0x00, /* RX and TX flags to indicate that */
11653 0x00, 0x00, /* this is the injected frame directly */
11654 };
11655 struct iovec iov[2] = {
11656 {
11657 .iov_base = &rtap_hdr,
11658 .iov_len = sizeof(rtap_hdr),
11659 },
11660 {
11661 .iov_base = (void *) data,
11662 .iov_len = len,
11663 }
11664 };
11665 struct msghdr msg = {
11666 .msg_name = NULL,
11667 .msg_namelen = 0,
11668 .msg_iov = iov,
11669 .msg_iovlen = 2,
11670 .msg_control = NULL,
11671 .msg_controllen = 0,
11672 .msg_flags = 0,
11673 };
11674
11675 if (encrypt)
11676 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
11677
11678 return sendmsg(s, &msg, 0);
11679}
11680
11681
11682int open_monitor(const char *ifname)
11683{
11684#ifdef __QNXNTO__
11685 struct sockaddr_dl ll;
11686 int s;
11687
11688 memset(&ll, 0, sizeof(ll));
11689 ll.sdl_family = AF_LINK;
11690 ll.sdl_index = if_nametoindex(ifname);
11691 if (ll.sdl_index == 0) {
11692 perror("if_nametoindex");
11693 return -1;
11694 }
11695 s = socket(PF_INET, SOCK_RAW, 0);
11696#else /* __QNXNTO__ */
11697 struct sockaddr_ll ll;
11698 int s;
11699
11700 memset(&ll, 0, sizeof(ll));
11701 ll.sll_family = AF_PACKET;
11702 ll.sll_ifindex = if_nametoindex(ifname);
11703 if (ll.sll_ifindex == 0) {
11704 perror("if_nametoindex");
11705 return -1;
11706 }
11707 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
11708#endif /* __QNXNTO__ */
11709 if (s < 0) {
11710 perror("socket[PF_PACKET,SOCK_RAW]");
11711 return -1;
11712 }
11713
11714 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
11715 perror("monitor socket bind");
11716 close(s);
11717 return -1;
11718 }
11719
11720 return s;
11721}
11722
11723
11724static int hex2num(char c)
11725{
11726 if (c >= '0' && c <= '9')
11727 return c - '0';
11728 if (c >= 'a' && c <= 'f')
11729 return c - 'a' + 10;
11730 if (c >= 'A' && c <= 'F')
11731 return c - 'A' + 10;
11732 return -1;
11733}
11734
11735
11736int hwaddr_aton(const char *txt, unsigned char *addr)
11737{
11738 int i;
11739
11740 for (i = 0; i < 6; i++) {
11741 int a, b;
11742
11743 a = hex2num(*txt++);
11744 if (a < 0)
11745 return -1;
11746 b = hex2num(*txt++);
11747 if (b < 0)
11748 return -1;
11749 *addr++ = (a << 4) | b;
11750 if (i < 5 && *txt++ != ':')
11751 return -1;
11752 }
11753
11754 return 0;
11755}
11756
11757#endif /* defined(__linux__) || defined(__QNXNTO__) */
11758
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011759
11760#ifdef NL80211_SUPPORT
11761static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
11762 const u8 *data, size_t data_len, int freq)
11763{
11764 struct nl_msg *msg;
11765 int ret = 0;
11766 int ifindex;
11767
11768 ifindex = if_nametoindex(intf);
11769 if (ifindex == 0) {
11770 sigma_dut_print(dut, DUT_MSG_ERROR,
11771 "%s: Index for interface %s failed",
11772 __func__, intf);
11773 return -1;
11774 }
11775
11776 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11777 NL80211_CMD_FRAME)) ||
11778 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11779 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
11780 sigma_dut_print(dut, DUT_MSG_ERROR,
11781 "%s: Error in adding NL80211_CMD_FRAME",
11782 __func__);
11783 nlmsg_free(msg);
11784 return -1;
11785 }
11786
11787 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11788 if (ret) {
11789 sigma_dut_print(dut, DUT_MSG_ERROR,
11790 "nl80211: Frame command failed: ret=%d (%s) req=%u",
11791 ret, strerror(-ret), freq);
11792 return -1;
11793 }
11794
11795 return 0;
11796}
11797#endif /* NL80211_SUPPORT */
11798
11799
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011800enum send_frame_type {
11801 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
11802};
11803enum send_frame_protection {
11804 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
11805};
11806
11807
11808static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011809 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011810 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011811 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011812{
11813#ifdef __linux__
11814 unsigned char buf[1000], *pos;
11815 int s, res;
11816 char bssid[20], addr[20];
11817 char result[32], ssid[100];
11818 size_t ssid_len;
11819
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011820 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011821 sizeof(result)) < 0 ||
11822 strncmp(result, "COMPLETED", 9) != 0) {
11823 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
11824 return 0;
11825 }
11826
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011827 if (get_wpa_status(get_station_ifname(dut), "bssid",
11828 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011829 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11830 "current BSSID");
11831 return 0;
11832 }
11833
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011834 if (get_wpa_status(get_station_ifname(dut), "address",
11835 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011836 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11837 "own MAC address");
11838 return 0;
11839 }
11840
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011841 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011842 < 0) {
11843 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11844 "current SSID");
11845 return 0;
11846 }
11847 ssid_len = strlen(ssid);
11848
11849 pos = buf;
11850
11851 /* Frame Control */
11852 switch (frame) {
11853 case DISASSOC:
11854 *pos++ = 0xa0;
11855 break;
11856 case DEAUTH:
11857 *pos++ = 0xc0;
11858 break;
11859 case SAQUERY:
11860 *pos++ = 0xd0;
11861 break;
11862 case AUTH:
11863 *pos++ = 0xb0;
11864 break;
11865 case ASSOCREQ:
11866 *pos++ = 0x00;
11867 break;
11868 case REASSOCREQ:
11869 *pos++ = 0x20;
11870 break;
11871 case DLS_REQ:
11872 *pos++ = 0xd0;
11873 break;
11874 }
11875
11876 if (protected == INCORRECT_KEY)
11877 *pos++ = 0x40; /* Set Protected field to 1 */
11878 else
11879 *pos++ = 0x00;
11880
11881 /* Duration */
11882 *pos++ = 0x00;
11883 *pos++ = 0x00;
11884
11885 /* addr1 = DA (current AP) */
11886 hwaddr_aton(bssid, pos);
11887 pos += 6;
11888 /* addr2 = SA (own address) */
11889 hwaddr_aton(addr, pos);
11890 pos += 6;
11891 /* addr3 = BSSID (current AP) */
11892 hwaddr_aton(bssid, pos);
11893 pos += 6;
11894
11895 /* Seq# (to be filled by driver/mac80211) */
11896 *pos++ = 0x00;
11897 *pos++ = 0x00;
11898
11899 if (protected == INCORRECT_KEY) {
11900 /* CCMP parameters */
11901 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
11902 pos += 8;
11903 }
11904
11905 if (protected == INCORRECT_KEY) {
11906 switch (frame) {
11907 case DEAUTH:
11908 /* Reason code (encrypted) */
11909 memcpy(pos, "\xa7\x39", 2);
11910 pos += 2;
11911 break;
11912 case DISASSOC:
11913 /* Reason code (encrypted) */
11914 memcpy(pos, "\xa7\x39", 2);
11915 pos += 2;
11916 break;
11917 case SAQUERY:
11918 /* Category|Action|TransID (encrypted) */
11919 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
11920 pos += 4;
11921 break;
11922 default:
11923 return -1;
11924 }
11925
11926 /* CCMP MIC */
11927 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
11928 pos += 8;
11929 } else {
11930 switch (frame) {
11931 case DEAUTH:
11932 /* reason code = 8 */
11933 *pos++ = 0x08;
11934 *pos++ = 0x00;
11935 break;
11936 case DISASSOC:
11937 /* reason code = 8 */
11938 *pos++ = 0x08;
11939 *pos++ = 0x00;
11940 break;
11941 case SAQUERY:
11942 /* Category - SA Query */
11943 *pos++ = 0x08;
11944 /* SA query Action - Request */
11945 *pos++ = 0x00;
11946 /* Transaction ID */
11947 *pos++ = 0x12;
11948 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011949 if (dut->saquery_oci_freq) {
11950 /* OCI IE - Extended ID */
11951 *pos++ = 0xFF;
11952 *pos++ = 0x04;
11953 *pos++ = 0x36;
11954 /* Operating Class */
11955 *pos++ = 0x74;
11956 /* Primary Channel */
11957 *pos++ = freq_to_channel(dut->saquery_oci_freq);
11958 /* Frequency Segment 1 Channel Number */
11959 *pos++ = 0x00;
11960 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011961 break;
11962 case AUTH:
11963 /* Auth Alg (Open) */
11964 *pos++ = 0x00;
11965 *pos++ = 0x00;
11966 /* Seq# */
11967 *pos++ = 0x01;
11968 *pos++ = 0x00;
11969 /* Status code */
11970 *pos++ = 0x00;
11971 *pos++ = 0x00;
11972 break;
11973 case ASSOCREQ:
11974 /* Capability Information */
11975 *pos++ = 0x31;
11976 *pos++ = 0x04;
11977 /* Listen Interval */
11978 *pos++ = 0x0a;
11979 *pos++ = 0x00;
11980 /* SSID */
11981 *pos++ = 0x00;
11982 *pos++ = ssid_len;
11983 memcpy(pos, ssid, ssid_len);
11984 pos += ssid_len;
11985 /* Supported Rates */
11986 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11987 10);
11988 pos += 10;
11989 /* Extended Supported Rates */
11990 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11991 pos += 6;
11992 /* RSN */
11993 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
11994 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
11995 "\x00\x00\x00\x00\x0f\xac\x06", 28);
11996 pos += 28;
11997 break;
11998 case REASSOCREQ:
11999 /* Capability Information */
12000 *pos++ = 0x31;
12001 *pos++ = 0x04;
12002 /* Listen Interval */
12003 *pos++ = 0x0a;
12004 *pos++ = 0x00;
12005 /* Current AP */
12006 hwaddr_aton(bssid, pos);
12007 pos += 6;
12008 /* SSID */
12009 *pos++ = 0x00;
12010 *pos++ = ssid_len;
12011 memcpy(pos, ssid, ssid_len);
12012 pos += ssid_len;
12013 /* Supported Rates */
12014 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
12015 10);
12016 pos += 10;
12017 /* Extended Supported Rates */
12018 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
12019 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053012020 /* RSNE - Group and Pairwise ciphers */
12021 memcpy(pos,
12022 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
12023 14);
12024 pos += 14;
12025 /* RSNE - AKM Suite count */
12026 *pos++ = 0x01;
12027 *pos++ = 0x00;
12028 /* RSNE - AKM Suites */
12029 if (dut->program == PROGRAM_WPA3)
12030 memcpy(pos, "\x00\x0f\xac\x08", 4);
12031 else
12032 memcpy(pos, "\x00\x0f\xac\x02", 4);
12033 pos += 4;
12034 /* RSNE - Capabilities */
12035 *pos++ = 0xc0;
12036 if (dut->ocvc)
12037 *pos++ = 0x40;
12038 else
12039 *pos++ = 0x00;
12040 /* RSNE - PMKID list and Group Management Ciphers */
12041 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
12042 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012043 break;
12044 case DLS_REQ:
12045 /* Category - DLS */
12046 *pos++ = 0x02;
12047 /* DLS Action - Request */
12048 *pos++ = 0x00;
12049 /* Destination MACAddress */
12050 if (dest)
12051 hwaddr_aton(dest, pos);
12052 else
12053 memset(pos, 0, 6);
12054 pos += 6;
12055 /* Source MACAddress */
12056 hwaddr_aton(addr, pos);
12057 pos += 6;
12058 /* Capability Information */
12059 *pos++ = 0x10; /* Privacy */
12060 *pos++ = 0x06; /* QoS */
12061 /* DLS Timeout Value */
12062 *pos++ = 0x00;
12063 *pos++ = 0x01;
12064 /* Supported rates */
12065 *pos++ = 0x01;
12066 *pos++ = 0x08;
12067 *pos++ = 0x0c; /* 6 Mbps */
12068 *pos++ = 0x12; /* 9 Mbps */
12069 *pos++ = 0x18; /* 12 Mbps */
12070 *pos++ = 0x24; /* 18 Mbps */
12071 *pos++ = 0x30; /* 24 Mbps */
12072 *pos++ = 0x48; /* 36 Mbps */
12073 *pos++ = 0x60; /* 48 Mbps */
12074 *pos++ = 0x6c; /* 54 Mbps */
12075 /* TODO: Extended Supported Rates */
12076 /* TODO: HT Capabilities */
12077 break;
12078 }
12079 }
12080
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012081 if (use_monitor) {
12082 s = open_monitor("sigmadut");
12083 if (s < 0) {
12084 send_resp(dut, conn, SIGMA_ERROR,
12085 "errorCode,Failed to open monitor socket");
12086 return 0;
12087 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012088
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012089 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
12090 if (res < 0) {
12091 send_resp(dut, conn, SIGMA_ERROR,
12092 "errorCode,Failed to inject frame");
12093 close(s);
12094 return 0;
12095 }
12096 if (res < pos - buf) {
12097 send_resp(dut, conn, SIGMA_ERROR,
12098 "errorCode,Only partial frame sent");
12099 close(s);
12100 return 0;
12101 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012102
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012103 close(s);
12104 } else {
12105#ifdef NL80211_SUPPORT
12106 int freq;
12107 char freq_str[10];
12108
12109 if (get_wpa_status(get_station_ifname(dut), "freq",
12110 freq_str, sizeof(freq_str)) < 0) {
12111 send_resp(dut, conn, SIGMA_ERROR,
12112 "errorCode,Could not get current operating frequency");
12113 return 0;
12114 }
12115 freq = atoi(freq_str);
12116
12117 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
12118 send_resp(dut, conn, SIGMA_ERROR,
12119 "errorCode,Failed to inject frame");
12120 return 0;
12121 }
12122#else /* NL80211_SUPPORT */
12123 send_resp(dut, conn, SIGMA_ERROR,
12124 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
12125 return 0;
12126#endif /* NL80211_SUPPORT */
12127 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012128
12129 return 1;
12130#else /* __linux__ */
12131 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
12132 "yet supported");
12133 return 0;
12134#endif /* __linux__ */
12135}
12136
12137
12138static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
12139 struct sigma_conn *conn,
12140 struct sigma_cmd *cmd)
12141{
12142 const char *intf = get_param(cmd, "Interface");
12143 const char *sta, *val;
12144 unsigned char addr[ETH_ALEN];
12145 char buf[100];
12146
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012147 if (!intf)
12148 return -1;
12149
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012150 sta = get_param(cmd, "peer");
12151 if (sta == NULL)
12152 sta = get_param(cmd, "station");
12153 if (sta == NULL) {
12154 send_resp(dut, conn, SIGMA_ERROR,
12155 "ErrorCode,Missing peer address");
12156 return 0;
12157 }
12158 if (hwaddr_aton(sta, addr) < 0) {
12159 send_resp(dut, conn, SIGMA_ERROR,
12160 "ErrorCode,Invalid peer address");
12161 return 0;
12162 }
12163
12164 val = get_param(cmd, "type");
12165 if (val == NULL)
12166 return -1;
12167
12168 if (strcasecmp(val, "DISCOVERY") == 0) {
12169 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
12170 if (wpa_command(intf, buf) < 0) {
12171 send_resp(dut, conn, SIGMA_ERROR,
12172 "ErrorCode,Failed to send TDLS discovery");
12173 return 0;
12174 }
12175 return 1;
12176 }
12177
12178 if (strcasecmp(val, "SETUP") == 0) {
12179 int status = 0, timeout = 0;
12180
12181 val = get_param(cmd, "Status");
12182 if (val)
12183 status = atoi(val);
12184
12185 val = get_param(cmd, "Timeout");
12186 if (val)
12187 timeout = atoi(val);
12188
12189 if (status != 0 && status != 37) {
12190 send_resp(dut, conn, SIGMA_ERROR,
12191 "ErrorCode,Unsupported status value");
12192 return 0;
12193 }
12194
12195 if (timeout != 0 && timeout != 301) {
12196 send_resp(dut, conn, SIGMA_ERROR,
12197 "ErrorCode,Unsupported timeout value");
12198 return 0;
12199 }
12200
12201 if (status && timeout) {
12202 send_resp(dut, conn, SIGMA_ERROR,
12203 "ErrorCode,Unsupported timeout+status "
12204 "combination");
12205 return 0;
12206 }
12207
12208 if (status == 37 &&
12209 wpa_command(intf, "SET tdls_testing 0x200")) {
12210 send_resp(dut, conn, SIGMA_ERROR,
12211 "ErrorCode,Failed to enable "
12212 "decline setup response test mode");
12213 return 0;
12214 }
12215
12216 if (timeout == 301) {
12217 int res;
12218 if (dut->no_tpk_expiration)
12219 res = wpa_command(intf,
12220 "SET tdls_testing 0x108");
12221 else
12222 res = wpa_command(intf,
12223 "SET tdls_testing 0x8");
12224 if (res) {
12225 send_resp(dut, conn, SIGMA_ERROR,
12226 "ErrorCode,Failed to set short TPK "
12227 "lifetime");
12228 return 0;
12229 }
12230 }
12231
12232 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
12233 if (wpa_command(intf, buf) < 0) {
12234 send_resp(dut, conn, SIGMA_ERROR,
12235 "ErrorCode,Failed to send TDLS setup");
12236 return 0;
12237 }
12238 return 1;
12239 }
12240
12241 if (strcasecmp(val, "TEARDOWN") == 0) {
12242 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
12243 if (wpa_command(intf, buf) < 0) {
12244 send_resp(dut, conn, SIGMA_ERROR,
12245 "ErrorCode,Failed to send TDLS teardown");
12246 return 0;
12247 }
12248 return 1;
12249 }
12250
12251 send_resp(dut, conn, SIGMA_ERROR,
12252 "ErrorCode,Unsupported TDLS frame");
12253 return 0;
12254}
12255
12256
12257static int sta_ap_known(const char *ifname, const char *bssid)
12258{
12259 char buf[4096];
12260
Jouni Malinendd32f192018-09-15 02:55:19 +030012261 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012262 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
12263 return 0;
12264 if (strncmp(buf, "id=", 3) != 0)
12265 return 0;
12266 return 1;
12267}
12268
12269
12270static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
12271 const char *bssid)
12272{
12273 int res;
12274 struct wpa_ctrl *ctrl;
12275 char buf[256];
12276
12277 if (sta_ap_known(ifname, bssid))
12278 return 0;
12279 sigma_dut_print(dut, DUT_MSG_DEBUG,
12280 "AP not in BSS table - start scan");
12281
12282 ctrl = open_wpa_mon(ifname);
12283 if (ctrl == NULL) {
12284 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12285 "wpa_supplicant monitor connection");
12286 return -1;
12287 }
12288
12289 if (wpa_command(ifname, "SCAN") < 0) {
12290 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
12291 wpa_ctrl_detach(ctrl);
12292 wpa_ctrl_close(ctrl);
12293 return -1;
12294 }
12295
12296 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12297 buf, sizeof(buf));
12298
12299 wpa_ctrl_detach(ctrl);
12300 wpa_ctrl_close(ctrl);
12301
12302 if (res < 0) {
12303 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
12304 return -1;
12305 }
12306
12307 if (sta_ap_known(ifname, bssid))
12308 return 0;
12309 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
12310 return -1;
12311}
12312
12313
12314static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
12315 struct sigma_conn *conn,
12316 struct sigma_cmd *cmd,
12317 const char *intf)
12318{
12319 char buf[200];
12320
12321 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
12322 if (system(buf) != 0) {
12323 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
12324 "ndsend");
12325 return 0;
12326 }
12327
12328 return 1;
12329}
12330
12331
12332static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
12333 struct sigma_conn *conn,
12334 struct sigma_cmd *cmd,
12335 const char *intf)
12336{
12337 char buf[200];
12338 const char *ip = get_param(cmd, "SenderIP");
12339
Peng Xu26b356d2017-10-04 17:58:16 -070012340 if (!ip)
12341 return 0;
12342
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012343 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
12344 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12345 if (system(buf) == 0) {
12346 sigma_dut_print(dut, DUT_MSG_INFO,
12347 "Neighbor Solicitation got a response "
12348 "for %s@%s", ip, intf);
12349 }
12350
12351 return 1;
12352}
12353
12354
12355static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
12356 struct sigma_conn *conn,
12357 struct sigma_cmd *cmd,
12358 const char *ifname)
12359{
12360 char buf[200];
12361 const char *ip = get_param(cmd, "SenderIP");
12362
12363 if (ip == NULL) {
12364 send_resp(dut, conn, SIGMA_ERROR,
12365 "ErrorCode,Missing SenderIP parameter");
12366 return 0;
12367 }
12368 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
12369 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12370 if (system(buf) != 0) {
12371 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
12372 "for %s@%s", ip, ifname);
12373 }
12374
12375 return 1;
12376}
12377
12378
12379static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
12380 struct sigma_conn *conn,
12381 struct sigma_cmd *cmd,
12382 const char *ifname)
12383{
12384 char buf[200];
12385 char ip[16];
12386 int s;
Peng Xub3756882017-10-04 14:39:09 -070012387 struct ifreq ifr;
12388 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012389
12390 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070012391 if (s < 0) {
12392 perror("socket");
12393 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012394 }
12395
Peng Xub3756882017-10-04 14:39:09 -070012396 memset(&ifr, 0, sizeof(ifr));
12397 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
12398 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
12399 sigma_dut_print(dut, DUT_MSG_INFO,
12400 "Failed to get %s IP address: %s",
12401 ifname, strerror(errno));
12402 close(s);
12403 return -1;
12404 }
12405 close(s);
12406
12407 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
12408 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
12409
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012410 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
12411 ip);
12412 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12413 if (system(buf) != 0) {
12414 }
12415
12416 return 1;
12417}
12418
12419
12420static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
12421 struct sigma_conn *conn,
12422 struct sigma_cmd *cmd,
12423 const char *ifname)
12424{
12425 char buf[200], addr[20];
12426 char dst[ETH_ALEN], src[ETH_ALEN];
12427 short ethtype = htons(ETH_P_ARP);
12428 char *pos;
12429 int s, res;
12430 const char *val;
12431 struct sockaddr_in taddr;
12432
12433 val = get_param(cmd, "dest");
12434 if (val)
12435 hwaddr_aton(val, (unsigned char *) dst);
12436
12437 val = get_param(cmd, "DestIP");
12438 if (val)
12439 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070012440 else
12441 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012442
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012443 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012444 sizeof(addr)) < 0)
12445 return -2;
12446 hwaddr_aton(addr, (unsigned char *) src);
12447
12448 pos = buf;
12449 *pos++ = 0x00;
12450 *pos++ = 0x01;
12451 *pos++ = 0x08;
12452 *pos++ = 0x00;
12453 *pos++ = 0x06;
12454 *pos++ = 0x04;
12455 *pos++ = 0x00;
12456 *pos++ = 0x02;
12457 memcpy(pos, src, ETH_ALEN);
12458 pos += ETH_ALEN;
12459 memcpy(pos, &taddr.sin_addr, 4);
12460 pos += 4;
12461 memcpy(pos, dst, ETH_ALEN);
12462 pos += ETH_ALEN;
12463 memcpy(pos, &taddr.sin_addr, 4);
12464 pos += 4;
12465
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012466 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012467 if (s < 0) {
12468 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
12469 "monitor socket");
12470 return 0;
12471 }
12472
12473 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
12474 if (res < 0) {
12475 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
12476 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053012477 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012478 return 0;
12479 }
12480
12481 close(s);
12482
12483 return 1;
12484}
12485
12486
12487static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
12488 struct sigma_conn *conn,
12489 struct sigma_cmd *cmd,
12490 const char *intf, const char *dest)
12491{
12492 char buf[100];
12493
12494 if (if_nametoindex("sigmadut") == 0) {
12495 snprintf(buf, sizeof(buf),
12496 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012497 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012498 if (system(buf) != 0 ||
12499 if_nametoindex("sigmadut") == 0) {
12500 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12501 "monitor interface with '%s'", buf);
12502 return -2;
12503 }
12504 }
12505
12506 if (system("ifconfig sigmadut up") != 0) {
12507 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12508 "monitor interface up");
12509 return -2;
12510 }
12511
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012512 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012513}
12514
12515
12516static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
12517 struct sigma_conn *conn,
12518 struct sigma_cmd *cmd)
12519{
12520 const char *intf = get_param(cmd, "Interface");
12521 const char *dest = get_param(cmd, "Dest");
12522 const char *type = get_param(cmd, "FrameName");
12523 const char *val;
12524 char buf[200], *pos, *end;
12525 int count, count2;
12526
12527 if (type == NULL)
12528 type = get_param(cmd, "Type");
12529
12530 if (intf == NULL || dest == NULL || type == NULL)
12531 return -1;
12532
12533 if (strcasecmp(type, "NeighAdv") == 0)
12534 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
12535
12536 if (strcasecmp(type, "NeighSolicitReq") == 0)
12537 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
12538
12539 if (strcasecmp(type, "ARPProbe") == 0)
12540 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
12541
12542 if (strcasecmp(type, "ARPAnnounce") == 0)
12543 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
12544
12545 if (strcasecmp(type, "ARPReply") == 0)
12546 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
12547
12548 if (strcasecmp(type, "DLS-request") == 0 ||
12549 strcasecmp(type, "DLSrequest") == 0)
12550 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
12551 dest);
12552
12553 if (strcasecmp(type, "ANQPQuery") != 0 &&
12554 strcasecmp(type, "Query") != 0) {
12555 send_resp(dut, conn, SIGMA_ERROR,
12556 "ErrorCode,Unsupported HS 2.0 send frame type");
12557 return 0;
12558 }
12559
12560 if (sta_scan_ap(dut, intf, dest) < 0) {
12561 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
12562 "the requested AP");
12563 return 0;
12564 }
12565
12566 pos = buf;
12567 end = buf + sizeof(buf);
12568 count = 0;
12569 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
12570
12571 val = get_param(cmd, "ANQP_CAP_LIST");
12572 if (val && atoi(val)) {
12573 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
12574 count++;
12575 }
12576
12577 val = get_param(cmd, "VENUE_NAME");
12578 if (val && atoi(val)) {
12579 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
12580 count++;
12581 }
12582
12583 val = get_param(cmd, "NETWORK_AUTH_TYPE");
12584 if (val && atoi(val)) {
12585 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
12586 count++;
12587 }
12588
12589 val = get_param(cmd, "ROAMING_CONS");
12590 if (val && atoi(val)) {
12591 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
12592 count++;
12593 }
12594
12595 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
12596 if (val && atoi(val)) {
12597 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
12598 count++;
12599 }
12600
12601 val = get_param(cmd, "NAI_REALM_LIST");
12602 if (val && atoi(val)) {
12603 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
12604 count++;
12605 }
12606
12607 val = get_param(cmd, "3GPP_INFO");
12608 if (val && atoi(val)) {
12609 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
12610 count++;
12611 }
12612
12613 val = get_param(cmd, "DOMAIN_LIST");
12614 if (val && atoi(val)) {
12615 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
12616 count++;
12617 }
12618
Jouni Malinen34cf9532018-04-29 19:26:33 +030012619 val = get_param(cmd, "Venue_URL");
12620 if (val && atoi(val)) {
12621 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
12622 count++;
12623 }
12624
Jouni Malinend3bca5d2018-04-29 17:25:23 +030012625 val = get_param(cmd, "Advice_Of_Charge");
12626 if (val && atoi(val)) {
12627 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
12628 count++;
12629 }
12630
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012631 if (count && wpa_command(intf, buf)) {
12632 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
12633 return 0;
12634 }
12635
12636 pos = buf;
12637 end = buf + sizeof(buf);
12638 count2 = 0;
12639 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
12640
12641 val = get_param(cmd, "HS_CAP_LIST");
12642 if (val && atoi(val)) {
12643 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
12644 count2++;
12645 }
12646
12647 val = get_param(cmd, "OPER_NAME");
12648 if (val && atoi(val)) {
12649 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
12650 count2++;
12651 }
12652
12653 val = get_param(cmd, "WAN_METRICS");
12654 if (!val)
12655 val = get_param(cmd, "WAN_MAT");
12656 if (!val)
12657 val = get_param(cmd, "WAN_MET");
12658 if (val && atoi(val)) {
12659 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
12660 count2++;
12661 }
12662
12663 val = get_param(cmd, "CONNECTION_CAPABILITY");
12664 if (val && atoi(val)) {
12665 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
12666 count2++;
12667 }
12668
12669 val = get_param(cmd, "OP_CLASS");
12670 if (val && atoi(val)) {
12671 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
12672 count2++;
12673 }
12674
12675 val = get_param(cmd, "OSU_PROVIDER_LIST");
12676 if (val && atoi(val)) {
12677 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
12678 count2++;
12679 }
12680
Jouni Malinenf67afec2018-04-29 19:24:58 +030012681 val = get_param(cmd, "OPER_ICON_METADATA");
12682 if (!val)
12683 val = get_param(cmd, "OPERATOR_ICON_METADATA");
12684 if (val && atoi(val)) {
12685 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
12686 count2++;
12687 }
12688
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012689 if (count && count2) {
12690 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
12691 "second query");
12692 sleep(1);
12693 }
12694
12695 if (count2 && wpa_command(intf, buf)) {
12696 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
12697 "failed");
12698 return 0;
12699 }
12700
12701 val = get_param(cmd, "NAI_HOME_REALM_LIST");
12702 if (val) {
12703 if (count || count2) {
12704 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12705 "sending out second query");
12706 sleep(1);
12707 }
12708
12709 if (strcmp(val, "1") == 0)
12710 val = "mail.example.com";
12711 snprintf(buf, end - pos,
12712 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
12713 dest, val);
12714 if (wpa_command(intf, buf)) {
12715 send_resp(dut, conn, SIGMA_ERROR,
12716 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
12717 "failed");
12718 return 0;
12719 }
12720 }
12721
12722 val = get_param(cmd, "ICON_REQUEST");
12723 if (val) {
12724 if (count || count2) {
12725 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12726 "sending out second query");
12727 sleep(1);
12728 }
12729
12730 snprintf(buf, end - pos,
12731 "HS20_ICON_REQUEST %s %s", dest, val);
12732 if (wpa_command(intf, buf)) {
12733 send_resp(dut, conn, SIGMA_ERROR,
12734 "ErrorCode,HS20_ICON_REQUEST failed");
12735 return 0;
12736 }
12737 }
12738
12739 return 1;
12740}
12741
12742
12743static int ath_sta_send_frame_vht(struct sigma_dut *dut,
12744 struct sigma_conn *conn,
12745 struct sigma_cmd *cmd)
12746{
12747 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012748 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012749 int chwidth, nss;
12750
12751 val = get_param(cmd, "framename");
12752 if (!val)
12753 return -1;
12754 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12755
12756 /* Command sequence to generate Op mode notification */
12757 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012758 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012759
12760 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012761 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012762
12763 /* Extract Channel width */
12764 val = get_param(cmd, "Channel_width");
12765 if (val) {
12766 switch (atoi(val)) {
12767 case 20:
12768 chwidth = 0;
12769 break;
12770 case 40:
12771 chwidth = 1;
12772 break;
12773 case 80:
12774 chwidth = 2;
12775 break;
12776 case 160:
12777 chwidth = 3;
12778 break;
12779 default:
12780 chwidth = 2;
12781 break;
12782 }
12783
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012784 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012785 }
12786
12787 /* Extract NSS */
12788 val = get_param(cmd, "NSS");
12789 if (val) {
12790 switch (atoi(val)) {
12791 case 1:
12792 nss = 1;
12793 break;
12794 case 2:
12795 nss = 3;
12796 break;
12797 case 3:
12798 nss = 7;
12799 break;
12800 default:
12801 /* We do not support NSS > 3 */
12802 nss = 3;
12803 break;
12804 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012805 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012806 }
12807
12808 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012809 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012810 }
12811
12812 return 1;
12813}
12814
12815
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012816static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
12817 enum send_frame_protection protected)
12818{
12819#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012820 return wcn_wifi_test_config_set_u8(
12821 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
12822 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012823#else /* NL80211_SUPPORT */
12824 sigma_dut_print(dut, DUT_MSG_ERROR,
12825 "PMF config cannot be set without NL80211_SUPPORT defined");
12826 return -1;
12827#endif /* NL80211_SUPPORT */
12828}
12829
12830
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012831static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
12832 struct sigma_conn *conn,
12833 struct sigma_cmd *cmd)
12834{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012835 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012836 case DRIVER_ATHEROS:
12837 return ath_sta_send_frame_vht(dut, conn, cmd);
12838 default:
12839 send_resp(dut, conn, SIGMA_ERROR,
12840 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
12841 return 0;
12842 }
12843}
12844
12845
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012846static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
12847{
12848#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012849 return wcn_wifi_test_config_set_flag(
12850 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012851#else /* NL80211_SUPPORT */
12852 sigma_dut_print(dut, DUT_MSG_ERROR,
12853 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
12854 return -1;
12855#endif /* NL80211_SUPPORT */
12856}
12857
12858
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012859static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
12860 struct sigma_cmd *cmd)
12861{
12862 const char *val;
12863 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012864 enum send_frame_protection protected;
12865 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012866
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012867 if (!intf)
12868 return -1;
12869
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012870 val = get_param(cmd, "framename");
12871 if (!val)
12872 return -1;
12873 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12874
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012875 pmf = get_param(cmd, "PMFProtected");
12876 if (!pmf)
12877 pmf = get_param(cmd, "Protected");
12878 if (pmf) {
12879 if (strcasecmp(pmf, "Correct-key") == 0 ||
12880 strcasecmp(pmf, "CorrectKey") == 0) {
12881 protected = CORRECT_KEY;
12882 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
12883 protected = INCORRECT_KEY;
12884 } else if (strcasecmp(pmf, "Unprotected") == 0) {
12885 protected = UNPROTECTED;
12886 } else {
12887 send_resp(dut, conn, SIGMA_ERROR,
12888 "errorCode,Unsupported PMFProtected");
12889 return STATUS_SENT_ERROR;
12890 }
12891 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
12892 protected);
12893 wcn_sta_set_pmf_config(dut, intf, protected);
12894 }
12895
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012896 /* Command sequence to generate Op mode notification */
12897 if (val && strcasecmp(val, "action") == 0) {
12898 val = get_param(cmd, "PPDUTxType");
12899 if (val && strcasecmp(val, "TB") == 0) {
12900 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
12901 sigma_dut_print(dut, DUT_MSG_ERROR,
12902 "failed to send TB PPDU Tx cfg");
12903 send_resp(dut, conn, SIGMA_ERROR,
12904 "ErrorCode,set TB PPDU Tx cfg failed");
12905 return 0;
12906 }
12907 return 1;
12908 }
12909
12910 sigma_dut_print(dut, DUT_MSG_ERROR,
12911 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012912
12913 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012914 }
12915
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012916 if (strcasecmp(val, "disassoc") == 0)
12917 wcn_sta_send_disassoc(dut, intf);
12918
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012919 return 1;
12920}
12921
12922
12923static int cmd_sta_send_frame_he(struct sigma_dut *dut,
12924 struct sigma_conn *conn,
12925 struct sigma_cmd *cmd)
12926{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012927 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012928 case DRIVER_WCN:
12929 return wcn_sta_send_frame_he(dut, conn, cmd);
12930 default:
12931 send_resp(dut, conn, SIGMA_ERROR,
12932 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
12933 return 0;
12934 }
12935}
12936
12937
Lior David0fe101e2017-03-09 16:09:50 +020012938#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012939
12940static int
12941wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
12942 const char *frame_name, const char *dest_mac)
12943{
12944 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
12945 const char *ssid = get_param(cmd, "ssid");
12946 const char *countstr = get_param(cmd, "count");
12947 const char *channelstr = get_param(cmd, "channel");
12948 const char *group_id = get_param(cmd, "groupid");
12949 const char *client_id = get_param(cmd, "clientmac");
12950 int count, channel, freq, i;
12951 const char *fname;
12952 char frame[1024], src_mac[20], group_id_attr[25],
12953 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
12954 const char *group_ssid;
12955 const int group_ssid_prefix_len = 9;
12956 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
12957 size_t framelen = sizeof(frame);
12958 struct template_frame_tag tags[2];
12959 size_t tags_total = ARRAY_SIZE(tags);
12960 int tag_index, len, dst_len;
12961
12962 if (!countstr || !channelstr) {
12963 sigma_dut_print(dut, DUT_MSG_ERROR,
12964 "Missing argument: count, channel");
12965 return -1;
12966 }
12967 if (isprobereq && !ssid) {
12968 sigma_dut_print(dut, DUT_MSG_ERROR,
12969 "Missing argument: ssid");
12970 return -1;
12971 }
12972 if (!isprobereq && (!group_id || !client_id)) {
12973 sigma_dut_print(dut, DUT_MSG_ERROR,
12974 "Missing argument: group_id, client_id");
12975 return -1;
12976 }
12977
12978 count = atoi(countstr);
12979 channel = atoi(channelstr);
12980 freq = channel_to_freq(dut, channel);
12981
12982 if (!freq) {
12983 sigma_dut_print(dut, DUT_MSG_ERROR,
12984 "invalid channel: %s", channelstr);
12985 return -1;
12986 }
12987
12988 if (isprobereq) {
12989 if (strcasecmp(ssid, "wildcard") == 0) {
12990 fname = "probe_req_wildcard.txt";
12991 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
12992 fname = "probe_req_P2P_Wildcard.txt";
12993 } else {
12994 sigma_dut_print(dut, DUT_MSG_ERROR,
12995 "invalid probe request type");
12996 return -1;
12997 }
12998 } else {
12999 fname = "P2P_device_discovery_req.txt";
13000 }
13001
13002 if (parse_template_frame_file(dut, fname, frame, &framelen,
13003 tags, &tags_total)) {
13004 sigma_dut_print(dut, DUT_MSG_ERROR,
13005 "invalid frame template: %s", fname);
13006 return -1;
13007 }
13008
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013009 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013010 src_mac, sizeof(src_mac)) < 0 ||
13011 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
13012 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
13013 return -1;
13014 /* Use wildcard BSSID, since we are in PBSS */
13015 memset(&hdr->addr3, 0xFF, ETH_ALEN);
13016
13017 if (!isprobereq) {
13018 tag_index = find_template_frame_tag(tags, tags_total, 1);
13019 if (tag_index < 0) {
13020 sigma_dut_print(dut, DUT_MSG_ERROR,
13021 "can't find device id attribute");
13022 return -1;
13023 }
13024 if (parse_mac_address(dut, client_id,
13025 (unsigned char *) client_mac)) {
13026 sigma_dut_print(dut, DUT_MSG_ERROR,
13027 "invalid client_id: %s", client_id);
13028 return -1;
13029 }
13030 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13031 framelen - tags[tag_index].offset,
13032 IEEE80211_P2P_ATTR_DEVICE_ID,
13033 client_mac, ETH_ALEN)) {
13034 sigma_dut_print(dut, DUT_MSG_ERROR,
13035 "fail to replace device id attribute");
13036 return -1;
13037 }
13038
13039 /*
13040 * group_id arg contains device MAC address followed by
13041 * space and SSID (DIRECT-somessid).
13042 * group id attribute contains device address (6 bytes)
13043 * followed by SSID prefix DIRECT-XX (9 bytes)
13044 */
13045 if (strlen(group_id) < sizeof(device_macstr)) {
13046 sigma_dut_print(dut, DUT_MSG_ERROR,
13047 "group_id arg too short");
13048 return -1;
13049 }
13050 memcpy(device_macstr, group_id, sizeof(device_macstr));
13051 device_macstr[sizeof(device_macstr) - 1] = '\0';
13052 if (parse_mac_address(dut, device_macstr,
13053 (unsigned char *) group_id_attr)) {
13054 sigma_dut_print(dut, DUT_MSG_ERROR,
13055 "fail to parse device address from group_id");
13056 return -1;
13057 }
13058 group_ssid = strchr(group_id, ' ');
13059 if (!group_ssid) {
13060 sigma_dut_print(dut, DUT_MSG_ERROR,
13061 "invalid group_id arg, no ssid");
13062 return -1;
13063 }
13064 group_ssid++;
13065 len = strlen(group_ssid);
13066 if (len < group_ssid_prefix_len) {
13067 sigma_dut_print(dut, DUT_MSG_ERROR,
13068 "group_id SSID too short");
13069 return -1;
13070 }
13071 dst_len = sizeof(group_id_attr) - ETH_ALEN;
13072 if (len > dst_len) {
13073 sigma_dut_print(dut, DUT_MSG_ERROR,
13074 "group_id SSID (%s) too long",
13075 group_ssid);
13076 return -1;
13077 }
13078
13079 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
13080 tag_index = find_template_frame_tag(tags, tags_total, 2);
13081 if (tag_index < 0) {
13082 sigma_dut_print(dut, DUT_MSG_ERROR,
13083 "can't find group id attribute");
13084 return -1;
13085 }
13086 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13087 framelen - tags[tag_index].offset,
13088 IEEE80211_P2P_ATTR_GROUP_ID,
13089 group_id_attr,
13090 sizeof(group_id_attr))) {
13091 sigma_dut_print(dut, DUT_MSG_ERROR,
13092 "fail to replace group id attribute");
13093 return -1;
13094 }
13095 }
13096
13097 for (i = 0; i < count; i++) {
13098 if (wil6210_transmit_frame(dut, freq,
13099 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
13100 frame, framelen)) {
13101 sigma_dut_print(dut, DUT_MSG_ERROR,
13102 "fail to transmit probe request frame");
13103 return -1;
13104 }
13105 }
13106
13107 return 0;
13108}
13109
13110
Lior David0fe101e2017-03-09 16:09:50 +020013111int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
13112 struct sigma_cmd *cmd)
13113{
13114 const char *frame_name = get_param(cmd, "framename");
13115 const char *mac = get_param(cmd, "dest_mac");
13116
13117 if (!frame_name || !mac) {
13118 sigma_dut_print(dut, DUT_MSG_ERROR,
13119 "framename and dest_mac must be provided");
13120 return -1;
13121 }
13122
13123 if (strcasecmp(frame_name, "brp") == 0) {
13124 const char *l_rx = get_param(cmd, "L-RX");
13125 int l_rx_i;
13126
13127 if (!l_rx) {
13128 sigma_dut_print(dut, DUT_MSG_ERROR,
13129 "L-RX must be provided");
13130 return -1;
13131 }
13132 l_rx_i = atoi(l_rx);
13133
13134 sigma_dut_print(dut, DUT_MSG_INFO,
13135 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
13136 mac, l_rx);
13137 if (l_rx_i != 16) {
13138 sigma_dut_print(dut, DUT_MSG_ERROR,
13139 "unsupported L-RX: %s", l_rx);
13140 return -1;
13141 }
13142
13143 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
13144 return -1;
13145 } else if (strcasecmp(frame_name, "ssw") == 0) {
13146 sigma_dut_print(dut, DUT_MSG_INFO,
13147 "dev_send_frame: SLS, dest_mac %s", mac);
13148 if (wil6210_send_sls(dut, mac))
13149 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013150 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
13151 (strcasecmp(frame_name, "devdiscreq") == 0)) {
13152 sigma_dut_print(dut, DUT_MSG_INFO,
13153 "dev_send_frame: %s, dest_mac %s", frame_name,
13154 mac);
13155 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
13156 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020013157 } else {
13158 sigma_dut_print(dut, DUT_MSG_ERROR,
13159 "unsupported frame type: %s", frame_name);
13160 return -1;
13161 }
13162
13163 return 1;
13164}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013165
Lior David0fe101e2017-03-09 16:09:50 +020013166#endif /* __linux__ */
13167
13168
13169static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
13170 struct sigma_conn *conn,
13171 struct sigma_cmd *cmd)
13172{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013173 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020013174#ifdef __linux__
13175 case DRIVER_WIL6210:
13176 return wil6210_send_frame_60g(dut, conn, cmd);
13177#endif /* __linux__ */
13178 default:
13179 send_resp(dut, conn, SIGMA_ERROR,
13180 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
13181 return 0;
13182 }
13183}
13184
13185
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013186static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13187 const char *intf, struct sigma_cmd *cmd)
13188{
13189 const char *val, *addr;
13190 char buf[100];
13191
13192 addr = get_param(cmd, "DestMac");
13193 if (!addr) {
13194 send_resp(dut, conn, SIGMA_INVALID,
13195 "ErrorCode,AP MAC address is missing");
13196 return 0;
13197 }
13198
13199 val = get_param(cmd, "ANQPQuery_ID");
13200 if (!val) {
13201 send_resp(dut, conn, SIGMA_INVALID,
13202 "ErrorCode,Missing ANQPQuery_ID");
13203 return 0;
13204 }
13205
13206 if (strcasecmp(val, "NeighborReportReq") == 0) {
13207 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
13208 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
13209 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
13210 } else {
13211 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
13212 val);
13213 send_resp(dut, conn, SIGMA_INVALID,
13214 "ErrorCode,Invalid ANQPQuery_ID");
13215 return 0;
13216 }
13217
Ashwini Patild174f2c2017-04-13 16:49:46 +053013218 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
13219 * (Address3 = Wildcard BSSID when sent to not-associated AP;
13220 * if associated, AP BSSID).
13221 */
13222 if (wpa_command(intf, "SET gas_address3 1") < 0) {
13223 send_resp(dut, conn, SIGMA_ERROR,
13224 "ErrorCode,Failed to set gas_address3");
13225 return 0;
13226 }
13227
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013228 if (wpa_command(intf, buf) < 0) {
13229 send_resp(dut, conn, SIGMA_ERROR,
13230 "ErrorCode,Failed to send ANQP query");
13231 return 0;
13232 }
13233
13234 return 1;
13235}
13236
13237
13238static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
13239 struct sigma_conn *conn,
13240 const char *intf,
13241 struct sigma_cmd *cmd)
13242{
13243 const char *val = get_param(cmd, "FrameName");
13244
13245 if (val && strcasecmp(val, "ANQPQuery") == 0)
13246 return mbo_send_anqp_query(dut, conn, intf, cmd);
13247
13248 return 2;
13249}
13250
13251
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013252static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
13253 struct sigma_conn *conn,
13254 const char *intf,
13255 struct sigma_cmd *cmd)
13256{
13257 const char *val = get_param(cmd, "framename");
13258
13259 if (!val)
13260 return INVALID_SEND_STATUS;
13261
13262 if (strcasecmp(val, "SAQueryReq") == 0) {
13263 val = get_param(cmd, "OCIChannel");
13264
13265 if (!val) {
13266 send_resp(dut, conn, SIGMA_ERROR,
13267 "errorCode,OCIChannel not present");
13268 return STATUS_SENT_ERROR;
13269 }
13270
13271 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
13272 if (!dut->saquery_oci_freq) {
13273 send_resp(dut, conn, SIGMA_ERROR,
13274 "errorCode,Invalid OCIChannel number");
13275 return STATUS_SENT_ERROR;
13276 }
13277
13278 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
13279 NULL, 0);
13280 }
13281
13282 if (strcasecmp(val, "reassocreq") == 0)
13283 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
13284 CORRECT_KEY, NULL, 0);
13285
Veerendranath9f81dfb2020-08-10 01:21:29 -070013286 if (strcasecmp(val, "ANQPQuery") == 0) {
13287 char buf[50];
13288 const char *dest = get_param(cmd, "DestMac");
13289 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013290 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070013291 int len, freq;
13292
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013293 if (freq_str)
13294 freq = atoi(freq_str);
13295 else
13296 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
13297
Veerendranath9f81dfb2020-08-10 01:21:29 -070013298 if (!dest || !freq)
13299 return INVALID_SEND_STATUS;
13300
13301 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
13302 dest, freq);
13303 if (len < 0 || len >= sizeof(buf)) {
13304 sigma_dut_print(dut, DUT_MSG_ERROR,
13305 "Failed to allocate buf");
13306 return ERROR_SEND_STATUS;
13307 }
13308
13309 if (wpa_command(intf, buf) != 0) {
13310 send_resp(dut, conn, SIGMA_ERROR,
13311 "ErrorCode,Failed to send ANQP Query frame");
13312 return STATUS_SENT_ERROR;
13313 }
13314
13315 sigma_dut_print(dut, DUT_MSG_DEBUG,
13316 "ANQP Query sent: %s", buf);
13317
13318 return SUCCESS_SEND_STATUS;
13319 }
13320
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013321 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
13322 return STATUS_SENT_ERROR;
13323}
13324
13325
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013326static int
13327get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13328 char *pos, int rem_len, int num_of_scs_desc,
13329 int num_of_tclas_elem)
13330{
13331 const char *val;
13332 int ipv6;
13333 int len, total_len = 0;
13334
13335 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
13336 num_of_tclas_elem);
13337 if (!val) {
13338 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
13339 __func__);
13340 return -1;
13341 }
13342
13343 if (strcmp(val, "6") == 0) {
13344 ipv6 = 1;
13345 } else if (strcmp(val, "4") == 0) {
13346 ipv6 = 0;
13347 } else {
13348 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
13349 __func__);
13350 return -1;
13351 }
13352
13353 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
13354 if (len < 0 || len >= rem_len)
13355 return -1;
13356
13357 pos += len;
13358 rem_len -= len;
13359 total_len += len;
13360
13361 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
13362 num_of_scs_desc, num_of_tclas_elem);
13363 if (val) {
13364 len = snprintf(pos, rem_len, " src_ip=%s", val);
13365 if (len < 0 || len >= rem_len)
13366 return -1;
13367
13368 pos += len;
13369 rem_len -= len;
13370 total_len += len;
13371 }
13372
13373 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
13374 num_of_scs_desc, num_of_tclas_elem);
13375 if (val) {
13376 len = snprintf(pos, rem_len, " dst_ip=%s", val);
13377 if (len < 0 || len >= rem_len)
13378 return -1;
13379
13380 pos += len;
13381 rem_len -= len;
13382 total_len += len;
13383 }
13384
13385 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
13386 num_of_tclas_elem);
13387 if (val) {
13388 len = snprintf(pos, rem_len, " src_port=%s", val);
13389 if (len < 0 || len >= rem_len)
13390 return -1;
13391
13392 pos += len;
13393 rem_len -= len;
13394 total_len += len;
13395 }
13396
13397 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
13398 num_of_scs_desc, num_of_tclas_elem);
13399 if (val) {
13400 len = snprintf(pos, rem_len, " dst_port=%s", val);
13401 if (len < 0 || len >= rem_len)
13402 return -1;
13403
13404 pos += len;
13405 rem_len -= len;
13406 total_len += len;
13407 }
13408
13409 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
13410 num_of_tclas_elem);
13411 if (val) {
13412 len = snprintf(pos, rem_len, " dscp=%s", val);
13413 if (len < 0 || len >= rem_len)
13414 return -1;
13415
13416 pos += len;
13417 rem_len -= len;
13418 total_len += len;
13419 }
13420
13421 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
13422 num_of_scs_desc, num_of_tclas_elem);
13423 if (val) {
13424 char *prot;
13425
13426 switch (atoi(val)) {
13427 case 17:
13428 prot = "udp";
13429 break;
13430 case 6:
13431 prot = "tcp";
13432 break;
13433 case 50:
13434 prot = "esp";
13435 break;
13436 default:
13437 sigma_dut_print(dut, DUT_MSG_ERROR,
13438 "Invalid protocol %d", atoi(val));
13439 return -1;
13440 }
13441
13442 if (ipv6)
13443 len = snprintf(pos, rem_len, " next_header=%s", prot);
13444 else
13445 len = snprintf(pos, rem_len, " protocol=%s", prot);
13446 if (len < 0 || len >= rem_len)
13447 return -1;
13448
13449 pos += len;
13450 rem_len -= len;
13451 total_len += len;
13452 }
13453
13454 return total_len;
13455}
13456
13457
13458static int
13459get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13460 char *pos, int rem_len, int num_of_scs_desc,
13461 int num_of_tclas_elem)
13462{
13463 const char *val;
13464 int len, total_len = 0;
13465
13466 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
13467 num_of_scs_desc, num_of_tclas_elem);
13468 if (val) {
13469 len = snprintf(pos, rem_len, " prot_instance=%s",
13470 val);
13471 if (len < 0 || len >= rem_len)
13472 return -1;
13473
13474 pos += len;
13475 rem_len -= len;
13476 total_len += len;
13477 }
13478
13479 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
13480 num_of_scs_desc, num_of_tclas_elem);
13481 if (val) {
13482 char *prot;
13483
13484 switch (atoi(val)) {
13485 case 17:
13486 prot = "udp";
13487 break;
13488 case 6:
13489 prot = "tcp";
13490 break;
13491 case 50:
13492 prot = "esp";
13493 break;
13494 default:
13495 sigma_dut_print(dut, DUT_MSG_ERROR,
13496 "Invalid protocol %d",
13497 atoi(val));
13498 return -1;
13499 }
13500
13501 len = snprintf(pos, rem_len, " prot_number=%s", prot);
13502 if (len < 0 || len >= rem_len)
13503 return -1;
13504
13505 pos += len;
13506 rem_len -= len;
13507 total_len += len;
13508 }
13509
13510 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
13511 num_of_scs_desc, num_of_tclas_elem);
13512 if (val) {
13513 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
13514 if (len < 0 || len >= rem_len)
13515 return -1;
13516
13517 pos += len;
13518 rem_len -= len;
13519 total_len += len;
13520 }
13521
13522 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
13523 num_of_tclas_elem);
13524 if (val && strlen(val) >= 2) {
13525 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
13526 if (len < 0 || len >= rem_len)
13527 return -1;
13528
13529 pos += len;
13530 rem_len -= len;
13531 total_len += len;
13532 }
13533
13534 return total_len;
13535}
13536
13537
13538static enum sigma_cmd_result
13539cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
13540 const char *intf, struct sigma_cmd *cmd)
13541{
13542 char buf[4096], *pos;
13543 const char *val, *scs_id, *classifier_type;
13544 int len, rem_len, total_bytes;
13545 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
13546
13547 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
13548 if (!scs_id) {
13549 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
13550 return INVALID_SEND_STATUS;
13551 }
13552
13553 rem_len = sizeof(buf);
13554 pos = buf;
13555
13556 len = snprintf(buf, sizeof(buf), "SCS");
13557 if (len < 0 || len > rem_len)
13558 goto fail;
13559
13560 pos += len;
13561 rem_len -= len;
13562
13563 while (scs_id) {
13564 num_of_scs_desc++;
13565
13566 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
13567 num_of_scs_desc);
13568 if (!val)
13569 return INVALID_SEND_STATUS;
13570
13571 if (strcasecmp(val, "Add") == 0) {
13572 len = snprintf(pos, rem_len, " scs_id=%s add",
13573 scs_id);
13574 } else if (strcasecmp(val, "Change") == 0) {
13575 len = snprintf(pos, rem_len, " scs_id=%s change",
13576 scs_id);
13577 } else if (strcasecmp(val, "Remove") == 0) {
13578 len = snprintf(pos, rem_len, " scs_id=%s remove",
13579 scs_id);
13580 if (len < 0 || len >= rem_len)
13581 goto fail;
13582
13583 pos += len;
13584 rem_len -= len;
13585 goto scs_desc_end;
13586 } else {
13587 sigma_dut_print(dut, DUT_MSG_ERROR,
13588 "%s: request type - %s is invalid",
13589 __func__, val);
13590 return INVALID_SEND_STATUS;
13591 }
13592
13593 if (len < 0 || len >= rem_len)
13594 goto fail;
13595
13596 pos += len;
13597 rem_len -= len;
13598
13599 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
13600 num_of_scs_desc);
13601 if (!val) {
13602 sigma_dut_print(dut, DUT_MSG_ERROR,
13603 "IntraAccess Priority empty");
13604 return INVALID_SEND_STATUS;
13605 }
13606
13607 len = snprintf(pos, rem_len, " scs_up=%s", val);
13608 if (len < 0 || len >= rem_len)
13609 goto fail;
13610
13611 pos += len;
13612 rem_len -= len;
13613
13614 classifier_type = get_param_fmt(cmd,
13615 "TCLASElem_ClassifierType_%d_1",
13616 num_of_scs_desc);
13617 if (!classifier_type) {
13618 sigma_dut_print(dut, DUT_MSG_ERROR,
13619 "classifier type missing");
13620 return INVALID_SEND_STATUS;
13621 }
13622
13623 while (classifier_type) {
13624 num_of_tclas_elem++;
13625
13626 len = snprintf(pos, rem_len, " classifier_type=%s",
13627 classifier_type);
13628 if (len < 0 || len >= rem_len)
13629 goto fail;
13630
13631 pos += len;
13632 rem_len -= len;
13633
13634 if (strcmp(classifier_type, "10") == 0) {
13635 total_bytes = get_type10_frame_classifier(
13636 dut, cmd, pos, rem_len,
13637 num_of_scs_desc,
13638 num_of_tclas_elem);
13639 } else if (strcmp(classifier_type, "4") == 0) {
13640 total_bytes = get_type4_frame_classifier(
13641 dut, cmd, pos, rem_len,
13642 num_of_scs_desc,
13643 num_of_tclas_elem);
13644 } else {
13645 sigma_dut_print(dut, DUT_MSG_ERROR,
13646 "classifier_type invalid");
13647 goto fail;
13648 }
13649
13650 if (total_bytes < 0)
13651 goto fail;
13652
13653 pos += total_bytes;
13654 rem_len -= total_bytes;
13655
13656 classifier_type = get_param_fmt(
13657 cmd, "TCLASElem_ClassifierType_%d_%d",
13658 num_of_scs_desc, num_of_tclas_elem + 1);
13659 }
13660
13661 if (num_of_tclas_elem > 1) {
13662 val = get_param_fmt(cmd,
13663 "TCLASProcessingElem_Processing_%d",
13664 num_of_scs_desc);
13665 if (!val) {
13666 sigma_dut_print(dut, DUT_MSG_ERROR,
13667 "Tclas_processing element %d empty",
13668 num_of_scs_desc);
13669 goto fail;
13670 }
13671
13672 len = snprintf(pos, rem_len,
13673 " tclas_processing=%s", val);
13674 if (len < 0 || len >= rem_len)
13675 goto fail;
13676
13677 pos += len;
13678 rem_len -= len;
13679 }
13680scs_desc_end:
13681 num_of_tclas_elem = 0;
13682 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
13683 num_of_scs_desc + 1);
13684 }
13685
13686 if (wpa_command(intf, buf) != 0) {
13687 send_resp(dut, conn, SIGMA_ERROR,
13688 "ErrorCode,Failed to send SCS frame request");
13689 return STATUS_SENT_ERROR;
13690 }
13691
13692 sigma_dut_print(dut, DUT_MSG_DEBUG,
13693 "SCS frame request sent: %s", buf);
13694
13695 return SUCCESS_SEND_STATUS;
13696fail:
13697 sigma_dut_print(dut, DUT_MSG_ERROR,
13698 "Failed to create SCS frame request");
13699 return ERROR_SEND_STATUS;
13700}
13701
13702
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013703static enum sigma_cmd_result
13704cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
13705 const char *intf, struct sigma_cmd *cmd)
13706{
13707 char buf[128], *pos;
13708 const char *val, *classifier_type = "04", *type;
13709 int len, rem_len;
13710 u8 up_bitmap;
13711
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013712 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013713 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013714 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013715 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013716 return INVALID_SEND_STATUS;
13717 }
13718
13719 rem_len = sizeof(buf);
13720 pos = buf;
13721 if (strcasecmp(type, "add") == 0) {
13722 len = snprintf(pos, rem_len, "MSCS add");
13723 } else if (strcasecmp(type, "update") == 0) {
13724 len = snprintf(pos, rem_len, "MSCS change");
13725 } else if (strcasecmp(type, "remove") == 0) {
13726 if (wpa_command(intf, "MSCS remove") != 0) {
13727 send_resp(dut, conn, SIGMA_ERROR,
13728 "ErrorCode,Failed to send MSCS frame req");
13729 return STATUS_SENT_ERROR;
13730 }
13731 return SUCCESS_SEND_STATUS;
13732 } else {
13733 sigma_dut_print(dut, DUT_MSG_ERROR,
13734 "%s: request type invalid", __func__);
13735 return INVALID_SEND_STATUS;
13736 }
13737
13738 if (len < 0 || len >= rem_len)
13739 goto fail;
13740
13741 pos += len;
13742 rem_len -= len;
13743
13744 val = get_param(cmd, "User_Priority_Bitmap");
13745 if (!val) {
13746 sigma_dut_print(dut, DUT_MSG_ERROR,
13747 "%s: user priority bitmap empty", __func__);
13748 return INVALID_SEND_STATUS;
13749 }
13750
13751 switch (atoi(val)) {
13752 case 0:
13753 up_bitmap = 0x00;
13754 break;
13755 case 1:
13756 up_bitmap = 0xF0;
13757 break;
13758 case 2:
13759 up_bitmap = 0xF6;
13760 break;
13761 default:
13762 sigma_dut_print(dut, DUT_MSG_ERROR,
13763 "%s: Unknown User_Priority_Bitmap value %d",
13764 __func__, atoi(val));
13765 return INVALID_SEND_STATUS;
13766 }
13767
13768 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
13769 if (len < 0 || len >= rem_len)
13770 goto fail;
13771
13772 pos += len;
13773 rem_len -= len;
13774
13775 val = get_param(cmd, "User_Priority_Limit");
13776 if (!val) {
13777 sigma_dut_print(dut, DUT_MSG_ERROR,
13778 "%s: invalid user priority limit", __func__);
13779 return INVALID_SEND_STATUS;
13780 }
13781
13782 len = snprintf(pos, rem_len, " up_limit=%s", val);
13783 if (len < 0 || len >= rem_len)
13784 goto fail;
13785
13786 pos += len;
13787 rem_len -= len;
13788
13789 val = get_param(cmd, "Stream_Timeout");
13790 if (!val)
13791 val = get_param(cmd, "Stream_Timtout");
13792 if (!val) {
13793 sigma_dut_print(dut, DUT_MSG_ERROR,
13794 "%s: invalid stream timeout", __func__);
13795 return INVALID_SEND_STATUS;
13796 }
13797
13798 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
13799 if (len < 0 || len >= rem_len)
13800 goto fail;
13801
13802 pos += len;
13803 rem_len -= len;
13804
13805 val = get_param(cmd, "TCLAS_Mask");
13806 if (!val) {
13807 sigma_dut_print(dut, DUT_MSG_ERROR,
13808 "%s: invalid tclas mask", __func__);
13809 return INVALID_SEND_STATUS;
13810 }
13811
13812 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
13813 classifier_type, strtol(val, NULL, 2), 0);
13814 if (len < 0 || len >= rem_len)
13815 goto fail;
13816
13817 if (wpa_command(intf, buf) != 0) {
13818 send_resp(dut, conn, SIGMA_ERROR,
13819 "ErrorCode,Failed to send MSCS frame req");
13820 return STATUS_SENT_ERROR;
13821 }
13822
13823 sigma_dut_print(dut, DUT_MSG_DEBUG,
13824 "MSCS frame request sent: %s", buf);
13825
13826 return SUCCESS_SEND_STATUS;
13827fail:
13828 sigma_dut_print(dut, DUT_MSG_ERROR,
13829 "Failed to create MSCS frame req");
13830 return ERROR_SEND_STATUS;
13831}
13832
13833
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013834static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013835cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13836 const char *intf, struct sigma_cmd *cmd)
13837{
13838 char buf[150], *pos;
13839 const char *val;
13840 int len, rem_len;
13841
13842 rem_len = sizeof(buf);
13843 pos = buf;
13844
13845 len = snprintf(pos, rem_len, "DSCP_QUERY");
13846 if (len < 0 || len >= rem_len)
13847 goto fail;
13848
13849 pos += len;
13850 rem_len -= len;
13851
13852 val = get_param(cmd, "Wildcard");
13853 if (val && strcasecmp(val, "Yes") == 0) {
13854 len = snprintf(pos, rem_len, " wildcard");
13855 if (len < 0 || len >= rem_len)
13856 goto fail;
13857 } else if (strlen(dut->qm_domain_name)) {
13858 len = snprintf(pos, rem_len, " domain_name=%s",
13859 dut->qm_domain_name);
13860 if (len < 0 || len >= rem_len)
13861 goto fail;
13862 } else {
13863 sigma_dut_print(dut, DUT_MSG_ERROR,
13864 "Invalid DSCP Query configuration");
13865 return INVALID_SEND_STATUS;
13866 }
13867
13868 if (wpa_command(intf, buf) != 0) {
13869 send_resp(dut, conn, SIGMA_ERROR,
13870 "ErrorCode,Failed to send DSCP policy query frame");
13871 return STATUS_SENT_ERROR;
13872 }
13873
13874 sigma_dut_print(dut, DUT_MSG_DEBUG,
13875 "DSCP policy query frame sent: %s", buf);
13876 return SUCCESS_SEND_STATUS;
13877fail:
13878 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
13879 return ERROR_SEND_STATUS;
13880}
13881
13882
13883static enum sigma_cmd_result
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013884cmd_sta_send_frame_dscp_response(struct sigma_dut *dut, struct sigma_conn *conn,
13885 const char *intf, struct sigma_cmd *cmd)
13886{
13887 char buf[256], *pos, *item, *list, *saveptr;
13888 const char *val;
13889 int len, rem_len;
13890
13891 pos = buf;
13892 rem_len = sizeof(buf);
13893
13894 len = snprintf(pos, rem_len, "DSCP_RESP");
13895 if (snprintf_error(rem_len, len)) {
13896 sigma_dut_print(dut, DUT_MSG_ERROR,
13897 "Failed to create DSCP Policy Response command");
13898 return ERROR_SEND_STATUS;
13899 }
13900
13901 pos += len;
13902 rem_len -= len;
13903
13904 val = get_param(cmd, "PolicyID_List");
13905 if (!val) {
13906 sigma_dut_print(dut, DUT_MSG_ERROR,
13907 "DSCP policy ID list missing");
13908 return INVALID_SEND_STATUS;
13909 }
13910
13911 list = strdup(val);
13912 if (!list)
13913 return ERROR_SEND_STATUS;
13914
13915 item = strtok_r(list, "_", &saveptr);
13916 while (item) {
13917 unsigned int i;
13918 int policy_id = atoi(item);
13919
13920 for (i = 0; i < dut->num_dscp_status; i++)
13921 if (dut->dscp_status[i].id == policy_id)
13922 break;
13923
13924 if (i == dut->num_dscp_status) {
13925 free(list);
13926 send_resp(dut, conn, SIGMA_ERROR,
13927 "ErrorCode,DSCP policy id not found in status list");
13928 return STATUS_SENT_ERROR;
13929 }
13930
13931 len = snprintf(pos, rem_len, " policy_id=%d status=%d",
13932 policy_id, dut->dscp_status[i].status);
13933 if (snprintf_error(rem_len, len)) {
13934 free(list);
13935 sigma_dut_print(dut, DUT_MSG_ERROR,
13936 "Failed to write DSCP policy list");
13937 return ERROR_SEND_STATUS;
13938 }
13939
13940 pos += len;
13941 rem_len -= len;
13942
13943 if (dut->dscp_status[i].status)
13944 remove_dscp_policy(dut, policy_id);
13945
13946 item = strtok_r(NULL, "_", &saveptr);
13947 }
13948
13949 free(list);
13950
13951 if (wpa_command(intf, buf) != 0) {
13952 send_resp(dut, conn, SIGMA_ERROR,
13953 "ErrorCode,Failed to send DSCP Policy Response frame");
13954 return STATUS_SENT_ERROR;
13955 }
13956
13957 sigma_dut_print(dut, DUT_MSG_DEBUG,
13958 "DSCP Policy Response frame sent: %s", buf);
13959 return SUCCESS_SEND_STATUS;
13960}
13961
13962
13963static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013964cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
13965 const char *intf, struct sigma_cmd *cmd)
13966{
13967 const char *val;
13968
13969 val = get_param(cmd, "FrameName");
13970 if (val) {
13971 if (strcasecmp(val, "MSCSReq") == 0)
13972 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
13973 if (strcasecmp(val, "SCSReq") == 0)
13974 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013975 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
13976 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
13977 cmd);
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013978 if (strcasecmp(val, "DSCPPolicyResponse") == 0)
13979 return cmd_sta_send_frame_dscp_response(dut, conn, intf,
13980 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013981
13982 sigma_dut_print(dut, DUT_MSG_ERROR,
13983 "%s: frame name - %s is invalid",
13984 __func__, val);
13985 }
13986
13987 return INVALID_SEND_STATUS;
13988}
13989
13990
Jouni Malinenf7222712019-06-13 01:50:21 +030013991enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
13992 struct sigma_conn *conn,
13993 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013994{
13995 const char *intf = get_param(cmd, "Interface");
13996 const char *val;
13997 enum send_frame_type frame;
13998 enum send_frame_protection protected;
13999 char buf[100];
14000 unsigned char addr[ETH_ALEN];
14001 int res;
14002
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030014003 if (!intf)
14004 return -1;
14005
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014006 val = get_param(cmd, "program");
14007 if (val == NULL)
14008 val = get_param(cmd, "frame");
14009 if (val && strcasecmp(val, "TDLS") == 0)
14010 return cmd_sta_send_frame_tdls(dut, conn, cmd);
14011 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014012 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014013 strcasecmp(val, "HS2-R3") == 0 ||
14014 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014015 return cmd_sta_send_frame_hs2(dut, conn, cmd);
14016 if (val && strcasecmp(val, "VHT") == 0)
14017 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070014018 if (val && strcasecmp(val, "HE") == 0)
14019 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070014020 if (val && strcasecmp(val, "LOC") == 0)
14021 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020014022 if (val && strcasecmp(val, "60GHz") == 0)
14023 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053014024 if (val && strcasecmp(val, "MBO") == 0) {
14025 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
14026 if (res != 2)
14027 return res;
14028 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053014029 if (val && strcasecmp(val, "WPA3") == 0)
14030 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053014031 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053014032 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014033
14034 val = get_param(cmd, "TD_DISC");
14035 if (val) {
14036 if (hwaddr_aton(val, addr) < 0)
14037 return -1;
14038 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
14039 if (wpa_command(intf, buf) < 0) {
14040 send_resp(dut, conn, SIGMA_ERROR,
14041 "ErrorCode,Failed to send TDLS discovery");
14042 return 0;
14043 }
14044 return 1;
14045 }
14046
14047 val = get_param(cmd, "TD_Setup");
14048 if (val) {
14049 if (hwaddr_aton(val, addr) < 0)
14050 return -1;
14051 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
14052 if (wpa_command(intf, buf) < 0) {
14053 send_resp(dut, conn, SIGMA_ERROR,
14054 "ErrorCode,Failed to start TDLS setup");
14055 return 0;
14056 }
14057 return 1;
14058 }
14059
14060 val = get_param(cmd, "TD_TearDown");
14061 if (val) {
14062 if (hwaddr_aton(val, addr) < 0)
14063 return -1;
14064 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
14065 if (wpa_command(intf, buf) < 0) {
14066 send_resp(dut, conn, SIGMA_ERROR,
14067 "ErrorCode,Failed to tear down TDLS link");
14068 return 0;
14069 }
14070 return 1;
14071 }
14072
14073 val = get_param(cmd, "TD_ChannelSwitch");
14074 if (val) {
14075 /* TODO */
14076 send_resp(dut, conn, SIGMA_ERROR,
14077 "ErrorCode,TD_ChannelSwitch not yet supported");
14078 return 0;
14079 }
14080
14081 val = get_param(cmd, "TD_NF");
14082 if (val) {
14083 /* TODO */
14084 send_resp(dut, conn, SIGMA_ERROR,
14085 "ErrorCode,TD_NF not yet supported");
14086 return 0;
14087 }
14088
14089 val = get_param(cmd, "PMFFrameType");
14090 if (val == NULL)
14091 val = get_param(cmd, "FrameName");
14092 if (val == NULL)
14093 val = get_param(cmd, "Type");
14094 if (val == NULL)
14095 return -1;
14096 if (strcasecmp(val, "disassoc") == 0)
14097 frame = DISASSOC;
14098 else if (strcasecmp(val, "deauth") == 0)
14099 frame = DEAUTH;
14100 else if (strcasecmp(val, "saquery") == 0)
14101 frame = SAQUERY;
14102 else if (strcasecmp(val, "auth") == 0)
14103 frame = AUTH;
14104 else if (strcasecmp(val, "assocreq") == 0)
14105 frame = ASSOCREQ;
14106 else if (strcasecmp(val, "reassocreq") == 0)
14107 frame = REASSOCREQ;
14108 else if (strcasecmp(val, "neigreq") == 0) {
14109 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
14110
14111 val = get_param(cmd, "ssid");
14112 if (val == NULL)
14113 return -1;
14114
14115 res = send_neighbor_request(dut, intf, val);
14116 if (res) {
14117 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14118 "Failed to send neighbor report request");
14119 return 0;
14120 }
14121
14122 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053014123 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
14124 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014125 sigma_dut_print(dut, DUT_MSG_DEBUG,
14126 "Got Transition Management Query");
14127
Ashwini Patil5acd7382017-04-13 15:55:04 +053014128 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014129 if (res) {
14130 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14131 "Failed to send Transition Management Query");
14132 return 0;
14133 }
14134
14135 return 1;
14136 } else {
14137 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14138 "PMFFrameType");
14139 return 0;
14140 }
14141
14142 val = get_param(cmd, "PMFProtected");
14143 if (val == NULL)
14144 val = get_param(cmd, "Protected");
14145 if (val == NULL)
14146 return -1;
14147 if (strcasecmp(val, "Correct-key") == 0 ||
14148 strcasecmp(val, "CorrectKey") == 0)
14149 protected = CORRECT_KEY;
14150 else if (strcasecmp(val, "IncorrectKey") == 0)
14151 protected = INCORRECT_KEY;
14152 else if (strcasecmp(val, "Unprotected") == 0)
14153 protected = UNPROTECTED;
14154 else {
14155 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14156 "PMFProtected");
14157 return 0;
14158 }
14159
14160 if (protected != UNPROTECTED &&
14161 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
14162 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
14163 "PMFProtected for auth/assocreq/reassocreq");
14164 return 0;
14165 }
14166
14167 if (if_nametoindex("sigmadut") == 0) {
14168 snprintf(buf, sizeof(buf),
14169 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014170 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014171 if (system(buf) != 0 ||
14172 if_nametoindex("sigmadut") == 0) {
14173 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
14174 "monitor interface with '%s'", buf);
14175 return -2;
14176 }
14177 }
14178
14179 if (system("ifconfig sigmadut up") != 0) {
14180 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
14181 "monitor interface up");
14182 return -2;
14183 }
14184
Veerendranath Jakkam49774122020-07-05 09:52:18 +053014185 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014186}
14187
14188
14189static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
14190 struct sigma_conn *conn,
14191 struct sigma_cmd *cmd,
14192 const char *ifname)
14193{
14194 char buf[200];
14195 const char *val;
14196
14197 val = get_param(cmd, "ClearARP");
14198 if (val && atoi(val) == 1) {
14199 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
14200 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14201 if (system(buf) != 0) {
14202 send_resp(dut, conn, SIGMA_ERROR,
14203 "errorCode,Failed to clear ARP cache");
14204 return 0;
14205 }
14206 }
14207
14208 return 1;
14209}
14210
14211
14212int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
14213 struct sigma_cmd *cmd)
14214{
14215 const char *intf = get_param(cmd, "Interface");
14216 const char *val;
14217
14218 if (intf == NULL)
14219 return -1;
14220
14221 val = get_param(cmd, "program");
14222 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014223 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014224 strcasecmp(val, "HS2-R3") == 0 ||
14225 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014226 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
14227
14228 return -1;
14229}
14230
14231
Jouni Malinenf7222712019-06-13 01:50:21 +030014232static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
14233 struct sigma_conn *conn,
14234 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014235{
14236 const char *intf = get_param(cmd, "Interface");
14237 const char *mac = get_param(cmd, "MAC");
14238
14239 if (intf == NULL || mac == NULL)
14240 return -1;
14241
14242 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
14243 "interface %s to %s", intf, mac);
14244
14245 if (dut->set_macaddr) {
14246 char buf[128];
14247 int res;
14248 if (strcasecmp(mac, "default") == 0) {
14249 res = snprintf(buf, sizeof(buf), "%s",
14250 dut->set_macaddr);
14251 dut->tmp_mac_addr = 0;
14252 } else {
14253 res = snprintf(buf, sizeof(buf), "%s %s",
14254 dut->set_macaddr, mac);
14255 dut->tmp_mac_addr = 1;
14256 }
14257 if (res < 0 || res >= (int) sizeof(buf))
14258 return -1;
14259 if (system(buf) != 0) {
14260 send_resp(dut, conn, SIGMA_ERROR,
14261 "errorCode,Failed to set MAC "
14262 "address");
14263 return 0;
14264 }
14265 return 1;
14266 }
14267
14268 if (strcasecmp(mac, "default") == 0)
14269 return 1;
14270
14271 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14272 "command");
14273 return 0;
14274}
14275
14276
14277static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
14278 struct sigma_conn *conn, const char *intf,
14279 int val)
14280{
14281 char buf[200];
14282 int res;
14283
14284 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
14285 intf, val);
14286 if (res < 0 || res >= (int) sizeof(buf))
14287 return -1;
14288 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14289 if (system(buf) != 0) {
14290 send_resp(dut, conn, SIGMA_ERROR,
14291 "errorCode,Failed to configure offchannel mode");
14292 return 0;
14293 }
14294
14295 return 1;
14296}
14297
14298
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014299static int off_chan_val(enum sec_ch_offset off)
14300{
14301 switch (off) {
14302 case SEC_CH_NO:
14303 return 0;
14304 case SEC_CH_40ABOVE:
14305 return 40;
14306 case SEC_CH_40BELOW:
14307 return -40;
14308 }
14309
14310 return 0;
14311}
14312
14313
14314static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
14315 const char *intf, int off_ch_num,
14316 enum sec_ch_offset sec)
14317{
14318 char buf[200];
14319 int res;
14320
14321 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
14322 intf, off_ch_num);
14323 if (res < 0 || res >= (int) sizeof(buf))
14324 return -1;
14325 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14326 if (system(buf) != 0) {
14327 send_resp(dut, conn, SIGMA_ERROR,
14328 "errorCode,Failed to set offchan");
14329 return 0;
14330 }
14331
14332 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
14333 intf, off_chan_val(sec));
14334 if (res < 0 || res >= (int) sizeof(buf))
14335 return -1;
14336 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14337 if (system(buf) != 0) {
14338 send_resp(dut, conn, SIGMA_ERROR,
14339 "errorCode,Failed to set sec chan offset");
14340 return 0;
14341 }
14342
14343 return 1;
14344}
14345
14346
14347static int tdls_set_offchannel_offset(struct sigma_dut *dut,
14348 struct sigma_conn *conn,
14349 const char *intf, int off_ch_num,
14350 enum sec_ch_offset sec)
14351{
14352 char buf[200];
14353 int res;
14354
14355 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
14356 off_ch_num);
14357 if (res < 0 || res >= (int) sizeof(buf))
14358 return -1;
14359 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14360
14361 if (wpa_command(intf, buf) < 0) {
14362 send_resp(dut, conn, SIGMA_ERROR,
14363 "ErrorCode,Failed to set offchan");
14364 return 0;
14365 }
14366 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
14367 off_chan_val(sec));
14368 if (res < 0 || res >= (int) sizeof(buf))
14369 return -1;
14370
14371 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14372
14373 if (wpa_command(intf, buf) < 0) {
14374 send_resp(dut, conn, SIGMA_ERROR,
14375 "ErrorCode,Failed to set sec chan offset");
14376 return 0;
14377 }
14378
14379 return 1;
14380}
14381
14382
14383static int tdls_set_offchannel_mode(struct sigma_dut *dut,
14384 struct sigma_conn *conn,
14385 const char *intf, int val)
14386{
14387 char buf[200];
14388 int res;
14389
14390 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
14391 val);
14392 if (res < 0 || res >= (int) sizeof(buf))
14393 return -1;
14394 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14395
14396 if (wpa_command(intf, buf) < 0) {
14397 send_resp(dut, conn, SIGMA_ERROR,
14398 "ErrorCode,Failed to configure offchannel mode");
14399 return 0;
14400 }
14401
14402 return 1;
14403}
14404
14405
14406static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
14407 struct sigma_conn *conn,
14408 struct sigma_cmd *cmd)
14409{
14410 const char *val;
14411 enum {
14412 CHSM_NOT_SET,
14413 CHSM_ENABLE,
14414 CHSM_DISABLE,
14415 CHSM_REJREQ,
14416 CHSM_UNSOLRESP
14417 } chsm = CHSM_NOT_SET;
14418 int off_ch_num = -1;
14419 enum sec_ch_offset sec_ch = SEC_CH_NO;
14420 int res;
14421
14422 val = get_param(cmd, "Uapsd");
14423 if (val) {
14424 char buf[100];
14425 if (strcasecmp(val, "Enable") == 0)
14426 snprintf(buf, sizeof(buf), "SET ps 99");
14427 else if (strcasecmp(val, "Disable") == 0)
14428 snprintf(buf, sizeof(buf), "SET ps 98");
14429 else {
14430 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14431 "Unsupported uapsd parameter value");
14432 return 0;
14433 }
14434 if (wpa_command(intf, buf)) {
14435 send_resp(dut, conn, SIGMA_ERROR,
14436 "ErrorCode,Failed to change U-APSD "
14437 "powersave mode");
14438 return 0;
14439 }
14440 }
14441
14442 val = get_param(cmd, "TPKTIMER");
14443 if (val && strcasecmp(val, "DISABLE") == 0) {
14444 if (wpa_command(intf, "SET tdls_testing 0x100")) {
14445 send_resp(dut, conn, SIGMA_ERROR,
14446 "ErrorCode,Failed to enable no TPK "
14447 "expiration test mode");
14448 return 0;
14449 }
14450 dut->no_tpk_expiration = 1;
14451 }
14452
14453 val = get_param(cmd, "ChSwitchMode");
14454 if (val) {
14455 if (strcasecmp(val, "Enable") == 0 ||
14456 strcasecmp(val, "Initiate") == 0)
14457 chsm = CHSM_ENABLE;
14458 else if (strcasecmp(val, "Disable") == 0 ||
14459 strcasecmp(val, "passive") == 0)
14460 chsm = CHSM_DISABLE;
14461 else if (strcasecmp(val, "RejReq") == 0)
14462 chsm = CHSM_REJREQ;
14463 else if (strcasecmp(val, "UnSolResp") == 0)
14464 chsm = CHSM_UNSOLRESP;
14465 else {
14466 send_resp(dut, conn, SIGMA_ERROR,
14467 "ErrorCode,Unknown ChSwitchMode value");
14468 return 0;
14469 }
14470 }
14471
14472 val = get_param(cmd, "OffChNum");
14473 if (val) {
14474 off_ch_num = atoi(val);
14475 if (off_ch_num == 0) {
14476 send_resp(dut, conn, SIGMA_ERROR,
14477 "ErrorCode,Invalid OffChNum");
14478 return 0;
14479 }
14480 }
14481
14482 val = get_param(cmd, "SecChOffset");
14483 if (val) {
14484 if (strcmp(val, "20") == 0)
14485 sec_ch = SEC_CH_NO;
14486 else if (strcasecmp(val, "40above") == 0)
14487 sec_ch = SEC_CH_40ABOVE;
14488 else if (strcasecmp(val, "40below") == 0)
14489 sec_ch = SEC_CH_40BELOW;
14490 else {
14491 send_resp(dut, conn, SIGMA_ERROR,
14492 "ErrorCode,Unknown SecChOffset value");
14493 return 0;
14494 }
14495 }
14496
14497 if (chsm == CHSM_NOT_SET) {
14498 /* no offchannel changes requested */
14499 return 1;
14500 }
14501
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014502 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
14503 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014504 send_resp(dut, conn, SIGMA_ERROR,
14505 "ErrorCode,Unknown interface");
14506 return 0;
14507 }
14508
14509 switch (chsm) {
14510 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030014511 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014512 break;
14513 case CHSM_ENABLE:
14514 if (off_ch_num < 0) {
14515 send_resp(dut, conn, SIGMA_ERROR,
14516 "ErrorCode,Missing OffChNum argument");
14517 return 0;
14518 }
14519 if (wifi_chip_type == DRIVER_WCN) {
14520 res = tdls_set_offchannel_offset(dut, conn, intf,
14521 off_ch_num, sec_ch);
14522 } else {
14523 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14524 sec_ch);
14525 }
14526 if (res != 1)
14527 return res;
14528 if (wifi_chip_type == DRIVER_WCN)
14529 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
14530 else
14531 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
14532 break;
14533 case CHSM_DISABLE:
14534 if (wifi_chip_type == DRIVER_WCN)
14535 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
14536 else
14537 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
14538 break;
14539 case CHSM_REJREQ:
14540 if (wifi_chip_type == DRIVER_WCN)
14541 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
14542 else
14543 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
14544 break;
14545 case CHSM_UNSOLRESP:
14546 if (off_ch_num < 0) {
14547 send_resp(dut, conn, SIGMA_ERROR,
14548 "ErrorCode,Missing OffChNum argument");
14549 return 0;
14550 }
14551 if (wifi_chip_type == DRIVER_WCN) {
14552 res = tdls_set_offchannel_offset(dut, conn, intf,
14553 off_ch_num, sec_ch);
14554 } else {
14555 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14556 sec_ch);
14557 }
14558 if (res != 1)
14559 return res;
14560 if (wifi_chip_type == DRIVER_WCN)
14561 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
14562 else
14563 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
14564 break;
14565 }
14566
14567 return res;
14568}
14569
14570
14571static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14572 struct sigma_conn *conn,
14573 struct sigma_cmd *cmd)
14574{
14575 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014576 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014577
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070014578 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080014579
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014580 val = get_param(cmd, "nss_mcs_opt");
14581 if (val) {
14582 /* String (nss_operating_mode; mcs_operating_mode) */
14583 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014584 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014585
14586 token = strdup(val);
14587 if (!token)
14588 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014589 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014590 if (!result) {
14591 sigma_dut_print(dut, DUT_MSG_ERROR,
14592 "VHT NSS not specified");
14593 goto failed;
14594 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014595 if (strcasecmp(result, "def") != 0) {
14596 nss = atoi(result);
14597 if (nss == 4)
14598 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014599 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014600 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014601
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014602 }
14603
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014604 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014605 if (!result) {
14606 sigma_dut_print(dut, DUT_MSG_ERROR,
14607 "VHT MCS not specified");
14608 goto failed;
14609 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014610 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014611 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014612 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014613 } else {
14614 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014615 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014616 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014617 }
14618 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014619 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014620 }
14621
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014622 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014623 return 1;
14624failed:
14625 free(token);
14626 return 0;
14627}
14628
14629
14630static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14631 struct sigma_conn *conn,
14632 struct sigma_cmd *cmd)
14633{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014634 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014635 case DRIVER_ATHEROS:
14636 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
14637 default:
14638 send_resp(dut, conn, SIGMA_ERROR,
14639 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
14640 return 0;
14641 }
14642}
14643
14644
Jouni Malinen1702fe32021-06-08 19:08:01 +030014645static enum sigma_cmd_result
14646wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14647 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014648{
14649 const char *val;
14650 char *token = NULL, *result;
14651 char buf[60];
14652
14653 val = get_param(cmd, "nss_mcs_opt");
14654 if (val) {
14655 /* String (nss_operating_mode; mcs_operating_mode) */
14656 int nss, mcs, ratecode;
14657 char *saveptr;
14658
14659 token = strdup(val);
14660 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014661 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014662
14663 result = strtok_r(token, ";", &saveptr);
14664 if (!result) {
14665 sigma_dut_print(dut, DUT_MSG_ERROR,
14666 "HE NSS not specified");
14667 goto failed;
14668 }
14669 nss = 1;
14670 if (strcasecmp(result, "def") != 0)
14671 nss = atoi(result);
14672
14673 result = strtok_r(NULL, ";", &saveptr);
14674 if (!result) {
14675 sigma_dut_print(dut, DUT_MSG_ERROR,
14676 "HE MCS not specified");
14677 goto failed;
14678 }
14679 mcs = 7;
14680 if (strcasecmp(result, "def") != 0)
14681 mcs = atoi(result);
14682
Arif Hussain557bf412018-05-25 17:29:36 -070014683 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014684 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070014685 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014686 } else if (nss > 2) {
14687 sigma_dut_print(dut, DUT_MSG_ERROR,
14688 "HE NSS %d not supported", nss);
14689 goto failed;
14690 }
14691
Arif Hussain557bf412018-05-25 17:29:36 -070014692 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
14693 if (system(buf) != 0) {
14694 sigma_dut_print(dut, DUT_MSG_ERROR,
14695 "nss_mcs_opt: iwpriv %s nss %d failed",
14696 intf, nss);
14697 goto failed;
14698 }
Arif Hussainac6c5112018-05-25 17:34:00 -070014699 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070014700
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014701 /* Add the MCS to the ratecode */
14702 if (mcs >= 0 && mcs <= 11) {
14703 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070014704#ifdef NL80211_SUPPORT
14705 if (dut->device_type == STA_testbed) {
14706 enum he_mcs_config mcs_config;
14707 int ret;
14708
14709 if (mcs <= 7)
14710 mcs_config = HE_80_MCS0_7;
14711 else if (mcs <= 9)
14712 mcs_config = HE_80_MCS0_9;
14713 else
14714 mcs_config = HE_80_MCS0_11;
14715 ret = sta_set_he_mcs(dut, intf, mcs_config);
14716 if (ret) {
14717 sigma_dut_print(dut, DUT_MSG_ERROR,
14718 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
14719 mcs, mcs_config, ret);
14720 goto failed;
14721 }
14722 }
14723#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014724 } else {
14725 sigma_dut_print(dut, DUT_MSG_ERROR,
14726 "HE MCS %d not supported", mcs);
14727 goto failed;
14728 }
14729 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
14730 intf, ratecode);
14731 if (system(buf) != 0) {
14732 sigma_dut_print(dut, DUT_MSG_ERROR,
14733 "iwpriv setting of 11ax rates failed");
14734 goto failed;
14735 }
14736 free(token);
14737 }
14738
14739 val = get_param(cmd, "GI");
14740 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014741 int fix_rate_sgi;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014742 u8 he_gi_val = 0;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014743
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014744 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014745 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014746 fix_rate_sgi = 1;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014747 he_gi_val = NL80211_RATE_INFO_HE_GI_0_8;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014748 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014749 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
14750 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014751 fix_rate_sgi = 2;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014752 he_gi_val = NL80211_RATE_INFO_HE_GI_1_6;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014753 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014754 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
14755 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014756 fix_rate_sgi = 3;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014757 he_gi_val = NL80211_RATE_INFO_HE_GI_3_2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014758 } else {
14759 send_resp(dut, conn, SIGMA_ERROR,
14760 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014761 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014762 }
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014763 if (wcn_set_he_gi(dut, intf, he_gi_val)) {
14764 sigma_dut_print(dut, DUT_MSG_INFO,
14765 "wcn_set_he_gi failed, using iwpriv");
14766 if (system(buf) != 0) {
14767 send_resp(dut, conn, SIGMA_ERROR,
14768 "errorCode,Failed to set shortgi");
14769 return STATUS_SENT_ERROR;
14770 }
14771 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
14772 intf, fix_rate_sgi);
14773 if (system(buf) != 0) {
14774 send_resp(dut, conn, SIGMA_ERROR,
14775 "errorCode,Failed to set fix rate shortgi");
14776 return STATUS_SENT_ERROR;
14777 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014778 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014779 }
14780
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014781 val = get_param(cmd, "LTF");
14782 if (val) {
14783#ifdef NL80211_SUPPORT
14784 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014785 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014786 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014787 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014788 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014789 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014790 } else {
14791 send_resp(dut, conn, SIGMA_ERROR,
14792 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014793 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014794 }
14795#else /* NL80211_SUPPORT */
14796 sigma_dut_print(dut, DUT_MSG_ERROR,
14797 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014798 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014799#endif /* NL80211_SUPPORT */
14800 }
14801
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070014802 val = get_param(cmd, "KeepAlive");
14803 if (val) {
14804 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
14805
14806 if (strcasecmp(val, "Data") == 0)
14807 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
14808 else if (strcasecmp(val, "Mgmt") == 0)
14809 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
14810
14811 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
14812 send_resp(dut, conn, SIGMA_ERROR,
14813 "ErrorCode,Failed to set keep alive type config");
14814 return STATUS_SENT_ERROR;
14815 }
14816 }
14817
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014818 val = get_param(cmd, "TxSUPPDU");
14819 if (val) {
14820 int set_val = 1;
14821
14822 if (strcasecmp(val, "Enable") == 0)
14823 set_val = 1;
14824 else if (strcasecmp(val, "Disable") == 0)
14825 set_val = 0;
14826
14827 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
14828 send_resp(dut, conn, SIGMA_ERROR,
14829 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014830 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014831 }
14832 }
14833
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070014834 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
14835 if (val) {
14836 int set_val = 0;
14837
14838 if (strcasecmp(val, "Enable") == 0)
14839 set_val = 0;
14840 else if (strcasecmp(val, "Disable") == 0)
14841 set_val = 1;
14842
14843 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
14844 send_resp(dut, conn, SIGMA_ERROR,
14845 "ErrorCode,Failed to set mgmt/data Tx disable config");
14846 return STATUS_SENT_ERROR;
14847 }
14848 }
14849
Arif Hussain480d5f42019-03-12 14:40:42 -070014850 val = get_param(cmd, "TWT_Setup");
14851 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014852#ifdef NL80211_SUPPORT
14853 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14854 sigma_dut_print(dut, DUT_MSG_ERROR,
14855 "Failed to open nl80211 event socket");
14856#endif /* NL80211_SUPPORT */
Arif Hussain480d5f42019-03-12 14:40:42 -070014857 if (strcasecmp(val, "Request") == 0) {
Kiran Kumar Lokereafac46a2021-11-29 14:03:20 -080014858 if (set_power_save_wcn(dut, intf, 1) < 0)
14859 sigma_dut_print(dut, DUT_MSG_ERROR,
14860 "Failed to enable power save");
Arif Hussain480d5f42019-03-12 14:40:42 -070014861 if (sta_twt_request(dut, conn, cmd)) {
14862 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014863 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014864 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014865 }
14866 } else if (strcasecmp(val, "Teardown") == 0) {
14867 if (sta_twt_teardown(dut, conn, cmd)) {
14868 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014869 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014870 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014871 }
14872 }
14873 }
14874
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014875 val = get_param(cmd, "TWT_Operation");
14876 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014877#ifdef NL80211_SUPPORT
14878 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14879 sigma_dut_print(dut, DUT_MSG_ERROR,
14880 "Failed to open nl80211 event socket");
14881#endif /* NL80211_SUPPORT */
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014882 if (strcasecmp(val, "Suspend") == 0) {
14883 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
14884 send_resp(dut, conn, SIGMA_ERROR,
14885 "ErrorCode,TWT suspend failed");
14886 return STATUS_SENT_ERROR;
14887 }
14888 } else if (strcasecmp(val, "Resume") == 0) {
14889 if (sta_twt_resume(dut, conn, cmd)) {
14890 send_resp(dut, conn, SIGMA_ERROR,
14891 "ErrorCode,TWT resume failed");
14892 return STATUS_SENT_ERROR;
14893 }
14894 }
14895 }
14896
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080014897 val = get_param(cmd, "transmitOMI");
14898 if (val && sta_transmit_omi(dut, conn, cmd)) {
14899 send_resp(dut, conn, SIGMA_ERROR,
14900 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014901 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070014902 }
14903
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014904 val = get_param(cmd, "Powersave");
14905 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014906 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014907
14908 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014909 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014910 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014911 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014912 } else {
14913 sigma_dut_print(dut, DUT_MSG_ERROR,
14914 "Unsupported Powersave value '%s'",
14915 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014916 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014917 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014918 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014919 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014920 }
14921
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080014922 val = get_param(cmd, "MU_EDCA");
14923 if (val) {
14924 if (strcasecmp(val, "Override") == 0) {
14925 if (sta_set_mu_edca_override(dut, intf, 1)) {
14926 send_resp(dut, conn, SIGMA_ERROR,
14927 "errorCode,MU EDCA override set failed");
14928 return STATUS_SENT;
14929 }
14930 } else if (strcasecmp(val, "Disable") == 0) {
14931 if (sta_set_mu_edca_override(dut, intf, 0)) {
14932 send_resp(dut, conn, SIGMA_ERROR,
14933 "errorCode,MU EDCA override disable failed");
14934 return STATUS_SENT;
14935 }
14936 }
14937 }
14938
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070014939 val = get_param(cmd, "RUAllocTone");
14940 if (val && strcasecmp(val, "242") == 0) {
14941 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
14942 send_resp(dut, conn, SIGMA_ERROR,
14943 "ErrorCode,Failed to set RU 242 tone Tx");
14944 return STATUS_SENT_ERROR;
14945 }
14946 }
14947
14948 val = get_param(cmd, "PPDUTxType");
14949 if (val && strcasecmp(val, "ER-SU") == 0) {
14950 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
14951 send_resp(dut, conn, SIGMA_ERROR,
14952 "ErrorCode,Failed to set ER-SU PPDU type Tx");
14953 return STATUS_SENT_ERROR;
14954 }
14955 }
14956
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070014957 val = get_param(cmd, "Ch_Pref");
14958 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14959 return STATUS_SENT;
14960
14961 val = get_param(cmd, "Cellular_Data_Cap");
14962 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14963 return STATUS_SENT;
14964
Jouni Malinen1702fe32021-06-08 19:08:01 +030014965 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014966
14967failed:
14968 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014969 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014970}
14971
14972
Jouni Malinen1702fe32021-06-08 19:08:01 +030014973static enum sigma_cmd_result
14974cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14975 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014976{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014977 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014978 case DRIVER_WCN:
14979 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
14980 default:
14981 send_resp(dut, conn, SIGMA_ERROR,
14982 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014983 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014984 }
14985}
14986
14987
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014988static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
14989 struct sigma_conn *conn,
14990 struct sigma_cmd *cmd)
14991{
14992 const char *val;
14993
14994 val = get_param(cmd, "powersave");
14995 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014996 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014997
14998 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014999 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015000 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015001 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015002 } else {
15003 sigma_dut_print(dut, DUT_MSG_ERROR,
15004 "Unsupported power save config");
15005 return -1;
15006 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053015007 if (set_power_save_wcn(dut, intf, ps) < 0)
15008 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080015009 return 1;
15010 }
15011
15012 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
15013
15014 return 0;
15015}
15016
15017
Ashwini Patil5acd7382017-04-13 15:55:04 +053015018static int btm_query_candidate_list(struct sigma_dut *dut,
15019 struct sigma_conn *conn,
15020 struct sigma_cmd *cmd)
15021{
15022 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
15023 int len, ret;
15024 char buf[10];
15025
15026 /*
15027 * Neighbor Report elements format:
15028 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
15029 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
15030 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
15031 */
15032
15033 bssid = get_param(cmd, "Nebor_BSSID");
15034 if (!bssid) {
15035 send_resp(dut, conn, SIGMA_INVALID,
15036 "errorCode,Nebor_BSSID is missing");
15037 return 0;
15038 }
15039
15040 info = get_param(cmd, "Nebor_Bssid_Info");
15041 if (!info) {
15042 sigma_dut_print(dut, DUT_MSG_INFO,
15043 "Using default value for Nebor_Bssid_Info: %s",
15044 DEFAULT_NEIGHBOR_BSSID_INFO);
15045 info = DEFAULT_NEIGHBOR_BSSID_INFO;
15046 }
15047
15048 op_class = get_param(cmd, "Nebor_Op_Class");
15049 if (!op_class) {
15050 send_resp(dut, conn, SIGMA_INVALID,
15051 "errorCode,Nebor_Op_Class is missing");
15052 return 0;
15053 }
15054
15055 ch = get_param(cmd, "Nebor_Op_Ch");
15056 if (!ch) {
15057 send_resp(dut, conn, SIGMA_INVALID,
15058 "errorCode,Nebor_Op_Ch is missing");
15059 return 0;
15060 }
15061
15062 phy_type = get_param(cmd, "Nebor_Phy_Type");
15063 if (!phy_type) {
15064 sigma_dut_print(dut, DUT_MSG_INFO,
15065 "Using default value for Nebor_Phy_Type: %s",
15066 DEFAULT_NEIGHBOR_PHY_TYPE);
15067 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
15068 }
15069
15070 /* Parse optional subelements */
15071 buf[0] = '\0';
15072 pref = get_param(cmd, "Nebor_Pref");
15073 if (pref) {
15074 /* hexdump for preferrence subelement */
15075 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
15076 if (ret < 0 || ret >= (int) sizeof(buf)) {
15077 sigma_dut_print(dut, DUT_MSG_ERROR,
15078 "snprintf failed for optional subelement ret: %d",
15079 ret);
15080 send_resp(dut, conn, SIGMA_ERROR,
15081 "errorCode,snprintf failed for subelement");
15082 return 0;
15083 }
15084 }
15085
15086 if (!dut->btm_query_cand_list) {
15087 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
15088 if (!dut->btm_query_cand_list) {
15089 send_resp(dut, conn, SIGMA_ERROR,
15090 "errorCode,Failed to allocate memory for btm_query_cand_list");
15091 return 0;
15092 }
15093 }
15094
15095 len = strlen(dut->btm_query_cand_list);
15096 ret = snprintf(dut->btm_query_cand_list + len,
15097 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
15098 bssid, info, op_class, ch, phy_type, buf);
15099 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
15100 sigma_dut_print(dut, DUT_MSG_ERROR,
15101 "snprintf failed for neighbor report list ret: %d",
15102 ret);
15103 send_resp(dut, conn, SIGMA_ERROR,
15104 "errorCode,snprintf failed for neighbor report");
15105 free(dut->btm_query_cand_list);
15106 dut->btm_query_cand_list = NULL;
15107 return 0;
15108 }
15109
15110 return 1;
15111}
15112
15113
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015114int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
15115 struct sigma_ese_alloc *allocs, int *allocs_size)
15116{
15117 int max_count = *allocs_size;
15118 int count = 0, i;
15119 const char *val;
15120
15121 do {
15122 val = get_param_indexed(cmd, "AllocID", count);
15123 if (val)
15124 count++;
15125 } while (val);
15126
15127 if (count == 0 || count > max_count) {
15128 sigma_dut_print(dut, DUT_MSG_ERROR,
15129 "Invalid number of allocations(%d)", count);
15130 return -1;
15131 }
15132
15133 for (i = 0; i < count; i++) {
15134 val = get_param_indexed(cmd, "PercentBI", i);
15135 if (!val) {
15136 sigma_dut_print(dut, DUT_MSG_ERROR,
15137 "Missing PercentBI parameter at index %d",
15138 i);
15139 return -1;
15140 }
15141 allocs[i].percent_bi = atoi(val);
15142
15143 val = get_param_indexed(cmd, "SrcAID", i);
15144 if (val)
15145 allocs[i].src_aid = strtol(val, NULL, 0);
15146 else
15147 allocs[i].src_aid = ESE_BCAST_AID;
15148
15149 val = get_param_indexed(cmd, "DestAID", i);
15150 if (val)
15151 allocs[i].dst_aid = strtol(val, NULL, 0);
15152 else
15153 allocs[i].dst_aid = ESE_BCAST_AID;
15154
15155 allocs[i].type = ESE_CBAP;
15156 sigma_dut_print(dut, DUT_MSG_INFO,
15157 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
15158 i, allocs[i].percent_bi, allocs[i].src_aid,
15159 allocs[i].dst_aid);
15160 }
15161
15162 *allocs_size = count;
15163 return 0;
15164}
15165
15166
15167static int sta_set_60g_ese(struct sigma_dut *dut, int count,
15168 struct sigma_ese_alloc *allocs)
15169{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015170 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015171#ifdef __linux__
15172 case DRIVER_WIL6210:
15173 if (wil6210_set_ese(dut, count, allocs))
15174 return -1;
15175 return 1;
15176#endif /* __linux__ */
15177 default:
15178 sigma_dut_print(dut, DUT_MSG_ERROR,
15179 "Unsupported sta_set_60g_ese with the current driver");
15180 return -1;
15181 }
15182}
15183
15184
15185static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
15186 struct sigma_conn *conn,
15187 struct sigma_cmd *cmd)
15188{
15189 const char *val;
15190
15191 val = get_param(cmd, "ExtSchIE");
15192 if (val && !strcasecmp(val, "Enable")) {
15193 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
15194 int count = MAX_ESE_ALLOCS;
15195
15196 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
15197 return -1;
15198 return sta_set_60g_ese(dut, count, allocs);
15199 }
15200
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015201 val = get_param(cmd, "MCS_FixedRate");
15202 if (val) {
15203 int sta_mcs = atoi(val);
15204
15205 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
15206 sta_mcs);
15207 wil6210_set_force_mcs(dut, 1, sta_mcs);
15208
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015209 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015210 }
15211
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015212 send_resp(dut, conn, SIGMA_ERROR,
15213 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015214 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015215}
15216
15217
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015218static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
15219 const char *oci_frametype, uint32_t oci_freq)
15220{
15221#ifdef NL80211_SUPPORT
15222 struct nl_msg *msg;
15223 int ret = 0;
15224 struct nlattr *params;
15225 struct nlattr *attr;
15226 int ifindex;
15227 u8 frame_type;
15228
15229 ifindex = if_nametoindex(intf);
15230 if (ifindex == 0) {
15231 sigma_dut_print(dut, DUT_MSG_ERROR,
15232 "%s: Index for interface %s failed",
15233 __func__, intf);
15234 return -1;
15235 }
15236
15237 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15238 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
15239 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15240 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
15241 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15242 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
15243 } else {
15244 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
15245 __func__, oci_frametype);
15246 return -1;
15247 }
15248
15249
15250 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
15251 NL80211_CMD_VENDOR)) ||
15252 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
15253 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
15254 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
15255 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
15256 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
15257 !(params = nla_nest_start(
15258 msg,
15259 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
15260 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
15261 frame_type) ||
15262 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
15263 oci_freq)) {
15264 sigma_dut_print(dut, DUT_MSG_ERROR,
15265 "%s: err in adding vendor_cmd and vendor_data",
15266 __func__);
15267 nlmsg_free(msg);
15268 return -1;
15269 }
15270 nla_nest_end(msg, params);
15271 nla_nest_end(msg, attr);
15272
15273 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
15274 if (ret) {
15275 sigma_dut_print(dut, DUT_MSG_ERROR,
15276 "%s: err in send_and_recv_msgs, ret=%d",
15277 __func__, ret);
15278 }
15279 return ret;
15280#else /* NL80211_SUPPORT */
15281 sigma_dut_print(dut, DUT_MSG_ERROR,
15282 "OCI override not possible without NL80211_SUPPORT defined");
15283 return -1;
15284#endif /* NL80211_SUPPORT */
15285}
15286
15287
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015288static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
15289 uint8_t ignore_csa)
15290{
15291#ifdef NL80211_SUPPORT
15292 return wcn_wifi_test_config_set_u8(
15293 dut, intf,
15294 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
15295#else /* NL80211_SUPPORT */
15296 sigma_dut_print(dut, DUT_MSG_ERROR,
15297 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
15298 return -1;
15299#endif /* NL80211_SUPPORT */
15300}
15301
15302
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015303static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
15304 uint8_t rsnxe_used)
15305{
15306#ifdef NL80211_SUPPORT
15307 return wcn_wifi_test_config_set_u8(
15308 dut, intf,
15309 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
15310 rsnxe_used);
15311#else /* NL80211_SUPPORT */
15312 sigma_dut_print(dut, DUT_MSG_ERROR,
15313 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
15314 return -1;
15315#endif /* NL80211_SUPPORT */
15316}
15317
15318
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015319static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
15320 const char *intf,
15321 uint8_t ignore_sa_query_timeout)
15322{
15323#ifdef NL80211_SUPPORT
15324 return wcn_wifi_test_config_set_u8(
15325 dut, intf,
15326 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
15327 ignore_sa_query_timeout);
15328#else /* NL80211_SUPPORT */
15329 sigma_dut_print(dut, DUT_MSG_ERROR,
15330 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
15331 return -1;
15332#endif /* NL80211_SUPPORT */
15333}
15334
15335
Jouni Malinen6250cb02020-04-15 13:54:45 +030015336static enum sigma_cmd_result
15337cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
15338 struct sigma_conn *conn,
15339 struct sigma_cmd *cmd)
15340{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015341 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030015342
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053015343 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030015344 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015345 if (wifi_chip_type == DRIVER_WCN) {
15346 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
15347 send_resp(dut, conn, SIGMA_ERROR,
15348 "errorCode,Failed to set ft_rsnxe_used");
15349 return STATUS_SENT_ERROR;
15350 }
15351 return SUCCESS_SEND_STATUS;
15352 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030015353 send_resp(dut, conn, SIGMA_ERROR,
15354 "errorCode,Failed to set ft_rsnxe_used");
15355 return STATUS_SENT_ERROR;
15356 }
15357 return SUCCESS_SEND_STATUS;
15358 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015359
15360 oci_chan = get_param(cmd, "OCIChannel");
15361 oci_frametype = get_param(cmd, "OCIFrameType");
15362 if (oci_chan && oci_frametype) {
15363 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
15364 char buf[100];
15365
15366 if (!oci_freq) {
15367 send_resp(dut, conn, SIGMA_ERROR,
15368 "errorCode,Invalid OCIChannel number");
15369 return STATUS_SENT_ERROR;
15370 }
15371
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015372 if (wifi_chip_type == DRIVER_WCN &&
15373 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
15374 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
15375 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
15376 if (wcn_sta_override_oci(dut, intf, oci_frametype,
15377 oci_freq)) {
15378 send_resp(dut, conn, SIGMA_ERROR,
15379 "errorCode,Failed to override OCI");
15380 return STATUS_SENT_ERROR;
15381 }
15382 return SUCCESS_SEND_STATUS;
15383 }
15384
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015385 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
15386 snprintf(buf, sizeof(buf),
15387 "SET oci_freq_override_eapol %d", oci_freq);
15388 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15389 snprintf(buf, sizeof(buf),
15390 "SET oci_freq_override_saquery_req %d",
15391 oci_freq);
15392 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15393 snprintf(buf, sizeof(buf),
15394 "SET oci_freq_override_saquery_resp %d",
15395 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015396 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
15397 snprintf(buf, sizeof(buf),
15398 "SET oci_freq_override_eapol_g2 %d",
15399 oci_freq);
15400 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15401 snprintf(buf, sizeof(buf),
15402 "SET oci_freq_override_ft_assoc %d",
15403 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015404 } else {
15405 send_resp(dut, conn, SIGMA_ERROR,
15406 "errorCode,Unsupported OCIFrameType");
15407 return STATUS_SENT_ERROR;
15408 }
15409 if (wpa_command(intf, buf) < 0) {
15410 send_resp(dut, conn, SIGMA_ERROR,
15411 "errorCode,Failed to set oci_freq_override");
15412 return STATUS_SENT_ERROR;
15413 }
15414 return SUCCESS_SEND_STATUS;
15415 }
15416
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015417 val = get_param(cmd, "IgnoreCSA");
15418 if (val && atoi(val) == 1) {
15419 if (wifi_chip_type == DRIVER_WCN) {
15420 if (wcn_sta_ignore_csa(dut, intf, 1)) {
15421 send_resp(dut, conn, SIGMA_ERROR,
15422 "errorCode,Failed to set ignore CSA");
15423 return STATUS_SENT_ERROR;
15424 }
15425 return SUCCESS_SEND_STATUS;
15426 }
15427 }
15428
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015429 val = get_param(cmd, "Deauth_Per_SAQueryResp");
15430 if (val && atoi(val) == 0) {
15431 if (wifi_chip_type == DRIVER_WCN) {
15432 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
15433 send_resp(dut, conn, SIGMA_ERROR,
15434 "errorCode,Failed to set ignore SA Query timeout");
15435 return STATUS_SENT_ERROR;
15436 }
15437 return SUCCESS_SEND_STATUS;
15438 }
15439 }
15440
Jouni Malinen6250cb02020-04-15 13:54:45 +030015441 send_resp(dut, conn, SIGMA_ERROR,
15442 "errorCode,Unsupported WPA3 rfeature");
15443 return STATUS_SENT_ERROR;
15444}
15445
15446
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015447static enum sigma_cmd_result
15448cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
15449 struct sigma_conn *conn, struct sigma_cmd *cmd)
15450{
15451 const char *val;
15452
15453 val = get_param(cmd, "DomainName_Domain");
15454 if (val) {
15455 if (strlen(val) >= sizeof(dut->qm_domain_name))
15456 return ERROR_SEND_STATUS;
15457
15458 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
15459 return SUCCESS_SEND_STATUS;
15460 }
15461
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053015462 val = get_param(cmd, "DSCPPolicy_PolicyID");
15463 if (val) {
15464 unsigned int i;
15465 int policy_id = atoi(val);
15466
15467 val = get_param(cmd, "DSCPPolicy_RequestType");
15468
15469 if (!policy_id || !val)
15470 return INVALID_SEND_STATUS;
15471
15472 if (dut->num_dscp_status >= ARRAY_SIZE(dut->dscp_status)) {
15473 send_resp(dut, conn, SIGMA_ERROR,
15474 "errorCode,DSCP status list full");
15475 return STATUS_SENT_ERROR;
15476 }
15477
15478 for (i = 0; i < dut->num_dscp_status; i++)
15479 if (dut->dscp_status[i].id == policy_id)
15480 break;
15481
15482 /* New policy configured */
15483 if (i == dut->num_dscp_status) {
15484 dut->dscp_status[i].id = policy_id;
15485 dut->num_dscp_status++;
15486 }
15487
15488 dut->dscp_status[i].status = strcasecmp(val, "Remove") ?
15489 DSCP_POLICY_SUCCESS : DSCP_POLICY_REJECT;
15490
15491 return SUCCESS_SEND_STATUS;
15492 }
15493
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015494 send_resp(dut, conn, SIGMA_ERROR,
15495 "errorCode,Unsupported QM rfeature");
15496 return STATUS_SENT_ERROR;
15497}
15498
15499
Jouni Malinenf7222712019-06-13 01:50:21 +030015500static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
15501 struct sigma_conn *conn,
15502 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015503{
15504 const char *intf = get_param(cmd, "Interface");
15505 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015506 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015507
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015508 if (!prog)
15509 prog = get_param(cmd, "Program");
15510
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015511 if (intf == NULL || prog == NULL)
15512 return -1;
15513
Ashwini Patil5acd7382017-04-13 15:55:04 +053015514 /* BSS Transition candidate list for BTM query */
15515 val = get_param(cmd, "Nebor_BSSID");
15516 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
15517 return 0;
15518
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015519 if (strcasecmp(prog, "TDLS") == 0)
15520 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
15521
15522 if (strcasecmp(prog, "VHT") == 0)
15523 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
15524
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015525 if (strcasecmp(prog, "HE") == 0)
15526 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
15527
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015528 if (strcasecmp(prog, "MBO") == 0) {
15529 val = get_param(cmd, "Cellular_Data_Cap");
15530 if (val &&
15531 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
15532 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053015533
15534 val = get_param(cmd, "Ch_Pref");
15535 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
15536 return 0;
15537
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015538 return 1;
15539 }
15540
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015541 if (strcasecmp(prog, "60GHz") == 0)
15542 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
15543
Jouni Malinen6250cb02020-04-15 13:54:45 +030015544 if (strcasecmp(prog, "WPA3") == 0)
15545 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015546 if (strcasecmp(prog, "QM") == 0)
15547 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030015548
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015549 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
15550 return 0;
15551}
15552
15553
Jouni Malinenf7222712019-06-13 01:50:21 +030015554static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
15555 struct sigma_conn *conn,
15556 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015557{
15558 const char *intf = get_param(cmd, "Interface");
15559 const char *mode = get_param(cmd, "Mode");
15560 int res;
15561
15562 if (intf == NULL || mode == NULL)
15563 return -1;
15564
15565 if (strcasecmp(mode, "On") == 0)
15566 res = wpa_command(intf, "SET radio_disabled 0");
15567 else if (strcasecmp(mode, "Off") == 0)
15568 res = wpa_command(intf, "SET radio_disabled 1");
15569 else
15570 return -1;
15571
15572 if (res) {
15573 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15574 "radio mode");
15575 return 0;
15576 }
15577
15578 return 1;
15579}
15580
15581
Jouni Malinenf7222712019-06-13 01:50:21 +030015582static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
15583 struct sigma_conn *conn,
15584 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015585{
15586 const char *intf = get_param(cmd, "Interface");
15587 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015588 const char *prog = get_param(cmd, "program");
15589 const char *powersave = get_param(cmd, "powersave");
15590 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015591
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015592 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015593 return -1;
15594
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015595 if (prog && strcasecmp(prog, "60GHz") == 0) {
15596 /*
15597 * The CAPI mode parameter does not exist in 60G
15598 * unscheduled PS.
15599 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080015600 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015601 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015602 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020015603 strcasecmp(prog, "HE") == 0) {
15604 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015605 } else {
15606 if (mode == NULL)
15607 return -1;
15608
15609 if (strcasecmp(mode, "On") == 0)
15610 res = set_ps(intf, dut, 1);
15611 else if (strcasecmp(mode, "Off") == 0)
15612 res = set_ps(intf, dut, 0);
15613 else
15614 return -1;
15615 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015616
15617 if (res) {
15618 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15619 "power save mode");
15620 return 0;
15621 }
15622
15623 return 1;
15624}
15625
15626
Jouni Malinenf7222712019-06-13 01:50:21 +030015627static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
15628 struct sigma_conn *conn,
15629 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015630{
15631 const char *intf = get_param(cmd, "Interface");
15632 const char *val, *bssid;
15633 int res;
15634 char *buf;
15635 size_t buf_len;
15636
15637 val = get_param(cmd, "BSSID_FILTER");
15638 if (val == NULL)
15639 return -1;
15640
15641 bssid = get_param(cmd, "BSSID_List");
15642 if (atoi(val) == 0 || bssid == NULL) {
15643 /* Disable BSSID filter */
15644 if (wpa_command(intf, "SET bssid_filter ")) {
15645 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
15646 "to disable BSSID filter");
15647 return 0;
15648 }
15649
15650 return 1;
15651 }
15652
15653 buf_len = 100 + strlen(bssid);
15654 buf = malloc(buf_len);
15655 if (buf == NULL)
15656 return -1;
15657
15658 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
15659 res = wpa_command(intf, buf);
15660 free(buf);
15661 if (res) {
15662 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
15663 "BSSID filter");
15664 return 0;
15665 }
15666
15667 return 1;
15668}
15669
15670
Jouni Malinenf7222712019-06-13 01:50:21 +030015671static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
15672 struct sigma_conn *conn,
15673 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015674{
15675 const char *intf = get_param(cmd, "Interface");
15676 const char *val;
15677
15678 /* TODO: ARP */
15679
15680 val = get_param(cmd, "HS2_CACHE_PROFILE");
15681 if (val && strcasecmp(val, "All") == 0)
15682 hs2_clear_credentials(intf);
15683
15684 return 1;
15685}
15686
15687
Jouni Malinenf7222712019-06-13 01:50:21 +030015688static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
15689 struct sigma_conn *conn,
15690 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015691{
15692 const char *intf = get_param(cmd, "Interface");
15693 const char *key_type = get_param(cmd, "KeyType");
15694 char buf[100], resp[200];
15695
15696 if (key_type == NULL)
15697 return -1;
15698
15699 if (strcasecmp(key_type, "GTK") == 0) {
15700 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
15701 strncmp(buf, "FAIL", 4) == 0) {
15702 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15703 "not fetch current GTK");
15704 return 0;
15705 }
15706 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
15707 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15708 return 0;
15709 } else {
15710 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
15711 "KeyType");
15712 return 0;
15713 }
15714
15715 return 1;
15716}
15717
15718
15719static int hs2_set_policy(struct sigma_dut *dut)
15720{
15721#ifdef ANDROID
15722 system("ip rule del prio 23000");
15723 if (system("ip rule add from all lookup main prio 23000") != 0) {
15724 sigma_dut_print(dut, DUT_MSG_ERROR,
15725 "Failed to run:ip rule add from all lookup main prio");
15726 return -1;
15727 }
15728 if (system("ip route flush cache") != 0) {
15729 sigma_dut_print(dut, DUT_MSG_ERROR,
15730 "Failed to run ip route flush cache");
15731 return -1;
15732 }
15733 return 1;
15734#else /* ANDROID */
15735 return 0;
15736#endif /* ANDROID */
15737}
15738
15739
Jouni Malinenf7222712019-06-13 01:50:21 +030015740static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
15741 struct sigma_conn *conn,
15742 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015743{
15744 const char *intf = get_param(cmd, "Interface");
15745 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030015746 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015747 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030015748 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015749 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
15750 int tries = 0;
15751 int ignore_blacklist = 0;
15752 const char *events[] = {
15753 "CTRL-EVENT-CONNECTED",
15754 "INTERWORKING-BLACKLISTED",
15755 "INTERWORKING-NO-MATCH",
15756 NULL
15757 };
15758
15759 start_sta_mode(dut);
15760
Jouni Malinen439352d2018-09-13 03:42:23 +030015761 if (band) {
15762 if (strcmp(band, "2.4") == 0) {
15763 wpa_command(intf, "SET setband 2G");
15764 } else if (strcmp(band, "5") == 0) {
15765 wpa_command(intf, "SET setband 5G");
15766 } else {
15767 send_resp(dut, conn, SIGMA_ERROR,
15768 "errorCode,Unsupported band");
15769 return 0;
15770 }
15771 }
15772
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015773 blacklisted[0] = '\0';
15774 if (val && atoi(val))
15775 ignore_blacklist = 1;
15776
15777try_again:
15778 ctrl = open_wpa_mon(intf);
15779 if (ctrl == NULL) {
15780 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15781 "wpa_supplicant monitor connection");
15782 return -2;
15783 }
15784
15785 tries++;
15786 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
15787 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
15788 "Interworking connection");
15789 wpa_ctrl_detach(ctrl);
15790 wpa_ctrl_close(ctrl);
15791 return 0;
15792 }
15793
15794 buf[0] = '\0';
15795 while (1) {
15796 char *pos;
15797 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15798 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
15799 if (!pos)
15800 break;
15801 pos += 25;
15802 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
15803 pos);
15804 if (!blacklisted[0])
15805 memcpy(blacklisted, pos, strlen(pos) + 1);
15806 }
15807
15808 if (ignore_blacklist && blacklisted[0]) {
15809 char *end;
15810 end = strchr(blacklisted, ' ');
15811 if (end)
15812 *end = '\0';
15813 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
15814 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030015815 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
15816 blacklisted);
15817 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015818 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
15819 wpa_ctrl_detach(ctrl);
15820 wpa_ctrl_close(ctrl);
15821 return 0;
15822 }
15823 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15824 buf, sizeof(buf));
15825 }
15826
15827 wpa_ctrl_detach(ctrl);
15828 wpa_ctrl_close(ctrl);
15829
15830 if (res < 0) {
15831 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15832 "connect");
15833 return 0;
15834 }
15835
15836 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
15837 strstr(buf, "INTERWORKING-BLACKLISTED")) {
15838 if (tries < 2) {
15839 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
15840 goto try_again;
15841 }
15842 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
15843 "matching credentials found");
15844 return 0;
15845 }
15846
15847 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15848 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15849 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15850 "get current BSSID/SSID");
15851 return 0;
15852 }
15853
15854 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
15855 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15856 hs2_set_policy(dut);
15857 return 0;
15858}
15859
15860
Jouni Malinenf7222712019-06-13 01:50:21 +030015861static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
15862 struct sigma_conn *conn,
15863 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015864{
15865 const char *intf = get_param(cmd, "Interface");
15866 const char *display = get_param(cmd, "Display");
15867 struct wpa_ctrl *ctrl;
15868 char buf[300], params[400], *pos;
15869 char bssid[20];
15870 int info_avail = 0;
15871 unsigned int old_timeout;
15872 int res;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015873 const char *events[] = { "RX-VENUE-URL", "ANQP-QUERY-DONE", NULL };
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015874
15875 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
15876 send_resp(dut, conn, SIGMA_ERROR,
15877 "ErrorCode,Could not get current BSSID");
15878 return 0;
15879 }
15880 ctrl = open_wpa_mon(intf);
15881 if (!ctrl) {
15882 sigma_dut_print(dut, DUT_MSG_ERROR,
15883 "Failed to open wpa_supplicant monitor connection");
15884 return -2;
15885 }
15886
15887 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
15888 wpa_command(intf, buf);
15889
15890 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
15891 if (res < 0) {
15892 send_resp(dut, conn, SIGMA_ERROR,
15893 "ErrorCode,Could not complete GAS query");
15894 goto fail;
15895 }
15896
15897 old_timeout = dut->default_timeout;
15898 dut->default_timeout = 2;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015899 for (;;) {
15900 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15901 if (res < 0)
15902 break;
15903 if (strstr(buf, "ANQP-QUERY-DONE") != NULL) {
15904 res = -1;
15905 break;
15906 }
15907 pos = strchr(buf, ' ');
15908 if (!pos)
15909 continue;
15910 pos++;
15911 pos = strchr(pos, ' ');
15912 if (!pos)
15913 continue;
15914 pos++;
15915
15916 if (strncmp(pos, "https://", 8) == 0)
15917 break;
15918
15919 sigma_dut_print(dut, DUT_MSG_DEBUG,
15920 "Ignore non-HTTPS venue URL: %s", pos);
15921 }
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015922 dut->default_timeout = old_timeout;
15923 if (res < 0)
15924 goto done;
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015925 info_avail = 1;
15926 snprintf(params, sizeof(params), "browser %s", pos);
15927
15928 if (display && strcasecmp(display, "Yes") == 0) {
15929 pid_t pid;
15930
15931 pid = fork();
15932 if (pid < 0) {
15933 perror("fork");
15934 return -1;
15935 }
15936
15937 if (pid == 0) {
15938 run_hs20_osu(dut, params);
15939 exit(0);
15940 }
15941 }
15942
15943done:
15944 snprintf(buf, sizeof(buf), "Info_available,%s",
15945 info_avail ? "Yes" : "No");
15946 send_resp(dut, conn, SIGMA_COMPLETE, buf);
15947fail:
15948 wpa_ctrl_detach(ctrl);
15949 wpa_ctrl_close(ctrl);
15950 return 0;
15951}
15952
15953
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015954static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
15955 struct sigma_conn *conn,
15956 const char *ifname,
15957 struct sigma_cmd *cmd)
15958{
15959 const char *val;
15960 int id;
15961
15962 id = add_cred(ifname);
15963 if (id < 0)
15964 return -2;
15965 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15966
15967 val = get_param(cmd, "prefer");
15968 if (val && atoi(val) > 0)
15969 set_cred(ifname, id, "priority", "1");
15970
15971 val = get_param(cmd, "REALM");
15972 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
15973 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15974 "realm");
15975 return 0;
15976 }
15977
15978 val = get_param(cmd, "HOME_FQDN");
15979 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
15980 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15981 "home_fqdn");
15982 return 0;
15983 }
15984
15985 val = get_param(cmd, "Username");
15986 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
15987 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15988 "username");
15989 return 0;
15990 }
15991
15992 val = get_param(cmd, "Password");
15993 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
15994 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15995 "password");
15996 return 0;
15997 }
15998
15999 val = get_param(cmd, "ROOT_CA");
16000 if (val) {
16001 char fname[200];
16002 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16003#ifdef __linux__
16004 if (!file_exists(fname)) {
16005 char msg[300];
16006 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16007 "file (%s) not found", fname);
16008 send_resp(dut, conn, SIGMA_ERROR, msg);
16009 return 0;
16010 }
16011#endif /* __linux__ */
16012 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16013 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16014 "not set root CA");
16015 return 0;
16016 }
16017 }
16018
16019 return 1;
16020}
16021
16022
16023static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
16024{
16025 FILE *in, *out;
16026 char buf[500];
16027 int found = 0;
16028
16029 in = fopen("devdetail.xml", "r");
16030 if (in == NULL)
16031 return -1;
16032 out = fopen("devdetail.xml.tmp", "w");
16033 if (out == NULL) {
16034 fclose(in);
16035 return -1;
16036 }
16037
16038 while (fgets(buf, sizeof(buf), in)) {
16039 char *pos = strstr(buf, "<IMSI>");
16040 if (pos) {
16041 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
16042 imsi);
16043 pos += 6;
16044 *pos = '\0';
16045 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
16046 found++;
16047 } else {
16048 fprintf(out, "%s", buf);
16049 }
16050 }
16051
16052 fclose(out);
16053 fclose(in);
16054 if (found)
16055 rename("devdetail.xml.tmp", "devdetail.xml");
16056 else
16057 unlink("devdetail.xml.tmp");
16058
16059 return 0;
16060}
16061
16062
16063static int sta_add_credential_sim(struct sigma_dut *dut,
16064 struct sigma_conn *conn,
16065 const char *ifname, struct sigma_cmd *cmd)
16066{
16067 const char *val, *imsi = NULL;
16068 int id;
16069 char buf[200];
16070 int res;
16071 const char *pos;
16072 size_t mnc_len;
16073 char plmn_mcc[4];
16074 char plmn_mnc[4];
16075
16076 id = add_cred(ifname);
16077 if (id < 0)
16078 return -2;
16079 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16080
16081 val = get_param(cmd, "prefer");
16082 if (val && atoi(val) > 0)
16083 set_cred(ifname, id, "priority", "1");
16084
16085 val = get_param(cmd, "PLMN_MCC");
16086 if (val == NULL) {
16087 send_resp(dut, conn, SIGMA_ERROR,
16088 "errorCode,Missing PLMN_MCC");
16089 return 0;
16090 }
16091 if (strlen(val) != 3) {
16092 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
16093 return 0;
16094 }
16095 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
16096
16097 val = get_param(cmd, "PLMN_MNC");
16098 if (val == NULL) {
16099 send_resp(dut, conn, SIGMA_ERROR,
16100 "errorCode,Missing PLMN_MNC");
16101 return 0;
16102 }
16103 if (strlen(val) != 2 && strlen(val) != 3) {
16104 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
16105 return 0;
16106 }
16107 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
16108
16109 val = get_param(cmd, "IMSI");
16110 if (val == NULL) {
16111 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
16112 "IMSI");
16113 return 0;
16114 }
16115
16116 imsi = pos = val;
16117
16118 if (strncmp(plmn_mcc, pos, 3) != 0) {
16119 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
16120 return 0;
16121 }
16122 pos += 3;
16123
16124 mnc_len = strlen(plmn_mnc);
16125 if (mnc_len < 2) {
16126 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
16127 return 0;
16128 }
16129
16130 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
16131 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
16132 return 0;
16133 }
16134 pos += mnc_len;
16135
16136 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
16137 if (res < 0 || res >= (int) sizeof(buf))
16138 return -1;
16139 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
16140 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16141 "not set IMSI");
16142 return 0;
16143 }
16144
16145 val = get_param(cmd, "Password");
16146 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
16147 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16148 "not set password");
16149 return 0;
16150 }
16151
Jouni Malinen9a742ff2022-01-27 00:43:14 +020016152 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
16153 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016154 /*
16155 * Set provisioning_sp for the test cases where SIM/USIM
16156 * provisioning is used.
16157 */
16158 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
16159 "wi-fi.org") < 0) {
16160 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16161 "not set provisioning_sp");
16162 return 0;
16163 }
16164
16165 update_devdetail_imsi(dut, imsi);
16166 }
16167
16168 return 1;
16169}
16170
16171
16172static int sta_add_credential_cert(struct sigma_dut *dut,
16173 struct sigma_conn *conn,
16174 const char *ifname,
16175 struct sigma_cmd *cmd)
16176{
16177 const char *val;
16178 int id;
16179
16180 id = add_cred(ifname);
16181 if (id < 0)
16182 return -2;
16183 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16184
16185 val = get_param(cmd, "prefer");
16186 if (val && atoi(val) > 0)
16187 set_cred(ifname, id, "priority", "1");
16188
16189 val = get_param(cmd, "REALM");
16190 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
16191 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16192 "realm");
16193 return 0;
16194 }
16195
16196 val = get_param(cmd, "HOME_FQDN");
16197 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
16198 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16199 "home_fqdn");
16200 return 0;
16201 }
16202
16203 val = get_param(cmd, "Username");
16204 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
16205 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16206 "username");
16207 return 0;
16208 }
16209
16210 val = get_param(cmd, "clientCertificate");
16211 if (val) {
16212 char fname[200];
16213 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16214#ifdef __linux__
16215 if (!file_exists(fname)) {
16216 char msg[300];
16217 snprintf(msg, sizeof(msg),
16218 "ErrorCode,clientCertificate "
16219 "file (%s) not found", fname);
16220 send_resp(dut, conn, SIGMA_ERROR, msg);
16221 return 0;
16222 }
16223#endif /* __linux__ */
16224 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
16225 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16226 "not set client_cert");
16227 return 0;
16228 }
16229 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
16230 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16231 "not set private_key");
16232 return 0;
16233 }
16234 }
16235
16236 val = get_param(cmd, "ROOT_CA");
16237 if (val) {
16238 char fname[200];
16239 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16240#ifdef __linux__
16241 if (!file_exists(fname)) {
16242 char msg[300];
16243 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16244 "file (%s) not found", fname);
16245 send_resp(dut, conn, SIGMA_ERROR, msg);
16246 return 0;
16247 }
16248#endif /* __linux__ */
16249 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16250 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16251 "not set root CA");
16252 return 0;
16253 }
16254 }
16255
16256 return 1;
16257}
16258
16259
Jouni Malinenf7222712019-06-13 01:50:21 +030016260static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
16261 struct sigma_conn *conn,
16262 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016263{
16264 const char *intf = get_param(cmd, "Interface");
16265 const char *type;
16266
16267 start_sta_mode(dut);
16268
16269 type = get_param(cmd, "Type");
16270 if (!type)
16271 return -1;
16272
16273 if (strcasecmp(type, "uname_pwd") == 0)
16274 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
16275
16276 if (strcasecmp(type, "sim") == 0)
16277 return sta_add_credential_sim(dut, conn, intf, cmd);
16278
16279 if (strcasecmp(type, "cert") == 0)
16280 return sta_add_credential_cert(dut, conn, intf, cmd);
16281
16282 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
16283 "type");
16284 return 0;
16285}
16286
16287
Jouni Malinenf7222712019-06-13 01:50:21 +030016288static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
16289 struct sigma_conn *conn,
16290 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016291{
16292 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016293 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070016294 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053016295 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016296 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016297 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016298 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016299 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016300
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020016301 start_sta_mode(dut);
16302
Arif Hussain66a4af02019-02-07 15:04:51 -080016303 val = get_param(cmd, "GetParameter");
16304 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016305 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080016306 buf, sizeof(buf)) < 0) {
16307 sigma_dut_print(dut, DUT_MSG_ERROR,
16308 "Could not get ssid bssid");
16309 return ERROR_SEND_STATUS;
16310 }
16311
16312 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
16313 send_resp(dut, conn, SIGMA_COMPLETE, buf);
16314 return STATUS_SENT;
16315 }
16316
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016317 val = get_param(cmd, "HESSID");
16318 if (val) {
16319 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
16320 if (res < 0 || res >= (int) sizeof(buf))
16321 return -1;
16322 wpa_command(intf, buf);
16323 }
16324
16325 val = get_param(cmd, "ACCS_NET_TYPE");
16326 if (val) {
16327 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
16328 val);
16329 if (res < 0 || res >= (int) sizeof(buf))
16330 return -1;
16331 wpa_command(intf, buf);
16332 }
16333
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016334 if (get_param(cmd, "RxMac"))
16335 sta_set_scan_unicast_probe(dut, intf, 1);
16336
vamsi krishna89ad8c62017-09-19 12:51:18 +053016337 bssid = get_param(cmd, "Bssid");
16338 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016339 if (!bssid)
16340 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053016341
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016342 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
16343 dut->device_type == STA_testbed) {
16344 ssid = NULL;
16345 wildcard_ssid = 1;
16346 }
16347
vamsi krishna89ad8c62017-09-19 12:51:18 +053016348 if (ssid) {
16349 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
16350 send_resp(dut, conn, SIGMA_ERROR,
16351 "ErrorCode,Too long SSID");
16352 return 0;
16353 }
16354 ascii2hexstr(ssid, ssid_hex);
16355 }
16356
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016357 short_ssid = get_param(cmd, "ShortSSID");
16358 if (short_ssid) {
16359 uint32_t short_ssid_hex;
16360
16361 short_ssid_hex = strtoul(short_ssid, NULL, 16);
16362 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
16363 (((short_ssid_hex >> 8) & 0xFF) << 16) |
16364 (((short_ssid_hex >> 16) & 0xFF) << 8) |
16365 ((short_ssid_hex >> 24) & 0xFF);
16366
16367 res = snprintf(buf, sizeof(buf),
16368 "VENDOR_ELEM_ADD 14 ff053a%08x",
16369 short_ssid_hex);
16370 if (res < 0 || res >= (int) sizeof(buf) ||
16371 wpa_command(intf, buf)) {
16372 send_resp(dut, conn, SIGMA_ERROR,
16373 "errorCode,Failed to add short SSID");
16374 return STATUS_SENT_ERROR;
16375 }
16376 }
16377
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016378 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053016379 if (scan_freq) {
16380 if (strcasecmp(scan_freq, "2G") == 0)
16381 scan_freq = "2412-2462";
16382 else if (strcasecmp(scan_freq, "5G") == 0)
16383 scan_freq = "5180-5925";
16384 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016385
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016386 val = get_param(cmd, "WaitCompletion");
16387 if (val && atoi(val) == 1) {
16388 ctrl = open_wpa_mon(intf);
16389 if (!ctrl) {
16390 send_resp(dut, conn, SIGMA_ERROR,
16391 "errorCode,Failed to open monitor socket");
16392 return STATUS_SENT_ERROR;
16393 }
16394 }
16395
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016396 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053016397 bssid ? " bssid=": "",
16398 bssid ? bssid : "",
16399 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016400 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016401 wildcard_ssid ? " wildcard_ssid=1" : "",
16402 scan_freq ? " freq=" : "",
16403 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016404 if (res < 0 || res >= (int) sizeof(buf)) {
16405 send_resp(dut, conn, SIGMA_ERROR,
16406 "errorCode,Could not build scan command");
16407 status = STATUS_SENT_ERROR;
16408 goto remove_s_ssid;
16409 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053016410
Veerendranathdc581b52020-08-10 03:29:08 -070016411 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
16412 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
16413 sigma_dut_print(dut, DUT_MSG_DEBUG,
16414 "Scan request rejected with busy status, abort ongoing scan and try again");
16415 wpa_command(intf, "ABORT_SCAN");
16416 res = wpa_command(intf, buf);
16417 }
16418
16419 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016420 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
16421 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016422 status = STATUS_SENT_ERROR;
16423 } else {
16424 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016425 }
16426
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016427remove_s_ssid:
16428 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
16429 sigma_dut_print(dut, DUT_MSG_ERROR,
16430 "Failed to delete vendor element");
16431
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016432 if (ctrl) {
16433 if (status == SUCCESS_SEND_STATUS) {
16434 res = get_wpa_cli_event(dut, ctrl,
16435 "CTRL-EVENT-SCAN-RESULTS",
16436 buf, sizeof(buf));
16437 if (res < 0) {
16438 send_resp(dut, conn, SIGMA_ERROR,
16439 "ErrorCode,scan did not complete");
16440 status = STATUS_SENT_ERROR;
16441 }
16442 }
16443
16444 wpa_ctrl_detach(ctrl);
16445 wpa_ctrl_close(ctrl);
16446 }
16447
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016448 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016449}
16450
16451
Jouni Malinenf7222712019-06-13 01:50:21 +030016452static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
16453 struct sigma_conn *conn,
16454 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016455{
16456 const char *intf = get_param(cmd, "Interface");
16457 const char *bssid;
16458 char buf[4096], *pos;
16459 int freq, chan;
16460 char *ssid;
16461 char resp[100];
16462 int res;
16463 struct wpa_ctrl *ctrl;
16464
16465 bssid = get_param(cmd, "BSSID");
16466 if (!bssid) {
16467 send_resp(dut, conn, SIGMA_INVALID,
16468 "errorCode,BSSID argument is missing");
16469 return 0;
16470 }
16471
16472 ctrl = open_wpa_mon(intf);
16473 if (!ctrl) {
16474 sigma_dut_print(dut, DUT_MSG_ERROR,
16475 "Failed to open wpa_supplicant monitor connection");
16476 return -1;
16477 }
16478
16479 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
16480 send_resp(dut, conn, SIGMA_ERROR,
16481 "errorCode,Could not start scan");
16482 wpa_ctrl_detach(ctrl);
16483 wpa_ctrl_close(ctrl);
16484 return 0;
16485 }
16486
16487 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
16488 buf, sizeof(buf));
16489
16490 wpa_ctrl_detach(ctrl);
16491 wpa_ctrl_close(ctrl);
16492
16493 if (res < 0) {
16494 send_resp(dut, conn, SIGMA_ERROR,
16495 "errorCode,Scan did not complete");
16496 return 0;
16497 }
16498
16499 snprintf(buf, sizeof(buf), "BSS %s", bssid);
16500 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
16501 strncmp(buf, "id=", 3) != 0) {
16502 send_resp(dut, conn, SIGMA_ERROR,
16503 "errorCode,Specified BSSID not found");
16504 return 0;
16505 }
16506
16507 pos = strstr(buf, "\nfreq=");
16508 if (!pos) {
16509 send_resp(dut, conn, SIGMA_ERROR,
16510 "errorCode,Channel not found");
16511 return 0;
16512 }
16513 freq = atoi(pos + 6);
16514 chan = freq_to_channel(freq);
16515
16516 pos = strstr(buf, "\nssid=");
16517 if (!pos) {
16518 send_resp(dut, conn, SIGMA_ERROR,
16519 "errorCode,SSID not found");
16520 return 0;
16521 }
16522 ssid = pos + 6;
16523 pos = strchr(ssid, '\n');
16524 if (pos)
16525 *pos = '\0';
16526 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
16527 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16528 return 0;
16529}
16530
16531
Jouni Malinenf7222712019-06-13 01:50:21 +030016532static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
16533 struct sigma_conn *conn,
16534 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016535{
16536#ifdef __linux__
16537 struct timeval tv;
16538 struct tm tm;
16539 time_t t;
16540 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016541 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016542
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016543 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016544
16545 memset(&tm, 0, sizeof(tm));
16546 val = get_param(cmd, "seconds");
16547 if (val)
16548 tm.tm_sec = atoi(val);
16549 val = get_param(cmd, "minutes");
16550 if (val)
16551 tm.tm_min = atoi(val);
16552 val = get_param(cmd, "hours");
16553 if (val)
16554 tm.tm_hour = atoi(val);
16555 val = get_param(cmd, "date");
16556 if (val)
16557 tm.tm_mday = atoi(val);
16558 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016559 if (val) {
16560 v = atoi(val);
16561 if (v < 1 || v > 12) {
16562 send_resp(dut, conn, SIGMA_INVALID,
16563 "errorCode,Invalid month");
16564 return 0;
16565 }
16566 tm.tm_mon = v - 1;
16567 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016568 val = get_param(cmd, "year");
16569 if (val) {
16570 int year = atoi(val);
16571#ifdef ANDROID
16572 if (year > 2035)
16573 year = 2035; /* years beyond 2035 not supported */
16574#endif /* ANDROID */
16575 tm.tm_year = year - 1900;
16576 }
16577 t = mktime(&tm);
16578 if (t == (time_t) -1) {
16579 send_resp(dut, conn, SIGMA_ERROR,
16580 "errorCode,Invalid date or time");
16581 return 0;
16582 }
16583
16584 memset(&tv, 0, sizeof(tv));
16585 tv.tv_sec = t;
16586
16587 if (settimeofday(&tv, NULL) < 0) {
16588 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
16589 strerror(errno));
16590 send_resp(dut, conn, SIGMA_ERROR,
16591 "errorCode,Failed to set time");
16592 return 0;
16593 }
16594
16595 return 1;
16596#endif /* __linux__ */
16597
16598 return -1;
16599}
16600
16601
Jouni Malinenf7222712019-06-13 01:50:21 +030016602static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
16603 struct sigma_conn *conn,
16604 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016605{
16606 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016607 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016608 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016609 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016610 int res;
16611 struct wpa_ctrl *ctrl;
16612
16613 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016614 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016615
16616 val = get_param(cmd, "ProdESSAssoc");
16617 if (val)
16618 prod_ess_assoc = atoi(val);
16619
16620 kill_dhcp_client(dut, intf);
16621 if (start_dhcp_client(dut, intf) < 0)
16622 return -2;
16623
16624 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
16625 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16626 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016627 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016628 prod_ess_assoc ? "" : "-N",
16629 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016630 name ? "'" : "",
16631 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
16632 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016633
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053016634 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016635 if (run_hs20_osu(dut, buf) < 0) {
16636 FILE *f;
16637
16638 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
16639
16640 f = fopen("hs20-osu-client.res", "r");
16641 if (f) {
16642 char resp[400], res[300], *pos;
16643 if (!fgets(res, sizeof(res), f))
16644 res[0] = '\0';
16645 pos = strchr(res, '\n');
16646 if (pos)
16647 *pos = '\0';
16648 fclose(f);
16649 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
16650 res);
16651 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
16652 if (system(resp) != 0) {
16653 }
16654 snprintf(resp, sizeof(resp),
16655 "SSID,,BSSID,,failureReason,%s", res);
16656 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16657 return 0;
16658 }
16659
16660 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16661 return 0;
16662 }
16663
16664 if (!prod_ess_assoc)
16665 goto report;
16666
16667 ctrl = open_wpa_mon(intf);
16668 if (ctrl == NULL) {
16669 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16670 "wpa_supplicant monitor connection");
16671 return -1;
16672 }
16673
16674 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
16675 buf, sizeof(buf));
16676
16677 wpa_ctrl_detach(ctrl);
16678 wpa_ctrl_close(ctrl);
16679
16680 if (res < 0) {
16681 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
16682 "network after OSU");
16683 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16684 return 0;
16685 }
16686
16687report:
16688 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
16689 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
16690 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
16691 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16692 return 0;
16693 }
16694
16695 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
16696 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016697 return 0;
16698}
16699
16700
Jouni Malinenf7222712019-06-13 01:50:21 +030016701static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
16702 struct sigma_conn *conn,
16703 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016704{
16705 const char *val;
16706 int timeout = 120;
16707
16708 val = get_param(cmd, "PolicyUpdate");
16709 if (val == NULL || atoi(val) == 0)
16710 return 1; /* No operation requested */
16711
16712 val = get_param(cmd, "Timeout");
16713 if (val)
16714 timeout = atoi(val);
16715
16716 if (timeout) {
16717 /* TODO: time out the command and return
16718 * PolicyUpdateStatus,TIMEOUT if needed. */
16719 }
16720
16721 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
16722 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16723 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
16724 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
16725 return 0;
16726 }
16727
16728 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
16729 return 0;
16730}
16731
16732
Jouni Malinenf7222712019-06-13 01:50:21 +030016733static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
16734 struct sigma_conn *conn,
16735 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016736{
16737 struct wpa_ctrl *ctrl;
16738 const char *intf = get_param(cmd, "Interface");
16739 const char *bssid = get_param(cmd, "Bssid");
16740 const char *ssid = get_param(cmd, "SSID");
16741 const char *security = get_param(cmd, "Security");
16742 const char *passphrase = get_param(cmd, "Passphrase");
16743 const char *pin = get_param(cmd, "PIN");
16744 char buf[1000];
16745 char ssid_hex[200], passphrase_hex[200];
16746 const char *keymgmt, *cipher;
16747
16748 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016749 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016750
16751 if (!bssid) {
16752 send_resp(dut, conn, SIGMA_ERROR,
16753 "ErrorCode,Missing Bssid argument");
16754 return 0;
16755 }
16756
16757 if (!ssid) {
16758 send_resp(dut, conn, SIGMA_ERROR,
16759 "ErrorCode,Missing SSID argument");
16760 return 0;
16761 }
16762
16763 if (!security) {
16764 send_resp(dut, conn, SIGMA_ERROR,
16765 "ErrorCode,Missing Security argument");
16766 return 0;
16767 }
16768
16769 if (!passphrase) {
16770 send_resp(dut, conn, SIGMA_ERROR,
16771 "ErrorCode,Missing Passphrase argument");
16772 return 0;
16773 }
16774
16775 if (!pin) {
16776 send_resp(dut, conn, SIGMA_ERROR,
16777 "ErrorCode,Missing PIN argument");
16778 return 0;
16779 }
16780
vamsi krishna8c9c1562017-05-12 15:51:46 +053016781 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
16782 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016783 send_resp(dut, conn, SIGMA_ERROR,
16784 "ErrorCode,Too long SSID/passphrase");
16785 return 0;
16786 }
16787
16788 ctrl = open_wpa_mon(intf);
16789 if (ctrl == NULL) {
16790 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16791 "wpa_supplicant monitor connection");
16792 return -2;
16793 }
16794
16795 if (strcasecmp(security, "wpa2-psk") == 0) {
16796 keymgmt = "WPA2PSK";
16797 cipher = "CCMP";
16798 } else {
16799 wpa_ctrl_detach(ctrl);
16800 wpa_ctrl_close(ctrl);
16801 send_resp(dut, conn, SIGMA_ERROR,
16802 "ErrorCode,Unsupported Security value");
16803 return 0;
16804 }
16805
16806 ascii2hexstr(ssid, ssid_hex);
16807 ascii2hexstr(passphrase, passphrase_hex);
16808 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
16809 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
16810
16811 if (wpa_command(intf, buf) < 0) {
16812 wpa_ctrl_detach(ctrl);
16813 wpa_ctrl_close(ctrl);
16814 send_resp(dut, conn, SIGMA_ERROR,
16815 "ErrorCode,Failed to start registrar");
16816 return 0;
16817 }
16818
16819 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
16820 dut->er_oper_performed = 1;
16821
16822 return wps_connection_event(dut, conn, ctrl, intf, 0);
16823}
16824
16825
Jouni Malinenf7222712019-06-13 01:50:21 +030016826static enum sigma_cmd_result
16827cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
16828 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016829{
16830 struct wpa_ctrl *ctrl;
16831 const char *intf = get_param(cmd, "Interface");
16832 const char *bssid = get_param(cmd, "Bssid");
16833 char buf[100];
16834
16835 if (!bssid) {
16836 send_resp(dut, conn, SIGMA_ERROR,
16837 "ErrorCode,Missing Bssid argument");
16838 return 0;
16839 }
16840
16841 ctrl = open_wpa_mon(intf);
16842 if (ctrl == NULL) {
16843 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16844 "wpa_supplicant monitor connection");
16845 return -2;
16846 }
16847
16848 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
16849
16850 if (wpa_command(intf, buf) < 0) {
16851 wpa_ctrl_detach(ctrl);
16852 wpa_ctrl_close(ctrl);
16853 send_resp(dut, conn, SIGMA_ERROR,
16854 "ErrorCode,Failed to start registrar");
16855 return 0;
16856 }
16857
16858 return wps_connection_event(dut, conn, ctrl, intf, 0);
16859}
16860
16861
Jouni Malinenf7222712019-06-13 01:50:21 +030016862static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
16863 struct sigma_conn *conn,
16864 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053016865{
16866 struct wpa_ctrl *ctrl;
16867 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016868 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016869 const char *config_method = get_param(cmd, "WPSConfigMethod");
16870 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053016871 int res;
16872 char buf[256];
16873 const char *events[] = {
16874 "CTRL-EVENT-CONNECTED",
16875 "WPS-OVERLAP-DETECTED",
16876 "WPS-TIMEOUT",
16877 "WPS-FAIL",
16878 NULL
16879 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016880 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053016881
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016882 /* 60G WPS tests do not pass Interface parameter */
16883 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016884 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016885
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016886 if (dut->mode == SIGMA_MODE_AP)
16887 return ap_wps_registration(dut, conn, cmd);
16888
16889 if (config_method) {
16890 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
16891 * sta_wps_enter_pin before calling start_wps_registration. */
16892 if (strcasecmp(config_method, "PBC") == 0)
16893 dut->wps_method = WFA_CS_WPS_PBC;
16894 }
16895 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
16896 send_resp(dut, conn, SIGMA_ERROR,
16897 "ErrorCode,WPS parameters not yet set");
16898 return STATUS_SENT;
16899 }
16900
16901 /* Make sure WPS is enabled (also for STA mode) */
16902 dut->wps_disable = 0;
16903
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016904 if (dut->band == WPS_BAND_60G && network_mode &&
16905 strcasecmp(network_mode, "PBSS") == 0) {
16906 sigma_dut_print(dut, DUT_MSG_DEBUG,
16907 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016908 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016909 return -2;
16910 }
16911
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016912 if (dut->force_rsn_ie) {
16913 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
16914 dut->force_rsn_ie);
16915 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
16916 sigma_dut_print(dut, DUT_MSG_INFO,
16917 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020016918 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016919 }
16920 }
16921
vamsi krishna9b144002017-09-20 13:28:13 +053016922 ctrl = open_wpa_mon(intf);
16923 if (!ctrl) {
16924 sigma_dut_print(dut, DUT_MSG_ERROR,
16925 "Failed to open wpa_supplicant monitor connection");
16926 return -2;
16927 }
16928
16929 role = get_param(cmd, "WpsRole");
16930 if (!role) {
16931 send_resp(dut, conn, SIGMA_INVALID,
16932 "ErrorCode,WpsRole not provided");
16933 goto fail;
16934 }
16935
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016936 if (strcasecmp(role, "Enrollee") != 0) {
16937 /* Registrar role for STA not supported */
16938 send_resp(dut, conn, SIGMA_ERROR,
16939 "ErrorCode,Unsupported WpsRole value");
16940 goto fail;
16941 }
16942
16943 if (is_60g_sigma_dut(dut)) {
16944 if (dut->wps_method == WFA_CS_WPS_PBC)
16945 snprintf(buf, sizeof(buf), "WPS_PBC");
16946 else /* WFA_CS_WPS_PIN_KEYPAD */
16947 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
16948 dut->wps_pin);
16949 if (wpa_command(intf, buf) < 0) {
16950 send_resp(dut, conn, SIGMA_ERROR,
16951 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053016952 goto fail;
16953 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016954 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16955 if (res < 0) {
16956 send_resp(dut, conn, SIGMA_ERROR,
16957 "ErrorCode,WPS connection did not complete");
16958 goto fail;
16959 }
16960 if (strstr(buf, "WPS-TIMEOUT")) {
16961 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
16962 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16963 send_resp(dut, conn, SIGMA_COMPLETE,
16964 "WpsState,OverlapSession");
16965 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16966 send_resp(dut, conn, SIGMA_COMPLETE,
16967 "WpsState,Successful");
16968 } else {
16969 send_resp(dut, conn, SIGMA_COMPLETE,
16970 "WpsState,Failure");
16971 }
16972 } else {
16973 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053016974 if (wpa_command(intf, "WPS_PBC") < 0) {
16975 send_resp(dut, conn, SIGMA_ERROR,
16976 "ErrorCode,Failed to enable PBC");
16977 goto fail;
16978 }
16979 } else {
16980 /* TODO: PIN method */
16981 send_resp(dut, conn, SIGMA_ERROR,
16982 "ErrorCode,Unsupported WpsConfigMethod value");
16983 goto fail;
16984 }
16985 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16986 if (res < 0) {
16987 send_resp(dut, conn, SIGMA_ERROR,
16988 "ErrorCode,WPS connection did not complete");
16989 goto fail;
16990 }
16991 if (strstr(buf, "WPS-TIMEOUT")) {
16992 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
16993 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16994 send_resp(dut, conn, SIGMA_ERROR,
16995 "ErrorCode,OverlapSession");
16996 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16997 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
16998 } else {
16999 send_resp(dut, conn, SIGMA_ERROR,
17000 "ErrorCode,WPS operation failed");
17001 }
vamsi krishna9b144002017-09-20 13:28:13 +053017002 }
17003
17004fail:
17005 wpa_ctrl_detach(ctrl);
17006 wpa_ctrl_close(ctrl);
17007 return 0;
17008}
17009
17010
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017011static int req_intf(struct sigma_cmd *cmd)
17012{
17013 return get_param(cmd, "interface") == NULL ? -1 : 0;
17014}
17015
17016
17017void sta_register_cmds(void)
17018{
17019 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
17020 cmd_sta_get_ip_config);
17021 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
17022 cmd_sta_set_ip_config);
17023 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
17024 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
17025 cmd_sta_get_mac_address);
17026 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
17027 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
17028 cmd_sta_verify_ip_connection);
17029 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
17030 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
17031 cmd_sta_set_encryption);
17032 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
17033 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
17034 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
17035 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
17036 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
17037 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
17038 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
17039 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
17040 cmd_sta_set_eapakaprime);
17041 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
17042 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
17043 /* TODO: sta_set_ibss */
17044 /* TODO: sta_set_mode */
17045 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
17046 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
17047 /* TODO: sta_up_load */
17048 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
17049 cmd_sta_preset_testparameters);
17050 /* TODO: sta_set_system */
17051 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
17052 /* TODO: sta_set_rifs_test */
17053 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
17054 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
17055 /* TODO: sta_send_coexist_mgmt */
17056 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
17057 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
17058 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
17059 sigma_dut_reg_cmd("sta_reset_default", req_intf,
17060 cmd_sta_reset_default);
17061 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
17062 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
17063 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
17064 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
17065 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020017066 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017067 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
17068 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
17069 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
17070 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
17071 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030017072 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
17073 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017074 sigma_dut_reg_cmd("sta_add_credential", req_intf,
17075 cmd_sta_add_credential);
17076 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020017077 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017078 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
17079 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
17080 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
17081 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
17082 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
17083 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030017084 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017085 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
17086 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020017087 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053017088 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017089}