blob: ecd88f5b6a6076802fbaf786f77f42496a3503e5 [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
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006439 return 1;
6440}
6441
6442
6443static const char * ath_get_radio_name(const char *radio_name)
6444{
6445 if (radio_name == NULL)
6446 return "wifi0";
6447 if (strcmp(radio_name, "wifi1") == 0)
6448 return "wifi1";
6449 if (strcmp(radio_name, "wifi2") == 0)
6450 return "wifi2";
6451 return "wifi0";
6452}
6453
6454
6455static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
6456 const char *val)
6457{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006458 unsigned int vht_mcsmap = 0;
6459 int txchainmask = 0;
6460 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6461
6462 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6463 if (dut->testbed_flag_txsp == 1) {
6464 vht_mcsmap = 0xfffc;
6465 dut->testbed_flag_txsp = 0;
6466 } else {
6467 vht_mcsmap = 0xfffe;
6468 }
6469 txchainmask = 1;
6470 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6471 if (dut->testbed_flag_txsp == 1) {
6472 vht_mcsmap = 0xfff0;
6473 dut->testbed_flag_txsp = 0;
6474 } else {
6475 vht_mcsmap = 0xfffa;
6476 }
6477 txchainmask = 3;
6478 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6479 if (dut->testbed_flag_txsp == 1) {
6480 vht_mcsmap = 0xffc0;
6481 dut->testbed_flag_txsp = 0;
6482 } else {
6483 vht_mcsmap = 0xffea;
6484 }
6485 txchainmask = 7;
6486 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6487 if (dut->testbed_flag_txsp == 1) {
6488 vht_mcsmap = 0xff00;
6489 dut->testbed_flag_txsp = 0;
6490 } else {
6491 vht_mcsmap = 0xffaa;
6492 }
6493 txchainmask = 15;
6494 } else {
6495 if (dut->testbed_flag_txsp == 1) {
6496 vht_mcsmap = 0xffc0;
6497 dut->testbed_flag_txsp = 0;
6498 } else {
6499 vht_mcsmap = 0xffea;
6500 }
6501 }
6502
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006503 if (txchainmask)
6504 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006505
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006506 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006507}
6508
6509
6510static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
6511 const char *val)
6512{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006513 unsigned int vht_mcsmap = 0;
6514 int rxchainmask = 0;
6515 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6516
6517 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6518 if (dut->testbed_flag_rxsp == 1) {
6519 vht_mcsmap = 0xfffc;
6520 dut->testbed_flag_rxsp = 0;
6521 } else {
6522 vht_mcsmap = 0xfffe;
6523 }
6524 rxchainmask = 1;
6525 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6526 if (dut->testbed_flag_rxsp == 1) {
6527 vht_mcsmap = 0xfff0;
6528 dut->testbed_flag_rxsp = 0;
6529 } else {
6530 vht_mcsmap = 0xfffa;
6531 }
6532 rxchainmask = 3;
6533 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6534 if (dut->testbed_flag_rxsp == 1) {
6535 vht_mcsmap = 0xffc0;
6536 dut->testbed_flag_rxsp = 0;
6537 } else {
6538 vht_mcsmap = 0xffea;
6539 }
6540 rxchainmask = 7;
6541 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6542 if (dut->testbed_flag_rxsp == 1) {
6543 vht_mcsmap = 0xff00;
6544 dut->testbed_flag_rxsp = 0;
6545 } else {
6546 vht_mcsmap = 0xffaa;
6547 }
6548 rxchainmask = 15;
6549 } else {
6550 if (dut->testbed_flag_rxsp == 1) {
6551 vht_mcsmap = 0xffc0;
6552 dut->testbed_flag_rxsp = 0;
6553 } else {
6554 vht_mcsmap = 0xffea;
6555 }
6556 }
6557
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006558 if (rxchainmask)
6559 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006560
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006561 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006562}
6563
6564
6565void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
6566{
6567 if (strcasecmp(val, "enable") == 0) {
6568 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
6569 != 0) {
6570 sigma_dut_print(dut, DUT_MSG_ERROR,
6571 "Disable BB_VHTSIGB_CRC_CALC failed");
6572 }
6573
6574 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
6575 != 0) {
6576 sigma_dut_print(dut, DUT_MSG_ERROR,
6577 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6578 }
6579 } else {
6580 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
6581 != 0) {
6582 sigma_dut_print(dut, DUT_MSG_ERROR,
6583 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6584 }
6585
6586 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
6587 != 0) {
6588 sigma_dut_print(dut, DUT_MSG_ERROR,
6589 "Enable BB_VHTSIGB_CRC_CALC failed");
6590 }
6591 }
6592}
6593
6594
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006595static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
6596 const char *val)
6597{
6598 char buf[60];
6599
Shivani Baranwal2a572842021-09-16 12:27:15 +05306600#ifdef NL80211_SUPPORT
6601 enum nl80211_chan_width qca_channel_width;
6602
6603 if (strcmp(val, "20") == 0) {
6604 qca_channel_width = NL80211_CHAN_WIDTH_20;
6605 dut->chwidth = 0;
6606 } else if (strcmp(val, "40") == 0) {
6607 qca_channel_width = NL80211_CHAN_WIDTH_40;
6608 dut->chwidth = 1;
6609 } else if (strcmp(val, "80") == 0) {
6610 qca_channel_width = NL80211_CHAN_WIDTH_80;
6611 dut->chwidth = 2;
6612 } else if (strcmp(val, "160") == 0) {
6613 qca_channel_width = NL80211_CHAN_WIDTH_160;
6614 dut->chwidth = 3;
6615 } else if (strcasecmp(val, "Auto") == 0) {
6616 return 0;
6617 } else {
6618 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6619 val);
6620 return -1;
6621 }
6622 if (sta_config_params(dut, intf, STA_SET_CHAN_WIDTH,
6623 qca_channel_width) == 0)
6624 return 0;
6625#endif /* NL80211_SUPPORT */
6626
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006627 if (strcmp(val, "20") == 0) {
6628 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
6629 dut->chwidth = 0;
6630 } else if (strcmp(val, "40") == 0) {
6631 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
6632 dut->chwidth = 1;
6633 } else if (strcmp(val, "80") == 0) {
6634 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
6635 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05306636 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006637 buf[0] = '\0';
6638 } else {
6639 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6640 val);
6641 return -1;
6642 }
6643
6644 if (buf[0] != '\0' && system(buf) != 0) {
6645 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
6646 return -1;
6647 }
6648
6649 return 0;
6650}
6651
6652
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006653static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
6654 const char *intf, int addbareject)
6655{
6656#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306657 return wcn_wifi_test_config_set_u8(
6658 dut, intf,
6659 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
6660 !addbareject);
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006661#else /* NL80211_SUPPORT */
6662 sigma_dut_print(dut, DUT_MSG_ERROR,
6663 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
6664 return -1;
6665#endif /* NL80211_SUPPORT */
6666}
6667
6668
6669static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
6670 int addbareject)
6671{
6672 int ret;
6673
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006674 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006675 case DRIVER_WCN:
6676 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
6677 if (ret) {
6678 sigma_dut_print(dut, DUT_MSG_ERROR,
6679 "nlvendor_sta_set_addba_reject failed, ret:%d",
6680 ret);
6681 return ret;
6682 }
6683 break;
6684 default:
6685 sigma_dut_print(dut, DUT_MSG_ERROR,
6686 "errorCode,Unsupported ADDBA_REJECT with the current driver");
6687 ret = -1;
6688 break;
6689 }
6690
6691 return ret;
6692}
6693
6694
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006695static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
6696 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006697{
6698#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306699 return wcn_wifi_test_config_set_u8(
6700 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
6701 enable);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006702#else /* NL80211_SUPPORT */
6703 sigma_dut_print(dut, DUT_MSG_ERROR,
6704 "Disable addba not possible without NL80211_SUPPORT defined");
6705 return -1;
6706#endif /* NL80211_SUPPORT */
6707}
6708
6709
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306710#ifdef NL80211_SUPPORT
6711static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6712{
6713 struct nl_msg *msg;
6714 int ret = 0;
6715 int ifindex;
6716
6717 ifindex = if_nametoindex(intf);
6718 if (ifindex == 0) {
6719 sigma_dut_print(dut, DUT_MSG_ERROR,
6720 "%s: Index for interface %s failed",
6721 __func__, intf);
6722 return -1;
6723 }
6724
6725 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6726 NL80211_CMD_SET_WIPHY)) ||
6727 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
6728 sigma_dut_print(dut, DUT_MSG_ERROR,
6729 "%s: err in adding RTS threshold",
6730 __func__);
6731 nlmsg_free(msg);
6732 return -1;
6733 }
6734
6735 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6736 if (ret) {
6737 sigma_dut_print(dut, DUT_MSG_ERROR,
6738 "%s: err in send_and_recv_msgs, ret=%d",
6739 __func__, ret);
6740 }
6741 return ret;
6742}
6743#endif /* NL80211_SUPPORT */
6744
6745
6746static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6747{
6748 char buf[100];
6749
6750#ifdef NL80211_SUPPORT
6751 if (nl80211_sta_set_rts(dut, intf, val) == 0)
6752 return 0;
6753 sigma_dut_print(dut, DUT_MSG_DEBUG,
6754 "Fall back to using iwconfig for setting RTS threshold");
6755#endif /* NL80211_SUPPORT */
6756
6757 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
6758 if (system(buf) != 0) {
6759 sigma_dut_print(dut, DUT_MSG_ERROR,
6760 "Failed to set RTS threshold %d", val);
6761 return -1;
6762 }
6763 return 0;
6764}
6765
6766
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006767static enum sigma_cmd_result
6768cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
6769 struct sigma_conn *conn, struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006770{
6771 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006772 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006773 char buf[128];
6774 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006775
6776 val = get_param(cmd, "40_INTOLERANT");
6777 if (val) {
6778 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6779 /* TODO: iwpriv ht40intol through wpa_supplicant */
6780 send_resp(dut, conn, SIGMA_ERROR,
6781 "ErrorCode,40_INTOLERANT not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006782 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006783 }
6784 }
6785
6786 val = get_param(cmd, "ADDBA_REJECT");
6787 if (val) {
6788 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6789 /* reject any ADDBA with status "decline" */
6790 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006791 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006792 } else {
6793 /* accept ADDBA */
6794 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006795 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006796 }
6797 }
6798
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006799 if (addbareject >= 0 &&
6800 sta_set_addba_reject(dut, intf, addbareject) < 0) {
6801 send_resp(dut, conn, SIGMA_ERROR,
6802 "ErrorCode,set addba_reject failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006803 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006804 }
6805
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006806 val = get_param(cmd, "AMPDU");
6807 if (val) {
6808 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6809 /* enable AMPDU Aggregation */
6810 if (ampdu == 0) {
6811 send_resp(dut, conn, SIGMA_ERROR,
6812 "ErrorCode,Mismatch in "
6813 "addba_reject/ampdu - "
6814 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006815 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006816 }
6817 ampdu = 1;
6818 } else {
6819 /* disable AMPDU Aggregation */
6820 if (ampdu == 1) {
6821 send_resp(dut, conn, SIGMA_ERROR,
6822 "ErrorCode,Mismatch in "
6823 "addba_reject/ampdu - "
6824 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006825 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006826 }
6827 ampdu = 0;
6828 }
6829 }
6830
6831 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006832 int ret;
6833
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006834 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
6835 ampdu ? "Enabling" : "Disabling");
6836 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07006837 if (wpa_command(intf, buf) < 0 &&
6838 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006839 send_resp(dut, conn, SIGMA_ERROR,
6840 "ErrorCode,set aggr failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006841 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006842 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006843
6844 if (ampdu == 0) {
6845 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006846 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006847 if (ret) {
6848 sigma_dut_print(dut, DUT_MSG_ERROR,
6849 "Failed to disable addba, ret:%d",
6850 ret);
6851 }
6852 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006853 }
6854
6855 val = get_param(cmd, "AMSDU");
6856 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006857 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006858 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006859 case DRIVER_WCN:
6860 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006861 break;
6862 default:
6863 if (strcmp(val, "1") == 0 ||
6864 strcasecmp(val, "Enable") == 0) {
6865 /* Enable AMSDU Aggregation */
6866 send_resp(dut, conn, SIGMA_ERROR,
6867 "ErrorCode,AMSDU aggregation not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006868 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006869 }
6870 break;
6871 }
6872 }
6873
6874 val = get_param(cmd, "STBC_RX");
6875 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006876 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006877 case DRIVER_ATHEROS:
6878 ath_sta_set_stbc(dut, intf, val);
6879 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05306880 case DRIVER_WCN:
6881 wcn_sta_set_stbc(dut, intf, val);
6882 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006883 default:
6884 send_resp(dut, conn, SIGMA_ERROR,
6885 "ErrorCode,STBC_RX not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006886 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006887 }
6888 }
6889
6890 val = get_param(cmd, "WIDTH");
6891 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006892 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006893 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006894 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006895 send_resp(dut, conn, SIGMA_ERROR,
6896 "ErrorCode,Failed to set WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006897 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006898 }
6899 break;
6900 case DRIVER_ATHEROS:
6901 if (ath_set_width(dut, conn, intf, val) < 0)
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006902 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006903 break;
6904 default:
6905 sigma_dut_print(dut, DUT_MSG_ERROR,
6906 "Setting WIDTH not supported");
6907 break;
6908 }
6909 }
6910
6911 val = get_param(cmd, "SMPS");
6912 if (val) {
6913 /* TODO: Dynamic/0, Static/1, No Limit/2 */
6914 send_resp(dut, conn, SIGMA_ERROR,
6915 "ErrorCode,SMPS not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006916 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006917 }
6918
6919 val = get_param(cmd, "TXSP_STREAM");
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:
6923 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6924 send_resp(dut, conn, SIGMA_ERROR,
6925 "ErrorCode,Failed to set TXSP_STREAM");
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 ath_sta_set_txsp_stream(dut, intf, val);
6931 break;
6932 default:
6933 sigma_dut_print(dut, DUT_MSG_ERROR,
6934 "Setting TXSP_STREAM not supported");
6935 break;
6936 }
6937 }
6938
6939 val = get_param(cmd, "RXSP_STREAM");
6940 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006941 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006942 case DRIVER_WCN:
6943 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6944 send_resp(dut, conn, SIGMA_ERROR,
6945 "ErrorCode,Failed to set RXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006946 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006947 }
6948 break;
6949 case DRIVER_ATHEROS:
6950 ath_sta_set_rxsp_stream(dut, intf, val);
6951 break;
6952 default:
6953 sigma_dut_print(dut, DUT_MSG_ERROR,
6954 "Setting RXSP_STREAM not supported");
6955 break;
6956 }
6957 }
6958
6959 val = get_param(cmd, "DYN_BW_SGNL");
6960 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006961 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006962 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08006963 if (strcasecmp(val, "enable") == 0) {
6964 snprintf(buf, sizeof(buf),
6965 "iwpriv %s cwmenable 1", intf);
6966 if (system(buf) != 0) {
6967 sigma_dut_print(dut, DUT_MSG_ERROR,
6968 "iwpriv cwmenable 1 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006969 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006970 }
6971 } else if (strcasecmp(val, "disable") == 0) {
6972 snprintf(buf, sizeof(buf),
6973 "iwpriv %s cwmenable 0", intf);
6974 if (system(buf) != 0) {
6975 sigma_dut_print(dut, DUT_MSG_ERROR,
6976 "iwpriv cwmenable 0 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006977 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006978 }
6979 } else {
6980 sigma_dut_print(dut, DUT_MSG_ERROR,
6981 "Unsupported DYN_BW_SGL");
6982 }
6983
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006984 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
6985 if (system(buf) != 0) {
6986 sigma_dut_print(dut, DUT_MSG_ERROR,
6987 "Failed to set cts_cbw in DYN_BW_SGNL");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006988 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006989 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006990 break;
6991 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07006992 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006993 ath_config_dyn_bw_sig(dut, intf, val);
6994 break;
6995 default:
6996 sigma_dut_print(dut, DUT_MSG_ERROR,
6997 "Failed to set DYN_BW_SGNL");
6998 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006999 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007000 }
7001
7002 val = get_param(cmd, "RTS_FORCE");
7003 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07007004 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007005 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307006 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007007 sigma_dut_print(dut, DUT_MSG_ERROR,
7008 "Failed to set RTS_FORCE 64");
7009 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03007010 res = snprintf(buf, sizeof(buf),
7011 "wifitool %s beeliner_fw_test 100 1",
7012 intf);
7013 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08007014 sigma_dut_print(dut, DUT_MSG_ERROR,
7015 "wifitool beeliner_fw_test 100 1 failed");
7016 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007017 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307018 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007019 sigma_dut_print(dut, DUT_MSG_ERROR,
7020 "Failed to set RTS_FORCE 2347");
7021 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007022 } else {
7023 send_resp(dut, conn, SIGMA_ERROR,
7024 "ErrorCode,RTS_FORCE value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007025 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007026 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007027 }
7028
7029 val = get_param(cmd, "CTS_WIDTH");
7030 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007031 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007032 case DRIVER_WCN:
7033 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
7034 send_resp(dut, conn, SIGMA_ERROR,
7035 "ErrorCode,Failed to set CTS_WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007036 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007037 }
7038 break;
7039 case DRIVER_ATHEROS:
7040 ath_set_cts_width(dut, intf, val);
7041 break;
7042 default:
7043 sigma_dut_print(dut, DUT_MSG_ERROR,
7044 "Setting CTS_WIDTH not supported");
7045 break;
7046 }
7047 }
7048
7049 val = get_param(cmd, "BW_SGNL");
7050 if (val) {
7051 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007052 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007053 } else if (strcasecmp(val, "Disable") == 0) {
7054 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007055 } else {
7056 send_resp(dut, conn, SIGMA_ERROR,
7057 "ErrorCode,BW_SGNL value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007058 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007059 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007060 }
7061
7062 val = get_param(cmd, "Band");
7063 if (val) {
7064 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
7065 /* STA supports all bands by default */
7066 } else {
7067 send_resp(dut, conn, SIGMA_ERROR,
7068 "ErrorCode,Unsupported Band");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007069 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007070 }
7071 }
7072
7073 val = get_param(cmd, "zero_crc");
7074 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007075 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007076 case DRIVER_ATHEROS:
7077 ath_set_zero_crc(dut, val);
7078 break;
7079 default:
7080 break;
7081 }
7082 }
7083
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007084 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007085}
7086
7087
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007088static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7089{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007090 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007091#ifdef __linux__
7092 case DRIVER_WIL6210:
7093 return wil6210_set_force_mcs(dut, force, mcs);
7094#endif /* __linux__ */
7095 default:
7096 sigma_dut_print(dut, DUT_MSG_ERROR,
7097 "Unsupported sta_set_force_mcs with the current driver");
7098 return -1;
7099 }
7100}
7101
7102
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007103static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
7104{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007105 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007106#ifdef __linux__
7107 case DRIVER_WIL6210:
7108 return wil6210_force_rsn_ie(dut, state);
7109#endif /* __linux__ */
7110 default:
7111 sigma_dut_print(dut, DUT_MSG_ERROR,
7112 "Unsupported sta_60g_force_rsn_ie with the current driver");
7113 return -1;
7114 }
7115}
7116
7117
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007118static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
7119 struct sigma_cmd *cmd)
7120{
7121 const char *val;
7122 char buf[100];
7123
7124 val = get_param(cmd, "MSDUSize");
7125 if (val) {
7126 int mtu;
7127
7128 dut->amsdu_size = atoi(val);
7129 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
7130 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
7131 sigma_dut_print(dut, DUT_MSG_ERROR,
7132 "MSDUSize %d is above max %d or below min %d",
7133 dut->amsdu_size,
7134 IEEE80211_MAX_DATA_LEN_DMG,
7135 IEEE80211_SNAP_LEN_DMG);
7136 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007137 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007138 }
7139
7140 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
7141 sigma_dut_print(dut, DUT_MSG_DEBUG,
7142 "Setting amsdu_size to %d", mtu);
7143 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007144 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007145
7146 if (system(buf) != 0) {
7147 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7148 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007149 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007150 }
7151 }
7152
7153 val = get_param(cmd, "BAckRcvBuf");
7154 if (val) {
7155 dut->back_rcv_buf = atoi(val);
7156 if (dut->back_rcv_buf == 0) {
7157 sigma_dut_print(dut, DUT_MSG_ERROR,
7158 "Failed to convert %s or value is 0",
7159 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007160 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007161 }
7162
7163 sigma_dut_print(dut, DUT_MSG_DEBUG,
7164 "Setting BAckRcvBuf to %s", val);
7165 }
7166
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007167 val = get_param(cmd, "MCS_FixedRate");
7168 if (val) {
7169 if (sta_set_force_mcs(dut, 1, atoi(val))) {
7170 sigma_dut_print(dut, DUT_MSG_ERROR,
7171 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007172 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007173 }
7174 }
7175
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007176 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007177}
7178
7179
7180static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
7181 struct sigma_cmd *cmd)
7182{
7183 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007184 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007185 const char *val;
7186 char buf[100];
7187
7188 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007189 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007190 if (wpa_command(ifname, "PING") != 0) {
7191 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007192 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007193 }
7194
7195 wpa_command(ifname, "FLUSH");
7196 net_id = add_network_common(dut, conn, ifname, cmd);
7197 if (net_id < 0) {
7198 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
7199 return net_id;
7200 }
7201
7202 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
7203 if (set_network(ifname, net_id, "mode", "2") < 0) {
7204 sigma_dut_print(dut, DUT_MSG_ERROR,
7205 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007206 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007207 }
7208
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02007209 if (set_network(ifname, net_id, "pbss", "1") < 0)
7210 return -2;
7211
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007212 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007213 "Supplicant set network with mode 2. network_id %d",
7214 net_id);
7215
7216 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
7217 sigma_dut_print(dut, DUT_MSG_INFO,
7218 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007219 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007220 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007221
7222 val = get_param(cmd, "Security");
7223 if (val && strcasecmp(val, "OPEN") == 0) {
7224 dut->ap_key_mgmt = AP_OPEN;
7225 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
7226 sigma_dut_print(dut, DUT_MSG_ERROR,
7227 "Failed to set supplicant to %s security",
7228 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007229 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007230 }
7231 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
7232 dut->ap_key_mgmt = AP_WPA2_PSK;
7233 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
7234 sigma_dut_print(dut, DUT_MSG_ERROR,
7235 "Failed to set supplicant to %s security",
7236 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007237 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007238 }
7239
7240 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
7241 sigma_dut_print(dut, DUT_MSG_ERROR,
7242 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007243 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007244 }
7245 } else if (val) {
7246 sigma_dut_print(dut, DUT_MSG_ERROR,
7247 "Requested Security %s is not supported on 60GHz",
7248 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007249 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007250 }
7251
7252 val = get_param(cmd, "Encrypt");
7253 if (val && strcasecmp(val, "AES-GCMP") == 0) {
7254 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
7255 sigma_dut_print(dut, DUT_MSG_ERROR,
7256 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007257 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007258 }
7259 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
7260 sigma_dut_print(dut, DUT_MSG_ERROR,
7261 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007262 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007263 }
7264 } else if (val) {
7265 sigma_dut_print(dut, DUT_MSG_ERROR,
7266 "Requested Encrypt %s is not supported on 60 GHz",
7267 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007268 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007269 }
7270
7271 val = get_param(cmd, "PSK");
7272 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
7273 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
7274 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007275 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007276 }
7277
7278 /* Convert 60G channel to freq */
7279 switch (dut->ap_channel) {
7280 case 1:
7281 val = "58320";
7282 break;
7283 case 2:
7284 val = "60480";
7285 break;
7286 case 3:
7287 val = "62640";
7288 break;
7289 default:
7290 sigma_dut_print(dut, DUT_MSG_ERROR,
7291 "Failed to configure channel %d. Not supported",
7292 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007293 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007294 }
7295
7296 if (set_network(ifname, net_id, "frequency", val) < 0) {
7297 sigma_dut_print(dut, DUT_MSG_ERROR,
7298 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007299 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007300 }
7301
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02007302 if (dut->eap_fragment) {
7303 sigma_dut_print(dut, DUT_MSG_DEBUG,
7304 "Set EAP fragment size to 128 bytes.");
7305 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
7306 return ERROR_SEND_STATUS;
7307 }
7308
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007309 sigma_dut_print(dut, DUT_MSG_DEBUG,
7310 "Supplicant set network with frequency");
7311
7312 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
7313 if (wpa_command(ifname, buf) < 0) {
7314 sigma_dut_print(dut, DUT_MSG_INFO,
7315 "Failed to select network id %d on %s",
7316 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007317 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007318 }
7319
7320 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
7321
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007322 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007323}
7324
7325
Lior David67543f52017-01-03 19:04:22 +02007326static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
7327{
7328 char buf[128], fname[128];
7329 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03007330 int res;
Lior David67543f52017-01-03 19:04:22 +02007331
7332 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
7333 sigma_dut_print(dut, DUT_MSG_ERROR,
7334 "failed to get wil6210 debugfs dir");
7335 return -1;
7336 }
7337
Jouni Malinen3aa72862019-05-29 23:14:51 +03007338 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
7339 if (res < 0 || res >= sizeof(fname))
7340 return -1;
Lior David67543f52017-01-03 19:04:22 +02007341 f = fopen(fname, "w");
7342 if (!f) {
7343 sigma_dut_print(dut, DUT_MSG_ERROR,
7344 "failed to open: %s", fname);
7345 return -1;
7346 }
7347
7348 fprintf(f, "%d\n", abft_len);
7349 fclose(f);
7350
7351 return 0;
7352}
7353
7354
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02007355int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
7356 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02007357{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007358 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02007359 case DRIVER_WIL6210:
7360 return wil6210_set_abft_len(dut, abft_len);
7361 default:
7362 sigma_dut_print(dut, DUT_MSG_ERROR,
7363 "set abft_len not supported");
7364 return -1;
7365 }
7366}
7367
7368
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007369static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
7370 struct sigma_cmd *cmd)
7371{
7372 const char *val;
Lior David67543f52017-01-03 19:04:22 +02007373 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007374
7375 if (dut->dev_role != DEVROLE_PCP) {
7376 send_resp(dut, conn, SIGMA_INVALID,
7377 "ErrorCode,Invalid DevRole");
7378 return 0;
7379 }
7380
7381 val = get_param(cmd, "SSID");
7382 if (val) {
7383 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
7384 send_resp(dut, conn, SIGMA_INVALID,
7385 "ErrorCode,Invalid SSID");
7386 return -1;
7387 }
7388
Peng Xub8fc5cc2017-05-10 17:27:28 -07007389 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007390 }
7391
7392 val = get_param(cmd, "CHANNEL");
7393 if (val) {
7394 const char *pos;
7395
7396 dut->ap_channel = atoi(val);
7397 pos = strchr(val, ';');
7398 if (pos) {
7399 pos++;
7400 dut->ap_channel_1 = atoi(pos);
7401 }
7402 }
7403
7404 switch (dut->ap_channel) {
7405 case 1:
7406 case 2:
7407 case 3:
7408 break;
7409 default:
7410 sigma_dut_print(dut, DUT_MSG_ERROR,
7411 "Channel %d is not supported", dut->ap_channel);
7412 send_resp(dut, conn, SIGMA_ERROR,
7413 "Requested channel is not supported");
7414 return -1;
7415 }
7416
7417 val = get_param(cmd, "BCNINT");
7418 if (val)
7419 dut->ap_bcnint = atoi(val);
7420
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007421 val = get_param(cmd, "AllocType");
7422 if (val) {
7423 send_resp(dut, conn, SIGMA_ERROR,
7424 "ErrorCode,AllocType is not supported yet");
7425 return -1;
7426 }
7427
7428 val = get_param(cmd, "PercentBI");
7429 if (val) {
7430 send_resp(dut, conn, SIGMA_ERROR,
7431 "ErrorCode,PercentBI is not supported yet");
7432 return -1;
7433 }
7434
7435 val = get_param(cmd, "CBAPOnly");
7436 if (val) {
7437 send_resp(dut, conn, SIGMA_ERROR,
7438 "ErrorCode,CBAPOnly is not supported yet");
7439 return -1;
7440 }
7441
7442 val = get_param(cmd, "AMPDU");
7443 if (val) {
7444 if (strcasecmp(val, "Enable") == 0)
7445 dut->ap_ampdu = 1;
7446 else if (strcasecmp(val, "Disable") == 0)
7447 dut->ap_ampdu = 2;
7448 else {
7449 send_resp(dut, conn, SIGMA_ERROR,
7450 "ErrorCode,AMPDU value is not Enable nor Disabled");
7451 return -1;
7452 }
7453 }
7454
7455 val = get_param(cmd, "AMSDU");
7456 if (val) {
7457 if (strcasecmp(val, "Enable") == 0)
7458 dut->ap_amsdu = 1;
7459 else if (strcasecmp(val, "Disable") == 0)
7460 dut->ap_amsdu = 2;
7461 }
7462
7463 val = get_param(cmd, "NumMSDU");
7464 if (val) {
7465 send_resp(dut, conn, SIGMA_ERROR,
7466 "ErrorCode, NumMSDU is not supported yet");
7467 return -1;
7468 }
7469
7470 val = get_param(cmd, "ABFTLRang");
7471 if (val) {
7472 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02007473 "ABFTLRang parameter %s", val);
7474 if (strcmp(val, "Gt1") == 0)
7475 abft_len = 2; /* 2 slots in this case */
7476 }
7477
7478 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
7479 send_resp(dut, conn, SIGMA_ERROR,
7480 "ErrorCode, Can't set ABFT length");
7481 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007482 }
7483
7484 if (sta_pcp_start(dut, conn, cmd) < 0) {
7485 send_resp(dut, conn, SIGMA_ERROR,
7486 "ErrorCode, Can't start PCP role");
7487 return -1;
7488 }
7489
7490 return sta_set_60g_common(dut, conn, cmd);
7491}
7492
7493
7494static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
7495 struct sigma_cmd *cmd)
7496{
7497 const char *val = get_param(cmd, "DiscoveryMode");
7498
7499 if (dut->dev_role != DEVROLE_STA) {
7500 send_resp(dut, conn, SIGMA_INVALID,
7501 "ErrorCode,Invalid DevRole");
7502 return 0;
7503 }
7504
7505 if (val) {
7506 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
7507 /* Ignore Discovery mode till Driver expose API. */
7508#if 0
7509 if (strcasecmp(val, "1") == 0) {
7510 send_resp(dut, conn, SIGMA_INVALID,
7511 "ErrorCode,DiscoveryMode 1 not supported");
7512 return 0;
7513 }
7514
7515 if (strcasecmp(val, "0") == 0) {
7516 /* OK */
7517 } else {
7518 send_resp(dut, conn, SIGMA_INVALID,
7519 "ErrorCode,DiscoveryMode not supported");
7520 return 0;
7521 }
7522#endif
7523 }
7524
7525 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007526 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007527 return sta_set_60g_common(dut, conn, cmd);
7528}
7529
7530
Jouni Malinenf7222712019-06-13 01:50:21 +03007531static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
7532 struct sigma_conn *conn,
7533 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007534{
7535 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02007536 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05307537
Jouni Malinened77e672018-01-10 16:45:13 +02007538 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08007539 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02007540 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05307541 wpa_command(intf, "DISCONNECT");
7542 return 1;
7543 }
7544
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007545 disconnect_station(dut);
7546 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
7547 * due to cached results. */
7548 wpa_command(intf, "SET ignore_old_scan_res 1");
7549 wpa_command(intf, "BSS_FLUSH");
7550 return 1;
7551}
7552
7553
Jouni Malinenf7222712019-06-13 01:50:21 +03007554static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
7555 struct sigma_conn *conn,
7556 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007557{
7558 const char *intf = get_param(cmd, "Interface");
7559 const char *bssid = get_param(cmd, "bssid");
7560 const char *val = get_param(cmd, "CHANNEL");
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007561 const char *freq_val = get_param(cmd, "ChnlFreq");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007562 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307563 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05307564 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007565 int res;
7566 int chan = 0;
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007567 int freq = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007568 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05307569 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007570 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007571
7572 if (bssid == NULL) {
7573 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
7574 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007575 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007576 }
7577
7578 if (val)
7579 chan = atoi(val);
7580
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007581 if (freq_val)
7582 freq = atoi(freq_val);
7583
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007584 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
7585 /* The current network may be from sta_associate or
7586 * sta_hs2_associate
7587 */
7588 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
7589 0 ||
7590 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007591 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007592 }
7593
7594 ctrl = open_wpa_mon(intf);
7595 if (ctrl == NULL) {
7596 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7597 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007598 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007599 }
7600
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007601 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05307602 sizeof(result)) < 0 ||
7603 strncmp(result, "COMPLETED", 9) != 0) {
7604 sigma_dut_print(dut, DUT_MSG_DEBUG,
7605 "sta_reassoc: Not connected");
7606 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007607 } else if (dut->sta_ft_ds) {
7608 sigma_dut_print(dut, DUT_MSG_DEBUG,
7609 "sta_reassoc: Use FT-over-DS");
7610 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05307611 }
7612
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307613 if (dut->rsne_override) {
7614#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007615 if (get_driver_type(dut) == DRIVER_WCN &&
7616 dut->config_rsnie == 0) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05307617 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307618 dut->config_rsnie = 1;
7619 }
7620#endif /* NL80211_SUPPORT */
7621 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
7622 dut->rsne_override);
7623 if (wpa_command(intf, buf) < 0) {
7624 send_resp(dut, conn, SIGMA_ERROR,
7625 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
7626 return 0;
7627 }
7628 }
7629
Shivani Baranwal7aa48602021-09-29 10:53:38 +05307630 if (ft_ds && get_driver_type(dut) != DRIVER_WCN) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007631 if (chan || freq) {
7632 if (!freq)
7633 freq = channel_to_freq(dut, chan);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007634 if (!freq) {
7635 sigma_dut_print(dut, DUT_MSG_ERROR,
7636 "Invalid channel number provided: %d",
7637 chan);
7638 send_resp(dut, conn, SIGMA_INVALID,
7639 "ErrorCode,Invalid channel number");
7640 goto close_mon_conn;
7641 }
7642 res = snprintf(buf, sizeof(buf),
7643 "SCAN TYPE=ONLY freq=%d", freq);
7644 } else {
7645 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7646 }
7647 if (res < 0 || res >= (int) sizeof(buf)) {
7648 send_resp(dut, conn, SIGMA_ERROR,
7649 "ErrorCode,snprintf failed");
7650 goto close_mon_conn;
7651 }
7652 if (wpa_command(intf, buf) < 0) {
7653 sigma_dut_print(dut, DUT_MSG_INFO,
7654 "Failed to start scan");
7655 send_resp(dut, conn, SIGMA_ERROR,
7656 "ErrorCode,scan failed");
7657 goto close_mon_conn;
7658 }
7659
7660 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7661 buf, sizeof(buf));
7662 if (res < 0) {
7663 sigma_dut_print(dut, DUT_MSG_INFO,
7664 "Scan did not complete");
7665 send_resp(dut, conn, SIGMA_ERROR,
7666 "ErrorCode,scan did not complete");
7667 goto close_mon_conn;
7668 }
7669
7670 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
7671 if (res > 0 && res < (int) sizeof(buf))
7672 res = wpa_command(intf, buf);
7673
7674 if (res < 0 || res >= (int) sizeof(buf)) {
7675 send_resp(dut, conn, SIGMA_ERROR,
7676 "errorCode,FT_DS command failed");
7677 status = STATUS_SENT_ERROR;
7678 goto close_mon_conn;
7679 }
7680 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007681 if (chan || freq) {
7682 if (!freq)
7683 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05307684 if (!freq) {
7685 sigma_dut_print(dut, DUT_MSG_ERROR,
7686 "Invalid channel number provided: %d",
7687 chan);
7688 send_resp(dut, conn, SIGMA_INVALID,
7689 "ErrorCode,Invalid channel number");
7690 goto close_mon_conn;
7691 }
7692 res = snprintf(buf, sizeof(buf),
7693 "SCAN TYPE=ONLY freq=%d", freq);
7694 } else {
7695 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7696 }
7697 if (res < 0 || res >= (int) sizeof(buf)) {
7698 send_resp(dut, conn, SIGMA_ERROR,
7699 "ErrorCode,snprintf failed");
7700 goto close_mon_conn;
7701 }
7702 if (wpa_command(intf, buf) < 0) {
7703 sigma_dut_print(dut, DUT_MSG_INFO,
7704 "Failed to start scan");
7705 send_resp(dut, conn, SIGMA_ERROR,
7706 "ErrorCode,scan failed");
7707 goto close_mon_conn;
7708 }
7709
7710 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7711 buf, sizeof(buf));
7712 if (res < 0) {
7713 sigma_dut_print(dut, DUT_MSG_INFO,
7714 "Scan did not complete");
7715 send_resp(dut, conn, SIGMA_ERROR,
7716 "ErrorCode,scan did not complete");
7717 goto close_mon_conn;
7718 }
7719
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007720 if (set_network(intf, dut->infra_network_id, "bssid", "any")
7721 < 0) {
7722 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7723 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007724 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05307725 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007726 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307727 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007728 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307729 if (res < 0 || res >= (int) sizeof(buf) ||
7730 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007731 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307732 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05307733 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007734 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007735 sigma_dut_print(dut, DUT_MSG_INFO,
7736 "sta_reassoc: Run %s successful", buf);
7737 } else if (wpa_command(intf, "REASSOCIATE")) {
7738 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
7739 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05307740 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007741 }
7742
7743 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
7744 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05307745 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007746 send_resp(dut, conn, SIGMA_ERROR,
7747 "errorCode,Connection did not complete");
7748 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05307749 goto close_mon_conn;
7750 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007751 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007752
Ashwini Patil467efef2017-05-25 12:18:27 +05307753close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007754 wpa_ctrl_detach(ctrl);
7755 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05307756 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007757}
7758
7759
7760static void hs2_clear_credentials(const char *intf)
7761{
7762 wpa_command(intf, "REMOVE_CRED all");
7763}
7764
7765
Lior Davidcc88b562017-01-03 18:52:09 +02007766#ifdef __linux__
7767static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
7768 unsigned int *aid)
7769{
Lior David0fe101e2017-03-09 16:09:50 +02007770 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02007771
Lior David0fe101e2017-03-09 16:09:50 +02007772 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02007773}
7774#endif /* __linux__ */
7775
7776
7777static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
7778 unsigned int *aid)
7779{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007780 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02007781#ifdef __linux__
7782 case DRIVER_WIL6210:
7783 return wil6210_get_aid(dut, bssid, aid);
7784#endif /* __linux__ */
7785 default:
7786 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
7787 return -1;
7788 }
7789}
7790
7791
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007792static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7793 struct sigma_cmd *cmd)
7794{
7795 char buf[MAX_CMD_LEN];
7796 char bss_list[MAX_CMD_LEN];
7797 const char *parameter = get_param(cmd, "Parameter");
7798
7799 if (parameter == NULL)
7800 return -1;
7801
Lior Davidcc88b562017-01-03 18:52:09 +02007802 if (strcasecmp(parameter, "AID") == 0) {
7803 unsigned int aid = 0;
7804 char bssid[20];
7805
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007806 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02007807 bssid, sizeof(bssid)) < 0) {
7808 sigma_dut_print(dut, DUT_MSG_ERROR,
7809 "could not get bssid");
7810 return -2;
7811 }
7812
7813 if (sta_get_aid_60g(dut, bssid, &aid))
7814 return -2;
7815
7816 snprintf(buf, sizeof(buf), "aid,%d", aid);
7817 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
7818 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7819 return 0;
7820 }
7821
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007822 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
7823 char *bss_line;
7824 char *bss_id = NULL;
7825 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307826 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007827
7828 if (ifname == NULL) {
7829 sigma_dut_print(dut, DUT_MSG_INFO,
7830 "For get DiscoveredDevList need Interface name.");
7831 return -1;
7832 }
7833
7834 /*
7835 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
7836 * of BSSIDs in "bssid=<BSSID>\n"
7837 */
7838 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
7839 bss_list,
7840 sizeof(bss_list)) < 0) {
7841 sigma_dut_print(dut, DUT_MSG_ERROR,
7842 "Failed to get bss list");
7843 return -1;
7844 }
7845
7846 sigma_dut_print(dut, DUT_MSG_DEBUG,
7847 "bss list for ifname:%s is:%s",
7848 ifname, bss_list);
7849
7850 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307851 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007852 while (bss_line) {
7853 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
7854 bss_id) {
7855 int len;
7856
7857 len = snprintf(buf + strlen(buf),
7858 sizeof(buf) - strlen(buf),
7859 ",%s", bss_id);
7860 free(bss_id);
7861 bss_id = NULL;
7862 if (len < 0) {
7863 sigma_dut_print(dut,
7864 DUT_MSG_ERROR,
7865 "Failed to read BSSID");
7866 send_resp(dut, conn, SIGMA_ERROR,
7867 "ErrorCode,Failed to read BSS ID");
7868 return 0;
7869 }
7870
7871 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
7872 sigma_dut_print(dut,
7873 DUT_MSG_ERROR,
7874 "Response buf too small for list");
7875 send_resp(dut, conn,
7876 SIGMA_ERROR,
7877 "ErrorCode,Response buf too small for list");
7878 return 0;
7879 }
7880 }
7881
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307882 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007883 }
7884
7885 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
7886 buf);
7887 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7888 return 0;
7889 }
7890
7891 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7892 return 0;
7893}
7894
7895
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007896static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
7897 struct sigma_cmd *cmd)
7898{
7899 char buf[MAX_CMD_LEN];
7900 const char *parameter = get_param(cmd, "Parameter");
7901
7902 if (!parameter)
7903 return -1;
7904
7905 if (strcasecmp(parameter, "RSSI") == 0) {
7906 char rssi[10];
7907
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007908 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007909 rssi, sizeof(rssi)) < 0) {
7910 sigma_dut_print(dut, DUT_MSG_ERROR,
7911 "Could not get RSSI");
7912 return -2;
7913 }
7914
7915 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
7916 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
7917 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7918 return 0;
7919 }
7920
7921 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7922 return 0;
7923}
7924
7925
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05307926#ifdef NL80211_SUPPORT
7927
7928struct station_info {
7929 uint64_t filled;
7930 uint32_t beacon_mic_error_count;
7931 uint32_t beacon_replay_count;
7932};
7933
7934
7935static int qca_get_sta_info_handler(struct nl_msg *msg, void *arg)
7936{
7937 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7938 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7939 struct station_info *data = arg;
7940 struct nlattr *info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
7941 static struct nla_policy info_policy[
7942 QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = {
7943 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT] = {
7944 .type = NLA_U32
7945 },
7946 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT] = {
7947 .type = NLA_U32
7948 },
7949 };
7950
7951 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7952 genlmsg_attrlen(gnlh, 0), NULL);
7953
7954 if (!tb[NL80211_ATTR_VENDOR_DATA])
7955 return NL_SKIP;
7956
7957 if (nla_parse_nested(info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
7958 tb[NL80211_ATTR_VENDOR_DATA], info_policy)) {
7959 return NL_SKIP;
7960 }
7961
7962 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]) {
7963 data->filled |=
7964 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT);
7965 data->beacon_mic_error_count =
7966 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]);
7967 }
7968
7969 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]) {
7970 data->filled |=
7971 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT);
7972 data->beacon_replay_count =
7973 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]);
7974 }
7975
7976 return NL_SKIP;
7977}
7978
7979
7980static int qca_nl80211_get_sta_info(struct sigma_dut *dut, const char *intf,
7981 struct station_info *sta_data)
7982{
7983 struct nl_msg *msg;
7984 int ifindex, ret;
7985
7986 ifindex = if_nametoindex(intf);
7987 if (ifindex == 0) {
7988 sigma_dut_print(dut, DUT_MSG_ERROR,
7989 "%s: Index for interface %s not found",
7990 __func__, intf);
7991 return -1;
7992 }
7993
7994 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7995 NL80211_CMD_VENDOR)) ||
7996 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7997 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7998 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7999 QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
8000 sigma_dut_print(dut, DUT_MSG_ERROR,
8001 "%s: err in adding vendor_cmd", __func__);
8002 nlmsg_free(msg);
8003 return -1;
8004 }
8005
8006 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg,
8007 qca_get_sta_info_handler, sta_data);
8008 if (ret) {
8009 sigma_dut_print(dut, DUT_MSG_ERROR,
8010 "%s: err in send_and_recv_msgs, ret=%d",
8011 __func__, ret);
8012 }
8013 return ret;
8014}
8015#endif /* NL80211_SUPPORT */
8016
8017
8018static int get_bip_mic_error_count(struct sigma_dut *dut,
8019 const char *ifname,
8020 unsigned int *count)
8021{
8022#ifdef NL80211_SUPPORT
8023 struct station_info sta_data;
8024#endif /* NL80211_SUPPORT */
8025
8026 if (get_driver_type(dut) != DRIVER_WCN) {
8027 sigma_dut_print(dut, DUT_MSG_ERROR,
8028 "BIP MIC error count not supported");
8029 return -1;
8030 }
8031
8032#ifdef NL80211_SUPPORT
8033 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8034 !(sta_data.filled &
8035 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT))) {
8036 sigma_dut_print(dut, DUT_MSG_ERROR,
8037 "BIP MIC error count fetching failed");
8038 return -1;
8039 }
8040
8041 *count = sta_data.beacon_mic_error_count;
8042 return 0;
8043#else /* NL80211_SUPPORT */
8044 sigma_dut_print(dut, DUT_MSG_ERROR,
8045 "BIP MIC error count cannot be fetched without NL80211_SUPPORT defined");
8046 return -1;
8047#endif /* NL80211_SUPPORT */
8048}
8049
8050
8051static int get_cmac_replay_count(struct sigma_dut *dut, const char *ifname,
8052 unsigned int *count)
8053{
8054#ifdef NL80211_SUPPORT
8055 struct station_info sta_data;
8056#endif /* NL80211_SUPPORT */
8057
8058 if (get_driver_type(dut) != DRIVER_WCN) {
8059 sigma_dut_print(dut, DUT_MSG_ERROR,
8060 "CMAC reply count not supported");
8061 return -1;
8062 }
8063
8064#ifdef NL80211_SUPPORT
8065 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8066 !(sta_data.filled &
8067 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT))) {
8068 sigma_dut_print(dut, DUT_MSG_ERROR,
8069 "CMAC replay count fetching failed");
8070 return -1;
8071 }
8072
8073 *count = sta_data.beacon_replay_count;
8074 return 0;
8075#else /* NL80211_SUPPORT */
8076 sigma_dut_print(dut, DUT_MSG_ERROR,
8077 "CMAC replay count cannot be fetched without NL80211_SUPPORT defined");
8078 return -1;
8079#endif /* NL80211_SUPPORT */
8080}
8081
8082
8083static enum sigma_cmd_result sta_get_parameter_wpa3(struct sigma_dut *dut,
8084 struct sigma_conn *conn,
8085 struct sigma_cmd *cmd)
8086{
8087 char buf[MAX_CMD_LEN];
8088 const char *ifname = get_param(cmd, "interface");
8089 const char *parameter = get_param(cmd, "Parameter");
8090 unsigned int val;
8091
8092 if (!ifname || !parameter)
8093 return INVALID_SEND_STATUS;
8094
8095 if (strcasecmp(parameter, "BIPMICErrors") == 0) {
8096 if (get_bip_mic_error_count(dut, ifname, &val)) {
8097 send_resp(dut, conn, SIGMA_ERROR,
8098 "ErrorCode,Failed to get BIPMICErrors");
8099 return STATUS_SENT_ERROR;
8100 }
8101 snprintf(buf, sizeof(buf), "BIPMICErrors,%d", val);
8102 sigma_dut_print(dut, DUT_MSG_INFO, "BIPMICErrors %s", buf);
8103 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8104 return STATUS_SENT;
8105 }
8106
8107 if (strcasecmp(parameter, "CMACReplays") == 0) {
8108 if (get_cmac_replay_count(dut, ifname, &val)) {
8109 send_resp(dut, conn, SIGMA_ERROR,
8110 "ErrorCode,Failed to get CMACReplays");
8111 return STATUS_SENT_ERROR;
8112 }
8113 snprintf(buf, sizeof(buf), "CMACReplays,%d", val);
8114 sigma_dut_print(dut, DUT_MSG_INFO, "CMACReplays %s", buf);
8115 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8116 return STATUS_SENT;
8117 }
8118
8119 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8120 return STATUS_SENT_ERROR;
8121}
8122
8123
Jouni Malinenca0abd32020-02-09 20:18:10 +02008124static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
8125 struct sigma_conn *conn,
8126 struct sigma_cmd *cmd)
8127{
8128 const char *intf = get_param(cmd, "Interface");
8129 char buf[4096], bssid[20], resp[200], *pos, *tmp;
8130
8131 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
8132 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8133 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
8134 send_resp(dut, conn, SIGMA_ERROR,
8135 "ErrorCode,PMKSA_GET not supported");
8136 return STATUS_SENT_ERROR;
8137 }
8138
8139 if (strncmp(buf, "FAIL", 4) == 0 ||
8140 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
8141 send_resp(dut, conn, SIGMA_ERROR,
8142 "ErrorCode,Could not find current network");
8143 return STATUS_SENT_ERROR;
8144 }
8145
8146 pos = buf;
8147 while (pos) {
8148 if (strncmp(pos, bssid, 17) == 0) {
8149 pos = strchr(pos, ' ');
8150 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308151 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008152 pos++;
8153 pos = strchr(pos, ' ');
8154 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308155 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008156 pos++;
8157 tmp = strchr(pos, ' ');
8158 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308159 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008160 *tmp = '\0';
8161 break;
8162 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02008163 pos = strchr(pos, '\n');
8164 if (pos)
8165 pos++;
8166 }
8167
8168 if (!pos) {
8169 send_resp(dut, conn, SIGMA_ERROR,
8170 "ErrorCode,PMK not available");
8171 return STATUS_SENT_ERROR;
8172 }
8173
8174 snprintf(resp, sizeof(resp), "PMK,%s", pos);
8175 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8176 return STATUS_SENT;
8177}
8178
8179
Jouni Malinenf7222712019-06-13 01:50:21 +03008180static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
8181 struct sigma_conn *conn,
8182 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008183{
8184 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02008185 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008186
Jouni Malinenca0abd32020-02-09 20:18:10 +02008187 if (!parameter)
8188 return INVALID_SEND_STATUS;
8189
8190 if (strcasecmp(parameter, "PMK") == 0)
8191 return sta_get_pmk(dut, conn, cmd);
8192
8193 if (!program)
8194 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008195
8196 if (strcasecmp(program, "P2PNFC") == 0)
8197 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
8198
8199 if (strcasecmp(program, "60ghz") == 0)
8200 return sta_get_parameter_60g(dut, conn, cmd);
8201
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07008202 if (strcasecmp(program, "he") == 0)
8203 return sta_get_parameter_he(dut, conn, cmd);
8204
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008205#ifdef ANDROID_NAN
8206 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07008207 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008208#endif /* ANDROID_NAN */
8209
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008210#ifdef MIRACAST
8211 if (strcasecmp(program, "WFD") == 0 ||
8212 strcasecmp(program, "DisplayR2") == 0)
8213 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
8214#endif /* MIRACAST */
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05308215 if (strcasecmp(program, "WPA3") == 0)
8216 return sta_get_parameter_wpa3(dut, conn, cmd);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008217
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008218 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8219 return 0;
8220}
8221
8222
8223static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
8224 const char *type)
8225{
8226 char buf[100];
8227
8228 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008229 run_iwpriv(dut, intf, "chwidth 2");
8230 run_iwpriv(dut, intf, "mode 11ACVHT80");
8231 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008232 }
8233
8234 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008235 run_iwpriv(dut, intf, "chwidth 0");
8236 run_iwpriv(dut, intf, "mode 11naht40");
8237 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008238 }
8239
8240 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008241 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008242
8243 /* Reset CTS width */
8244 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
8245 intf);
8246 if (system(buf) != 0) {
8247 sigma_dut_print(dut, DUT_MSG_ERROR,
8248 "wifitool %s beeliner_fw_test 54 0 failed",
8249 intf);
8250 }
8251
8252 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008253 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008254
8255 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
8256 if (system(buf) != 0) {
8257 sigma_dut_print(dut, DUT_MSG_ERROR,
8258 "iwpriv rts failed");
8259 }
8260 }
8261
8262 if (type && strcasecmp(type, "Testbed") == 0) {
8263 dut->testbed_flag_txsp = 1;
8264 dut->testbed_flag_rxsp = 1;
8265 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008266 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008267
8268 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008269 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008270
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008271 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008272
8273 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008274 run_iwpriv(dut, intf, "tx_stbc 0");
8275 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008276
8277 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008278 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008279 }
8280
8281 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008282 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07008283 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008284
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008285 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008286 }
8287}
8288
8289
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008290#ifdef NL80211_SUPPORT
8291static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
8292 enum he_mcs_config mcs)
8293{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308294 return wcn_wifi_test_config_set_u8(
8295 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS, mcs);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008296}
8297#endif /* NL80211_SUPPORT */
8298
8299
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008300static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
8301 const char *intf, int enable)
8302{
8303#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308304 return wcn_wifi_test_config_set_u8(
8305 dut, intf,
8306 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
8307 enable);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008308#else /* NL80211_SUPPORT */
8309 sigma_dut_print(dut, DUT_MSG_ERROR,
8310 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
8311 return -1;
8312#endif /* NL80211_SUPPORT */
8313}
8314
8315
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008316static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
8317 const char *intf, int enable)
8318{
8319#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308320 return wcn_wifi_test_config_set_u8(
8321 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
8322 enable);
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008323#else /* NL80211_SUPPORT */
8324 sigma_dut_print(dut, DUT_MSG_ERROR,
8325 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
8326 return -1;
8327#endif /* NL80211_SUPPORT */
8328}
8329
8330
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008331#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008332
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008333static int sta_set_he_testbed_def(struct sigma_dut *dut,
8334 const char *intf, int cfg)
8335{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308336 return wcn_wifi_test_config_set_u8(
8337 dut, intf,
8338 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
8339 cfg);
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008340}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008341
8342
8343static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
8344{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308345 return wcn_wifi_test_config_set_u8(
8346 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
8347 cfg);
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008348}
8349
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008350#endif /* NL80211_SUPPORT */
8351
8352
Qiwei Caib6806972020-01-15 13:52:11 +08008353int sta_set_addba_buf_size(struct sigma_dut *dut,
8354 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008355{
8356#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308357 return wcn_wifi_test_config_set_u16(
8358 dut, intf,
8359 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE, bufsize);
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008360#else /* NL80211_SUPPORT */
8361 sigma_dut_print(dut, DUT_MSG_ERROR,
8362 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
8363 return -1;
8364#endif /* NL80211_SUPPORT */
8365}
8366
8367
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008368static int sta_set_scan_unicast_probe(struct sigma_dut *dut,
8369 const char *intf, int val)
8370{
8371#ifdef NL80211_SUPPORT
8372 return wcn_wifi_test_config_set_u8(
8373 dut, intf,
8374 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA,
8375 val);
8376#else /* NL80211_SUPPORT */
8377 sigma_dut_print(dut, DUT_MSG_ERROR,
8378 "Unicast RA in Probe Request frame cannot be set without NL80211_SUPPORT defined");
8379 return -1;
8380#endif /* NL80211_SUPPORT */
8381}
8382
8383
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07008384static int sta_set_rx_ctrl_multi_bss(struct sigma_dut *dut, const char *intf,
8385 int enable)
8386{
8387#ifdef NL80211_SUPPORT
8388 return wcn_wifi_test_config_set_u8(
8389 dut, intf,
8390 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS,
8391 enable);
8392#else /* NL80211_SUPPORT */
8393 sigma_dut_print(dut, DUT_MSG_ERROR,
8394 "Rx ctrl frame to Multi-BSS cannot be changed without NL80211_SUPPORT defined");
8395 return -1;
8396#endif /* NL80211_SUPPORT */
8397}
8398
8399
8400static int sta_set_bcast_twt_support(struct sigma_dut *dut, const char *intf,
8401 int enable)
8402{
8403#ifdef NL80211_SUPPORT
8404 return wcn_wifi_test_config_set_u8(
8405 dut, intf,
8406 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT,
8407 enable);
8408#else /* NL80211_SUPPORT */
8409 sigma_dut_print(dut, DUT_MSG_ERROR,
8410 "BCAST TWT cannot be changed without NL80211_SUPPORT defined");
8411 return -1;
8412#endif /* NL80211_SUPPORT */
8413}
8414
8415
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008416static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
8417 int enable)
8418{
8419#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308420 return wcn_wifi_test_config_set_u8(
8421 dut, intf,
8422 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
8423 enable);
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008424#else /* NL80211_SUPPORT */
8425 sigma_dut_print(dut, DUT_MSG_ERROR,
8426 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
8427 return -1;
8428#endif /* NL80211_SUPPORT */
8429}
8430
8431
Arif Hussain9765f7d2018-07-03 08:28:26 -07008432static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
8433 int val)
8434{
8435#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308436 return wcn_wifi_test_config_set_u8(
8437 dut, intf,
8438 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
8439 val);
Arif Hussain9765f7d2018-07-03 08:28:26 -07008440#else /* NL80211_SUPPORT */
8441 sigma_dut_print(dut, DUT_MSG_ERROR,
8442 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
8443 return -1;
8444#endif /* NL80211_SUPPORT */
8445}
8446
8447
Arif Hussain68d23f52018-07-11 13:39:08 -07008448#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008449static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
8450 enum qca_wlan_he_mac_padding_dur val)
8451{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308452 return wcn_wifi_test_config_set_u8(
8453 dut, intf,
8454 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR, val);
Arif Hussain68d23f52018-07-11 13:39:08 -07008455}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008456#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008457
8458
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008459static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
8460 int val)
8461{
8462#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308463 return wcn_wifi_test_config_set_u8(
8464 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
8465 val);
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008466#else /* NL80211_SUPPORT */
8467 sigma_dut_print(dut, DUT_MSG_ERROR,
8468 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
8469 return -1;
8470#endif /* NL80211_SUPPORT */
8471}
8472
8473
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008474static int sta_set_mgmt_data_tx_disable_cfg(struct sigma_dut *dut,
8475 const char *intf, int val)
8476{
8477#ifdef NL80211_SUPPORT
8478 return wcn_wifi_test_config_set_u8(
8479 dut, intf,
8480 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX,
8481 val);
8482#else /* NL80211_SUPPORT */
8483 sigma_dut_print(dut, DUT_MSG_ERROR,
8484 "Tx disable config cannot be set without NL80211_SUPPORT defined");
8485 return -1;
8486#endif /* NL80211_SUPPORT */
8487}
8488
8489
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -07008490static int sta_set_keep_alive_data_cfg(struct sigma_dut *dut, const char *intf,
8491 int val)
8492{
8493#ifdef NL80211_SUPPORT
8494 return wcn_wifi_test_config_set_u8(
8495 dut, intf,
8496 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE,
8497 val);
8498#else /* NL80211_SUPPORT */
8499 sigma_dut_print(dut, DUT_MSG_ERROR,
8500 "Keep alive data type cannot be set without NL80211_SUPPORT defined");
8501 return -1;
8502#endif /* NL80211_SUPPORT */
8503}
8504
8505
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008506#ifdef NL80211_SUPPORT
8507static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
8508{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308509 return wcn_wifi_test_config_set_flag(
8510 dut, intf,
8511 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG);
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008512}
8513#endif /* NL80211_SUPPORT */
8514
8515
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008516static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
8517 int val)
8518{
8519#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308520 return wcn_wifi_test_config_set_u8(
8521 dut, intf,
8522 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA, val);
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008523#else /* NL80211_SUPPORT */
8524 sigma_dut_print(dut, DUT_MSG_ERROR,
8525 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
8526 return -1;
8527#endif /* NL80211_SUPPORT */
8528}
8529
8530
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008531static int sta_set_er_su_ppdu_type_tx(struct sigma_dut *dut, const char *intf,
8532 int val)
8533{
8534#ifdef NL80211_SUPPORT
8535 return wcn_wifi_test_config_set_u8(
8536 dut, intf,
8537 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE, val);
8538#else /* NL80211_SUPPORT */
8539 sigma_dut_print(dut, DUT_MSG_ERROR,
8540 "ER-SU PPDU type cannot be set without NL80211_SUPPORT defined");
8541 return -1;
8542#endif /* NL80211_SUPPORT */
8543}
8544
8545
8546static int sta_set_ru_242_tone_tx(struct sigma_dut *dut, const char *intf,
8547 int val)
8548{
8549#ifdef NL80211_SUPPORT
8550 return wcn_wifi_test_config_set_u8(
8551 dut, intf,
8552 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX, val);
8553#else /* NL80211_SUPPORT */
8554 sigma_dut_print(dut, DUT_MSG_ERROR,
8555 "RU 242 tone cannot be set without NL80211_SUPPORT defined");
8556 return -1;
8557#endif /* NL80211_SUPPORT */
8558}
8559
8560
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008561static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
8562 int val)
8563{
8564#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308565 return wcn_wifi_test_config_set_u8(
8566 dut, intf,
8567 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP, val);
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008568#else /* NL80211_SUPPORT */
8569 sigma_dut_print(dut, DUT_MSG_ERROR,
8570 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
8571 return -1;
8572#endif /* NL80211_SUPPORT */
8573}
8574
8575
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008576#ifdef NL80211_SUPPORT
8577
8578struct features_info {
8579 unsigned char flags[8];
8580 size_t flags_len;
8581};
8582
8583static int features_info_handler(struct nl_msg *msg, void *arg)
8584{
8585 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8586 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8587 struct features_info *info = arg;
8588 struct nlattr *nl_vend, *attr;
8589
8590 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8591 genlmsg_attrlen(gnlh, 0), NULL);
8592
8593 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
8594 if (nl_vend) {
8595 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
8596
8597 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
8598 nla_data(nl_vend), nla_len(nl_vend), NULL);
8599
8600 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
8601 if (attr) {
8602 int len = nla_len(attr);
8603
Vamsi Krishna79a91132021-08-16 21:40:22 +05308604 if (info && len <= sizeof(info->flags)) {
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008605 memcpy(info->flags, nla_data(attr), len);
8606 info->flags_len = len;
8607 }
8608 }
8609 }
8610
8611 return NL_SKIP;
8612}
8613
8614
8615static int check_feature(enum qca_wlan_vendor_features feature,
8616 struct features_info *info)
8617{
8618 size_t idx = feature / 8;
8619
Vamsi Krishna79a91132021-08-16 21:40:22 +05308620 if (!info)
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008621 return 0;
8622
8623 return (idx < info->flags_len) &&
8624 (info->flags[idx] & BIT(feature % 8));
8625}
8626
8627#endif /* NL80211_SUPPORT */
8628
8629
8630static void sta_get_twt_feature_async_supp(struct sigma_dut *dut,
8631 const char *intf)
8632{
8633#ifdef NL80211_SUPPORT
8634 struct nl_msg *msg;
8635 struct features_info info = { 0 };
8636 int ifindex, ret;
8637
8638 ifindex = if_nametoindex(intf);
8639 if (ifindex == 0) {
8640 sigma_dut_print(dut, DUT_MSG_ERROR,
8641 "%s: Index for interface %s failed",
8642 __func__, intf);
8643 return;
8644 }
8645
8646 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8647 NL80211_CMD_VENDOR)) ||
8648 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8649 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8650 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8651 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
8652 sigma_dut_print(dut, DUT_MSG_ERROR,
8653 "%s: err in adding vendor_cmd and vendor_data",
8654 __func__);
8655 nlmsg_free(msg);
8656 return;
8657 }
8658
8659 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, features_info_handler,
8660 &info);
8661 if (ret) {
8662 sigma_dut_print(dut, DUT_MSG_ERROR,
8663 "%s: err in send_and_recv_msgs, ret=%d",
8664 __func__, ret);
8665 return;
8666 }
8667
8668 if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info))
8669 dut->sta_async_twt_supp = 1;
8670 else
8671 dut->sta_async_twt_supp = 0;
8672
8673 sigma_dut_print(dut, DUT_MSG_DEBUG,
8674 "%s: sta_async_twt_supp %d",
8675 __func__, dut->sta_async_twt_supp);
8676#else /* NL80211_SUPPORT */
8677 sigma_dut_print(dut, DUT_MSG_INFO,
8678 "TWT async supp get cannot be done without NL80211_SUPPORT defined");
8679 dut->sta_async_twt_supp = 0;
8680#endif /* NL80211_SUPPORT */
8681}
8682
8683
Arif Hussain480d5f42019-03-12 14:40:42 -07008684static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
8685 int val)
8686{
8687#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308688 return wcn_wifi_test_config_set_u8(
8689 dut, intf,
8690 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT, val);
Arif Hussain480d5f42019-03-12 14:40:42 -07008691#else /* NL80211_SUPPORT */
8692 sigma_dut_print(dut, DUT_MSG_ERROR,
8693 "TWT Request cannot be changed without NL80211_SUPPORT defined");
8694 return -1;
8695#endif /* NL80211_SUPPORT */
8696}
8697
8698
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07008699static int sta_set_bss_max_idle_period(struct sigma_dut *dut, const char *intf,
8700 int val)
8701{
8702#ifdef NL80211_SUPPORT
8703 return wcn_wifi_test_config_set_u16(
8704 dut, intf,
8705 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD, val);
8706#else /* NL80211_SUPPORT */
8707 sigma_dut_print(dut, DUT_MSG_ERROR,
8708 "BSS max idle period cannot be set without NL80211_SUPPORT defined");
8709 return -1;
8710#endif /* NL80211_SUPPORT */
8711}
8712
8713
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07008714static int sta_set_bss_max_idle_support(struct sigma_dut *dut, const char *intf,
8715 int val)
8716{
8717#ifdef NL80211_SUPPORT
8718 return wcn_wifi_test_config_set_u8(
8719 dut, intf,
8720 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE,
8721 val);
8722#else /* NL80211_SUPPORT */
8723 sigma_dut_print(dut, DUT_MSG_ERROR,
8724 "BSS max idle support cannot be set without NL80211_SUPPORT defined");
8725 return -1;
8726#endif /* NL80211_SUPPORT */
8727}
8728
8729
Srinivas Girigowda0525e292020-11-12 13:28:21 -08008730static int sta_set_fullbw_ulmumimo(struct sigma_dut *dut, const char *intf,
8731 int val)
8732{
8733#ifdef NL80211_SUPPORT
8734 return wcn_wifi_test_config_set_u8(
8735 dut, intf,
8736 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO, val);
8737#else /* NL80211_SUPPORT */
8738 sigma_dut_print(dut, DUT_MSG_ERROR,
8739 "Full BW UL MU MIMO cannot be changed without NL80211_SUPPORT defined");
8740 return -1;
8741#endif /* NL80211_SUPPORT */
8742}
8743
8744
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07008745static int sta_set_punctured_preamble_rx(struct sigma_dut *dut,
8746 const char *intf, int val)
8747{
8748#ifdef NL80211_SUPPORT
8749 return wcn_wifi_test_config_set_u8(
8750 dut, intf,
8751 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX,
8752 val);
8753#else /* NL80211_SUPPORT */
8754 sigma_dut_print(dut, DUT_MSG_ERROR,
8755 "Punctured preamble Rx cannot be set without NL80211_SUPPORT defined");
8756 return -1;
8757#endif /* NL80211_SUPPORT */
8758}
8759
8760
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -08008761int wcn_set_he_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8762{
8763 #ifdef NL80211_SUPPORT
8764 struct nlattr *attr;
8765 struct nlattr *attr1;
8766 int ifindex, ret;
8767 struct nl_msg *msg;
8768
8769 ifindex = if_nametoindex(intf);
8770 if (ifindex == 0) {
8771 sigma_dut_print(dut, DUT_MSG_ERROR,
8772 "%s: Index for interface %s failed",
8773 __func__, intf);
8774 return -1;
8775 }
8776
8777 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8778 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8779 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8780 sigma_dut_print(dut, DUT_MSG_ERROR,
8781 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8782 __func__);
8783 nlmsg_free(msg);
8784 return -1;
8785 }
8786
8787 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting HE GI %d",
8788 __func__, gi_val);
8789
8790 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8791 if (!attr1) {
8792 sigma_dut_print(dut, DUT_MSG_ERROR,
8793 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8794 __func__);
8795 nlmsg_free(msg);
8796 return -1;
8797 }
8798 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8799 nla_nest_end(msg, attr1);
8800
8801 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8802 if (!attr1) {
8803 sigma_dut_print(dut, DUT_MSG_ERROR,
8804 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8805 __func__);
8806 nlmsg_free(msg);
8807 return -1;
8808 }
8809 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8810 nla_nest_end(msg, attr1);
8811
8812 nla_nest_end(msg, attr);
8813 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8814 if (ret) {
8815 sigma_dut_print(dut, DUT_MSG_ERROR,
8816 "%s: send_and_recv_msgs failed, ret=%d",
8817 __func__, ret);
8818 }
8819 return ret;
8820#else /* NL80211_SUPPORT */
8821 return -1;
8822#endif /* NL80211_SUPPORT */
8823}
8824
8825
8826static int sta_set_vht_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8827{
8828 #ifdef NL80211_SUPPORT
8829 struct nlattr *attr;
8830 struct nlattr *attr1;
8831 int ifindex, ret;
8832 struct nl_msg *msg;
8833
8834 ifindex = if_nametoindex(intf);
8835 if (ifindex == 0) {
8836 sigma_dut_print(dut, DUT_MSG_ERROR,
8837 "%s: Index for interface %s failed",
8838 __func__, intf);
8839 return -1;
8840 }
8841
8842 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8843 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8844 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8845 sigma_dut_print(dut, DUT_MSG_ERROR,
8846 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8847 __func__);
8848 nlmsg_free(msg);
8849 return -1;
8850 }
8851
8852 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting VHT GI %d",
8853 __func__, gi_val);
8854
8855 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8856 if (!attr1) {
8857 sigma_dut_print(dut, DUT_MSG_ERROR,
8858 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8859 __func__);
8860 nlmsg_free(msg);
8861 return -1;
8862 }
8863 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8864 nla_nest_end(msg, attr1);
8865
8866 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8867 if (!attr1) {
8868 sigma_dut_print(dut, DUT_MSG_ERROR,
8869 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8870 __func__);
8871 nlmsg_free(msg);
8872 return -1;
8873 }
8874 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8875 nla_nest_end(msg, attr1);
8876 nla_nest_end(msg, attr);
8877
8878 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8879 if (ret) {
8880 sigma_dut_print(dut, DUT_MSG_ERROR,
8881 "%s: send_and_recv_msgs failed, ret=%d",
8882 __func__, ret);
8883 }
8884 return ret;
8885#else /* NL80211_SUPPORT */
8886 return -1;
8887#endif /* NL80211_SUPPORT */
8888}
8889
8890
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008891static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
8892 const char *type)
8893{
8894 char buf[60];
8895
8896 if (dut->program == PROGRAM_HE) {
8897 /* resetting phymode to auto in case of HE program */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05308898 sta_set_phymode(dut, intf, "auto");
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008899
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07008900 /* reset the rate to Auto rate */
8901 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
8902 intf);
8903 if (system(buf) != 0) {
8904 sigma_dut_print(dut, DUT_MSG_ERROR,
8905 "iwpriv %s set_11ax_rate 0xff failed",
8906 intf);
8907 }
8908
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07008909 /* reset the LDPC setting */
8910 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
8911 if (system(buf) != 0) {
8912 sigma_dut_print(dut, DUT_MSG_ERROR,
8913 "iwpriv %s ldpc 1 failed", intf);
8914 }
8915
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008916 /* reset the power save setting */
Vinita S. Malooa8b62722020-04-23 01:45:41 +05308917 set_power_save_wcn(dut, intf, 2);
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008918
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008919 /* remove all network profiles */
8920 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008921
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008922 /* Configure ADDBA Req/Rsp buffer size to be 64 */
8923 sta_set_addba_buf_size(dut, intf, 64);
8924
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008925 if (dut->sta_async_twt_supp == -1)
8926 sta_get_twt_feature_async_supp(dut, intf);
8927
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008928 sta_set_scan_unicast_probe(dut, intf, 0);
8929
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008930#ifdef NL80211_SUPPORT
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08008931 nl80211_close_event_sock(dut);
8932
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008933 /* Reset the device HE capabilities to its default supported
8934 * configuration. */
8935 sta_set_he_testbed_def(dut, intf, 0);
8936
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008937 /* Disable noackpolicy for all AC */
8938 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
8939 sigma_dut_print(dut, DUT_MSG_ERROR,
8940 "Disable of noackpolicy for all AC failed");
8941 }
8942#endif /* NL80211_SUPPORT */
8943
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08008944 /* Enable WMM by default */
8945 if (wcn_sta_set_wmm(dut, intf, "on")) {
8946 sigma_dut_print(dut, DUT_MSG_ERROR,
8947 "Enable of WMM in sta_reset_default_wcn failed");
8948 }
8949
8950 /* Disable ADDBA_REJECT by default */
8951 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
8952 sigma_dut_print(dut, DUT_MSG_ERROR,
8953 "Disable of addba_reject in sta_reset_default_wcn failed");
8954 }
8955
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08008956 /* Enable sending of ADDBA by default */
8957 if (nlvendor_config_send_addba(dut, intf, 1)) {
8958 sigma_dut_print(dut, DUT_MSG_ERROR,
8959 "Enable sending of ADDBA in sta_reset_default_wcn failed");
8960 }
8961
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08008962 /* Enable AMPDU by default */
8963 iwpriv_sta_set_ampdu(dut, intf, 1);
8964
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008965#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08008966 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008967 sigma_dut_print(dut, DUT_MSG_ERROR,
8968 "Set LTF config to default in sta_reset_default_wcn failed");
8969 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07008970
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08008971 /* set the beamformee NSTS(maximum number of
8972 * space-time streams) to default DUT config
8973 */
8974 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07008975 sigma_dut_print(dut, DUT_MSG_ERROR,
8976 "Failed to set BeamformeeSTS");
8977 }
Arif Hussain68d23f52018-07-11 13:39:08 -07008978
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008979 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, 0)) {
8980 sigma_dut_print(dut, DUT_MSG_ERROR,
8981 "Failed to reset mgmt/data Tx disable config");
8982 }
8983
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008984 if (sta_set_mac_padding_duration(
8985 dut, intf,
8986 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008987 sigma_dut_print(dut, DUT_MSG_ERROR,
8988 "Failed to set MAC padding duration");
8989 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008990
8991 if (sta_set_mu_edca_override(dut, intf, 0)) {
8992 sigma_dut_print(dut, DUT_MSG_ERROR,
8993 "ErrorCode,Failed to set MU EDCA override disable");
8994 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008995
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008996 if (sta_set_ru_242_tone_tx(dut, intf, 0)) {
8997 sigma_dut_print(dut, DUT_MSG_ERROR,
8998 "Failed to set RU 242 tone Tx");
8999 }
9000
9001 if (sta_set_er_su_ppdu_type_tx(dut, intf, 0)) {
9002 sigma_dut_print(dut, DUT_MSG_ERROR,
9003 "Failed to set ER-SU PPDU type Tx");
9004 }
9005
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009006 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
9007 sigma_dut_print(dut, DUT_MSG_ERROR,
9008 "Failed to set OM ctrl supp");
9009 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07009010
9011 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
9012 sigma_dut_print(dut, DUT_MSG_ERROR,
9013 "Failed to set Tx SU PPDU enable");
9014 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009015
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009016 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
9017 sigma_dut_print(dut, DUT_MSG_ERROR,
9018 "failed to send TB PPDU Tx cfg");
9019 }
9020
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009021 if (sta_set_he_om_ctrl_reset(dut, intf)) {
9022 sigma_dut_print(dut, DUT_MSG_ERROR,
9023 "Failed to set OM ctrl reset");
9024 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009025
9026 /* +HTC-HE support default on */
9027 if (sta_set_he_htc_supp(dut, intf, 1)) {
9028 sigma_dut_print(dut, DUT_MSG_ERROR,
9029 "Setting of +HTC-HE support failed");
9030 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009031#endif /* NL80211_SUPPORT */
9032
Arif Hussain8d5b27b2018-05-14 14:31:03 -07009033 if (sta_set_tx_beamformee(dut, intf, 1)) {
9034 sigma_dut_print(dut, DUT_MSG_ERROR,
9035 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
9036 }
9037
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009038 wpa_command(intf, "SET oce 1");
9039
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009040 /* Set nss to 1 and MCS 0-7 in case of testbed */
9041 if (type && strcasecmp(type, "Testbed") == 0) {
9042#ifdef NL80211_SUPPORT
9043 int ret;
9044#endif /* NL80211_SUPPORT */
9045
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009046 wpa_command(intf, "SET oce 0");
9047
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009048 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
9049 if (system(buf) != 0) {
9050 sigma_dut_print(dut, DUT_MSG_ERROR,
9051 "iwpriv %s nss failed", intf);
9052 }
9053
9054#ifdef NL80211_SUPPORT
9055 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
9056 if (ret) {
9057 sigma_dut_print(dut, DUT_MSG_ERROR,
9058 "Setting of MCS failed, ret:%d",
9059 ret);
9060 }
9061#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08009062
9063 /* Disable STBC as default */
9064 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08009065
9066 /* Disable AMSDU as default */
9067 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009068
9069#ifdef NL80211_SUPPORT
9070 /* HE fragmentation default off */
9071 if (sta_set_he_fragmentation(dut, intf,
9072 HE_FRAG_DISABLE)) {
9073 sigma_dut_print(dut, DUT_MSG_ERROR,
9074 "Setting of HE fragmentation failed");
9075 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009076
9077 /* set the beamformee NSTS(maximum number of
9078 * space-time streams) to default testbed config
9079 */
9080 if (sta_set_beamformee_sts(dut, intf, 3)) {
9081 sigma_dut_print(dut, DUT_MSG_ERROR,
9082 "Failed to set BeamformeeSTS");
9083 }
9084
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07009085 if (sta_set_punctured_preamble_rx(dut, intf, 0)) {
9086 sigma_dut_print(dut, DUT_MSG_ERROR,
9087 "Failed to reset PreamblePunctRx support");
9088 }
9089
Kiran Kumar Lokere727687f2021-06-24 00:35:49 -07009090 if (sta_set_bss_max_idle_period(dut, intf, 0)) {
9091 sigma_dut_print(dut, DUT_MSG_ERROR,
9092 "Failed to reset BSS max idle period");
9093 }
9094
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009095 /* +HTC-HE support default off */
9096 if (sta_set_he_htc_supp(dut, intf, 0)) {
9097 sigma_dut_print(dut, DUT_MSG_ERROR,
9098 "Setting of +HTC-HE support failed");
9099 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08009100
9101 /* Set device HE capabilities to testbed default
9102 * configuration. */
9103 if (sta_set_he_testbed_def(dut, intf, 1)) {
9104 sigma_dut_print(dut, DUT_MSG_DEBUG,
9105 "Failed to set HE defaults");
9106 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08009107
9108 /* Disable VHT support in 2.4 GHz for testbed */
9109 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009110#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08009111
9112 /* Enable WEP/TKIP with HE capability in testbed */
9113 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
9114 sigma_dut_print(dut, DUT_MSG_ERROR,
9115 "Enabling HE config with WEP/TKIP failed");
9116 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009117 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009118
9119 /* Defaults in case of DUT */
9120 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07009121 /* Enable STBC by default */
9122 wcn_sta_set_stbc(dut, intf, "1");
9123
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009124 /* set nss to 2 */
9125 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
9126 if (system(buf) != 0) {
9127 sigma_dut_print(dut, DUT_MSG_ERROR,
9128 "iwpriv %s nss 2 failed", intf);
9129 }
Arif Hussainac6c5112018-05-25 17:34:00 -07009130 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009131
9132#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07009133 /* Set HE_MCS to 0-11 */
9134 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009135 sigma_dut_print(dut, DUT_MSG_ERROR,
9136 "Setting of MCS failed");
9137 }
9138#endif /* NL80211_SUPPORT */
9139
9140 /* Disable WEP/TKIP with HE capability in DUT */
9141 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
9142 sigma_dut_print(dut, DUT_MSG_ERROR,
9143 "Enabling HE config with WEP/TKIP failed");
9144 }
9145 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009146 }
9147}
9148
9149
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309150static int sta_set_client_privacy(struct sigma_dut *dut,
9151 struct sigma_conn *conn, const char *intf,
9152 int enable)
9153{
9154 if (enable &&
9155 (wpa_command(intf, "SET mac_addr 1") < 0 ||
9156 wpa_command(intf, "SET rand_addr_lifetime 1") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309157 (wpa_command(intf, "MAC_RAND_SCAN enable=1 all") < 0 &&
9158 wpa_command(intf, "SET preassoc_mac_addr 1") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309159 wpa_command(intf, "SET gas_rand_mac_addr 1") < 0 ||
9160 wpa_command(intf, "SET gas_rand_addr_lifetime 1") < 0))
9161 return -1;
9162
9163 if (!enable &&
9164 (wpa_command(intf, "SET mac_addr 0") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309165 (wpa_command(intf, "MAC_RAND_SCAN enable=0 all") < 0 &&
9166 wpa_command(intf, "SET preassoc_mac_addr 0") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309167 wpa_command(intf, "SET gas_rand_mac_addr 0") < 0))
9168 return -1;
9169
9170 dut->client_privacy = enable;
9171 return 0;
9172}
9173
9174
Jouni Malinenf7222712019-06-13 01:50:21 +03009175static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
9176 struct sigma_conn *conn,
9177 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009178{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009179 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009180 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009181 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009182 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309183 const char *dev_role = get_param(cmd, "DevRole");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309184 char resp[20];
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309185 char buf[100];
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309186 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009187
Shivani Baranwal31182012021-12-07 21:11:13 +05309188#ifdef ANDROID
9189 kill_pid(dut, concat_sigma_tmpdir(dut, "/sigma_dut-dnsmasq.pid",
9190 buf, sizeof(buf)));
9191#endif /* ANDROID */
9192
Jouni Malinenb21f0542019-11-04 17:53:38 +02009193 if (dut->station_ifname_2g &&
9194 strcmp(dut->station_ifname_2g, intf) == 0)
9195 dut->use_5g = 0;
9196 else if (dut->station_ifname_5g &&
9197 strcmp(dut->station_ifname_5g, intf) == 0)
9198 dut->use_5g = 1;
9199
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009200 if (!program)
9201 program = get_param(cmd, "prog");
9202 dut->program = sigma_program_to_enum(program);
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05309203
9204 if (dut->program == PROGRAM_WFD && dut->user_config_timeout)
9205 dut->default_timeout = dut->user_config_timeout;
9206
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009207 dut->device_type = STA_unknown;
9208 type = get_param(cmd, "type");
9209 if (type && strcasecmp(type, "Testbed") == 0)
9210 dut->device_type = STA_testbed;
9211 if (type && strcasecmp(type, "DUT") == 0)
9212 dut->device_type = STA_dut;
9213
9214 if (dut->program == PROGRAM_TDLS) {
9215 /* Clear TDLS testing mode */
9216 wpa_command(intf, "SET tdls_disabled 0");
9217 wpa_command(intf, "SET tdls_testing 0");
9218 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009219 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05309220 /* Enable the WCN driver in TDLS Explicit trigger mode
9221 */
9222 wpa_command(intf, "SET tdls_external_control 0");
9223 wpa_command(intf, "SET tdls_trigger_control 0");
9224 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009225 }
9226
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009227#ifdef MIRACAST
9228 if (dut->program == PROGRAM_WFD ||
9229 dut->program == PROGRAM_DISPLAYR2)
9230 miracast_sta_reset_default(dut, conn, cmd);
9231#endif /* MIRACAST */
9232
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009233 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009234 case DRIVER_ATHEROS:
9235 sta_reset_default_ath(dut, intf, type);
9236 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009237 case DRIVER_WCN:
9238 sta_reset_default_wcn(dut, intf, type);
9239 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009240 default:
9241 break;
9242 }
9243
9244#ifdef ANDROID_NAN
9245 if (dut->program == PROGRAM_NAN)
9246 nan_cmd_sta_reset_default(dut, conn, cmd);
9247#endif /* ANDROID_NAN */
9248
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05309249 if (dut->program == PROGRAM_LOC &&
9250 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
9251 return ERROR_SEND_STATUS;
9252
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009253 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
9254 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009255 unlink("SP/wi-fi.org/pps.xml");
9256 if (system("rm -r SP/*") != 0) {
9257 }
9258 unlink("next-client-cert.pem");
9259 unlink("next-client-key.pem");
9260 }
9261
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009262 /* For WPS program of the 60 GHz band the band type needs to be saved */
9263 if (dut->program == PROGRAM_WPS) {
9264 if (band && strcasecmp(band, "60GHz") == 0) {
9265 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009266 /* For 60 GHz enable WPS for WPS TCs */
9267 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009268 } else {
9269 dut->band = WPS_BAND_NON_60G;
9270 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009271 } else if (dut->program == PROGRAM_60GHZ) {
9272 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
9273 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009274 }
9275
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02009276 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009277 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009278 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009279
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009280 sigma_dut_print(dut, DUT_MSG_INFO,
9281 "WPS 60 GHz program, wps_disable = %d",
9282 dut->wps_disable);
9283
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009284 if (!dev_role) {
9285 send_resp(dut, conn, SIGMA_ERROR,
9286 "errorCode,Missing DevRole argument");
9287 return 0;
9288 }
9289
9290 if (strcasecmp(dev_role, "STA") == 0)
9291 dut->dev_role = DEVROLE_STA;
9292 else if (strcasecmp(dev_role, "PCP") == 0)
9293 dut->dev_role = DEVROLE_PCP;
9294 else {
9295 send_resp(dut, conn, SIGMA_ERROR,
9296 "errorCode,Unknown DevRole");
9297 return 0;
9298 }
9299
9300 if (dut->device_type == STA_unknown) {
9301 sigma_dut_print(dut, DUT_MSG_ERROR,
9302 "Device type is not STA testbed or DUT");
9303 send_resp(dut, conn, SIGMA_ERROR,
9304 "errorCode,Unknown device type");
9305 return 0;
9306 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009307
9308 sigma_dut_print(dut, DUT_MSG_DEBUG,
9309 "Setting msdu_size to MAX: 7912");
9310 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009311 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009312
9313 if (system(buf) != 0) {
9314 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9315 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009316 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009317 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009318
9319 if (sta_set_force_mcs(dut, 0, 1)) {
9320 sigma_dut_print(dut, DUT_MSG_ERROR,
9321 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009322 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009323 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009324 }
9325
9326 wpa_command(intf, "WPS_ER_STOP");
9327 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05309328 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009329 wpa_command(intf, "SET radio_disabled 0");
9330
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02009331 dut->wps_forced_version = 0;
9332
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009333 if (dut->wsc_fragment) {
9334 dut->wsc_fragment = 0;
9335 wpa_command(intf, "SET device_name Test client");
9336 wpa_command(intf, "SET manufacturer ");
9337 wpa_command(intf, "SET model_name ");
9338 wpa_command(intf, "SET model_number ");
9339 wpa_command(intf, "SET serial_number ");
9340 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02009341 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
9342 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
9343 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
9344 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009345
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009346 if (dut->tmp_mac_addr && dut->set_macaddr) {
9347 dut->tmp_mac_addr = 0;
9348 if (system(dut->set_macaddr) != 0) {
9349 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
9350 "temporary MAC address");
9351 }
9352 }
9353
9354 set_ps(intf, dut, 0);
9355
Jouni Malinenba630452018-06-22 11:49:59 +03009356 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009357 dut->program == PROGRAM_HS2_R3 || dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009358 wpa_command(intf, "SET interworking 1");
9359 wpa_command(intf, "SET hs20 1");
9360 }
9361
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009362 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03009363 dut->program == PROGRAM_HS2_R3 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009364 dut->program == PROGRAM_HS2_R4 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009365 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009366 wpa_command(intf, "SET pmf 1");
9367 } else {
9368 wpa_command(intf, "SET pmf 0");
9369 }
9370
9371 hs2_clear_credentials(intf);
9372 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
9373 wpa_command(intf, "SET access_network_type 15");
9374
9375 static_ip_file(0, NULL, NULL, NULL);
9376 kill_dhcp_client(dut, intf);
9377 clear_ip_addr(dut, intf);
9378
9379 dut->er_oper_performed = 0;
9380 dut->er_oper_bssid[0] = '\0';
9381
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009382 if (dut->program == PROGRAM_LOC) {
9383 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009384 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009385 }
9386
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07009387 if (dut->program == PROGRAM_MBO || dut->program == PROGRAM_HE) {
Ashwini Patil00402582017-04-13 12:29:39 +05309388 free(dut->non_pref_ch_list);
9389 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309390 free(dut->btm_query_cand_list);
9391 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05309392 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05309393 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05309394 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05309395 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05309396 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05309397 }
9398
Jouni Malinen3c367e82017-06-23 17:01:47 +03009399 free(dut->rsne_override);
9400 dut->rsne_override = NULL;
9401
Jouni Malinen68143132017-09-02 02:34:08 +03009402 free(dut->sae_commit_override);
9403 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03009404 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02009405 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03009406
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009407 dut->sta_associate_wait_connect = 0;
9408 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03009409 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009410 dut->sta_tod_policy = 0;
9411
Jouni Malinend86e5822017-08-29 03:55:32 +03009412 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02009413 free(dut->dpp_peer_uri);
9414 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02009415 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02009416 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03009417 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinend86e5822017-08-29 03:55:32 +03009418
Jouni Malinenfac9cad2017-10-10 18:35:55 +03009419 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
9420
vamsi krishnaa2799492017-12-05 14:28:01 +05309421 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309422 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05309423 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05309424 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
9425 dut->fils_hlp = 0;
9426#ifdef ANDROID
9427 hlp_thread_cleanup(dut);
9428#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05309429 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309430
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309431 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309432 wpa_command(intf, "SET interworking 1");
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309433 wpa_command(intf, "SET enable_dscp_policy_capa 1");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05309434 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309435 dut->reject_dscp_policies = 0;
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +05309436 dut->num_dscp_status = 0;
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309437 snprintf(buf, sizeof(buf),
9438 "ip -6 route replace fe80::/64 dev %s table local",
9439 intf);
9440 if (system(buf) != 0)
9441 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
9442 buf);
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05309443
9444 stop_dscp_policy_mon_thread(dut);
9445 clear_all_dscp_policies(dut);
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309446 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309447
Jouni Malinen8179fee2019-03-28 03:19:47 +02009448 dut->akm_values = 0;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05309449
9450#ifdef NL80211_SUPPORT
9451 if (get_driver_type(dut) == DRIVER_WCN)
9452 sta_config_params(dut, intf, STA_SET_FT_DS, 0);
9453#endif /* NL80211_SUPPORT */
9454
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03009455 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02009456
Sunil Dutt076081f2018-02-05 19:45:50 +05309457#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009458 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05309459 dut->config_rsnie == 1) {
9460 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309461 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05309462 }
9463#endif /* NL80211_SUPPORT */
9464
Sunil Duttfebf8a82018-02-09 18:50:13 +05309465 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
9466 dut->dev_role = DEVROLE_STA_CFON;
9467 return sta_cfon_reset_default(dut, conn, cmd);
9468 }
9469
Jouni Malinen439352d2018-09-13 03:42:23 +03009470 wpa_command(intf, "SET setband AUTO");
9471
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309472 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
9473 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
9474
9475 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
9476 sizeof(resp));
9477 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
9478
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309479 if (sta_set_client_privacy(dut, conn, intf,
9480 dut->program == PROGRAM_WPA3 &&
9481 dut->device_type == STA_dut &&
9482 dut->client_privacy_default)) {
9483 sigma_dut_print(dut, DUT_MSG_ERROR,
9484 "Failed to set client privacy functionality");
9485 /* sta_reset_default command is not really supposed to fail,
9486 * so allow this to continue. */
9487 }
9488
Veerendranath Jakkamca239592021-10-11 20:48:00 +05309489 if (get_driver_type(dut) == DRIVER_WCN)
9490 wcn_set_ignore_h2e_rsnxe(dut, intf, 0);
9491
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05309492 dut->saquery_oci_freq = 0;
Shivani Baranwalebde8f62021-10-19 12:26:02 +05309493 dut->prev_disable_scs_support = 0;
9494 dut->prev_disable_mscs_support = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309495
Sunil Duttfebf8a82018-02-09 18:50:13 +05309496 if (dut->program != PROGRAM_VHT)
9497 return cmd_sta_p2p_reset(dut, conn, cmd);
9498
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08009499 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009500}
9501
9502
Jouni Malinenf7222712019-06-13 01:50:21 +03009503static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
9504 struct sigma_conn *conn,
9505 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009506{
9507 const char *program = get_param(cmd, "Program");
9508
9509 if (program == NULL)
9510 return -1;
9511#ifdef ANDROID_NAN
9512 if (strcasecmp(program, "NAN") == 0)
9513 return nan_cmd_sta_get_events(dut, conn, cmd);
9514#endif /* ANDROID_NAN */
9515 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9516 return 0;
9517}
9518
9519
Jouni Malinen82905202018-04-29 17:20:10 +03009520static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
9521 struct sigma_cmd *cmd)
9522{
9523 const char *url = get_param(cmd, "url");
9524 const char *method = get_param(cmd, "method");
9525 pid_t pid;
9526 int status;
9527
9528 if (!url || !method)
9529 return -1;
9530
9531 /* TODO: Add support for method,post */
9532 if (strcasecmp(method, "get") != 0) {
9533 send_resp(dut, conn, SIGMA_ERROR,
9534 "ErrorCode,Unsupported method");
9535 return 0;
9536 }
9537
9538 pid = fork();
9539 if (pid < 0) {
9540 perror("fork");
9541 return -1;
9542 }
9543
9544 if (pid == 0) {
9545 char * argv[5] = { "wget", "-O", "/dev/null",
9546 (char *) url, NULL };
9547
9548 execv("/usr/bin/wget", argv);
9549 perror("execv");
9550 exit(0);
9551 return -1;
9552 }
9553
9554 if (waitpid(pid, &status, 0) < 0) {
9555 perror("waitpid");
9556 return -1;
9557 }
9558
9559 if (WIFEXITED(status)) {
9560 const char *errmsg;
9561
9562 if (WEXITSTATUS(status) == 0)
9563 return 1;
9564 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
9565 WEXITSTATUS(status));
9566 switch (WEXITSTATUS(status)) {
9567 case 4:
9568 errmsg = "errmsg,Network failure";
9569 break;
9570 case 8:
9571 errmsg = "errmsg,Server issued an error response";
9572 break;
9573 default:
9574 errmsg = "errmsg,Unknown failure from wget";
9575 break;
9576 }
9577 send_resp(dut, conn, SIGMA_ERROR, errmsg);
9578 return 0;
9579 }
9580
9581 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
9582 return 0;
9583}
9584
9585
Jouni Malinenf7222712019-06-13 01:50:21 +03009586static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
9587 struct sigma_conn *conn,
9588 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009589{
9590 const char *program = get_param(cmd, "Prog");
9591
Jouni Malinen82905202018-04-29 17:20:10 +03009592 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009593 return -1;
9594#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03009595 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009596 return nan_cmd_sta_exec_action(dut, conn, cmd);
9597#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03009598
9599 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009600 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03009601
9602 if (get_param(cmd, "url"))
9603 return sta_exec_action_url(dut, conn, cmd);
9604
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009605 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9606 return 0;
9607}
9608
9609
Jouni Malinenf7222712019-06-13 01:50:21 +03009610static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
9611 struct sigma_conn *conn,
9612 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009613{
9614 const char *intf = get_param(cmd, "Interface");
9615 const char *val, *mcs32, *rate;
9616
9617 val = get_param(cmd, "GREENFIELD");
9618 if (val) {
9619 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
9620 /* Enable GD */
9621 send_resp(dut, conn, SIGMA_ERROR,
9622 "ErrorCode,GF not supported");
9623 return 0;
9624 }
9625 }
9626
9627 val = get_param(cmd, "SGI20");
9628 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009629 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009630 case DRIVER_ATHEROS:
9631 ath_sta_set_sgi(dut, intf, val);
9632 break;
9633 default:
9634 send_resp(dut, conn, SIGMA_ERROR,
9635 "ErrorCode,SGI20 not supported");
9636 return 0;
9637 }
9638 }
9639
9640 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
9641 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
9642 if (mcs32 && rate) {
9643 /* TODO */
9644 send_resp(dut, conn, SIGMA_ERROR,
9645 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
9646 return 0;
9647 } else if (mcs32 && !rate) {
9648 /* TODO */
9649 send_resp(dut, conn, SIGMA_ERROR,
9650 "ErrorCode,MCS32 not supported");
9651 return 0;
9652 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009653 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009654 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07009655 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009656 ath_sta_set_11nrates(dut, intf, rate);
9657 break;
9658 default:
9659 send_resp(dut, conn, SIGMA_ERROR,
9660 "ErrorCode,MCS32_FIXEDRATE not supported");
9661 return 0;
9662 }
9663 }
9664
9665 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9666}
9667
9668
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009669static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
9670 int mcs_config)
9671{
9672#ifdef NL80211_SUPPORT
9673 int ret;
9674
9675 switch (mcs_config) {
9676 case HE_80_MCS0_7:
9677 case HE_80_MCS0_9:
9678 case HE_80_MCS0_11:
9679 ret = sta_set_he_mcs(dut, intf, mcs_config);
9680 if (ret) {
9681 sigma_dut_print(dut, DUT_MSG_ERROR,
9682 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
9683 mcs_config, ret);
9684 }
9685 break;
9686 default:
9687 sigma_dut_print(dut, DUT_MSG_ERROR,
9688 "cmd_set_max_he_mcs: Invalid mcs %d",
9689 mcs_config);
9690 break;
9691 }
9692#else /* NL80211_SUPPORT */
9693 sigma_dut_print(dut, DUT_MSG_ERROR,
9694 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
9695#endif /* NL80211_SUPPORT */
9696}
9697
9698
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009699struct wait_event {
9700 struct sigma_dut *dut;
9701 int cmd;
9702 unsigned int twt_op;
9703};
9704
9705#ifdef NL80211_SUPPORT
9706
9707static int twt_event_handler(struct nl_msg *msg, void *arg)
9708{
9709 struct wait_event *wait = arg;
9710 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9711 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9712 uint32_t subcmd;
9713 uint8_t *data = NULL;
9714 size_t len = 0;
9715 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
9716 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
9717 int cmd_id;
9718 unsigned char val;
9719
9720 if (!wait)
9721 return NL_SKIP;
9722
9723 if (gnlh->cmd != NL80211_CMD_VENDOR) {
9724 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9725 "%s: NL cmd is not vendor %d", __func__,
9726 gnlh->cmd);
9727 return NL_SKIP;
9728 }
9729
9730 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9731 genlmsg_attrlen(gnlh, 0), NULL);
9732
9733 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
9734 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9735 "%s: vendor ID not found", __func__);
9736 return NL_SKIP;
9737 }
9738 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
9739
9740 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
9741 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9742 "%s: Not a TWT_cmd %d", __func__, subcmd);
9743 return NL_SKIP;
9744 }
9745 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9746 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
9747 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
9748 } else {
9749 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9750 "%s: vendor data not present", __func__);
9751 return NL_SKIP;
9752 }
9753 if (!data || !len) {
9754 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9755 "Invalid vendor data or len");
9756 return NL_SKIP;
9757 }
9758 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
9759 "event data len %ld", len);
9760 hex_dump(wait->dut, data, len);
9761 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
9762 (struct nlattr *) data, len, NULL)) {
9763 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9764 "vendor data parse error");
9765 return NL_SKIP;
9766 }
9767
9768 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
9769 if (val != wait->twt_op) {
9770 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9771 "Invalid TWT operation, expected %d, rcvd %d",
9772 wait->twt_op, val);
9773 return NL_SKIP;
9774 }
9775 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
9776 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
9777 NULL)) {
9778 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9779 "nla_parse failed for TWT event");
9780 return NL_SKIP;
9781 }
9782
9783 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
9784 if (!twt_status[cmd_id]) {
9785 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9786 "%s TWT resp status missing", __func__);
9787 wait->cmd = -1;
9788 } else {
9789 val = nla_get_u8(twt_status[cmd_id]);
9790 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
9791 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9792 "%s TWT resp status %d", __func__, val);
9793 wait->cmd = -1;
9794 } else {
9795 wait->cmd = 1;
9796 }
9797 }
9798
9799 return NL_SKIP;
9800}
9801
9802
9803static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
9804 unsigned int timeout)
9805{
9806 fd_set read_fd_set;
9807 int retval;
9808 int sock_fd;
9809 struct timeval time_out;
9810
9811 time_out.tv_sec = timeout;
9812 time_out.tv_usec = 0;
9813
9814 FD_ZERO(&read_fd_set);
9815
9816 if (!sock)
9817 return -1;
9818
9819 sock_fd = nl_socket_get_fd(sock);
9820 FD_SET(sock_fd, &read_fd_set);
9821
9822 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
9823
9824 if (retval == 0)
9825 sigma_dut_print(dut, DUT_MSG_ERROR,
9826 "%s: TWT event response timedout", __func__);
9827
9828 if (retval < 0)
9829 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
9830 __func__, retval);
9831
9832 return retval;
9833}
9834
9835
9836#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
9837
9838static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
9839{
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009840 struct nl_cb *cb = NULL;
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009841 int err_code = 0, select_retval = 0;
9842 struct wait_event wait_info;
9843
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009844 if (dut->nl_ctx->event_sock)
9845 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009846 if (!cb) {
9847 sigma_dut_print(dut, DUT_MSG_ERROR,
9848 "event callback not found");
9849 return ERROR_SEND_STATUS;
9850 }
9851
9852 wait_info.cmd = 0;
9853 wait_info.dut = dut;
9854 wait_info.twt_op = twt_op;
9855
9856 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
9857
9858 while (!wait_info.cmd) {
9859 select_retval = wait_on_nl_socket(
9860 dut->nl_ctx->event_sock, dut,
9861 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
9862
9863 if (select_retval > 0) {
9864 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
9865 if (err_code < 0) {
9866 sigma_dut_print(dut, DUT_MSG_ERROR,
9867 "%s: nl rcv failed, err_code %d",
9868 __func__, err_code);
9869 break;
9870 }
9871 } else {
9872 sigma_dut_print(dut, DUT_MSG_ERROR,
9873 "%s: wait on socket failed %d",
9874 __func__, select_retval);
9875 err_code = 1;
9876 break;
9877 }
9878
9879 }
9880 nl_cb_put(cb);
9881
9882 if (wait_info.cmd < 0)
9883 err_code = 1;
9884
9885 sigma_dut_print(dut, DUT_MSG_DEBUG,
9886 "%s: rcvd cmd %d, err_code %d, s_ret %d",
9887 __func__, wait_info.cmd, err_code, select_retval);
9888
9889 return err_code;
9890}
9891
9892#endif /* NL80211_SUPPORT */
9893
9894
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009895static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
9896 struct sigma_cmd *cmd)
9897{
9898#ifdef NL80211_SUPPORT
9899 struct nlattr *attr, *attr1;
9900 struct nl_msg *msg;
9901 int ifindex, ret;
9902 const char *intf = get_param(cmd, "Interface");
9903
9904 ifindex = if_nametoindex(intf);
9905 if (ifindex == 0) {
9906 sigma_dut_print(dut, DUT_MSG_ERROR,
9907 "%s: Index for interface %s failed",
9908 __func__, intf);
9909 return ERROR_SEND_STATUS;
9910 }
9911
9912 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9913 NL80211_CMD_VENDOR)) ||
9914 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9915 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9916 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9917 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9918 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9919 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9920 QCA_WLAN_TWT_SUSPEND) ||
9921 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07009922 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009923 sigma_dut_print(dut, DUT_MSG_ERROR,
9924 "%s: err in adding vendor_cmd and vendor_data",
9925 __func__);
9926 nlmsg_free(msg);
9927 return ERROR_SEND_STATUS;
9928 }
9929 nla_nest_end(msg, attr1);
9930 nla_nest_end(msg, attr);
9931
9932 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9933 if (ret) {
9934 sigma_dut_print(dut, DUT_MSG_ERROR,
9935 "%s: err in send_and_recv_msgs, ret=%d",
9936 __func__, ret);
9937 }
9938
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009939 if (!dut->sta_async_twt_supp)
9940 return ret;
9941
9942 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009943#else /* NL80211_SUPPORT */
9944 sigma_dut_print(dut, DUT_MSG_ERROR,
9945 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9946 return ERROR_SEND_STATUS;
9947#endif /* NL80211_SUPPORT */
9948}
9949
9950
9951static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
9952 struct sigma_cmd *cmd,
9953 unsigned int suspend_duration)
9954{
9955#ifdef NL80211_SUPPORT
9956 struct nlattr *attr, *attr1;
9957 struct nl_msg *msg;
9958 int ifindex, ret;
9959 const char *intf = get_param(cmd, "Interface");
9960 int next_twt_size = 1;
9961
9962 ifindex = if_nametoindex(intf);
9963 if (ifindex == 0) {
9964 sigma_dut_print(dut, DUT_MSG_ERROR,
9965 "%s: Index for interface %s failed",
9966 __func__, intf);
9967 return ERROR_SEND_STATUS;
9968 }
9969
9970 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9971 NL80211_CMD_VENDOR)) ||
9972 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9973 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9974 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9975 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9976 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9977 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9978 QCA_WLAN_TWT_NUDGE) ||
9979 !(attr1 = nla_nest_start(msg,
9980 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
9981 (suspend_duration &&
9982 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
9983 suspend_duration)) ||
9984 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009985 next_twt_size) ||
9986 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009987 sigma_dut_print(dut, DUT_MSG_ERROR,
9988 "%s: err in adding vendor_cmd and vendor_data",
9989 __func__);
9990 nlmsg_free(msg);
9991 return ERROR_SEND_STATUS;
9992 }
9993 nla_nest_end(msg, attr1);
9994 nla_nest_end(msg, attr);
9995
9996 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9997 if (ret) {
9998 sigma_dut_print(dut, DUT_MSG_ERROR,
9999 "%s: err in send_and_recv_msgs, ret=%d",
10000 __func__, ret);
10001 }
10002
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010003 if (!dut->sta_async_twt_supp)
10004 return ret;
10005
10006 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010007#else /* NL80211_SUPPORT */
10008 sigma_dut_print(dut, DUT_MSG_ERROR,
10009 "TWT suspend cannot be done without NL80211_SUPPORT defined");
10010 return ERROR_SEND_STATUS;
10011#endif /* NL80211_SUPPORT */
10012}
10013
10014
10015static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
10016 struct sigma_conn *conn,
10017 struct sigma_cmd *cmd)
10018{
10019 const char *val;
10020
10021 val = get_param(cmd, "TWT_SuspendDuration");
10022 if (val) {
10023 unsigned int suspend_duration;
10024
10025 suspend_duration = atoi(val);
10026 suspend_duration = suspend_duration * 1000 * 1000;
10027 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
10028 }
10029
10030 return sta_twt_send_suspend(dut, conn, cmd);
10031}
10032
10033
10034static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
10035 struct sigma_cmd *cmd)
10036{
10037#ifdef NL80211_SUPPORT
10038 struct nlattr *attr, *attr1;
10039 struct nl_msg *msg;
10040 int ifindex, ret;
10041 const char *intf = get_param(cmd, "Interface");
10042 int next2_twt_size = 1;
10043 unsigned int resume_duration = 0;
10044 const char *val;
10045
10046 ifindex = if_nametoindex(intf);
10047 if (ifindex == 0) {
10048 sigma_dut_print(dut, DUT_MSG_ERROR,
10049 "%s: Index for interface %s failed",
10050 __func__, intf);
10051 return ERROR_SEND_STATUS;
10052 }
10053
10054 val = get_param(cmd, "TWT_ResumeDuration");
10055 if (val) {
10056 resume_duration = atoi(val);
10057 resume_duration = resume_duration * 1000 * 1000;
10058 }
10059
10060 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10061 NL80211_CMD_VENDOR)) ||
10062 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10063 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10064 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10065 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10066 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10067 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10068 QCA_WLAN_TWT_RESUME) ||
10069 !(attr1 = nla_nest_start(msg,
10070 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10071 (resume_duration &&
10072 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
10073 resume_duration)) ||
10074 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
10075 next2_twt_size)) {
10076 sigma_dut_print(dut, DUT_MSG_ERROR,
10077 "%s: err in adding vendor_cmd and vendor_data",
10078 __func__);
10079 nlmsg_free(msg);
10080 return ERROR_SEND_STATUS;
10081 }
10082 nla_nest_end(msg, attr1);
10083 nla_nest_end(msg, attr);
10084
10085 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10086 if (ret) {
10087 sigma_dut_print(dut, DUT_MSG_ERROR,
10088 "%s: err in send_and_recv_msgs, ret=%d",
10089 __func__, ret);
10090 }
10091
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010092 if (!dut->sta_async_twt_supp)
10093 return ret;
10094
10095 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010096#else /* NL80211_SUPPORT */
10097 sigma_dut_print(dut, DUT_MSG_ERROR,
10098 "TWT resume cannot be done without NL80211_SUPPORT defined");
10099 return ERROR_SEND_STATUS;
10100#endif /* NL80211_SUPPORT */
10101}
10102
10103
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010104#define TWT_REQUEST_CMD 0
10105#define TWT_SUGGEST_CMD 1
10106#define TWT_DEMAND_CMD 2
10107
Arif Hussain480d5f42019-03-12 14:40:42 -070010108static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
10109 struct sigma_cmd *cmd)
10110{
10111#ifdef NL80211_SUPPORT
10112 struct nlattr *params;
10113 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010114 struct nl_msg *msg;
10115 int ifindex, ret;
10116 const char *val;
10117 const char *intf = get_param(cmd, "Interface");
10118 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
10119 wake_interval_mantissa = 512;
10120 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010121 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010122 int bcast_twt = 0;
10123 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -070010124
10125 ifindex = if_nametoindex(intf);
10126 if (ifindex == 0) {
10127 sigma_dut_print(dut, DUT_MSG_ERROR,
10128 "%s: Index for interface %s failed",
10129 __func__, intf);
10130 return -1;
10131 }
10132
10133 val = get_param(cmd, "FlowType");
10134 if (val) {
10135 flow_type = atoi(val);
10136 if (flow_type != 0 && flow_type != 1) {
10137 sigma_dut_print(dut, DUT_MSG_ERROR,
10138 "TWT: Invalid FlowType %d", flow_type);
10139 return -1;
10140 }
10141 }
10142
10143 val = get_param(cmd, "TWT_Trigger");
10144 if (val) {
10145 twt_trigger = atoi(val);
10146 if (twt_trigger != 0 && twt_trigger != 1) {
10147 sigma_dut_print(dut, DUT_MSG_ERROR,
10148 "TWT: Invalid TWT_Trigger %d",
10149 twt_trigger);
10150 return -1;
10151 }
10152 }
10153
10154 val = get_param(cmd, "Protection");
10155 if (val) {
10156 protection = atoi(val);
10157 if (protection != 0 && protection != 1) {
10158 sigma_dut_print(dut, DUT_MSG_ERROR,
10159 "TWT: Invalid Protection %d",
10160 protection);
10161 return -1;
10162 }
10163 }
10164
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010165 val = get_param(cmd, "SetupCommand");
10166 if (val) {
10167 cmd_type = atoi(val);
10168 if (cmd_type == TWT_REQUEST_CMD)
10169 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
10170 else if (cmd_type == TWT_SUGGEST_CMD)
10171 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
10172 else if (cmd_type == TWT_DEMAND_CMD)
10173 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
10174 else
10175 sigma_dut_print(dut, DUT_MSG_ERROR,
10176 "Default suggest is used for cmd %d",
10177 cmd_type);
10178 }
10179
Arif Hussain480d5f42019-03-12 14:40:42 -070010180 val = get_param(cmd, "TargetWakeTime");
10181 if (val)
10182 target_wake_time = atoi(val);
10183
10184 val = get_param(cmd, "WakeIntervalMantissa");
10185 if (val)
10186 wake_interval_mantissa = atoi(val);
10187
10188 val = get_param(cmd, "WakeIntervalExp");
10189 if (val)
10190 wake_interval_exp = atoi(val);
10191
10192 val = get_param(cmd, "NominalMinWakeDur");
10193 if (val)
10194 nominal_min_wake_dur = atoi(val);
10195
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010196 val = get_param(cmd, "BTWT_ID");
10197 if (val) {
10198 bcast_twt_id = atoi(val);
10199 bcast_twt = 1;
10200 }
10201
10202 val = get_param(cmd, "BTWT_Persistence");
10203 if (val) {
10204 bcast_twt_persis = atoi(val);
10205 bcast_twt = 1;
10206 }
10207
10208 val = get_param(cmd, "BTWT_Recommendation");
10209 if (val) {
10210 bcast_twt_recommdn = atoi(val);
10211 bcast_twt = 1;
10212 }
10213
10214 if (bcast_twt)
10215 sigma_dut_print(dut, DUT_MSG_DEBUG,
10216 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
10217 bcast_twt_id, bcast_twt_recommdn,
10218 bcast_twt_persis);
10219
Arif Hussain480d5f42019-03-12 14:40:42 -070010220 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10221 NL80211_CMD_VENDOR)) ||
10222 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10223 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10224 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010225 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010226 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010227 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10228 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010229 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010230 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010231 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
10232 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010233 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010234 (twt_trigger &&
10235 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010236 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
10237 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010238 (protection &&
10239 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010240 (bcast_twt &&
10241 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10242 (bcast_twt &&
10243 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10244 bcast_twt_id)) ||
10245 (bcast_twt &&
10246 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
10247 bcast_twt_persis)) ||
10248 (bcast_twt &&
10249 nla_put_u8(msg,
10250 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
10251 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010252 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
10253 target_wake_time) ||
10254 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
10255 nominal_min_wake_dur) ||
10256 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
10257 wake_interval_mantissa)) {
10258 sigma_dut_print(dut, DUT_MSG_ERROR,
10259 "%s: err in adding vendor_cmd and vendor_data",
10260 __func__);
10261 nlmsg_free(msg);
10262 return -1;
10263 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010264 nla_nest_end(msg, params);
10265 nla_nest_end(msg, attr);
10266
10267 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10268 if (ret) {
10269 sigma_dut_print(dut, DUT_MSG_ERROR,
10270 "%s: err in send_and_recv_msgs, ret=%d",
10271 __func__, ret);
10272 }
10273
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010274 if (!dut->sta_async_twt_supp)
10275 return ret;
10276
10277 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -070010278#else /* NL80211_SUPPORT */
10279 sigma_dut_print(dut, DUT_MSG_ERROR,
10280 "TWT request cannot be done without NL80211_SUPPORT defined");
10281 return -1;
10282#endif /* NL80211_SUPPORT */
10283}
10284
10285
10286static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
10287 struct sigma_cmd *cmd)
10288{
10289 #ifdef NL80211_SUPPORT
10290 struct nlattr *params;
10291 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010292 int ifindex, ret;
10293 struct nl_msg *msg;
10294 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010295 int bcast_twt = 0;
10296 int bcast_twt_id = 0;
10297 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -070010298
10299 ifindex = if_nametoindex(intf);
10300 if (ifindex == 0) {
10301 sigma_dut_print(dut, DUT_MSG_ERROR,
10302 "%s: Index for interface %s failed",
10303 __func__, intf);
10304 return -1;
10305 }
10306
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010307 val = get_param(cmd, "BTWT_ID");
10308 if (val) {
10309 bcast_twt_id = atoi(val);
10310 bcast_twt = 1;
10311 }
10312
Arif Hussain480d5f42019-03-12 14:40:42 -070010313 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10314 NL80211_CMD_VENDOR)) ||
10315 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10316 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10317 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010318 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010319 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010320 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10321 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010322 !(params = nla_nest_start(
10323 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010324 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010325 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
10326 (bcast_twt &&
10327 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10328 (bcast_twt &&
10329 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10330 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -070010331 sigma_dut_print(dut, DUT_MSG_ERROR,
10332 "%s: err in adding vendor_cmd and vendor_data",
10333 __func__);
10334 nlmsg_free(msg);
10335 return -1;
10336 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010337 nla_nest_end(msg, params);
10338 nla_nest_end(msg, attr);
10339
10340 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10341 if (ret) {
10342 sigma_dut_print(dut, DUT_MSG_ERROR,
10343 "%s: err in send_and_recv_msgs, ret=%d",
10344 __func__, ret);
10345 }
10346
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010347 if (!dut->sta_async_twt_supp)
10348 return ret;
10349
10350 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -070010351#else /* NL80211_SUPPORT */
10352 sigma_dut_print(dut, DUT_MSG_ERROR,
10353 "TWT teardown cannot be done without NL80211_SUPPORT defined");
10354 return -1;
10355#endif /* NL80211_SUPPORT */
10356}
10357
10358
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080010359static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
10360 struct sigma_cmd *cmd)
10361{
10362#ifdef NL80211_SUPPORT
10363 struct nlattr *params;
10364 struct nlattr *attr;
10365 struct nlattr *attr1;
10366 struct nl_msg *msg;
10367 int ifindex, ret;
10368 const char *val;
10369 const char *intf = get_param(cmd, "Interface");
10370 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
10371 ulmu_data_dis = 0;
10372
10373 ifindex = if_nametoindex(intf);
10374 if (ifindex == 0) {
10375 sigma_dut_print(dut, DUT_MSG_ERROR,
10376 "%s: Index for interface %s failed",
10377 __func__, intf);
10378 return -1;
10379 }
10380 val = get_param(cmd, "OMCtrl_RxNSS");
10381 if (val)
10382 rx_nss = atoi(val);
10383
10384 val = get_param(cmd, "OMCtrl_ChnlWidth");
10385 if (val)
10386 ch_bw = atoi(val);
10387
10388 val = get_param(cmd, "OMCtrl_ULMUDisable");
10389 if (val)
10390 ulmu_dis = atoi(val);
10391
10392 val = get_param(cmd, "OMCtrl_TxNSTS");
10393 if (val)
10394 tx_nsts = atoi(val);
10395
10396 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
10397 if (val)
10398 ulmu_data_dis = atoi(val);
10399
10400 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10401 NL80211_CMD_VENDOR)) ||
10402 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10403 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10404 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10405 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10406 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10407 !(params = nla_nest_start(
10408 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
10409 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10410 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
10411 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
10412 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
10413 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
10414 ulmu_data_dis) ||
10415 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
10416 ulmu_dis)) {
10417 sigma_dut_print(dut, DUT_MSG_ERROR,
10418 "%s: err in adding vendor_cmd and vendor_data",
10419 __func__);
10420 nlmsg_free(msg);
10421 return -1;
10422 }
10423 nla_nest_end(msg, attr1);
10424 nla_nest_end(msg, params);
10425 nla_nest_end(msg, attr);
10426
10427 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10428 if (ret) {
10429 sigma_dut_print(dut, DUT_MSG_ERROR,
10430 "%s: err in send_and_recv_msgs, ret=%d",
10431 __func__, ret);
10432 }
10433
10434 return ret;
10435#else /* NL80211_SUPPORT */
10436 sigma_dut_print(dut, DUT_MSG_ERROR,
10437 "OMI TX cannot be processed without NL80211_SUPPORT defined");
10438 return -1;
10439#endif /* NL80211_SUPPORT */
10440}
10441
10442
Jouni Malinen224e3902021-06-09 16:41:27 +030010443static enum sigma_cmd_result
10444cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10445 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010446{
10447 const char *intf = get_param(cmd, "Interface");
10448 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -070010449 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010450 int tkip = -1;
10451 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010452 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010453
Arif Hussaina37e9552018-06-20 17:05:59 -070010454 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010455 val = get_param(cmd, "SGI80");
10456 if (val) {
10457 int sgi80;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010458 enum nl80211_txrate_gi gi_val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010459
10460 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010461 if (sgi80)
10462 gi_val = NL80211_TXRATE_FORCE_LGI;
10463 else
10464 gi_val = NL80211_TXRATE_FORCE_SGI;
10465 if (sta_set_vht_gi(dut, intf, (u8) gi_val)) {
10466 sigma_dut_print(dut, DUT_MSG_INFO,
10467 "sta_set_vht_gi failed, using iwpriv");
10468 run_iwpriv(dut, intf, "shortgi %d", sgi80);
10469 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010470 }
10471
10472 val = get_param(cmd, "TxBF");
10473 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010474 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010475 case DRIVER_WCN:
10476 if (sta_set_tx_beamformee(dut, intf, 1)) {
10477 send_resp(dut, conn, SIGMA_ERROR,
10478 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010479 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010480 }
10481 break;
10482 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010483 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010484 send_resp(dut, conn, SIGMA_ERROR,
10485 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010486 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010487 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010488 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010489 send_resp(dut, conn, SIGMA_ERROR,
10490 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010491 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010492 }
10493 break;
10494 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010495 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010496 "Unsupported driver type");
10497 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010498 }
10499 }
10500
10501 val = get_param(cmd, "MU_TxBF");
10502 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010503 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010504 case DRIVER_ATHEROS:
10505 ath_sta_set_txsp_stream(dut, intf, "1SS");
10506 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010507 run_iwpriv(dut, intf, "vhtmubfee 1");
10508 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +053010509 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010510 case DRIVER_WCN:
10511 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
10512 send_resp(dut, conn, SIGMA_ERROR,
10513 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +030010514 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010515 }
Sunil Duttae9e5d12018-06-29 11:50:47 +053010516 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010517 default:
10518 sigma_dut_print(dut, DUT_MSG_ERROR,
10519 "Setting SP_STREAM not supported");
10520 break;
10521 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010522 }
10523
10524 val = get_param(cmd, "LDPC");
10525 if (val) {
10526 int ldpc;
10527
10528 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010529 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
10530 if (iwpriv_status)
10531 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010532 }
10533
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010534 val = get_param(cmd, "BCC");
10535 if (val) {
10536 int bcc;
10537
10538 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10539 /* use LDPC iwpriv itself to set bcc coding, bcc coding
10540 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010541 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
10542 if (iwpriv_status)
10543 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010544 }
10545
Arif Hussain7b47d2d2018-05-09 10:44:02 -070010546 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
10547 if (val && dut->sta_nss == 1)
10548 cmd_set_max_he_mcs(dut, intf, atoi(val));
10549
10550 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
10551 if (val && dut->sta_nss == 2)
10552 cmd_set_max_he_mcs(dut, intf, atoi(val));
10553
Arif Hussainac6c5112018-05-25 17:34:00 -070010554 val = get_param(cmd, "MCS_FixedRate");
10555 if (val) {
10556#ifdef NL80211_SUPPORT
10557 int mcs, ratecode = 0;
10558 enum he_mcs_config mcs_config;
10559 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +030010560 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -070010561
10562 ratecode = (0x07 & dut->sta_nss) << 5;
10563 mcs = atoi(val);
10564 /* Add the MCS to the ratecode */
10565 if (mcs >= 0 && mcs <= 11) {
10566 ratecode += mcs;
10567 if (dut->device_type == STA_testbed &&
10568 mcs > 7 && mcs <= 11) {
10569 if (mcs <= 9)
10570 mcs_config = HE_80_MCS0_9;
10571 else
10572 mcs_config = HE_80_MCS0_11;
10573 ret = sta_set_he_mcs(dut, intf, mcs_config);
10574 if (ret) {
10575 sigma_dut_print(dut, DUT_MSG_ERROR,
10576 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10577 mcs, mcs_config, ret);
10578 }
10579 }
10580 snprintf(buf, sizeof(buf),
10581 "iwpriv %s set_11ax_rate 0x%03x",
10582 intf, ratecode);
10583 if (system(buf) != 0) {
10584 sigma_dut_print(dut, DUT_MSG_ERROR,
10585 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
10586 ratecode);
10587 }
10588 } else {
10589 sigma_dut_print(dut, DUT_MSG_ERROR,
10590 "MCS_FixedRate: HE MCS %d not supported",
10591 mcs);
10592 }
10593#else /* NL80211_SUPPORT */
10594 sigma_dut_print(dut, DUT_MSG_ERROR,
10595 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
10596#endif /* NL80211_SUPPORT */
10597 }
10598
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010599 val = get_param(cmd, "opt_md_notif_ie");
10600 if (val) {
10601 char *result = NULL;
10602 char delim[] = ";";
10603 char token[30];
10604 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010605 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010606
Peng Xub8fc5cc2017-05-10 17:27:28 -070010607 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010608 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010609
10610 /* Extract the NSS information */
10611 if (result) {
10612 value = atoi(result);
10613 switch (value) {
10614 case 1:
10615 config_val = 1;
10616 break;
10617 case 2:
10618 config_val = 3;
10619 break;
10620 case 3:
10621 config_val = 7;
10622 break;
10623 case 4:
10624 config_val = 15;
10625 break;
10626 default:
10627 config_val = 3;
10628 break;
10629 }
10630
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010631 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
10632 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010633
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010634 }
10635
10636 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010637 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010638 if (result) {
10639 value = atoi(result);
10640 switch (value) {
10641 case 20:
10642 config_val = 0;
10643 break;
10644 case 40:
10645 config_val = 1;
10646 break;
10647 case 80:
10648 config_val = 2;
10649 break;
10650 case 160:
10651 config_val = 3;
10652 break;
10653 default:
10654 config_val = 2;
10655 break;
10656 }
10657
10658 dut->chwidth = config_val;
10659
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010660 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010661 }
10662
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010663 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010664 }
10665
10666 val = get_param(cmd, "nss_mcs_cap");
10667 if (val) {
10668 int nss, mcs;
10669 char token[20];
10670 char *result = NULL;
10671 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010672 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010673
Peng Xub8fc5cc2017-05-10 17:27:28 -070010674 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010675 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010676 if (!result) {
10677 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010678 "NSS not specified");
10679 send_resp(dut, conn, SIGMA_ERROR,
10680 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010681 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010682 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010683 nss = atoi(result);
10684
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010685 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -070010686 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010687
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010688 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010689 if (result == NULL) {
10690 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010691 "MCS not specified");
10692 send_resp(dut, conn, SIGMA_ERROR,
10693 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010694 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010695 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010696 result = strtok_r(result, "-", &saveptr);
10697 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010698 if (!result) {
10699 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010700 "MCS not specified");
10701 send_resp(dut, conn, SIGMA_ERROR,
10702 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010703 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010704 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010705 mcs = atoi(result);
10706
Arif Hussaina37e9552018-06-20 17:05:59 -070010707 if (program && strcasecmp(program, "HE") == 0) {
10708#ifdef NL80211_SUPPORT
10709 enum he_mcs_config mcs_config;
10710 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010711
Arif Hussaina37e9552018-06-20 17:05:59 -070010712 if (mcs >= 0 && mcs <= 7) {
10713 mcs_config = HE_80_MCS0_7;
10714 } else if (mcs > 7 && mcs <= 9) {
10715 mcs_config = HE_80_MCS0_9;
10716 } else if (mcs > 9 && mcs <= 11) {
10717 mcs_config = HE_80_MCS0_11;
10718 } else {
10719 sigma_dut_print(dut, DUT_MSG_ERROR,
10720 "nss_mcs_cap: HE: Invalid mcs: %d",
10721 mcs);
10722 send_resp(dut, conn, SIGMA_ERROR,
10723 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010724 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010725 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010726
10727 ret = sta_set_he_mcs(dut, intf, mcs_config);
10728 if (ret) {
10729 sigma_dut_print(dut, DUT_MSG_ERROR,
10730 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
10731 mcs_config, ret);
10732 send_resp(dut, conn, SIGMA_ERROR,
10733 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010734 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010735 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010736#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010737 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010738 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
10739#endif /* NL80211_SUPPORT */
10740 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010741 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -070010742
10743 switch (nss) {
10744 case 1:
10745 switch (mcs) {
10746 case 7:
10747 vht_mcsmap = 0xfffc;
10748 break;
10749 case 8:
10750 vht_mcsmap = 0xfffd;
10751 break;
10752 case 9:
10753 vht_mcsmap = 0xfffe;
10754 break;
10755 default:
10756 vht_mcsmap = 0xfffe;
10757 break;
10758 }
10759 break;
10760 case 2:
10761 switch (mcs) {
10762 case 7:
10763 vht_mcsmap = 0xfff0;
10764 break;
10765 case 8:
10766 vht_mcsmap = 0xfff5;
10767 break;
10768 case 9:
10769 vht_mcsmap = 0xfffa;
10770 break;
10771 default:
10772 vht_mcsmap = 0xfffa;
10773 break;
10774 }
10775 break;
10776 case 3:
10777 switch (mcs) {
10778 case 7:
10779 vht_mcsmap = 0xffc0;
10780 break;
10781 case 8:
10782 vht_mcsmap = 0xffd5;
10783 break;
10784 case 9:
10785 vht_mcsmap = 0xffea;
10786 break;
10787 default:
10788 vht_mcsmap = 0xffea;
10789 break;
10790 }
10791 break;
10792 default:
10793 vht_mcsmap = 0xffea;
10794 break;
10795 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010796 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010797 }
10798 }
10799
10800 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
10801
10802 val = get_param(cmd, "Vht_tkip");
10803 if (val)
10804 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10805
10806 val = get_param(cmd, "Vht_wep");
10807 if (val)
10808 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10809
10810 if (tkip != -1 || wep != -1) {
10811 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010812 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010813 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010814 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010815 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +030010816 send_resp(dut, conn, SIGMA_ERROR,
10817 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
10818 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010819 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010820 }
10821
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -070010822 val = get_param(cmd, "TWTSchedSTASupport");
10823 if (val) {
10824 int set_val;
10825
10826 switch (get_driver_type(dut)) {
10827 case DRIVER_WCN:
10828 if (strcasecmp(val, "Enable") == 0) {
10829 set_val = 1;
10830 } else if (strcasecmp(val, "Disable") == 0) {
10831 set_val = 0;
10832 } else {
10833 send_resp(dut, conn, SIGMA_ERROR,
10834 "ErrorCode,Invalid TWTSchedSTASupport");
10835 return STATUS_SENT_ERROR;
10836 }
10837
10838 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
10839 send_resp(dut, conn, SIGMA_ERROR,
10840 "ErrorCode,Failed to set TWTSchedSTASupport");
10841 return STATUS_SENT_ERROR;
10842 }
10843 break;
10844 default:
10845 sigma_dut_print(dut, DUT_MSG_ERROR,
10846 "Setting TWTSchedSTASupport not supported");
10847 break;
10848 }
10849 }
10850
10851 val = get_param(cmd, "MBSSID_RxCtrl");
10852 if (val) {
10853 int set_val;
10854
10855 switch (get_driver_type(dut)) {
10856 case DRIVER_WCN:
10857 if (strcasecmp(val, "Enable") == 0) {
10858 set_val = 1;
10859 } else if (strcasecmp(val, "Disable") == 0) {
10860 set_val = 0;
10861 } else {
10862 send_resp(dut, conn, SIGMA_ERROR,
10863 "ErrorCode,Invalid MBSSID_RxCtrl");
10864 return STATUS_SENT_ERROR;
10865 }
10866
10867 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
10868 send_resp(dut, conn, SIGMA_ERROR,
10869 "ErrorCode,Failed to set MBSSID_RxCtrl");
10870 return STATUS_SENT_ERROR;
10871 }
10872 break;
10873 default:
10874 sigma_dut_print(dut, DUT_MSG_ERROR,
10875 "Setting MBSSID_RxCtrl not supported");
10876 break;
10877 }
10878 }
10879
Arif Hussain55f00da2018-07-03 08:28:26 -070010880 val = get_param(cmd, "txBandwidth");
10881 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010882 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -070010883 case DRIVER_WCN:
10884 if (wcn_sta_set_width(dut, intf, val) < 0) {
10885 send_resp(dut, conn, SIGMA_ERROR,
10886 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010887 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010888 }
10889 break;
10890 case DRIVER_ATHEROS:
10891 if (ath_set_width(dut, conn, intf, val) < 0) {
10892 send_resp(dut, conn, SIGMA_ERROR,
10893 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010894 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010895 }
10896 break;
10897 default:
10898 sigma_dut_print(dut, DUT_MSG_ERROR,
10899 "Setting txBandwidth not supported");
10900 break;
10901 }
10902 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010903
Arif Hussain9765f7d2018-07-03 08:28:26 -070010904 val = get_param(cmd, "BeamformeeSTS");
10905 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010906 if (sta_set_tx_beamformee(dut, intf, 1)) {
10907 send_resp(dut, conn, SIGMA_ERROR,
10908 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010909 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010910 }
10911
Arif Hussain9765f7d2018-07-03 08:28:26 -070010912 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
10913 send_resp(dut, conn, SIGMA_ERROR,
10914 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010915 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -070010916 }
10917 }
10918
Arif Hussain68d23f52018-07-11 13:39:08 -070010919 val = get_param(cmd, "Trig_MAC_Padding_Dur");
10920 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010921#ifdef NL80211_SUPPORT
10922 enum qca_wlan_he_mac_padding_dur set_val;
10923
10924 switch (atoi(val)) {
10925 case 16:
10926 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
10927 break;
10928 case 8:
10929 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
10930 break;
10931 default:
10932 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
10933 break;
10934 }
10935 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -070010936 send_resp(dut, conn, SIGMA_ERROR,
10937 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +030010938 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -070010939 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010940#else /* NL80211_SUPPORT */
10941 sigma_dut_print(dut, DUT_MSG_ERROR,
10942 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
10943#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -070010944 }
10945
Arif Hussain480d5f42019-03-12 14:40:42 -070010946 val = get_param(cmd, "TWT_ReqSupport");
10947 if (val) {
10948 int set_val;
10949
10950 if (strcasecmp(val, "Enable") == 0) {
10951 set_val = 1;
10952 } else if (strcasecmp(val, "Disable") == 0) {
10953 set_val = 0;
10954 } else {
10955 send_resp(dut, conn, SIGMA_ERROR,
10956 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010957 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010958 }
10959
10960 if (sta_set_twt_req_support(dut, intf, set_val)) {
10961 sigma_dut_print(dut, DUT_MSG_ERROR,
10962 "Failed to set TWT req support %d",
10963 set_val);
10964 send_resp(dut, conn, SIGMA_ERROR,
10965 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010966 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010967 }
10968 }
10969
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -070010970 val = get_param(cmd, "PreamblePunctRx");
10971 if (val && get_driver_type(dut) == DRIVER_WCN) {
10972 int set_val;
10973
10974 if (strcasecmp(val, "Enable") == 0) {
10975 set_val = 1;
10976 } else if (strcasecmp(val, "Disable") == 0) {
10977 set_val = 0;
10978 } else {
10979 send_resp(dut, conn, SIGMA_ERROR,
10980 "ErrorCode,Invalid PreamblePunctRx");
10981 return STATUS_SENT_ERROR;
10982 }
10983
10984 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
10985 sigma_dut_print(dut, DUT_MSG_ERROR,
10986 "Failed to set PreamblePunctRx support %d",
10987 set_val);
10988 send_resp(dut, conn, SIGMA_ERROR,
10989 "ErrorCode,Failed to set PreamblePunctRx");
10990 return STATUS_SENT_ERROR;
10991 }
10992 }
10993
Srinivas Girigowda0525e292020-11-12 13:28:21 -080010994 val = get_param(cmd, "FullBW_ULMUMIMO");
10995 if (val) {
10996 int set_val;
10997
10998 if (strcasecmp(val, "Enable") == 0) {
10999 set_val = 1;
11000 } else if (strcasecmp(val, "Disable") == 0) {
11001 set_val = 0;
11002 } else {
11003 send_resp(dut, conn, SIGMA_ERROR,
11004 "ErrorCode,Invalid FullBW_ULMUMIMO");
11005 return STATUS_SENT_ERROR;
11006 }
11007
11008 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
11009 sigma_dut_print(dut, DUT_MSG_ERROR,
11010 "Failed to set FullBW_ULMUMIMO %d",
11011 set_val);
11012 send_resp(dut, conn, SIGMA_ERROR,
11013 "ErrorCode,Failed to set FullBW_ULMUMIMO");
11014 return STATUS_SENT_ERROR;
11015 }
11016 }
11017
Srinivas Girigowda6707f032020-10-26 15:24:46 -070011018 val = get_param(cmd, "TWTInfoFrameTx");
11019 if (val) {
11020 if (strcasecmp(val, "Enable") == 0) {
11021 /* No-op */
11022 } else if (strcasecmp(val, "Disable") == 0) {
11023 /* No-op */
11024 } else {
11025 send_resp(dut, conn, SIGMA_ERROR,
11026 "ErrorCode,Invalid TWTInfoFrameTx");
11027 return STATUS_SENT_ERROR;
11028 }
11029 }
11030
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011031 val = get_param(cmd, "MU_EDCA");
11032 if (val && (strcasecmp(val, "Override") == 0)) {
11033 if (sta_set_mu_edca_override(dut, intf, 1)) {
11034 send_resp(dut, conn, SIGMA_ERROR,
11035 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +030011036 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011037 }
11038 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011039
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070011040 val = get_param(cmd, "PPDUTxType");
11041 if (val && strcasecmp(val, "ER-SU") == 0) {
11042 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
11043 send_resp(dut, conn, SIGMA_ERROR,
11044 "ErrorCode,Failed to set ER-SU PPDU type Tx");
11045 return STATUS_SENT_ERROR;
11046 }
11047 }
11048
11049 val = get_param(cmd, "RUAllocTone");
11050 if (val && strcasecmp(val, "242") == 0) {
11051 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
11052 send_resp(dut, conn, SIGMA_ERROR,
11053 "ErrorCode,Failed to set RU 242 tone Tx");
11054 return STATUS_SENT_ERROR;
11055 }
11056 }
11057
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011058 val = get_param(cmd, "OMControl");
11059 if (val) {
11060 int set_val = 1;
11061
11062 if (strcasecmp(val, "Enable") == 0)
11063 set_val = 1;
11064 else if (strcasecmp(val, "Disable") == 0)
11065 set_val = 0;
11066
11067 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
11068 send_resp(dut, conn, SIGMA_ERROR,
11069 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +030011070 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011071 }
11072 }
11073
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -070011074 val = get_param(cmd, "BSSMaxIdlePeriod");
11075 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
11076 send_resp(dut, conn, SIGMA_ERROR,
11077 "ErrorCode,Failed to set BSS max idle period");
11078 return STATUS_SENT_ERROR;
11079 }
11080
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -070011081 val = get_param(cmd, "BSS_max_idle");
11082 if (val) {
11083 int set_val = 0;
11084
11085 if (strcasecmp(val, "Enable") == 0)
11086 set_val = 1;
11087 else if (strcasecmp(val, "Disable") == 0)
11088 set_val = 0;
11089 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
11090 send_resp(dut, conn, SIGMA_ERROR,
11091 "ErrorCode,Failed to set BSS max idle support");
11092 return STATUS_SENT_ERROR;
11093 }
11094 }
11095
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011096 val = get_param(cmd, "ADDBAResp_BufSize");
11097 if (val) {
11098 int buf_size;
11099
11100 if (strcasecmp(val, "gt64") == 0)
11101 buf_size = 256;
11102 else
11103 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011104 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011105 sta_set_addba_buf_size(dut, intf, buf_size)) {
11106 send_resp(dut, conn, SIGMA_ERROR,
11107 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011108 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011109 }
11110 }
11111
11112 val = get_param(cmd, "ADDBAReq_BufSize");
11113 if (val) {
11114 int buf_size;
11115
11116 if (strcasecmp(val, "gt64") == 0)
11117 buf_size = 256;
11118 else
11119 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011120 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011121 sta_set_addba_buf_size(dut, intf, buf_size)) {
11122 send_resp(dut, conn, SIGMA_ERROR,
11123 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011124 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011125 }
11126 }
11127
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011128 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11129}
11130
11131
11132static int sta_set_wireless_60g(struct sigma_dut *dut,
11133 struct sigma_conn *conn,
11134 struct sigma_cmd *cmd)
11135{
11136 const char *dev_role = get_param(cmd, "DevRole");
11137
11138 if (!dev_role) {
11139 send_resp(dut, conn, SIGMA_INVALID,
11140 "ErrorCode,DevRole not specified");
11141 return 0;
11142 }
11143
11144 if (strcasecmp(dev_role, "PCP") == 0)
11145 return sta_set_60g_pcp(dut, conn, cmd);
11146 if (strcasecmp(dev_role, "STA") == 0)
11147 return sta_set_60g_sta(dut, conn, cmd);
11148 send_resp(dut, conn, SIGMA_INVALID,
11149 "ErrorCode,DevRole not supported");
11150 return 0;
11151}
11152
11153
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011154static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
11155 struct sigma_cmd *cmd)
11156{
11157 int status;
11158 const char *intf = get_param(cmd, "Interface");
11159 const char *val = get_param(cmd, "DevRole");
11160
11161 if (val && strcasecmp(val, "STA-CFON") == 0) {
11162 status = sta_cfon_set_wireless(dut, conn, cmd);
11163 if (status)
11164 return status;
11165 }
11166 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11167}
11168
11169
Jouni Malinen67433fc2020-06-26 22:50:33 +030011170static enum sigma_cmd_result
11171sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
11172 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011173{
11174 const char *intf = get_param(cmd, "Interface");
11175 const char *val;
11176
11177 val = get_param(cmd, "ocvc");
11178 if (val)
11179 dut->ocvc = atoi(val);
11180
Jouni Malinen67433fc2020-06-26 22:50:33 +030011181 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +053011182 if (val && dut->client_privacy != atoi(val) &&
11183 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
11184 send_resp(dut, conn, SIGMA_ERROR,
11185 "errorCode,Failed to configure random MAC address use");
11186 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +030011187 }
11188
Veerendranath Jakkam9ce2b642022-02-28 18:49:25 +053011189 val = get_param(cmd, "GKH_G2_Tx");
11190 if (val) {
11191 char buf[50];
11192
11193 snprintf(buf, sizeof(buf), "SET disable_eapol_g2_tx %d",
11194 strcasecmp(val, "disable") == 0);
11195
11196 if (wpa_command(intf, buf) < 0) {
11197 send_resp(dut, conn, SIGMA_ERROR,
11198 "errorCode,Failed to enable/disable G2 transmit");
11199 return STATUS_SENT_ERROR;
11200 }
11201 }
11202
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011203 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11204}
11205
11206
Jouni Malinenf7222712019-06-13 01:50:21 +030011207static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
11208 struct sigma_conn *conn,
11209 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011210{
11211 const char *val;
11212
11213 val = get_param(cmd, "Program");
Veerendranath Jakkam9ce2b642022-02-28 18:49:25 +053011214 if (!val)
11215 val = get_param(cmd, "Prog");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011216 if (val) {
11217 if (strcasecmp(val, "11n") == 0)
11218 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080011219 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011220 return cmd_sta_set_wireless_vht(dut, conn, cmd);
11221 if (strcasecmp(val, "60ghz") == 0)
11222 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011223 if (strcasecmp(val, "OCE") == 0)
11224 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020011225 /* sta_set_wireless in WPS program is only used for 60G */
11226 if (is_60g_sigma_dut(dut))
11227 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011228 if (strcasecmp(val, "WPA3") == 0)
11229 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011230 send_resp(dut, conn, SIGMA_ERROR,
11231 "ErrorCode,Program value not supported");
11232 } else {
11233 send_resp(dut, conn, SIGMA_ERROR,
11234 "ErrorCode,Program argument not available");
11235 }
11236
11237 return 0;
11238}
11239
11240
11241static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
11242 int tid)
11243{
11244 char buf[100];
11245 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
11246
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053011247 if (tid < 0 ||
11248 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
11249 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
11250 return;
11251 }
11252
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011253 /*
11254 * Two ways to ensure that addba request with a
11255 * non zero TID could be sent out. EV 117296
11256 */
11257 snprintf(buf, sizeof(buf),
11258 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
11259 tid);
11260 if (system(buf) != 0) {
11261 sigma_dut_print(dut, DUT_MSG_ERROR,
11262 "Ping did not send out");
11263 }
11264
11265 snprintf(buf, sizeof(buf),
11266 "iwconfig %s | grep Access | awk '{print $6}' > %s",
11267 intf, VI_QOS_TMP_FILE);
11268 if (system(buf) != 0)
11269 return;
11270
11271 snprintf(buf, sizeof(buf),
11272 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
11273 intf, VI_QOS_TMP_FILE);
11274 if (system(buf) != 0)
11275 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
11276
11277 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
11278 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
11279 if (system(buf) != 0) {
11280 sigma_dut_print(dut, DUT_MSG_ERROR,
11281 "VI_QOS_TEMP_FILE generation error failed");
11282 }
11283 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11284 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11285 if (system(buf) != 0) {
11286 sigma_dut_print(dut, DUT_MSG_ERROR,
11287 "VI_QOS_FILE generation failed");
11288 }
11289
11290 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11291 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11292 if (system(buf) != 0) {
11293 sigma_dut_print(dut, DUT_MSG_ERROR,
11294 "VI_QOS_FILE generation failed");
11295 }
11296
11297 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
11298 if (system(buf) != 0) {
11299 }
11300}
11301
11302
11303static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11304 struct sigma_cmd *cmd)
11305{
11306 const char *intf = get_param(cmd, "Interface");
11307 const char *val;
11308 int tid = 0;
11309 char buf[100];
11310
11311 val = get_param(cmd, "TID");
11312 if (val) {
11313 tid = atoi(val);
11314 if (tid)
11315 ath_sta_inject_frame(dut, intf, tid);
11316 }
11317
11318 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011319 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011320
11321 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
11322 if (system(buf) != 0) {
11323 sigma_dut_print(dut, DUT_MSG_ERROR,
11324 "wifitool senddelba failed");
11325 }
11326
11327 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
11328 if (system(buf) != 0) {
11329 sigma_dut_print(dut, DUT_MSG_ERROR,
11330 "wifitool sendaddba failed");
11331 }
11332
11333 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11334
11335 return 1;
11336}
11337
11338
Lior David9981b512017-01-20 13:16:40 +020011339#ifdef __linux__
11340
11341static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
11342 int agg_size)
11343{
11344 char dir[128], buf[128];
11345 FILE *f;
11346 regex_t re;
11347 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030011348 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020011349
11350 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
11351 sigma_dut_print(dut, DUT_MSG_ERROR,
11352 "failed to get wil6210 debugfs dir");
11353 return -1;
11354 }
11355
Jouni Malinen3aa72862019-05-29 23:14:51 +030011356 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
11357 if (res < 0 || res >= sizeof(buf))
11358 return -1;
Lior David9981b512017-01-20 13:16:40 +020011359 f = fopen(buf, "r");
11360 if (!f) {
11361 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011362 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030011363 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
11364 if (res < 0 || res >= sizeof(buf))
11365 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011366 f = fopen(buf, "r");
11367 if (!f) {
11368 sigma_dut_print(dut, DUT_MSG_ERROR,
11369 "failed to open: %s", buf);
11370 return -1;
11371 }
Lior David9981b512017-01-20 13:16:40 +020011372 }
11373
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011374 /* can be either VRING tx... or RING... */
11375 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020011376 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
11377 goto out;
11378 }
11379
11380 /* find TX VRING for the mac address */
11381 found = 0;
11382 while (fgets(buf, sizeof(buf), f)) {
11383 if (strcasestr(buf, dest_mac)) {
11384 found = 1;
11385 break;
11386 }
11387 }
11388
11389 if (!found) {
11390 sigma_dut_print(dut, DUT_MSG_ERROR,
11391 "no TX VRING for %s", dest_mac);
11392 goto out;
11393 }
11394
11395 /* extract VRING ID, "VRING tx_<id> = {" */
11396 if (!fgets(buf, sizeof(buf), f)) {
11397 sigma_dut_print(dut, DUT_MSG_ERROR,
11398 "no VRING start line for %s", dest_mac);
11399 goto out;
11400 }
11401
11402 rc = regexec(&re, buf, 2, m, 0);
11403 regfree(&re);
11404 if (rc || m[1].rm_so < 0) {
11405 sigma_dut_print(dut, DUT_MSG_ERROR,
11406 "no VRING TX ID for %s", dest_mac);
11407 goto out;
11408 }
11409 buf[m[1].rm_eo] = 0;
11410 vring_id = atoi(&buf[m[1].rm_so]);
11411
11412 /* send the addba command */
11413 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011414 res = snprintf(buf, sizeof(buf), "%s/back", dir);
11415 if (res < 0 || res >= sizeof(buf))
11416 return -1;
Lior David9981b512017-01-20 13:16:40 +020011417 f = fopen(buf, "w");
11418 if (!f) {
11419 sigma_dut_print(dut, DUT_MSG_ERROR,
11420 "failed to open: %s", buf);
11421 return -1;
11422 }
11423
11424 fprintf(f, "add %d %d\n", vring_id, agg_size);
11425
11426 ret = 0;
11427
11428out:
11429 fclose(f);
11430
11431 return ret;
11432}
11433
11434
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011435int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11436 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011437{
11438 const char *val;
11439 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011440
11441 val = get_param(cmd, "TID");
11442 if (val) {
11443 tid = atoi(val);
11444 if (tid != 0) {
11445 sigma_dut_print(dut, DUT_MSG_ERROR,
11446 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
11447 tid);
11448 }
11449 }
11450
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011451 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011452 if (!val) {
11453 sigma_dut_print(dut, DUT_MSG_ERROR,
11454 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011455 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011456 }
11457
Lior David9981b512017-01-20 13:16:40 +020011458 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011459 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011460
11461 return 1;
11462}
11463
Lior David9981b512017-01-20 13:16:40 +020011464#endif /* __linux__ */
11465
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011466
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011467static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11468 struct sigma_cmd *cmd)
11469{
11470#ifdef NL80211_SUPPORT
11471 const char *intf = get_param(cmd, "Interface");
11472 const char *val;
11473 int tid = -1;
11474 int bufsize = 64;
11475 struct nl_msg *msg;
11476 int ret = 0;
11477 struct nlattr *params;
11478 int ifindex;
11479
11480 val = get_param(cmd, "TID");
11481 if (val)
11482 tid = atoi(val);
11483
11484 if (tid == -1) {
11485 send_resp(dut, conn, SIGMA_ERROR,
11486 "ErrorCode,sta_send_addba tid invalid");
11487 return 0;
11488 }
11489
11490 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11491
11492 ifindex = if_nametoindex(intf);
11493 if (ifindex == 0) {
11494 sigma_dut_print(dut, DUT_MSG_ERROR,
11495 "%s: Index for interface %s failed",
11496 __func__, intf);
11497 send_resp(dut, conn, SIGMA_ERROR,
11498 "ErrorCode,sta_send_addba interface invalid");
11499 return 0;
11500 }
11501
11502 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11503 NL80211_CMD_VENDOR)) ||
11504 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
11505 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
11506 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
11507 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
11508 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
11509 nla_put_u8(msg,
11510 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
11511 QCA_WLAN_ADD_BA) ||
11512 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
11513 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070011514 nla_put_u16(msg,
11515 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
11516 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011517 sigma_dut_print(dut, DUT_MSG_ERROR,
11518 "%s: err in adding vendor_cmd and vendor_data",
11519 __func__);
11520 nlmsg_free(msg);
11521 send_resp(dut, conn, SIGMA_ERROR,
11522 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
11523 return 0;
11524 }
11525 nla_nest_end(msg, params);
11526
11527 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11528 if (ret) {
11529 sigma_dut_print(dut, DUT_MSG_ERROR,
11530 "%s: err in send_and_recv_msgs, ret=%d",
11531 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053011532 if (ret == -EOPNOTSUPP)
11533 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011534 send_resp(dut, conn, SIGMA_ERROR,
11535 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
11536 return 0;
11537 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011538#else /* NL80211_SUPPORT */
11539 sigma_dut_print(dut, DUT_MSG_ERROR,
11540 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011541#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053011542
11543 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011544}
11545
11546
Jouni Malinenf7222712019-06-13 01:50:21 +030011547static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
11548 struct sigma_conn *conn,
11549 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011550{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011551 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011552 case DRIVER_ATHEROS:
11553 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011554 case DRIVER_WCN:
11555 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020011556#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011557 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011558 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020011559#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011560 default:
11561 /*
11562 * There is no driver specific implementation for other drivers.
11563 * Ignore the command and report COMPLETE since the following
11564 * throughput test operation will end up sending ADDBA anyway.
11565 */
11566 return 1;
11567 }
11568}
11569
11570
11571int inject_eth_frame(int s, const void *data, size_t len,
11572 unsigned short ethtype, char *dst, char *src)
11573{
11574 struct iovec iov[4] = {
11575 {
11576 .iov_base = dst,
11577 .iov_len = ETH_ALEN,
11578 },
11579 {
11580 .iov_base = src,
11581 .iov_len = ETH_ALEN,
11582 },
11583 {
11584 .iov_base = &ethtype,
11585 .iov_len = sizeof(unsigned short),
11586 },
11587 {
11588 .iov_base = (void *) data,
11589 .iov_len = len,
11590 }
11591 };
11592 struct msghdr msg = {
11593 .msg_name = NULL,
11594 .msg_namelen = 0,
11595 .msg_iov = iov,
11596 .msg_iovlen = 4,
11597 .msg_control = NULL,
11598 .msg_controllen = 0,
11599 .msg_flags = 0,
11600 };
11601
11602 return sendmsg(s, &msg, 0);
11603}
11604
11605#if defined(__linux__) || defined(__QNXNTO__)
11606
11607int inject_frame(int s, const void *data, size_t len, int encrypt)
11608{
11609#define IEEE80211_RADIOTAP_F_WEP 0x04
11610#define IEEE80211_RADIOTAP_F_FRAG 0x08
11611 unsigned char rtap_hdr[] = {
11612 0x00, 0x00, /* radiotap version */
11613 0x0e, 0x00, /* radiotap length */
11614 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
11615 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
11616 0x00, /* padding */
11617 0x00, 0x00, /* RX and TX flags to indicate that */
11618 0x00, 0x00, /* this is the injected frame directly */
11619 };
11620 struct iovec iov[2] = {
11621 {
11622 .iov_base = &rtap_hdr,
11623 .iov_len = sizeof(rtap_hdr),
11624 },
11625 {
11626 .iov_base = (void *) data,
11627 .iov_len = len,
11628 }
11629 };
11630 struct msghdr msg = {
11631 .msg_name = NULL,
11632 .msg_namelen = 0,
11633 .msg_iov = iov,
11634 .msg_iovlen = 2,
11635 .msg_control = NULL,
11636 .msg_controllen = 0,
11637 .msg_flags = 0,
11638 };
11639
11640 if (encrypt)
11641 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
11642
11643 return sendmsg(s, &msg, 0);
11644}
11645
11646
11647int open_monitor(const char *ifname)
11648{
11649#ifdef __QNXNTO__
11650 struct sockaddr_dl ll;
11651 int s;
11652
11653 memset(&ll, 0, sizeof(ll));
11654 ll.sdl_family = AF_LINK;
11655 ll.sdl_index = if_nametoindex(ifname);
11656 if (ll.sdl_index == 0) {
11657 perror("if_nametoindex");
11658 return -1;
11659 }
11660 s = socket(PF_INET, SOCK_RAW, 0);
11661#else /* __QNXNTO__ */
11662 struct sockaddr_ll ll;
11663 int s;
11664
11665 memset(&ll, 0, sizeof(ll));
11666 ll.sll_family = AF_PACKET;
11667 ll.sll_ifindex = if_nametoindex(ifname);
11668 if (ll.sll_ifindex == 0) {
11669 perror("if_nametoindex");
11670 return -1;
11671 }
11672 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
11673#endif /* __QNXNTO__ */
11674 if (s < 0) {
11675 perror("socket[PF_PACKET,SOCK_RAW]");
11676 return -1;
11677 }
11678
11679 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
11680 perror("monitor socket bind");
11681 close(s);
11682 return -1;
11683 }
11684
11685 return s;
11686}
11687
11688
11689static int hex2num(char c)
11690{
11691 if (c >= '0' && c <= '9')
11692 return c - '0';
11693 if (c >= 'a' && c <= 'f')
11694 return c - 'a' + 10;
11695 if (c >= 'A' && c <= 'F')
11696 return c - 'A' + 10;
11697 return -1;
11698}
11699
11700
11701int hwaddr_aton(const char *txt, unsigned char *addr)
11702{
11703 int i;
11704
11705 for (i = 0; i < 6; i++) {
11706 int a, b;
11707
11708 a = hex2num(*txt++);
11709 if (a < 0)
11710 return -1;
11711 b = hex2num(*txt++);
11712 if (b < 0)
11713 return -1;
11714 *addr++ = (a << 4) | b;
11715 if (i < 5 && *txt++ != ':')
11716 return -1;
11717 }
11718
11719 return 0;
11720}
11721
11722#endif /* defined(__linux__) || defined(__QNXNTO__) */
11723
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011724
11725#ifdef NL80211_SUPPORT
11726static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
11727 const u8 *data, size_t data_len, int freq)
11728{
11729 struct nl_msg *msg;
11730 int ret = 0;
11731 int ifindex;
11732
11733 ifindex = if_nametoindex(intf);
11734 if (ifindex == 0) {
11735 sigma_dut_print(dut, DUT_MSG_ERROR,
11736 "%s: Index for interface %s failed",
11737 __func__, intf);
11738 return -1;
11739 }
11740
11741 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11742 NL80211_CMD_FRAME)) ||
11743 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11744 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
11745 sigma_dut_print(dut, DUT_MSG_ERROR,
11746 "%s: Error in adding NL80211_CMD_FRAME",
11747 __func__);
11748 nlmsg_free(msg);
11749 return -1;
11750 }
11751
11752 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11753 if (ret) {
11754 sigma_dut_print(dut, DUT_MSG_ERROR,
11755 "nl80211: Frame command failed: ret=%d (%s) req=%u",
11756 ret, strerror(-ret), freq);
11757 return -1;
11758 }
11759
11760 return 0;
11761}
11762#endif /* NL80211_SUPPORT */
11763
11764
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011765enum send_frame_type {
11766 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
11767};
11768enum send_frame_protection {
11769 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
11770};
11771
11772
11773static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011774 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011775 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011776 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011777{
11778#ifdef __linux__
11779 unsigned char buf[1000], *pos;
11780 int s, res;
11781 char bssid[20], addr[20];
11782 char result[32], ssid[100];
11783 size_t ssid_len;
11784
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011785 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011786 sizeof(result)) < 0 ||
11787 strncmp(result, "COMPLETED", 9) != 0) {
11788 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
11789 return 0;
11790 }
11791
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011792 if (get_wpa_status(get_station_ifname(dut), "bssid",
11793 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011794 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11795 "current BSSID");
11796 return 0;
11797 }
11798
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011799 if (get_wpa_status(get_station_ifname(dut), "address",
11800 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011801 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11802 "own MAC address");
11803 return 0;
11804 }
11805
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011806 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011807 < 0) {
11808 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11809 "current SSID");
11810 return 0;
11811 }
11812 ssid_len = strlen(ssid);
11813
11814 pos = buf;
11815
11816 /* Frame Control */
11817 switch (frame) {
11818 case DISASSOC:
11819 *pos++ = 0xa0;
11820 break;
11821 case DEAUTH:
11822 *pos++ = 0xc0;
11823 break;
11824 case SAQUERY:
11825 *pos++ = 0xd0;
11826 break;
11827 case AUTH:
11828 *pos++ = 0xb0;
11829 break;
11830 case ASSOCREQ:
11831 *pos++ = 0x00;
11832 break;
11833 case REASSOCREQ:
11834 *pos++ = 0x20;
11835 break;
11836 case DLS_REQ:
11837 *pos++ = 0xd0;
11838 break;
11839 }
11840
11841 if (protected == INCORRECT_KEY)
11842 *pos++ = 0x40; /* Set Protected field to 1 */
11843 else
11844 *pos++ = 0x00;
11845
11846 /* Duration */
11847 *pos++ = 0x00;
11848 *pos++ = 0x00;
11849
11850 /* addr1 = DA (current AP) */
11851 hwaddr_aton(bssid, pos);
11852 pos += 6;
11853 /* addr2 = SA (own address) */
11854 hwaddr_aton(addr, pos);
11855 pos += 6;
11856 /* addr3 = BSSID (current AP) */
11857 hwaddr_aton(bssid, pos);
11858 pos += 6;
11859
11860 /* Seq# (to be filled by driver/mac80211) */
11861 *pos++ = 0x00;
11862 *pos++ = 0x00;
11863
11864 if (protected == INCORRECT_KEY) {
11865 /* CCMP parameters */
11866 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
11867 pos += 8;
11868 }
11869
11870 if (protected == INCORRECT_KEY) {
11871 switch (frame) {
11872 case DEAUTH:
11873 /* Reason code (encrypted) */
11874 memcpy(pos, "\xa7\x39", 2);
11875 pos += 2;
11876 break;
11877 case DISASSOC:
11878 /* Reason code (encrypted) */
11879 memcpy(pos, "\xa7\x39", 2);
11880 pos += 2;
11881 break;
11882 case SAQUERY:
11883 /* Category|Action|TransID (encrypted) */
11884 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
11885 pos += 4;
11886 break;
11887 default:
11888 return -1;
11889 }
11890
11891 /* CCMP MIC */
11892 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
11893 pos += 8;
11894 } else {
11895 switch (frame) {
11896 case DEAUTH:
11897 /* reason code = 8 */
11898 *pos++ = 0x08;
11899 *pos++ = 0x00;
11900 break;
11901 case DISASSOC:
11902 /* reason code = 8 */
11903 *pos++ = 0x08;
11904 *pos++ = 0x00;
11905 break;
11906 case SAQUERY:
11907 /* Category - SA Query */
11908 *pos++ = 0x08;
11909 /* SA query Action - Request */
11910 *pos++ = 0x00;
11911 /* Transaction ID */
11912 *pos++ = 0x12;
11913 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011914 if (dut->saquery_oci_freq) {
11915 /* OCI IE - Extended ID */
11916 *pos++ = 0xFF;
11917 *pos++ = 0x04;
11918 *pos++ = 0x36;
11919 /* Operating Class */
11920 *pos++ = 0x74;
11921 /* Primary Channel */
11922 *pos++ = freq_to_channel(dut->saquery_oci_freq);
11923 /* Frequency Segment 1 Channel Number */
11924 *pos++ = 0x00;
11925 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011926 break;
11927 case AUTH:
11928 /* Auth Alg (Open) */
11929 *pos++ = 0x00;
11930 *pos++ = 0x00;
11931 /* Seq# */
11932 *pos++ = 0x01;
11933 *pos++ = 0x00;
11934 /* Status code */
11935 *pos++ = 0x00;
11936 *pos++ = 0x00;
11937 break;
11938 case ASSOCREQ:
11939 /* Capability Information */
11940 *pos++ = 0x31;
11941 *pos++ = 0x04;
11942 /* Listen Interval */
11943 *pos++ = 0x0a;
11944 *pos++ = 0x00;
11945 /* SSID */
11946 *pos++ = 0x00;
11947 *pos++ = ssid_len;
11948 memcpy(pos, ssid, ssid_len);
11949 pos += ssid_len;
11950 /* Supported Rates */
11951 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11952 10);
11953 pos += 10;
11954 /* Extended Supported Rates */
11955 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11956 pos += 6;
11957 /* RSN */
11958 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
11959 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
11960 "\x00\x00\x00\x00\x0f\xac\x06", 28);
11961 pos += 28;
11962 break;
11963 case REASSOCREQ:
11964 /* Capability Information */
11965 *pos++ = 0x31;
11966 *pos++ = 0x04;
11967 /* Listen Interval */
11968 *pos++ = 0x0a;
11969 *pos++ = 0x00;
11970 /* Current AP */
11971 hwaddr_aton(bssid, pos);
11972 pos += 6;
11973 /* SSID */
11974 *pos++ = 0x00;
11975 *pos++ = ssid_len;
11976 memcpy(pos, ssid, ssid_len);
11977 pos += ssid_len;
11978 /* Supported Rates */
11979 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11980 10);
11981 pos += 10;
11982 /* Extended Supported Rates */
11983 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11984 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011985 /* RSNE - Group and Pairwise ciphers */
11986 memcpy(pos,
11987 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
11988 14);
11989 pos += 14;
11990 /* RSNE - AKM Suite count */
11991 *pos++ = 0x01;
11992 *pos++ = 0x00;
11993 /* RSNE - AKM Suites */
11994 if (dut->program == PROGRAM_WPA3)
11995 memcpy(pos, "\x00\x0f\xac\x08", 4);
11996 else
11997 memcpy(pos, "\x00\x0f\xac\x02", 4);
11998 pos += 4;
11999 /* RSNE - Capabilities */
12000 *pos++ = 0xc0;
12001 if (dut->ocvc)
12002 *pos++ = 0x40;
12003 else
12004 *pos++ = 0x00;
12005 /* RSNE - PMKID list and Group Management Ciphers */
12006 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
12007 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012008 break;
12009 case DLS_REQ:
12010 /* Category - DLS */
12011 *pos++ = 0x02;
12012 /* DLS Action - Request */
12013 *pos++ = 0x00;
12014 /* Destination MACAddress */
12015 if (dest)
12016 hwaddr_aton(dest, pos);
12017 else
12018 memset(pos, 0, 6);
12019 pos += 6;
12020 /* Source MACAddress */
12021 hwaddr_aton(addr, pos);
12022 pos += 6;
12023 /* Capability Information */
12024 *pos++ = 0x10; /* Privacy */
12025 *pos++ = 0x06; /* QoS */
12026 /* DLS Timeout Value */
12027 *pos++ = 0x00;
12028 *pos++ = 0x01;
12029 /* Supported rates */
12030 *pos++ = 0x01;
12031 *pos++ = 0x08;
12032 *pos++ = 0x0c; /* 6 Mbps */
12033 *pos++ = 0x12; /* 9 Mbps */
12034 *pos++ = 0x18; /* 12 Mbps */
12035 *pos++ = 0x24; /* 18 Mbps */
12036 *pos++ = 0x30; /* 24 Mbps */
12037 *pos++ = 0x48; /* 36 Mbps */
12038 *pos++ = 0x60; /* 48 Mbps */
12039 *pos++ = 0x6c; /* 54 Mbps */
12040 /* TODO: Extended Supported Rates */
12041 /* TODO: HT Capabilities */
12042 break;
12043 }
12044 }
12045
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012046 if (use_monitor) {
12047 s = open_monitor("sigmadut");
12048 if (s < 0) {
12049 send_resp(dut, conn, SIGMA_ERROR,
12050 "errorCode,Failed to open monitor socket");
12051 return 0;
12052 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012053
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012054 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
12055 if (res < 0) {
12056 send_resp(dut, conn, SIGMA_ERROR,
12057 "errorCode,Failed to inject frame");
12058 close(s);
12059 return 0;
12060 }
12061 if (res < pos - buf) {
12062 send_resp(dut, conn, SIGMA_ERROR,
12063 "errorCode,Only partial frame sent");
12064 close(s);
12065 return 0;
12066 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012067
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012068 close(s);
12069 } else {
12070#ifdef NL80211_SUPPORT
12071 int freq;
12072 char freq_str[10];
12073
12074 if (get_wpa_status(get_station_ifname(dut), "freq",
12075 freq_str, sizeof(freq_str)) < 0) {
12076 send_resp(dut, conn, SIGMA_ERROR,
12077 "errorCode,Could not get current operating frequency");
12078 return 0;
12079 }
12080 freq = atoi(freq_str);
12081
12082 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
12083 send_resp(dut, conn, SIGMA_ERROR,
12084 "errorCode,Failed to inject frame");
12085 return 0;
12086 }
12087#else /* NL80211_SUPPORT */
12088 send_resp(dut, conn, SIGMA_ERROR,
12089 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
12090 return 0;
12091#endif /* NL80211_SUPPORT */
12092 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012093
12094 return 1;
12095#else /* __linux__ */
12096 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
12097 "yet supported");
12098 return 0;
12099#endif /* __linux__ */
12100}
12101
12102
12103static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
12104 struct sigma_conn *conn,
12105 struct sigma_cmd *cmd)
12106{
12107 const char *intf = get_param(cmd, "Interface");
12108 const char *sta, *val;
12109 unsigned char addr[ETH_ALEN];
12110 char buf[100];
12111
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012112 if (!intf)
12113 return -1;
12114
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012115 sta = get_param(cmd, "peer");
12116 if (sta == NULL)
12117 sta = get_param(cmd, "station");
12118 if (sta == NULL) {
12119 send_resp(dut, conn, SIGMA_ERROR,
12120 "ErrorCode,Missing peer address");
12121 return 0;
12122 }
12123 if (hwaddr_aton(sta, addr) < 0) {
12124 send_resp(dut, conn, SIGMA_ERROR,
12125 "ErrorCode,Invalid peer address");
12126 return 0;
12127 }
12128
12129 val = get_param(cmd, "type");
12130 if (val == NULL)
12131 return -1;
12132
12133 if (strcasecmp(val, "DISCOVERY") == 0) {
12134 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
12135 if (wpa_command(intf, buf) < 0) {
12136 send_resp(dut, conn, SIGMA_ERROR,
12137 "ErrorCode,Failed to send TDLS discovery");
12138 return 0;
12139 }
12140 return 1;
12141 }
12142
12143 if (strcasecmp(val, "SETUP") == 0) {
12144 int status = 0, timeout = 0;
12145
12146 val = get_param(cmd, "Status");
12147 if (val)
12148 status = atoi(val);
12149
12150 val = get_param(cmd, "Timeout");
12151 if (val)
12152 timeout = atoi(val);
12153
12154 if (status != 0 && status != 37) {
12155 send_resp(dut, conn, SIGMA_ERROR,
12156 "ErrorCode,Unsupported status value");
12157 return 0;
12158 }
12159
12160 if (timeout != 0 && timeout != 301) {
12161 send_resp(dut, conn, SIGMA_ERROR,
12162 "ErrorCode,Unsupported timeout value");
12163 return 0;
12164 }
12165
12166 if (status && timeout) {
12167 send_resp(dut, conn, SIGMA_ERROR,
12168 "ErrorCode,Unsupported timeout+status "
12169 "combination");
12170 return 0;
12171 }
12172
12173 if (status == 37 &&
12174 wpa_command(intf, "SET tdls_testing 0x200")) {
12175 send_resp(dut, conn, SIGMA_ERROR,
12176 "ErrorCode,Failed to enable "
12177 "decline setup response test mode");
12178 return 0;
12179 }
12180
12181 if (timeout == 301) {
12182 int res;
12183 if (dut->no_tpk_expiration)
12184 res = wpa_command(intf,
12185 "SET tdls_testing 0x108");
12186 else
12187 res = wpa_command(intf,
12188 "SET tdls_testing 0x8");
12189 if (res) {
12190 send_resp(dut, conn, SIGMA_ERROR,
12191 "ErrorCode,Failed to set short TPK "
12192 "lifetime");
12193 return 0;
12194 }
12195 }
12196
12197 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
12198 if (wpa_command(intf, buf) < 0) {
12199 send_resp(dut, conn, SIGMA_ERROR,
12200 "ErrorCode,Failed to send TDLS setup");
12201 return 0;
12202 }
12203 return 1;
12204 }
12205
12206 if (strcasecmp(val, "TEARDOWN") == 0) {
12207 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
12208 if (wpa_command(intf, buf) < 0) {
12209 send_resp(dut, conn, SIGMA_ERROR,
12210 "ErrorCode,Failed to send TDLS teardown");
12211 return 0;
12212 }
12213 return 1;
12214 }
12215
12216 send_resp(dut, conn, SIGMA_ERROR,
12217 "ErrorCode,Unsupported TDLS frame");
12218 return 0;
12219}
12220
12221
12222static int sta_ap_known(const char *ifname, const char *bssid)
12223{
12224 char buf[4096];
12225
Jouni Malinendd32f192018-09-15 02:55:19 +030012226 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012227 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
12228 return 0;
12229 if (strncmp(buf, "id=", 3) != 0)
12230 return 0;
12231 return 1;
12232}
12233
12234
12235static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
12236 const char *bssid)
12237{
12238 int res;
12239 struct wpa_ctrl *ctrl;
12240 char buf[256];
12241
12242 if (sta_ap_known(ifname, bssid))
12243 return 0;
12244 sigma_dut_print(dut, DUT_MSG_DEBUG,
12245 "AP not in BSS table - start scan");
12246
12247 ctrl = open_wpa_mon(ifname);
12248 if (ctrl == NULL) {
12249 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12250 "wpa_supplicant monitor connection");
12251 return -1;
12252 }
12253
12254 if (wpa_command(ifname, "SCAN") < 0) {
12255 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
12256 wpa_ctrl_detach(ctrl);
12257 wpa_ctrl_close(ctrl);
12258 return -1;
12259 }
12260
12261 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12262 buf, sizeof(buf));
12263
12264 wpa_ctrl_detach(ctrl);
12265 wpa_ctrl_close(ctrl);
12266
12267 if (res < 0) {
12268 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
12269 return -1;
12270 }
12271
12272 if (sta_ap_known(ifname, bssid))
12273 return 0;
12274 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
12275 return -1;
12276}
12277
12278
12279static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
12280 struct sigma_conn *conn,
12281 struct sigma_cmd *cmd,
12282 const char *intf)
12283{
12284 char buf[200];
12285
12286 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
12287 if (system(buf) != 0) {
12288 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
12289 "ndsend");
12290 return 0;
12291 }
12292
12293 return 1;
12294}
12295
12296
12297static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
12298 struct sigma_conn *conn,
12299 struct sigma_cmd *cmd,
12300 const char *intf)
12301{
12302 char buf[200];
12303 const char *ip = get_param(cmd, "SenderIP");
12304
Peng Xu26b356d2017-10-04 17:58:16 -070012305 if (!ip)
12306 return 0;
12307
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012308 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
12309 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12310 if (system(buf) == 0) {
12311 sigma_dut_print(dut, DUT_MSG_INFO,
12312 "Neighbor Solicitation got a response "
12313 "for %s@%s", ip, intf);
12314 }
12315
12316 return 1;
12317}
12318
12319
12320static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
12321 struct sigma_conn *conn,
12322 struct sigma_cmd *cmd,
12323 const char *ifname)
12324{
12325 char buf[200];
12326 const char *ip = get_param(cmd, "SenderIP");
12327
12328 if (ip == NULL) {
12329 send_resp(dut, conn, SIGMA_ERROR,
12330 "ErrorCode,Missing SenderIP parameter");
12331 return 0;
12332 }
12333 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
12334 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12335 if (system(buf) != 0) {
12336 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
12337 "for %s@%s", ip, ifname);
12338 }
12339
12340 return 1;
12341}
12342
12343
12344static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
12345 struct sigma_conn *conn,
12346 struct sigma_cmd *cmd,
12347 const char *ifname)
12348{
12349 char buf[200];
12350 char ip[16];
12351 int s;
Peng Xub3756882017-10-04 14:39:09 -070012352 struct ifreq ifr;
12353 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012354
12355 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070012356 if (s < 0) {
12357 perror("socket");
12358 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012359 }
12360
Peng Xub3756882017-10-04 14:39:09 -070012361 memset(&ifr, 0, sizeof(ifr));
12362 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
12363 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
12364 sigma_dut_print(dut, DUT_MSG_INFO,
12365 "Failed to get %s IP address: %s",
12366 ifname, strerror(errno));
12367 close(s);
12368 return -1;
12369 }
12370 close(s);
12371
12372 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
12373 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
12374
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012375 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
12376 ip);
12377 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12378 if (system(buf) != 0) {
12379 }
12380
12381 return 1;
12382}
12383
12384
12385static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
12386 struct sigma_conn *conn,
12387 struct sigma_cmd *cmd,
12388 const char *ifname)
12389{
12390 char buf[200], addr[20];
12391 char dst[ETH_ALEN], src[ETH_ALEN];
12392 short ethtype = htons(ETH_P_ARP);
12393 char *pos;
12394 int s, res;
12395 const char *val;
12396 struct sockaddr_in taddr;
12397
12398 val = get_param(cmd, "dest");
12399 if (val)
12400 hwaddr_aton(val, (unsigned char *) dst);
12401
12402 val = get_param(cmd, "DestIP");
12403 if (val)
12404 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070012405 else
12406 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012407
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012408 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012409 sizeof(addr)) < 0)
12410 return -2;
12411 hwaddr_aton(addr, (unsigned char *) src);
12412
12413 pos = buf;
12414 *pos++ = 0x00;
12415 *pos++ = 0x01;
12416 *pos++ = 0x08;
12417 *pos++ = 0x00;
12418 *pos++ = 0x06;
12419 *pos++ = 0x04;
12420 *pos++ = 0x00;
12421 *pos++ = 0x02;
12422 memcpy(pos, src, ETH_ALEN);
12423 pos += ETH_ALEN;
12424 memcpy(pos, &taddr.sin_addr, 4);
12425 pos += 4;
12426 memcpy(pos, dst, ETH_ALEN);
12427 pos += ETH_ALEN;
12428 memcpy(pos, &taddr.sin_addr, 4);
12429 pos += 4;
12430
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012431 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012432 if (s < 0) {
12433 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
12434 "monitor socket");
12435 return 0;
12436 }
12437
12438 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
12439 if (res < 0) {
12440 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
12441 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053012442 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012443 return 0;
12444 }
12445
12446 close(s);
12447
12448 return 1;
12449}
12450
12451
12452static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
12453 struct sigma_conn *conn,
12454 struct sigma_cmd *cmd,
12455 const char *intf, const char *dest)
12456{
12457 char buf[100];
12458
12459 if (if_nametoindex("sigmadut") == 0) {
12460 snprintf(buf, sizeof(buf),
12461 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012462 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012463 if (system(buf) != 0 ||
12464 if_nametoindex("sigmadut") == 0) {
12465 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12466 "monitor interface with '%s'", buf);
12467 return -2;
12468 }
12469 }
12470
12471 if (system("ifconfig sigmadut up") != 0) {
12472 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12473 "monitor interface up");
12474 return -2;
12475 }
12476
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012477 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012478}
12479
12480
12481static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
12482 struct sigma_conn *conn,
12483 struct sigma_cmd *cmd)
12484{
12485 const char *intf = get_param(cmd, "Interface");
12486 const char *dest = get_param(cmd, "Dest");
12487 const char *type = get_param(cmd, "FrameName");
12488 const char *val;
12489 char buf[200], *pos, *end;
12490 int count, count2;
12491
12492 if (type == NULL)
12493 type = get_param(cmd, "Type");
12494
12495 if (intf == NULL || dest == NULL || type == NULL)
12496 return -1;
12497
12498 if (strcasecmp(type, "NeighAdv") == 0)
12499 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
12500
12501 if (strcasecmp(type, "NeighSolicitReq") == 0)
12502 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
12503
12504 if (strcasecmp(type, "ARPProbe") == 0)
12505 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
12506
12507 if (strcasecmp(type, "ARPAnnounce") == 0)
12508 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
12509
12510 if (strcasecmp(type, "ARPReply") == 0)
12511 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
12512
12513 if (strcasecmp(type, "DLS-request") == 0 ||
12514 strcasecmp(type, "DLSrequest") == 0)
12515 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
12516 dest);
12517
12518 if (strcasecmp(type, "ANQPQuery") != 0 &&
12519 strcasecmp(type, "Query") != 0) {
12520 send_resp(dut, conn, SIGMA_ERROR,
12521 "ErrorCode,Unsupported HS 2.0 send frame type");
12522 return 0;
12523 }
12524
12525 if (sta_scan_ap(dut, intf, dest) < 0) {
12526 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
12527 "the requested AP");
12528 return 0;
12529 }
12530
12531 pos = buf;
12532 end = buf + sizeof(buf);
12533 count = 0;
12534 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
12535
12536 val = get_param(cmd, "ANQP_CAP_LIST");
12537 if (val && atoi(val)) {
12538 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
12539 count++;
12540 }
12541
12542 val = get_param(cmd, "VENUE_NAME");
12543 if (val && atoi(val)) {
12544 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
12545 count++;
12546 }
12547
12548 val = get_param(cmd, "NETWORK_AUTH_TYPE");
12549 if (val && atoi(val)) {
12550 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
12551 count++;
12552 }
12553
12554 val = get_param(cmd, "ROAMING_CONS");
12555 if (val && atoi(val)) {
12556 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
12557 count++;
12558 }
12559
12560 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
12561 if (val && atoi(val)) {
12562 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
12563 count++;
12564 }
12565
12566 val = get_param(cmd, "NAI_REALM_LIST");
12567 if (val && atoi(val)) {
12568 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
12569 count++;
12570 }
12571
12572 val = get_param(cmd, "3GPP_INFO");
12573 if (val && atoi(val)) {
12574 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
12575 count++;
12576 }
12577
12578 val = get_param(cmd, "DOMAIN_LIST");
12579 if (val && atoi(val)) {
12580 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
12581 count++;
12582 }
12583
Jouni Malinen34cf9532018-04-29 19:26:33 +030012584 val = get_param(cmd, "Venue_URL");
12585 if (val && atoi(val)) {
12586 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
12587 count++;
12588 }
12589
Jouni Malinend3bca5d2018-04-29 17:25:23 +030012590 val = get_param(cmd, "Advice_Of_Charge");
12591 if (val && atoi(val)) {
12592 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
12593 count++;
12594 }
12595
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012596 if (count && wpa_command(intf, buf)) {
12597 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
12598 return 0;
12599 }
12600
12601 pos = buf;
12602 end = buf + sizeof(buf);
12603 count2 = 0;
12604 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
12605
12606 val = get_param(cmd, "HS_CAP_LIST");
12607 if (val && atoi(val)) {
12608 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
12609 count2++;
12610 }
12611
12612 val = get_param(cmd, "OPER_NAME");
12613 if (val && atoi(val)) {
12614 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
12615 count2++;
12616 }
12617
12618 val = get_param(cmd, "WAN_METRICS");
12619 if (!val)
12620 val = get_param(cmd, "WAN_MAT");
12621 if (!val)
12622 val = get_param(cmd, "WAN_MET");
12623 if (val && atoi(val)) {
12624 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
12625 count2++;
12626 }
12627
12628 val = get_param(cmd, "CONNECTION_CAPABILITY");
12629 if (val && atoi(val)) {
12630 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
12631 count2++;
12632 }
12633
12634 val = get_param(cmd, "OP_CLASS");
12635 if (val && atoi(val)) {
12636 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
12637 count2++;
12638 }
12639
12640 val = get_param(cmd, "OSU_PROVIDER_LIST");
12641 if (val && atoi(val)) {
12642 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
12643 count2++;
12644 }
12645
Jouni Malinenf67afec2018-04-29 19:24:58 +030012646 val = get_param(cmd, "OPER_ICON_METADATA");
12647 if (!val)
12648 val = get_param(cmd, "OPERATOR_ICON_METADATA");
12649 if (val && atoi(val)) {
12650 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
12651 count2++;
12652 }
12653
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012654 if (count && count2) {
12655 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
12656 "second query");
12657 sleep(1);
12658 }
12659
12660 if (count2 && wpa_command(intf, buf)) {
12661 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
12662 "failed");
12663 return 0;
12664 }
12665
12666 val = get_param(cmd, "NAI_HOME_REALM_LIST");
12667 if (val) {
12668 if (count || count2) {
12669 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12670 "sending out second query");
12671 sleep(1);
12672 }
12673
12674 if (strcmp(val, "1") == 0)
12675 val = "mail.example.com";
12676 snprintf(buf, end - pos,
12677 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
12678 dest, val);
12679 if (wpa_command(intf, buf)) {
12680 send_resp(dut, conn, SIGMA_ERROR,
12681 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
12682 "failed");
12683 return 0;
12684 }
12685 }
12686
12687 val = get_param(cmd, "ICON_REQUEST");
12688 if (val) {
12689 if (count || count2) {
12690 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12691 "sending out second query");
12692 sleep(1);
12693 }
12694
12695 snprintf(buf, end - pos,
12696 "HS20_ICON_REQUEST %s %s", dest, val);
12697 if (wpa_command(intf, buf)) {
12698 send_resp(dut, conn, SIGMA_ERROR,
12699 "ErrorCode,HS20_ICON_REQUEST failed");
12700 return 0;
12701 }
12702 }
12703
12704 return 1;
12705}
12706
12707
12708static int ath_sta_send_frame_vht(struct sigma_dut *dut,
12709 struct sigma_conn *conn,
12710 struct sigma_cmd *cmd)
12711{
12712 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012713 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012714 int chwidth, nss;
12715
12716 val = get_param(cmd, "framename");
12717 if (!val)
12718 return -1;
12719 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12720
12721 /* Command sequence to generate Op mode notification */
12722 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012723 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012724
12725 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012726 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012727
12728 /* Extract Channel width */
12729 val = get_param(cmd, "Channel_width");
12730 if (val) {
12731 switch (atoi(val)) {
12732 case 20:
12733 chwidth = 0;
12734 break;
12735 case 40:
12736 chwidth = 1;
12737 break;
12738 case 80:
12739 chwidth = 2;
12740 break;
12741 case 160:
12742 chwidth = 3;
12743 break;
12744 default:
12745 chwidth = 2;
12746 break;
12747 }
12748
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012749 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012750 }
12751
12752 /* Extract NSS */
12753 val = get_param(cmd, "NSS");
12754 if (val) {
12755 switch (atoi(val)) {
12756 case 1:
12757 nss = 1;
12758 break;
12759 case 2:
12760 nss = 3;
12761 break;
12762 case 3:
12763 nss = 7;
12764 break;
12765 default:
12766 /* We do not support NSS > 3 */
12767 nss = 3;
12768 break;
12769 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012770 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012771 }
12772
12773 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012774 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012775 }
12776
12777 return 1;
12778}
12779
12780
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012781static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
12782 enum send_frame_protection protected)
12783{
12784#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012785 return wcn_wifi_test_config_set_u8(
12786 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
12787 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012788#else /* NL80211_SUPPORT */
12789 sigma_dut_print(dut, DUT_MSG_ERROR,
12790 "PMF config cannot be set without NL80211_SUPPORT defined");
12791 return -1;
12792#endif /* NL80211_SUPPORT */
12793}
12794
12795
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012796static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
12797 struct sigma_conn *conn,
12798 struct sigma_cmd *cmd)
12799{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012800 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012801 case DRIVER_ATHEROS:
12802 return ath_sta_send_frame_vht(dut, conn, cmd);
12803 default:
12804 send_resp(dut, conn, SIGMA_ERROR,
12805 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
12806 return 0;
12807 }
12808}
12809
12810
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012811static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
12812{
12813#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012814 return wcn_wifi_test_config_set_flag(
12815 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012816#else /* NL80211_SUPPORT */
12817 sigma_dut_print(dut, DUT_MSG_ERROR,
12818 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
12819 return -1;
12820#endif /* NL80211_SUPPORT */
12821}
12822
12823
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012824static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
12825 struct sigma_cmd *cmd)
12826{
12827 const char *val;
12828 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012829 enum send_frame_protection protected;
12830 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012831
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012832 if (!intf)
12833 return -1;
12834
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012835 val = get_param(cmd, "framename");
12836 if (!val)
12837 return -1;
12838 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12839
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012840 pmf = get_param(cmd, "PMFProtected");
12841 if (!pmf)
12842 pmf = get_param(cmd, "Protected");
12843 if (pmf) {
12844 if (strcasecmp(pmf, "Correct-key") == 0 ||
12845 strcasecmp(pmf, "CorrectKey") == 0) {
12846 protected = CORRECT_KEY;
12847 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
12848 protected = INCORRECT_KEY;
12849 } else if (strcasecmp(pmf, "Unprotected") == 0) {
12850 protected = UNPROTECTED;
12851 } else {
12852 send_resp(dut, conn, SIGMA_ERROR,
12853 "errorCode,Unsupported PMFProtected");
12854 return STATUS_SENT_ERROR;
12855 }
12856 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
12857 protected);
12858 wcn_sta_set_pmf_config(dut, intf, protected);
12859 }
12860
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012861 /* Command sequence to generate Op mode notification */
12862 if (val && strcasecmp(val, "action") == 0) {
12863 val = get_param(cmd, "PPDUTxType");
12864 if (val && strcasecmp(val, "TB") == 0) {
12865 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
12866 sigma_dut_print(dut, DUT_MSG_ERROR,
12867 "failed to send TB PPDU Tx cfg");
12868 send_resp(dut, conn, SIGMA_ERROR,
12869 "ErrorCode,set TB PPDU Tx cfg failed");
12870 return 0;
12871 }
12872 return 1;
12873 }
12874
12875 sigma_dut_print(dut, DUT_MSG_ERROR,
12876 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012877
12878 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012879 }
12880
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012881 if (strcasecmp(val, "disassoc") == 0)
12882 wcn_sta_send_disassoc(dut, intf);
12883
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012884 return 1;
12885}
12886
12887
12888static int cmd_sta_send_frame_he(struct sigma_dut *dut,
12889 struct sigma_conn *conn,
12890 struct sigma_cmd *cmd)
12891{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012892 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012893 case DRIVER_WCN:
12894 return wcn_sta_send_frame_he(dut, conn, cmd);
12895 default:
12896 send_resp(dut, conn, SIGMA_ERROR,
12897 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
12898 return 0;
12899 }
12900}
12901
12902
Lior David0fe101e2017-03-09 16:09:50 +020012903#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012904
12905static int
12906wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
12907 const char *frame_name, const char *dest_mac)
12908{
12909 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
12910 const char *ssid = get_param(cmd, "ssid");
12911 const char *countstr = get_param(cmd, "count");
12912 const char *channelstr = get_param(cmd, "channel");
12913 const char *group_id = get_param(cmd, "groupid");
12914 const char *client_id = get_param(cmd, "clientmac");
12915 int count, channel, freq, i;
12916 const char *fname;
12917 char frame[1024], src_mac[20], group_id_attr[25],
12918 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
12919 const char *group_ssid;
12920 const int group_ssid_prefix_len = 9;
12921 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
12922 size_t framelen = sizeof(frame);
12923 struct template_frame_tag tags[2];
12924 size_t tags_total = ARRAY_SIZE(tags);
12925 int tag_index, len, dst_len;
12926
12927 if (!countstr || !channelstr) {
12928 sigma_dut_print(dut, DUT_MSG_ERROR,
12929 "Missing argument: count, channel");
12930 return -1;
12931 }
12932 if (isprobereq && !ssid) {
12933 sigma_dut_print(dut, DUT_MSG_ERROR,
12934 "Missing argument: ssid");
12935 return -1;
12936 }
12937 if (!isprobereq && (!group_id || !client_id)) {
12938 sigma_dut_print(dut, DUT_MSG_ERROR,
12939 "Missing argument: group_id, client_id");
12940 return -1;
12941 }
12942
12943 count = atoi(countstr);
12944 channel = atoi(channelstr);
12945 freq = channel_to_freq(dut, channel);
12946
12947 if (!freq) {
12948 sigma_dut_print(dut, DUT_MSG_ERROR,
12949 "invalid channel: %s", channelstr);
12950 return -1;
12951 }
12952
12953 if (isprobereq) {
12954 if (strcasecmp(ssid, "wildcard") == 0) {
12955 fname = "probe_req_wildcard.txt";
12956 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
12957 fname = "probe_req_P2P_Wildcard.txt";
12958 } else {
12959 sigma_dut_print(dut, DUT_MSG_ERROR,
12960 "invalid probe request type");
12961 return -1;
12962 }
12963 } else {
12964 fname = "P2P_device_discovery_req.txt";
12965 }
12966
12967 if (parse_template_frame_file(dut, fname, frame, &framelen,
12968 tags, &tags_total)) {
12969 sigma_dut_print(dut, DUT_MSG_ERROR,
12970 "invalid frame template: %s", fname);
12971 return -1;
12972 }
12973
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012974 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012975 src_mac, sizeof(src_mac)) < 0 ||
12976 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
12977 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
12978 return -1;
12979 /* Use wildcard BSSID, since we are in PBSS */
12980 memset(&hdr->addr3, 0xFF, ETH_ALEN);
12981
12982 if (!isprobereq) {
12983 tag_index = find_template_frame_tag(tags, tags_total, 1);
12984 if (tag_index < 0) {
12985 sigma_dut_print(dut, DUT_MSG_ERROR,
12986 "can't find device id attribute");
12987 return -1;
12988 }
12989 if (parse_mac_address(dut, client_id,
12990 (unsigned char *) client_mac)) {
12991 sigma_dut_print(dut, DUT_MSG_ERROR,
12992 "invalid client_id: %s", client_id);
12993 return -1;
12994 }
12995 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
12996 framelen - tags[tag_index].offset,
12997 IEEE80211_P2P_ATTR_DEVICE_ID,
12998 client_mac, ETH_ALEN)) {
12999 sigma_dut_print(dut, DUT_MSG_ERROR,
13000 "fail to replace device id attribute");
13001 return -1;
13002 }
13003
13004 /*
13005 * group_id arg contains device MAC address followed by
13006 * space and SSID (DIRECT-somessid).
13007 * group id attribute contains device address (6 bytes)
13008 * followed by SSID prefix DIRECT-XX (9 bytes)
13009 */
13010 if (strlen(group_id) < sizeof(device_macstr)) {
13011 sigma_dut_print(dut, DUT_MSG_ERROR,
13012 "group_id arg too short");
13013 return -1;
13014 }
13015 memcpy(device_macstr, group_id, sizeof(device_macstr));
13016 device_macstr[sizeof(device_macstr) - 1] = '\0';
13017 if (parse_mac_address(dut, device_macstr,
13018 (unsigned char *) group_id_attr)) {
13019 sigma_dut_print(dut, DUT_MSG_ERROR,
13020 "fail to parse device address from group_id");
13021 return -1;
13022 }
13023 group_ssid = strchr(group_id, ' ');
13024 if (!group_ssid) {
13025 sigma_dut_print(dut, DUT_MSG_ERROR,
13026 "invalid group_id arg, no ssid");
13027 return -1;
13028 }
13029 group_ssid++;
13030 len = strlen(group_ssid);
13031 if (len < group_ssid_prefix_len) {
13032 sigma_dut_print(dut, DUT_MSG_ERROR,
13033 "group_id SSID too short");
13034 return -1;
13035 }
13036 dst_len = sizeof(group_id_attr) - ETH_ALEN;
13037 if (len > dst_len) {
13038 sigma_dut_print(dut, DUT_MSG_ERROR,
13039 "group_id SSID (%s) too long",
13040 group_ssid);
13041 return -1;
13042 }
13043
13044 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
13045 tag_index = find_template_frame_tag(tags, tags_total, 2);
13046 if (tag_index < 0) {
13047 sigma_dut_print(dut, DUT_MSG_ERROR,
13048 "can't find group id attribute");
13049 return -1;
13050 }
13051 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13052 framelen - tags[tag_index].offset,
13053 IEEE80211_P2P_ATTR_GROUP_ID,
13054 group_id_attr,
13055 sizeof(group_id_attr))) {
13056 sigma_dut_print(dut, DUT_MSG_ERROR,
13057 "fail to replace group id attribute");
13058 return -1;
13059 }
13060 }
13061
13062 for (i = 0; i < count; i++) {
13063 if (wil6210_transmit_frame(dut, freq,
13064 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
13065 frame, framelen)) {
13066 sigma_dut_print(dut, DUT_MSG_ERROR,
13067 "fail to transmit probe request frame");
13068 return -1;
13069 }
13070 }
13071
13072 return 0;
13073}
13074
13075
Lior David0fe101e2017-03-09 16:09:50 +020013076int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
13077 struct sigma_cmd *cmd)
13078{
13079 const char *frame_name = get_param(cmd, "framename");
13080 const char *mac = get_param(cmd, "dest_mac");
13081
13082 if (!frame_name || !mac) {
13083 sigma_dut_print(dut, DUT_MSG_ERROR,
13084 "framename and dest_mac must be provided");
13085 return -1;
13086 }
13087
13088 if (strcasecmp(frame_name, "brp") == 0) {
13089 const char *l_rx = get_param(cmd, "L-RX");
13090 int l_rx_i;
13091
13092 if (!l_rx) {
13093 sigma_dut_print(dut, DUT_MSG_ERROR,
13094 "L-RX must be provided");
13095 return -1;
13096 }
13097 l_rx_i = atoi(l_rx);
13098
13099 sigma_dut_print(dut, DUT_MSG_INFO,
13100 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
13101 mac, l_rx);
13102 if (l_rx_i != 16) {
13103 sigma_dut_print(dut, DUT_MSG_ERROR,
13104 "unsupported L-RX: %s", l_rx);
13105 return -1;
13106 }
13107
13108 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
13109 return -1;
13110 } else if (strcasecmp(frame_name, "ssw") == 0) {
13111 sigma_dut_print(dut, DUT_MSG_INFO,
13112 "dev_send_frame: SLS, dest_mac %s", mac);
13113 if (wil6210_send_sls(dut, mac))
13114 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013115 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
13116 (strcasecmp(frame_name, "devdiscreq") == 0)) {
13117 sigma_dut_print(dut, DUT_MSG_INFO,
13118 "dev_send_frame: %s, dest_mac %s", frame_name,
13119 mac);
13120 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
13121 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020013122 } else {
13123 sigma_dut_print(dut, DUT_MSG_ERROR,
13124 "unsupported frame type: %s", frame_name);
13125 return -1;
13126 }
13127
13128 return 1;
13129}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013130
Lior David0fe101e2017-03-09 16:09:50 +020013131#endif /* __linux__ */
13132
13133
13134static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
13135 struct sigma_conn *conn,
13136 struct sigma_cmd *cmd)
13137{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013138 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020013139#ifdef __linux__
13140 case DRIVER_WIL6210:
13141 return wil6210_send_frame_60g(dut, conn, cmd);
13142#endif /* __linux__ */
13143 default:
13144 send_resp(dut, conn, SIGMA_ERROR,
13145 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
13146 return 0;
13147 }
13148}
13149
13150
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013151static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13152 const char *intf, struct sigma_cmd *cmd)
13153{
13154 const char *val, *addr;
13155 char buf[100];
13156
13157 addr = get_param(cmd, "DestMac");
13158 if (!addr) {
13159 send_resp(dut, conn, SIGMA_INVALID,
13160 "ErrorCode,AP MAC address is missing");
13161 return 0;
13162 }
13163
13164 val = get_param(cmd, "ANQPQuery_ID");
13165 if (!val) {
13166 send_resp(dut, conn, SIGMA_INVALID,
13167 "ErrorCode,Missing ANQPQuery_ID");
13168 return 0;
13169 }
13170
13171 if (strcasecmp(val, "NeighborReportReq") == 0) {
13172 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
13173 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
13174 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
13175 } else {
13176 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
13177 val);
13178 send_resp(dut, conn, SIGMA_INVALID,
13179 "ErrorCode,Invalid ANQPQuery_ID");
13180 return 0;
13181 }
13182
Ashwini Patild174f2c2017-04-13 16:49:46 +053013183 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
13184 * (Address3 = Wildcard BSSID when sent to not-associated AP;
13185 * if associated, AP BSSID).
13186 */
13187 if (wpa_command(intf, "SET gas_address3 1") < 0) {
13188 send_resp(dut, conn, SIGMA_ERROR,
13189 "ErrorCode,Failed to set gas_address3");
13190 return 0;
13191 }
13192
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013193 if (wpa_command(intf, buf) < 0) {
13194 send_resp(dut, conn, SIGMA_ERROR,
13195 "ErrorCode,Failed to send ANQP query");
13196 return 0;
13197 }
13198
13199 return 1;
13200}
13201
13202
13203static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
13204 struct sigma_conn *conn,
13205 const char *intf,
13206 struct sigma_cmd *cmd)
13207{
13208 const char *val = get_param(cmd, "FrameName");
13209
13210 if (val && strcasecmp(val, "ANQPQuery") == 0)
13211 return mbo_send_anqp_query(dut, conn, intf, cmd);
13212
13213 return 2;
13214}
13215
13216
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013217static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
13218 struct sigma_conn *conn,
13219 const char *intf,
13220 struct sigma_cmd *cmd)
13221{
13222 const char *val = get_param(cmd, "framename");
13223
13224 if (!val)
13225 return INVALID_SEND_STATUS;
13226
13227 if (strcasecmp(val, "SAQueryReq") == 0) {
13228 val = get_param(cmd, "OCIChannel");
13229
13230 if (!val) {
13231 send_resp(dut, conn, SIGMA_ERROR,
13232 "errorCode,OCIChannel not present");
13233 return STATUS_SENT_ERROR;
13234 }
13235
13236 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
13237 if (!dut->saquery_oci_freq) {
13238 send_resp(dut, conn, SIGMA_ERROR,
13239 "errorCode,Invalid OCIChannel number");
13240 return STATUS_SENT_ERROR;
13241 }
13242
13243 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
13244 NULL, 0);
13245 }
13246
13247 if (strcasecmp(val, "reassocreq") == 0)
13248 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
13249 CORRECT_KEY, NULL, 0);
13250
Veerendranath9f81dfb2020-08-10 01:21:29 -070013251 if (strcasecmp(val, "ANQPQuery") == 0) {
13252 char buf[50];
13253 const char *dest = get_param(cmd, "DestMac");
13254 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013255 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070013256 int len, freq;
13257
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013258 if (freq_str)
13259 freq = atoi(freq_str);
13260 else
13261 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
13262
Veerendranath9f81dfb2020-08-10 01:21:29 -070013263 if (!dest || !freq)
13264 return INVALID_SEND_STATUS;
13265
13266 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
13267 dest, freq);
13268 if (len < 0 || len >= sizeof(buf)) {
13269 sigma_dut_print(dut, DUT_MSG_ERROR,
13270 "Failed to allocate buf");
13271 return ERROR_SEND_STATUS;
13272 }
13273
13274 if (wpa_command(intf, buf) != 0) {
13275 send_resp(dut, conn, SIGMA_ERROR,
13276 "ErrorCode,Failed to send ANQP Query frame");
13277 return STATUS_SENT_ERROR;
13278 }
13279
13280 sigma_dut_print(dut, DUT_MSG_DEBUG,
13281 "ANQP Query sent: %s", buf);
13282
13283 return SUCCESS_SEND_STATUS;
13284 }
13285
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013286 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
13287 return STATUS_SENT_ERROR;
13288}
13289
13290
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013291static int
13292get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13293 char *pos, int rem_len, int num_of_scs_desc,
13294 int num_of_tclas_elem)
13295{
13296 const char *val;
13297 int ipv6;
13298 int len, total_len = 0;
13299
13300 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
13301 num_of_tclas_elem);
13302 if (!val) {
13303 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
13304 __func__);
13305 return -1;
13306 }
13307
13308 if (strcmp(val, "6") == 0) {
13309 ipv6 = 1;
13310 } else if (strcmp(val, "4") == 0) {
13311 ipv6 = 0;
13312 } else {
13313 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
13314 __func__);
13315 return -1;
13316 }
13317
13318 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
13319 if (len < 0 || len >= rem_len)
13320 return -1;
13321
13322 pos += len;
13323 rem_len -= len;
13324 total_len += len;
13325
13326 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
13327 num_of_scs_desc, num_of_tclas_elem);
13328 if (val) {
13329 len = snprintf(pos, rem_len, " src_ip=%s", val);
13330 if (len < 0 || len >= rem_len)
13331 return -1;
13332
13333 pos += len;
13334 rem_len -= len;
13335 total_len += len;
13336 }
13337
13338 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
13339 num_of_scs_desc, num_of_tclas_elem);
13340 if (val) {
13341 len = snprintf(pos, rem_len, " dst_ip=%s", val);
13342 if (len < 0 || len >= rem_len)
13343 return -1;
13344
13345 pos += len;
13346 rem_len -= len;
13347 total_len += len;
13348 }
13349
13350 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
13351 num_of_tclas_elem);
13352 if (val) {
13353 len = snprintf(pos, rem_len, " src_port=%s", val);
13354 if (len < 0 || len >= rem_len)
13355 return -1;
13356
13357 pos += len;
13358 rem_len -= len;
13359 total_len += len;
13360 }
13361
13362 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
13363 num_of_scs_desc, num_of_tclas_elem);
13364 if (val) {
13365 len = snprintf(pos, rem_len, " dst_port=%s", val);
13366 if (len < 0 || len >= rem_len)
13367 return -1;
13368
13369 pos += len;
13370 rem_len -= len;
13371 total_len += len;
13372 }
13373
13374 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
13375 num_of_tclas_elem);
13376 if (val) {
13377 len = snprintf(pos, rem_len, " dscp=%s", val);
13378 if (len < 0 || len >= rem_len)
13379 return -1;
13380
13381 pos += len;
13382 rem_len -= len;
13383 total_len += len;
13384 }
13385
13386 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
13387 num_of_scs_desc, num_of_tclas_elem);
13388 if (val) {
13389 char *prot;
13390
13391 switch (atoi(val)) {
13392 case 17:
13393 prot = "udp";
13394 break;
13395 case 6:
13396 prot = "tcp";
13397 break;
13398 case 50:
13399 prot = "esp";
13400 break;
13401 default:
13402 sigma_dut_print(dut, DUT_MSG_ERROR,
13403 "Invalid protocol %d", atoi(val));
13404 return -1;
13405 }
13406
13407 if (ipv6)
13408 len = snprintf(pos, rem_len, " next_header=%s", prot);
13409 else
13410 len = snprintf(pos, rem_len, " protocol=%s", prot);
13411 if (len < 0 || len >= rem_len)
13412 return -1;
13413
13414 pos += len;
13415 rem_len -= len;
13416 total_len += len;
13417 }
13418
13419 return total_len;
13420}
13421
13422
13423static int
13424get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13425 char *pos, int rem_len, int num_of_scs_desc,
13426 int num_of_tclas_elem)
13427{
13428 const char *val;
13429 int len, total_len = 0;
13430
13431 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
13432 num_of_scs_desc, num_of_tclas_elem);
13433 if (val) {
13434 len = snprintf(pos, rem_len, " prot_instance=%s",
13435 val);
13436 if (len < 0 || len >= rem_len)
13437 return -1;
13438
13439 pos += len;
13440 rem_len -= len;
13441 total_len += len;
13442 }
13443
13444 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
13445 num_of_scs_desc, num_of_tclas_elem);
13446 if (val) {
13447 char *prot;
13448
13449 switch (atoi(val)) {
13450 case 17:
13451 prot = "udp";
13452 break;
13453 case 6:
13454 prot = "tcp";
13455 break;
13456 case 50:
13457 prot = "esp";
13458 break;
13459 default:
13460 sigma_dut_print(dut, DUT_MSG_ERROR,
13461 "Invalid protocol %d",
13462 atoi(val));
13463 return -1;
13464 }
13465
13466 len = snprintf(pos, rem_len, " prot_number=%s", prot);
13467 if (len < 0 || len >= rem_len)
13468 return -1;
13469
13470 pos += len;
13471 rem_len -= len;
13472 total_len += len;
13473 }
13474
13475 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
13476 num_of_scs_desc, num_of_tclas_elem);
13477 if (val) {
13478 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
13479 if (len < 0 || len >= rem_len)
13480 return -1;
13481
13482 pos += len;
13483 rem_len -= len;
13484 total_len += len;
13485 }
13486
13487 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
13488 num_of_tclas_elem);
13489 if (val && strlen(val) >= 2) {
13490 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
13491 if (len < 0 || len >= rem_len)
13492 return -1;
13493
13494 pos += len;
13495 rem_len -= len;
13496 total_len += len;
13497 }
13498
13499 return total_len;
13500}
13501
13502
13503static enum sigma_cmd_result
13504cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
13505 const char *intf, struct sigma_cmd *cmd)
13506{
13507 char buf[4096], *pos;
13508 const char *val, *scs_id, *classifier_type;
13509 int len, rem_len, total_bytes;
13510 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
13511
13512 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
13513 if (!scs_id) {
13514 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
13515 return INVALID_SEND_STATUS;
13516 }
13517
13518 rem_len = sizeof(buf);
13519 pos = buf;
13520
13521 len = snprintf(buf, sizeof(buf), "SCS");
13522 if (len < 0 || len > rem_len)
13523 goto fail;
13524
13525 pos += len;
13526 rem_len -= len;
13527
13528 while (scs_id) {
13529 num_of_scs_desc++;
13530
13531 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
13532 num_of_scs_desc);
13533 if (!val)
13534 return INVALID_SEND_STATUS;
13535
13536 if (strcasecmp(val, "Add") == 0) {
13537 len = snprintf(pos, rem_len, " scs_id=%s add",
13538 scs_id);
13539 } else if (strcasecmp(val, "Change") == 0) {
13540 len = snprintf(pos, rem_len, " scs_id=%s change",
13541 scs_id);
13542 } else if (strcasecmp(val, "Remove") == 0) {
13543 len = snprintf(pos, rem_len, " scs_id=%s remove",
13544 scs_id);
13545 if (len < 0 || len >= rem_len)
13546 goto fail;
13547
13548 pos += len;
13549 rem_len -= len;
13550 goto scs_desc_end;
13551 } else {
13552 sigma_dut_print(dut, DUT_MSG_ERROR,
13553 "%s: request type - %s is invalid",
13554 __func__, val);
13555 return INVALID_SEND_STATUS;
13556 }
13557
13558 if (len < 0 || len >= rem_len)
13559 goto fail;
13560
13561 pos += len;
13562 rem_len -= len;
13563
13564 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
13565 num_of_scs_desc);
13566 if (!val) {
13567 sigma_dut_print(dut, DUT_MSG_ERROR,
13568 "IntraAccess Priority empty");
13569 return INVALID_SEND_STATUS;
13570 }
13571
13572 len = snprintf(pos, rem_len, " scs_up=%s", val);
13573 if (len < 0 || len >= rem_len)
13574 goto fail;
13575
13576 pos += len;
13577 rem_len -= len;
13578
13579 classifier_type = get_param_fmt(cmd,
13580 "TCLASElem_ClassifierType_%d_1",
13581 num_of_scs_desc);
13582 if (!classifier_type) {
13583 sigma_dut_print(dut, DUT_MSG_ERROR,
13584 "classifier type missing");
13585 return INVALID_SEND_STATUS;
13586 }
13587
13588 while (classifier_type) {
13589 num_of_tclas_elem++;
13590
13591 len = snprintf(pos, rem_len, " classifier_type=%s",
13592 classifier_type);
13593 if (len < 0 || len >= rem_len)
13594 goto fail;
13595
13596 pos += len;
13597 rem_len -= len;
13598
13599 if (strcmp(classifier_type, "10") == 0) {
13600 total_bytes = get_type10_frame_classifier(
13601 dut, cmd, pos, rem_len,
13602 num_of_scs_desc,
13603 num_of_tclas_elem);
13604 } else if (strcmp(classifier_type, "4") == 0) {
13605 total_bytes = get_type4_frame_classifier(
13606 dut, cmd, pos, rem_len,
13607 num_of_scs_desc,
13608 num_of_tclas_elem);
13609 } else {
13610 sigma_dut_print(dut, DUT_MSG_ERROR,
13611 "classifier_type invalid");
13612 goto fail;
13613 }
13614
13615 if (total_bytes < 0)
13616 goto fail;
13617
13618 pos += total_bytes;
13619 rem_len -= total_bytes;
13620
13621 classifier_type = get_param_fmt(
13622 cmd, "TCLASElem_ClassifierType_%d_%d",
13623 num_of_scs_desc, num_of_tclas_elem + 1);
13624 }
13625
13626 if (num_of_tclas_elem > 1) {
13627 val = get_param_fmt(cmd,
13628 "TCLASProcessingElem_Processing_%d",
13629 num_of_scs_desc);
13630 if (!val) {
13631 sigma_dut_print(dut, DUT_MSG_ERROR,
13632 "Tclas_processing element %d empty",
13633 num_of_scs_desc);
13634 goto fail;
13635 }
13636
13637 len = snprintf(pos, rem_len,
13638 " tclas_processing=%s", val);
13639 if (len < 0 || len >= rem_len)
13640 goto fail;
13641
13642 pos += len;
13643 rem_len -= len;
13644 }
13645scs_desc_end:
13646 num_of_tclas_elem = 0;
13647 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
13648 num_of_scs_desc + 1);
13649 }
13650
13651 if (wpa_command(intf, buf) != 0) {
13652 send_resp(dut, conn, SIGMA_ERROR,
13653 "ErrorCode,Failed to send SCS frame request");
13654 return STATUS_SENT_ERROR;
13655 }
13656
13657 sigma_dut_print(dut, DUT_MSG_DEBUG,
13658 "SCS frame request sent: %s", buf);
13659
13660 return SUCCESS_SEND_STATUS;
13661fail:
13662 sigma_dut_print(dut, DUT_MSG_ERROR,
13663 "Failed to create SCS frame request");
13664 return ERROR_SEND_STATUS;
13665}
13666
13667
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013668static enum sigma_cmd_result
13669cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
13670 const char *intf, struct sigma_cmd *cmd)
13671{
13672 char buf[128], *pos;
13673 const char *val, *classifier_type = "04", *type;
13674 int len, rem_len;
13675 u8 up_bitmap;
13676
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013677 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013678 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013679 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013680 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013681 return INVALID_SEND_STATUS;
13682 }
13683
13684 rem_len = sizeof(buf);
13685 pos = buf;
13686 if (strcasecmp(type, "add") == 0) {
13687 len = snprintf(pos, rem_len, "MSCS add");
13688 } else if (strcasecmp(type, "update") == 0) {
13689 len = snprintf(pos, rem_len, "MSCS change");
13690 } else if (strcasecmp(type, "remove") == 0) {
13691 if (wpa_command(intf, "MSCS remove") != 0) {
13692 send_resp(dut, conn, SIGMA_ERROR,
13693 "ErrorCode,Failed to send MSCS frame req");
13694 return STATUS_SENT_ERROR;
13695 }
13696 return SUCCESS_SEND_STATUS;
13697 } else {
13698 sigma_dut_print(dut, DUT_MSG_ERROR,
13699 "%s: request type invalid", __func__);
13700 return INVALID_SEND_STATUS;
13701 }
13702
13703 if (len < 0 || len >= rem_len)
13704 goto fail;
13705
13706 pos += len;
13707 rem_len -= len;
13708
13709 val = get_param(cmd, "User_Priority_Bitmap");
13710 if (!val) {
13711 sigma_dut_print(dut, DUT_MSG_ERROR,
13712 "%s: user priority bitmap empty", __func__);
13713 return INVALID_SEND_STATUS;
13714 }
13715
13716 switch (atoi(val)) {
13717 case 0:
13718 up_bitmap = 0x00;
13719 break;
13720 case 1:
13721 up_bitmap = 0xF0;
13722 break;
13723 case 2:
13724 up_bitmap = 0xF6;
13725 break;
13726 default:
13727 sigma_dut_print(dut, DUT_MSG_ERROR,
13728 "%s: Unknown User_Priority_Bitmap value %d",
13729 __func__, atoi(val));
13730 return INVALID_SEND_STATUS;
13731 }
13732
13733 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
13734 if (len < 0 || len >= rem_len)
13735 goto fail;
13736
13737 pos += len;
13738 rem_len -= len;
13739
13740 val = get_param(cmd, "User_Priority_Limit");
13741 if (!val) {
13742 sigma_dut_print(dut, DUT_MSG_ERROR,
13743 "%s: invalid user priority limit", __func__);
13744 return INVALID_SEND_STATUS;
13745 }
13746
13747 len = snprintf(pos, rem_len, " up_limit=%s", val);
13748 if (len < 0 || len >= rem_len)
13749 goto fail;
13750
13751 pos += len;
13752 rem_len -= len;
13753
13754 val = get_param(cmd, "Stream_Timeout");
13755 if (!val)
13756 val = get_param(cmd, "Stream_Timtout");
13757 if (!val) {
13758 sigma_dut_print(dut, DUT_MSG_ERROR,
13759 "%s: invalid stream timeout", __func__);
13760 return INVALID_SEND_STATUS;
13761 }
13762
13763 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
13764 if (len < 0 || len >= rem_len)
13765 goto fail;
13766
13767 pos += len;
13768 rem_len -= len;
13769
13770 val = get_param(cmd, "TCLAS_Mask");
13771 if (!val) {
13772 sigma_dut_print(dut, DUT_MSG_ERROR,
13773 "%s: invalid tclas mask", __func__);
13774 return INVALID_SEND_STATUS;
13775 }
13776
13777 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
13778 classifier_type, strtol(val, NULL, 2), 0);
13779 if (len < 0 || len >= rem_len)
13780 goto fail;
13781
13782 if (wpa_command(intf, buf) != 0) {
13783 send_resp(dut, conn, SIGMA_ERROR,
13784 "ErrorCode,Failed to send MSCS frame req");
13785 return STATUS_SENT_ERROR;
13786 }
13787
13788 sigma_dut_print(dut, DUT_MSG_DEBUG,
13789 "MSCS frame request sent: %s", buf);
13790
13791 return SUCCESS_SEND_STATUS;
13792fail:
13793 sigma_dut_print(dut, DUT_MSG_ERROR,
13794 "Failed to create MSCS frame req");
13795 return ERROR_SEND_STATUS;
13796}
13797
13798
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013799static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013800cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13801 const char *intf, struct sigma_cmd *cmd)
13802{
13803 char buf[150], *pos;
13804 const char *val;
13805 int len, rem_len;
13806
13807 rem_len = sizeof(buf);
13808 pos = buf;
13809
13810 len = snprintf(pos, rem_len, "DSCP_QUERY");
13811 if (len < 0 || len >= rem_len)
13812 goto fail;
13813
13814 pos += len;
13815 rem_len -= len;
13816
13817 val = get_param(cmd, "Wildcard");
13818 if (val && strcasecmp(val, "Yes") == 0) {
13819 len = snprintf(pos, rem_len, " wildcard");
13820 if (len < 0 || len >= rem_len)
13821 goto fail;
13822 } else if (strlen(dut->qm_domain_name)) {
13823 len = snprintf(pos, rem_len, " domain_name=%s",
13824 dut->qm_domain_name);
13825 if (len < 0 || len >= rem_len)
13826 goto fail;
13827 } else {
13828 sigma_dut_print(dut, DUT_MSG_ERROR,
13829 "Invalid DSCP Query configuration");
13830 return INVALID_SEND_STATUS;
13831 }
13832
13833 if (wpa_command(intf, buf) != 0) {
13834 send_resp(dut, conn, SIGMA_ERROR,
13835 "ErrorCode,Failed to send DSCP policy query frame");
13836 return STATUS_SENT_ERROR;
13837 }
13838
13839 sigma_dut_print(dut, DUT_MSG_DEBUG,
13840 "DSCP policy query frame sent: %s", buf);
13841 return SUCCESS_SEND_STATUS;
13842fail:
13843 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
13844 return ERROR_SEND_STATUS;
13845}
13846
13847
13848static enum sigma_cmd_result
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013849cmd_sta_send_frame_dscp_response(struct sigma_dut *dut, struct sigma_conn *conn,
13850 const char *intf, struct sigma_cmd *cmd)
13851{
13852 char buf[256], *pos, *item, *list, *saveptr;
13853 const char *val;
13854 int len, rem_len;
13855
13856 pos = buf;
13857 rem_len = sizeof(buf);
13858
13859 len = snprintf(pos, rem_len, "DSCP_RESP");
13860 if (snprintf_error(rem_len, len)) {
13861 sigma_dut_print(dut, DUT_MSG_ERROR,
13862 "Failed to create DSCP Policy Response command");
13863 return ERROR_SEND_STATUS;
13864 }
13865
13866 pos += len;
13867 rem_len -= len;
13868
13869 val = get_param(cmd, "PolicyID_List");
13870 if (!val) {
13871 sigma_dut_print(dut, DUT_MSG_ERROR,
13872 "DSCP policy ID list missing");
13873 return INVALID_SEND_STATUS;
13874 }
13875
13876 list = strdup(val);
13877 if (!list)
13878 return ERROR_SEND_STATUS;
13879
13880 item = strtok_r(list, "_", &saveptr);
13881 while (item) {
13882 unsigned int i;
13883 int policy_id = atoi(item);
13884
13885 for (i = 0; i < dut->num_dscp_status; i++)
13886 if (dut->dscp_status[i].id == policy_id)
13887 break;
13888
13889 if (i == dut->num_dscp_status) {
13890 free(list);
13891 send_resp(dut, conn, SIGMA_ERROR,
13892 "ErrorCode,DSCP policy id not found in status list");
13893 return STATUS_SENT_ERROR;
13894 }
13895
13896 len = snprintf(pos, rem_len, " policy_id=%d status=%d",
13897 policy_id, dut->dscp_status[i].status);
13898 if (snprintf_error(rem_len, len)) {
13899 free(list);
13900 sigma_dut_print(dut, DUT_MSG_ERROR,
13901 "Failed to write DSCP policy list");
13902 return ERROR_SEND_STATUS;
13903 }
13904
13905 pos += len;
13906 rem_len -= len;
13907
13908 if (dut->dscp_status[i].status)
13909 remove_dscp_policy(dut, policy_id);
13910
13911 item = strtok_r(NULL, "_", &saveptr);
13912 }
13913
13914 free(list);
13915
13916 if (wpa_command(intf, buf) != 0) {
13917 send_resp(dut, conn, SIGMA_ERROR,
13918 "ErrorCode,Failed to send DSCP Policy Response frame");
13919 return STATUS_SENT_ERROR;
13920 }
13921
13922 sigma_dut_print(dut, DUT_MSG_DEBUG,
13923 "DSCP Policy Response frame sent: %s", buf);
13924 return SUCCESS_SEND_STATUS;
13925}
13926
13927
13928static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013929cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
13930 const char *intf, struct sigma_cmd *cmd)
13931{
13932 const char *val;
13933
13934 val = get_param(cmd, "FrameName");
13935 if (val) {
13936 if (strcasecmp(val, "MSCSReq") == 0)
13937 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
13938 if (strcasecmp(val, "SCSReq") == 0)
13939 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013940 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
13941 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
13942 cmd);
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013943 if (strcasecmp(val, "DSCPPolicyResponse") == 0)
13944 return cmd_sta_send_frame_dscp_response(dut, conn, intf,
13945 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013946
13947 sigma_dut_print(dut, DUT_MSG_ERROR,
13948 "%s: frame name - %s is invalid",
13949 __func__, val);
13950 }
13951
13952 return INVALID_SEND_STATUS;
13953}
13954
13955
Jouni Malinenf7222712019-06-13 01:50:21 +030013956enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
13957 struct sigma_conn *conn,
13958 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013959{
13960 const char *intf = get_param(cmd, "Interface");
13961 const char *val;
13962 enum send_frame_type frame;
13963 enum send_frame_protection protected;
13964 char buf[100];
13965 unsigned char addr[ETH_ALEN];
13966 int res;
13967
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030013968 if (!intf)
13969 return -1;
13970
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013971 val = get_param(cmd, "program");
13972 if (val == NULL)
13973 val = get_param(cmd, "frame");
13974 if (val && strcasecmp(val, "TDLS") == 0)
13975 return cmd_sta_send_frame_tdls(dut, conn, cmd);
13976 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030013977 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020013978 strcasecmp(val, "HS2-R3") == 0 ||
13979 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013980 return cmd_sta_send_frame_hs2(dut, conn, cmd);
13981 if (val && strcasecmp(val, "VHT") == 0)
13982 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070013983 if (val && strcasecmp(val, "HE") == 0)
13984 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070013985 if (val && strcasecmp(val, "LOC") == 0)
13986 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020013987 if (val && strcasecmp(val, "60GHz") == 0)
13988 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013989 if (val && strcasecmp(val, "MBO") == 0) {
13990 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
13991 if (res != 2)
13992 return res;
13993 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013994 if (val && strcasecmp(val, "WPA3") == 0)
13995 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013996 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013997 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013998
13999 val = get_param(cmd, "TD_DISC");
14000 if (val) {
14001 if (hwaddr_aton(val, addr) < 0)
14002 return -1;
14003 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
14004 if (wpa_command(intf, buf) < 0) {
14005 send_resp(dut, conn, SIGMA_ERROR,
14006 "ErrorCode,Failed to send TDLS discovery");
14007 return 0;
14008 }
14009 return 1;
14010 }
14011
14012 val = get_param(cmd, "TD_Setup");
14013 if (val) {
14014 if (hwaddr_aton(val, addr) < 0)
14015 return -1;
14016 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
14017 if (wpa_command(intf, buf) < 0) {
14018 send_resp(dut, conn, SIGMA_ERROR,
14019 "ErrorCode,Failed to start TDLS setup");
14020 return 0;
14021 }
14022 return 1;
14023 }
14024
14025 val = get_param(cmd, "TD_TearDown");
14026 if (val) {
14027 if (hwaddr_aton(val, addr) < 0)
14028 return -1;
14029 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
14030 if (wpa_command(intf, buf) < 0) {
14031 send_resp(dut, conn, SIGMA_ERROR,
14032 "ErrorCode,Failed to tear down TDLS link");
14033 return 0;
14034 }
14035 return 1;
14036 }
14037
14038 val = get_param(cmd, "TD_ChannelSwitch");
14039 if (val) {
14040 /* TODO */
14041 send_resp(dut, conn, SIGMA_ERROR,
14042 "ErrorCode,TD_ChannelSwitch not yet supported");
14043 return 0;
14044 }
14045
14046 val = get_param(cmd, "TD_NF");
14047 if (val) {
14048 /* TODO */
14049 send_resp(dut, conn, SIGMA_ERROR,
14050 "ErrorCode,TD_NF not yet supported");
14051 return 0;
14052 }
14053
14054 val = get_param(cmd, "PMFFrameType");
14055 if (val == NULL)
14056 val = get_param(cmd, "FrameName");
14057 if (val == NULL)
14058 val = get_param(cmd, "Type");
14059 if (val == NULL)
14060 return -1;
14061 if (strcasecmp(val, "disassoc") == 0)
14062 frame = DISASSOC;
14063 else if (strcasecmp(val, "deauth") == 0)
14064 frame = DEAUTH;
14065 else if (strcasecmp(val, "saquery") == 0)
14066 frame = SAQUERY;
14067 else if (strcasecmp(val, "auth") == 0)
14068 frame = AUTH;
14069 else if (strcasecmp(val, "assocreq") == 0)
14070 frame = ASSOCREQ;
14071 else if (strcasecmp(val, "reassocreq") == 0)
14072 frame = REASSOCREQ;
14073 else if (strcasecmp(val, "neigreq") == 0) {
14074 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
14075
14076 val = get_param(cmd, "ssid");
14077 if (val == NULL)
14078 return -1;
14079
14080 res = send_neighbor_request(dut, intf, val);
14081 if (res) {
14082 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14083 "Failed to send neighbor report request");
14084 return 0;
14085 }
14086
14087 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053014088 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
14089 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014090 sigma_dut_print(dut, DUT_MSG_DEBUG,
14091 "Got Transition Management Query");
14092
Ashwini Patil5acd7382017-04-13 15:55:04 +053014093 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014094 if (res) {
14095 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14096 "Failed to send Transition Management Query");
14097 return 0;
14098 }
14099
14100 return 1;
14101 } else {
14102 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14103 "PMFFrameType");
14104 return 0;
14105 }
14106
14107 val = get_param(cmd, "PMFProtected");
14108 if (val == NULL)
14109 val = get_param(cmd, "Protected");
14110 if (val == NULL)
14111 return -1;
14112 if (strcasecmp(val, "Correct-key") == 0 ||
14113 strcasecmp(val, "CorrectKey") == 0)
14114 protected = CORRECT_KEY;
14115 else if (strcasecmp(val, "IncorrectKey") == 0)
14116 protected = INCORRECT_KEY;
14117 else if (strcasecmp(val, "Unprotected") == 0)
14118 protected = UNPROTECTED;
14119 else {
14120 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14121 "PMFProtected");
14122 return 0;
14123 }
14124
14125 if (protected != UNPROTECTED &&
14126 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
14127 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
14128 "PMFProtected for auth/assocreq/reassocreq");
14129 return 0;
14130 }
14131
14132 if (if_nametoindex("sigmadut") == 0) {
14133 snprintf(buf, sizeof(buf),
14134 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014135 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014136 if (system(buf) != 0 ||
14137 if_nametoindex("sigmadut") == 0) {
14138 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
14139 "monitor interface with '%s'", buf);
14140 return -2;
14141 }
14142 }
14143
14144 if (system("ifconfig sigmadut up") != 0) {
14145 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
14146 "monitor interface up");
14147 return -2;
14148 }
14149
Veerendranath Jakkam49774122020-07-05 09:52:18 +053014150 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014151}
14152
14153
14154static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
14155 struct sigma_conn *conn,
14156 struct sigma_cmd *cmd,
14157 const char *ifname)
14158{
14159 char buf[200];
14160 const char *val;
14161
14162 val = get_param(cmd, "ClearARP");
14163 if (val && atoi(val) == 1) {
14164 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
14165 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14166 if (system(buf) != 0) {
14167 send_resp(dut, conn, SIGMA_ERROR,
14168 "errorCode,Failed to clear ARP cache");
14169 return 0;
14170 }
14171 }
14172
14173 return 1;
14174}
14175
14176
14177int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
14178 struct sigma_cmd *cmd)
14179{
14180 const char *intf = get_param(cmd, "Interface");
14181 const char *val;
14182
14183 if (intf == NULL)
14184 return -1;
14185
14186 val = get_param(cmd, "program");
14187 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014188 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014189 strcasecmp(val, "HS2-R3") == 0 ||
14190 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014191 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
14192
14193 return -1;
14194}
14195
14196
Jouni Malinenf7222712019-06-13 01:50:21 +030014197static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
14198 struct sigma_conn *conn,
14199 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014200{
14201 const char *intf = get_param(cmd, "Interface");
14202 const char *mac = get_param(cmd, "MAC");
14203
14204 if (intf == NULL || mac == NULL)
14205 return -1;
14206
14207 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
14208 "interface %s to %s", intf, mac);
14209
14210 if (dut->set_macaddr) {
14211 char buf[128];
14212 int res;
14213 if (strcasecmp(mac, "default") == 0) {
14214 res = snprintf(buf, sizeof(buf), "%s",
14215 dut->set_macaddr);
14216 dut->tmp_mac_addr = 0;
14217 } else {
14218 res = snprintf(buf, sizeof(buf), "%s %s",
14219 dut->set_macaddr, mac);
14220 dut->tmp_mac_addr = 1;
14221 }
14222 if (res < 0 || res >= (int) sizeof(buf))
14223 return -1;
14224 if (system(buf) != 0) {
14225 send_resp(dut, conn, SIGMA_ERROR,
14226 "errorCode,Failed to set MAC "
14227 "address");
14228 return 0;
14229 }
14230 return 1;
14231 }
14232
14233 if (strcasecmp(mac, "default") == 0)
14234 return 1;
14235
14236 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14237 "command");
14238 return 0;
14239}
14240
14241
14242static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
14243 struct sigma_conn *conn, const char *intf,
14244 int val)
14245{
14246 char buf[200];
14247 int res;
14248
14249 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
14250 intf, val);
14251 if (res < 0 || res >= (int) sizeof(buf))
14252 return -1;
14253 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14254 if (system(buf) != 0) {
14255 send_resp(dut, conn, SIGMA_ERROR,
14256 "errorCode,Failed to configure offchannel mode");
14257 return 0;
14258 }
14259
14260 return 1;
14261}
14262
14263
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014264static int off_chan_val(enum sec_ch_offset off)
14265{
14266 switch (off) {
14267 case SEC_CH_NO:
14268 return 0;
14269 case SEC_CH_40ABOVE:
14270 return 40;
14271 case SEC_CH_40BELOW:
14272 return -40;
14273 }
14274
14275 return 0;
14276}
14277
14278
14279static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
14280 const char *intf, int off_ch_num,
14281 enum sec_ch_offset sec)
14282{
14283 char buf[200];
14284 int res;
14285
14286 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
14287 intf, off_ch_num);
14288 if (res < 0 || res >= (int) sizeof(buf))
14289 return -1;
14290 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14291 if (system(buf) != 0) {
14292 send_resp(dut, conn, SIGMA_ERROR,
14293 "errorCode,Failed to set offchan");
14294 return 0;
14295 }
14296
14297 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
14298 intf, off_chan_val(sec));
14299 if (res < 0 || res >= (int) sizeof(buf))
14300 return -1;
14301 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14302 if (system(buf) != 0) {
14303 send_resp(dut, conn, SIGMA_ERROR,
14304 "errorCode,Failed to set sec chan offset");
14305 return 0;
14306 }
14307
14308 return 1;
14309}
14310
14311
14312static int tdls_set_offchannel_offset(struct sigma_dut *dut,
14313 struct sigma_conn *conn,
14314 const char *intf, int off_ch_num,
14315 enum sec_ch_offset sec)
14316{
14317 char buf[200];
14318 int res;
14319
14320 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
14321 off_ch_num);
14322 if (res < 0 || res >= (int) sizeof(buf))
14323 return -1;
14324 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14325
14326 if (wpa_command(intf, buf) < 0) {
14327 send_resp(dut, conn, SIGMA_ERROR,
14328 "ErrorCode,Failed to set offchan");
14329 return 0;
14330 }
14331 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
14332 off_chan_val(sec));
14333 if (res < 0 || res >= (int) sizeof(buf))
14334 return -1;
14335
14336 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14337
14338 if (wpa_command(intf, buf) < 0) {
14339 send_resp(dut, conn, SIGMA_ERROR,
14340 "ErrorCode,Failed to set sec chan offset");
14341 return 0;
14342 }
14343
14344 return 1;
14345}
14346
14347
14348static int tdls_set_offchannel_mode(struct sigma_dut *dut,
14349 struct sigma_conn *conn,
14350 const char *intf, int val)
14351{
14352 char buf[200];
14353 int res;
14354
14355 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
14356 val);
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 configure offchannel mode");
14364 return 0;
14365 }
14366
14367 return 1;
14368}
14369
14370
14371static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
14372 struct sigma_conn *conn,
14373 struct sigma_cmd *cmd)
14374{
14375 const char *val;
14376 enum {
14377 CHSM_NOT_SET,
14378 CHSM_ENABLE,
14379 CHSM_DISABLE,
14380 CHSM_REJREQ,
14381 CHSM_UNSOLRESP
14382 } chsm = CHSM_NOT_SET;
14383 int off_ch_num = -1;
14384 enum sec_ch_offset sec_ch = SEC_CH_NO;
14385 int res;
14386
14387 val = get_param(cmd, "Uapsd");
14388 if (val) {
14389 char buf[100];
14390 if (strcasecmp(val, "Enable") == 0)
14391 snprintf(buf, sizeof(buf), "SET ps 99");
14392 else if (strcasecmp(val, "Disable") == 0)
14393 snprintf(buf, sizeof(buf), "SET ps 98");
14394 else {
14395 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14396 "Unsupported uapsd parameter value");
14397 return 0;
14398 }
14399 if (wpa_command(intf, buf)) {
14400 send_resp(dut, conn, SIGMA_ERROR,
14401 "ErrorCode,Failed to change U-APSD "
14402 "powersave mode");
14403 return 0;
14404 }
14405 }
14406
14407 val = get_param(cmd, "TPKTIMER");
14408 if (val && strcasecmp(val, "DISABLE") == 0) {
14409 if (wpa_command(intf, "SET tdls_testing 0x100")) {
14410 send_resp(dut, conn, SIGMA_ERROR,
14411 "ErrorCode,Failed to enable no TPK "
14412 "expiration test mode");
14413 return 0;
14414 }
14415 dut->no_tpk_expiration = 1;
14416 }
14417
14418 val = get_param(cmd, "ChSwitchMode");
14419 if (val) {
14420 if (strcasecmp(val, "Enable") == 0 ||
14421 strcasecmp(val, "Initiate") == 0)
14422 chsm = CHSM_ENABLE;
14423 else if (strcasecmp(val, "Disable") == 0 ||
14424 strcasecmp(val, "passive") == 0)
14425 chsm = CHSM_DISABLE;
14426 else if (strcasecmp(val, "RejReq") == 0)
14427 chsm = CHSM_REJREQ;
14428 else if (strcasecmp(val, "UnSolResp") == 0)
14429 chsm = CHSM_UNSOLRESP;
14430 else {
14431 send_resp(dut, conn, SIGMA_ERROR,
14432 "ErrorCode,Unknown ChSwitchMode value");
14433 return 0;
14434 }
14435 }
14436
14437 val = get_param(cmd, "OffChNum");
14438 if (val) {
14439 off_ch_num = atoi(val);
14440 if (off_ch_num == 0) {
14441 send_resp(dut, conn, SIGMA_ERROR,
14442 "ErrorCode,Invalid OffChNum");
14443 return 0;
14444 }
14445 }
14446
14447 val = get_param(cmd, "SecChOffset");
14448 if (val) {
14449 if (strcmp(val, "20") == 0)
14450 sec_ch = SEC_CH_NO;
14451 else if (strcasecmp(val, "40above") == 0)
14452 sec_ch = SEC_CH_40ABOVE;
14453 else if (strcasecmp(val, "40below") == 0)
14454 sec_ch = SEC_CH_40BELOW;
14455 else {
14456 send_resp(dut, conn, SIGMA_ERROR,
14457 "ErrorCode,Unknown SecChOffset value");
14458 return 0;
14459 }
14460 }
14461
14462 if (chsm == CHSM_NOT_SET) {
14463 /* no offchannel changes requested */
14464 return 1;
14465 }
14466
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014467 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
14468 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014469 send_resp(dut, conn, SIGMA_ERROR,
14470 "ErrorCode,Unknown interface");
14471 return 0;
14472 }
14473
14474 switch (chsm) {
14475 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030014476 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014477 break;
14478 case CHSM_ENABLE:
14479 if (off_ch_num < 0) {
14480 send_resp(dut, conn, SIGMA_ERROR,
14481 "ErrorCode,Missing OffChNum argument");
14482 return 0;
14483 }
14484 if (wifi_chip_type == DRIVER_WCN) {
14485 res = tdls_set_offchannel_offset(dut, conn, intf,
14486 off_ch_num, sec_ch);
14487 } else {
14488 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14489 sec_ch);
14490 }
14491 if (res != 1)
14492 return res;
14493 if (wifi_chip_type == DRIVER_WCN)
14494 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
14495 else
14496 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
14497 break;
14498 case CHSM_DISABLE:
14499 if (wifi_chip_type == DRIVER_WCN)
14500 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
14501 else
14502 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
14503 break;
14504 case CHSM_REJREQ:
14505 if (wifi_chip_type == DRIVER_WCN)
14506 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
14507 else
14508 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
14509 break;
14510 case CHSM_UNSOLRESP:
14511 if (off_ch_num < 0) {
14512 send_resp(dut, conn, SIGMA_ERROR,
14513 "ErrorCode,Missing OffChNum argument");
14514 return 0;
14515 }
14516 if (wifi_chip_type == DRIVER_WCN) {
14517 res = tdls_set_offchannel_offset(dut, conn, intf,
14518 off_ch_num, sec_ch);
14519 } else {
14520 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14521 sec_ch);
14522 }
14523 if (res != 1)
14524 return res;
14525 if (wifi_chip_type == DRIVER_WCN)
14526 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
14527 else
14528 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
14529 break;
14530 }
14531
14532 return res;
14533}
14534
14535
14536static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14537 struct sigma_conn *conn,
14538 struct sigma_cmd *cmd)
14539{
14540 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014541 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014542
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070014543 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080014544
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014545 val = get_param(cmd, "nss_mcs_opt");
14546 if (val) {
14547 /* String (nss_operating_mode; mcs_operating_mode) */
14548 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014549 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014550
14551 token = strdup(val);
14552 if (!token)
14553 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014554 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014555 if (!result) {
14556 sigma_dut_print(dut, DUT_MSG_ERROR,
14557 "VHT NSS not specified");
14558 goto failed;
14559 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014560 if (strcasecmp(result, "def") != 0) {
14561 nss = atoi(result);
14562 if (nss == 4)
14563 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014564 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014565 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014566
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014567 }
14568
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014569 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014570 if (!result) {
14571 sigma_dut_print(dut, DUT_MSG_ERROR,
14572 "VHT MCS not specified");
14573 goto failed;
14574 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014575 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014576 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014577 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014578 } else {
14579 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014580 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014581 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014582 }
14583 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014584 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014585 }
14586
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014587 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014588 return 1;
14589failed:
14590 free(token);
14591 return 0;
14592}
14593
14594
14595static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14596 struct sigma_conn *conn,
14597 struct sigma_cmd *cmd)
14598{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014599 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014600 case DRIVER_ATHEROS:
14601 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
14602 default:
14603 send_resp(dut, conn, SIGMA_ERROR,
14604 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
14605 return 0;
14606 }
14607}
14608
14609
Jouni Malinen1702fe32021-06-08 19:08:01 +030014610static enum sigma_cmd_result
14611wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14612 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014613{
14614 const char *val;
14615 char *token = NULL, *result;
14616 char buf[60];
14617
14618 val = get_param(cmd, "nss_mcs_opt");
14619 if (val) {
14620 /* String (nss_operating_mode; mcs_operating_mode) */
14621 int nss, mcs, ratecode;
14622 char *saveptr;
14623
14624 token = strdup(val);
14625 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014626 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014627
14628 result = strtok_r(token, ";", &saveptr);
14629 if (!result) {
14630 sigma_dut_print(dut, DUT_MSG_ERROR,
14631 "HE NSS not specified");
14632 goto failed;
14633 }
14634 nss = 1;
14635 if (strcasecmp(result, "def") != 0)
14636 nss = atoi(result);
14637
14638 result = strtok_r(NULL, ";", &saveptr);
14639 if (!result) {
14640 sigma_dut_print(dut, DUT_MSG_ERROR,
14641 "HE MCS not specified");
14642 goto failed;
14643 }
14644 mcs = 7;
14645 if (strcasecmp(result, "def") != 0)
14646 mcs = atoi(result);
14647
Arif Hussain557bf412018-05-25 17:29:36 -070014648 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014649 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070014650 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014651 } else if (nss > 2) {
14652 sigma_dut_print(dut, DUT_MSG_ERROR,
14653 "HE NSS %d not supported", nss);
14654 goto failed;
14655 }
14656
Arif Hussain557bf412018-05-25 17:29:36 -070014657 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
14658 if (system(buf) != 0) {
14659 sigma_dut_print(dut, DUT_MSG_ERROR,
14660 "nss_mcs_opt: iwpriv %s nss %d failed",
14661 intf, nss);
14662 goto failed;
14663 }
Arif Hussainac6c5112018-05-25 17:34:00 -070014664 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070014665
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014666 /* Add the MCS to the ratecode */
14667 if (mcs >= 0 && mcs <= 11) {
14668 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070014669#ifdef NL80211_SUPPORT
14670 if (dut->device_type == STA_testbed) {
14671 enum he_mcs_config mcs_config;
14672 int ret;
14673
14674 if (mcs <= 7)
14675 mcs_config = HE_80_MCS0_7;
14676 else if (mcs <= 9)
14677 mcs_config = HE_80_MCS0_9;
14678 else
14679 mcs_config = HE_80_MCS0_11;
14680 ret = sta_set_he_mcs(dut, intf, mcs_config);
14681 if (ret) {
14682 sigma_dut_print(dut, DUT_MSG_ERROR,
14683 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
14684 mcs, mcs_config, ret);
14685 goto failed;
14686 }
14687 }
14688#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014689 } else {
14690 sigma_dut_print(dut, DUT_MSG_ERROR,
14691 "HE MCS %d not supported", mcs);
14692 goto failed;
14693 }
14694 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
14695 intf, ratecode);
14696 if (system(buf) != 0) {
14697 sigma_dut_print(dut, DUT_MSG_ERROR,
14698 "iwpriv setting of 11ax rates failed");
14699 goto failed;
14700 }
14701 free(token);
14702 }
14703
14704 val = get_param(cmd, "GI");
14705 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014706 int fix_rate_sgi;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014707 u8 he_gi_val = 0;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014708
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014709 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014710 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014711 fix_rate_sgi = 1;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014712 he_gi_val = NL80211_RATE_INFO_HE_GI_0_8;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014713 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014714 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
14715 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014716 fix_rate_sgi = 2;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014717 he_gi_val = NL80211_RATE_INFO_HE_GI_1_6;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014718 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014719 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
14720 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014721 fix_rate_sgi = 3;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014722 he_gi_val = NL80211_RATE_INFO_HE_GI_3_2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014723 } else {
14724 send_resp(dut, conn, SIGMA_ERROR,
14725 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014726 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014727 }
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014728 if (wcn_set_he_gi(dut, intf, he_gi_val)) {
14729 sigma_dut_print(dut, DUT_MSG_INFO,
14730 "wcn_set_he_gi failed, using iwpriv");
14731 if (system(buf) != 0) {
14732 send_resp(dut, conn, SIGMA_ERROR,
14733 "errorCode,Failed to set shortgi");
14734 return STATUS_SENT_ERROR;
14735 }
14736 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
14737 intf, fix_rate_sgi);
14738 if (system(buf) != 0) {
14739 send_resp(dut, conn, SIGMA_ERROR,
14740 "errorCode,Failed to set fix rate shortgi");
14741 return STATUS_SENT_ERROR;
14742 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014743 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014744 }
14745
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014746 val = get_param(cmd, "LTF");
14747 if (val) {
14748#ifdef NL80211_SUPPORT
14749 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014750 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014751 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014752 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014753 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014754 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014755 } else {
14756 send_resp(dut, conn, SIGMA_ERROR,
14757 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014758 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014759 }
14760#else /* NL80211_SUPPORT */
14761 sigma_dut_print(dut, DUT_MSG_ERROR,
14762 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014763 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014764#endif /* NL80211_SUPPORT */
14765 }
14766
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070014767 val = get_param(cmd, "KeepAlive");
14768 if (val) {
14769 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
14770
14771 if (strcasecmp(val, "Data") == 0)
14772 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
14773 else if (strcasecmp(val, "Mgmt") == 0)
14774 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
14775
14776 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
14777 send_resp(dut, conn, SIGMA_ERROR,
14778 "ErrorCode,Failed to set keep alive type config");
14779 return STATUS_SENT_ERROR;
14780 }
14781 }
14782
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014783 val = get_param(cmd, "TxSUPPDU");
14784 if (val) {
14785 int set_val = 1;
14786
14787 if (strcasecmp(val, "Enable") == 0)
14788 set_val = 1;
14789 else if (strcasecmp(val, "Disable") == 0)
14790 set_val = 0;
14791
14792 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
14793 send_resp(dut, conn, SIGMA_ERROR,
14794 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014795 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014796 }
14797 }
14798
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070014799 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
14800 if (val) {
14801 int set_val = 0;
14802
14803 if (strcasecmp(val, "Enable") == 0)
14804 set_val = 0;
14805 else if (strcasecmp(val, "Disable") == 0)
14806 set_val = 1;
14807
14808 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
14809 send_resp(dut, conn, SIGMA_ERROR,
14810 "ErrorCode,Failed to set mgmt/data Tx disable config");
14811 return STATUS_SENT_ERROR;
14812 }
14813 }
14814
Arif Hussain480d5f42019-03-12 14:40:42 -070014815 val = get_param(cmd, "TWT_Setup");
14816 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014817#ifdef NL80211_SUPPORT
14818 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14819 sigma_dut_print(dut, DUT_MSG_ERROR,
14820 "Failed to open nl80211 event socket");
14821#endif /* NL80211_SUPPORT */
Arif Hussain480d5f42019-03-12 14:40:42 -070014822 if (strcasecmp(val, "Request") == 0) {
Kiran Kumar Lokereafac46a2021-11-29 14:03:20 -080014823 if (set_power_save_wcn(dut, intf, 1) < 0)
14824 sigma_dut_print(dut, DUT_MSG_ERROR,
14825 "Failed to enable power save");
Arif Hussain480d5f42019-03-12 14:40:42 -070014826 if (sta_twt_request(dut, conn, cmd)) {
14827 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014828 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014829 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014830 }
14831 } else if (strcasecmp(val, "Teardown") == 0) {
14832 if (sta_twt_teardown(dut, conn, cmd)) {
14833 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014834 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014835 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014836 }
14837 }
14838 }
14839
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014840 val = get_param(cmd, "TWT_Operation");
14841 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014842#ifdef NL80211_SUPPORT
14843 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14844 sigma_dut_print(dut, DUT_MSG_ERROR,
14845 "Failed to open nl80211 event socket");
14846#endif /* NL80211_SUPPORT */
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014847 if (strcasecmp(val, "Suspend") == 0) {
14848 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
14849 send_resp(dut, conn, SIGMA_ERROR,
14850 "ErrorCode,TWT suspend failed");
14851 return STATUS_SENT_ERROR;
14852 }
14853 } else if (strcasecmp(val, "Resume") == 0) {
14854 if (sta_twt_resume(dut, conn, cmd)) {
14855 send_resp(dut, conn, SIGMA_ERROR,
14856 "ErrorCode,TWT resume failed");
14857 return STATUS_SENT_ERROR;
14858 }
14859 }
14860 }
14861
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080014862 val = get_param(cmd, "transmitOMI");
14863 if (val && sta_transmit_omi(dut, conn, cmd)) {
14864 send_resp(dut, conn, SIGMA_ERROR,
14865 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014866 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070014867 }
14868
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014869 val = get_param(cmd, "Powersave");
14870 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014871 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014872
14873 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014874 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014875 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014876 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014877 } else {
14878 sigma_dut_print(dut, DUT_MSG_ERROR,
14879 "Unsupported Powersave value '%s'",
14880 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014881 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014882 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014883 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014884 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014885 }
14886
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080014887 val = get_param(cmd, "MU_EDCA");
14888 if (val) {
14889 if (strcasecmp(val, "Override") == 0) {
14890 if (sta_set_mu_edca_override(dut, intf, 1)) {
14891 send_resp(dut, conn, SIGMA_ERROR,
14892 "errorCode,MU EDCA override set failed");
14893 return STATUS_SENT;
14894 }
14895 } else if (strcasecmp(val, "Disable") == 0) {
14896 if (sta_set_mu_edca_override(dut, intf, 0)) {
14897 send_resp(dut, conn, SIGMA_ERROR,
14898 "errorCode,MU EDCA override disable failed");
14899 return STATUS_SENT;
14900 }
14901 }
14902 }
14903
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070014904 val = get_param(cmd, "RUAllocTone");
14905 if (val && strcasecmp(val, "242") == 0) {
14906 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
14907 send_resp(dut, conn, SIGMA_ERROR,
14908 "ErrorCode,Failed to set RU 242 tone Tx");
14909 return STATUS_SENT_ERROR;
14910 }
14911 }
14912
14913 val = get_param(cmd, "PPDUTxType");
14914 if (val && strcasecmp(val, "ER-SU") == 0) {
14915 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
14916 send_resp(dut, conn, SIGMA_ERROR,
14917 "ErrorCode,Failed to set ER-SU PPDU type Tx");
14918 return STATUS_SENT_ERROR;
14919 }
14920 }
14921
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070014922 val = get_param(cmd, "Ch_Pref");
14923 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14924 return STATUS_SENT;
14925
14926 val = get_param(cmd, "Cellular_Data_Cap");
14927 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14928 return STATUS_SENT;
14929
Jouni Malinen1702fe32021-06-08 19:08:01 +030014930 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014931
14932failed:
14933 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014934 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014935}
14936
14937
Jouni Malinen1702fe32021-06-08 19:08:01 +030014938static enum sigma_cmd_result
14939cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14940 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014941{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014942 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014943 case DRIVER_WCN:
14944 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
14945 default:
14946 send_resp(dut, conn, SIGMA_ERROR,
14947 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014948 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014949 }
14950}
14951
14952
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014953static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
14954 struct sigma_conn *conn,
14955 struct sigma_cmd *cmd)
14956{
14957 const char *val;
14958
14959 val = get_param(cmd, "powersave");
14960 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014961 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014962
14963 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014964 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014965 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014966 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014967 } else {
14968 sigma_dut_print(dut, DUT_MSG_ERROR,
14969 "Unsupported power save config");
14970 return -1;
14971 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014972 if (set_power_save_wcn(dut, intf, ps) < 0)
14973 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014974 return 1;
14975 }
14976
14977 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
14978
14979 return 0;
14980}
14981
14982
Ashwini Patil5acd7382017-04-13 15:55:04 +053014983static int btm_query_candidate_list(struct sigma_dut *dut,
14984 struct sigma_conn *conn,
14985 struct sigma_cmd *cmd)
14986{
14987 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
14988 int len, ret;
14989 char buf[10];
14990
14991 /*
14992 * Neighbor Report elements format:
14993 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
14994 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
14995 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
14996 */
14997
14998 bssid = get_param(cmd, "Nebor_BSSID");
14999 if (!bssid) {
15000 send_resp(dut, conn, SIGMA_INVALID,
15001 "errorCode,Nebor_BSSID is missing");
15002 return 0;
15003 }
15004
15005 info = get_param(cmd, "Nebor_Bssid_Info");
15006 if (!info) {
15007 sigma_dut_print(dut, DUT_MSG_INFO,
15008 "Using default value for Nebor_Bssid_Info: %s",
15009 DEFAULT_NEIGHBOR_BSSID_INFO);
15010 info = DEFAULT_NEIGHBOR_BSSID_INFO;
15011 }
15012
15013 op_class = get_param(cmd, "Nebor_Op_Class");
15014 if (!op_class) {
15015 send_resp(dut, conn, SIGMA_INVALID,
15016 "errorCode,Nebor_Op_Class is missing");
15017 return 0;
15018 }
15019
15020 ch = get_param(cmd, "Nebor_Op_Ch");
15021 if (!ch) {
15022 send_resp(dut, conn, SIGMA_INVALID,
15023 "errorCode,Nebor_Op_Ch is missing");
15024 return 0;
15025 }
15026
15027 phy_type = get_param(cmd, "Nebor_Phy_Type");
15028 if (!phy_type) {
15029 sigma_dut_print(dut, DUT_MSG_INFO,
15030 "Using default value for Nebor_Phy_Type: %s",
15031 DEFAULT_NEIGHBOR_PHY_TYPE);
15032 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
15033 }
15034
15035 /* Parse optional subelements */
15036 buf[0] = '\0';
15037 pref = get_param(cmd, "Nebor_Pref");
15038 if (pref) {
15039 /* hexdump for preferrence subelement */
15040 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
15041 if (ret < 0 || ret >= (int) sizeof(buf)) {
15042 sigma_dut_print(dut, DUT_MSG_ERROR,
15043 "snprintf failed for optional subelement ret: %d",
15044 ret);
15045 send_resp(dut, conn, SIGMA_ERROR,
15046 "errorCode,snprintf failed for subelement");
15047 return 0;
15048 }
15049 }
15050
15051 if (!dut->btm_query_cand_list) {
15052 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
15053 if (!dut->btm_query_cand_list) {
15054 send_resp(dut, conn, SIGMA_ERROR,
15055 "errorCode,Failed to allocate memory for btm_query_cand_list");
15056 return 0;
15057 }
15058 }
15059
15060 len = strlen(dut->btm_query_cand_list);
15061 ret = snprintf(dut->btm_query_cand_list + len,
15062 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
15063 bssid, info, op_class, ch, phy_type, buf);
15064 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
15065 sigma_dut_print(dut, DUT_MSG_ERROR,
15066 "snprintf failed for neighbor report list ret: %d",
15067 ret);
15068 send_resp(dut, conn, SIGMA_ERROR,
15069 "errorCode,snprintf failed for neighbor report");
15070 free(dut->btm_query_cand_list);
15071 dut->btm_query_cand_list = NULL;
15072 return 0;
15073 }
15074
15075 return 1;
15076}
15077
15078
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015079int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
15080 struct sigma_ese_alloc *allocs, int *allocs_size)
15081{
15082 int max_count = *allocs_size;
15083 int count = 0, i;
15084 const char *val;
15085
15086 do {
15087 val = get_param_indexed(cmd, "AllocID", count);
15088 if (val)
15089 count++;
15090 } while (val);
15091
15092 if (count == 0 || count > max_count) {
15093 sigma_dut_print(dut, DUT_MSG_ERROR,
15094 "Invalid number of allocations(%d)", count);
15095 return -1;
15096 }
15097
15098 for (i = 0; i < count; i++) {
15099 val = get_param_indexed(cmd, "PercentBI", i);
15100 if (!val) {
15101 sigma_dut_print(dut, DUT_MSG_ERROR,
15102 "Missing PercentBI parameter at index %d",
15103 i);
15104 return -1;
15105 }
15106 allocs[i].percent_bi = atoi(val);
15107
15108 val = get_param_indexed(cmd, "SrcAID", i);
15109 if (val)
15110 allocs[i].src_aid = strtol(val, NULL, 0);
15111 else
15112 allocs[i].src_aid = ESE_BCAST_AID;
15113
15114 val = get_param_indexed(cmd, "DestAID", i);
15115 if (val)
15116 allocs[i].dst_aid = strtol(val, NULL, 0);
15117 else
15118 allocs[i].dst_aid = ESE_BCAST_AID;
15119
15120 allocs[i].type = ESE_CBAP;
15121 sigma_dut_print(dut, DUT_MSG_INFO,
15122 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
15123 i, allocs[i].percent_bi, allocs[i].src_aid,
15124 allocs[i].dst_aid);
15125 }
15126
15127 *allocs_size = count;
15128 return 0;
15129}
15130
15131
15132static int sta_set_60g_ese(struct sigma_dut *dut, int count,
15133 struct sigma_ese_alloc *allocs)
15134{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015135 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015136#ifdef __linux__
15137 case DRIVER_WIL6210:
15138 if (wil6210_set_ese(dut, count, allocs))
15139 return -1;
15140 return 1;
15141#endif /* __linux__ */
15142 default:
15143 sigma_dut_print(dut, DUT_MSG_ERROR,
15144 "Unsupported sta_set_60g_ese with the current driver");
15145 return -1;
15146 }
15147}
15148
15149
15150static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
15151 struct sigma_conn *conn,
15152 struct sigma_cmd *cmd)
15153{
15154 const char *val;
15155
15156 val = get_param(cmd, "ExtSchIE");
15157 if (val && !strcasecmp(val, "Enable")) {
15158 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
15159 int count = MAX_ESE_ALLOCS;
15160
15161 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
15162 return -1;
15163 return sta_set_60g_ese(dut, count, allocs);
15164 }
15165
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015166 val = get_param(cmd, "MCS_FixedRate");
15167 if (val) {
15168 int sta_mcs = atoi(val);
15169
15170 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
15171 sta_mcs);
15172 wil6210_set_force_mcs(dut, 1, sta_mcs);
15173
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015174 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015175 }
15176
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015177 send_resp(dut, conn, SIGMA_ERROR,
15178 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015179 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015180}
15181
15182
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015183static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
15184 const char *oci_frametype, uint32_t oci_freq)
15185{
15186#ifdef NL80211_SUPPORT
15187 struct nl_msg *msg;
15188 int ret = 0;
15189 struct nlattr *params;
15190 struct nlattr *attr;
15191 int ifindex;
15192 u8 frame_type;
15193
15194 ifindex = if_nametoindex(intf);
15195 if (ifindex == 0) {
15196 sigma_dut_print(dut, DUT_MSG_ERROR,
15197 "%s: Index for interface %s failed",
15198 __func__, intf);
15199 return -1;
15200 }
15201
15202 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15203 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
15204 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15205 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
15206 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15207 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
15208 } else {
15209 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
15210 __func__, oci_frametype);
15211 return -1;
15212 }
15213
15214
15215 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
15216 NL80211_CMD_VENDOR)) ||
15217 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
15218 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
15219 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
15220 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
15221 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
15222 !(params = nla_nest_start(
15223 msg,
15224 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
15225 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
15226 frame_type) ||
15227 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
15228 oci_freq)) {
15229 sigma_dut_print(dut, DUT_MSG_ERROR,
15230 "%s: err in adding vendor_cmd and vendor_data",
15231 __func__);
15232 nlmsg_free(msg);
15233 return -1;
15234 }
15235 nla_nest_end(msg, params);
15236 nla_nest_end(msg, attr);
15237
15238 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
15239 if (ret) {
15240 sigma_dut_print(dut, DUT_MSG_ERROR,
15241 "%s: err in send_and_recv_msgs, ret=%d",
15242 __func__, ret);
15243 }
15244 return ret;
15245#else /* NL80211_SUPPORT */
15246 sigma_dut_print(dut, DUT_MSG_ERROR,
15247 "OCI override not possible without NL80211_SUPPORT defined");
15248 return -1;
15249#endif /* NL80211_SUPPORT */
15250}
15251
15252
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015253static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
15254 uint8_t ignore_csa)
15255{
15256#ifdef NL80211_SUPPORT
15257 return wcn_wifi_test_config_set_u8(
15258 dut, intf,
15259 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
15260#else /* NL80211_SUPPORT */
15261 sigma_dut_print(dut, DUT_MSG_ERROR,
15262 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
15263 return -1;
15264#endif /* NL80211_SUPPORT */
15265}
15266
15267
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015268static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
15269 uint8_t rsnxe_used)
15270{
15271#ifdef NL80211_SUPPORT
15272 return wcn_wifi_test_config_set_u8(
15273 dut, intf,
15274 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
15275 rsnxe_used);
15276#else /* NL80211_SUPPORT */
15277 sigma_dut_print(dut, DUT_MSG_ERROR,
15278 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
15279 return -1;
15280#endif /* NL80211_SUPPORT */
15281}
15282
15283
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015284static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
15285 const char *intf,
15286 uint8_t ignore_sa_query_timeout)
15287{
15288#ifdef NL80211_SUPPORT
15289 return wcn_wifi_test_config_set_u8(
15290 dut, intf,
15291 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
15292 ignore_sa_query_timeout);
15293#else /* NL80211_SUPPORT */
15294 sigma_dut_print(dut, DUT_MSG_ERROR,
15295 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
15296 return -1;
15297#endif /* NL80211_SUPPORT */
15298}
15299
15300
Jouni Malinen6250cb02020-04-15 13:54:45 +030015301static enum sigma_cmd_result
15302cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
15303 struct sigma_conn *conn,
15304 struct sigma_cmd *cmd)
15305{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015306 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030015307
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053015308 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030015309 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015310 if (wifi_chip_type == DRIVER_WCN) {
15311 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
15312 send_resp(dut, conn, SIGMA_ERROR,
15313 "errorCode,Failed to set ft_rsnxe_used");
15314 return STATUS_SENT_ERROR;
15315 }
15316 return SUCCESS_SEND_STATUS;
15317 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030015318 send_resp(dut, conn, SIGMA_ERROR,
15319 "errorCode,Failed to set ft_rsnxe_used");
15320 return STATUS_SENT_ERROR;
15321 }
15322 return SUCCESS_SEND_STATUS;
15323 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015324
15325 oci_chan = get_param(cmd, "OCIChannel");
15326 oci_frametype = get_param(cmd, "OCIFrameType");
15327 if (oci_chan && oci_frametype) {
15328 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
15329 char buf[100];
15330
15331 if (!oci_freq) {
15332 send_resp(dut, conn, SIGMA_ERROR,
15333 "errorCode,Invalid OCIChannel number");
15334 return STATUS_SENT_ERROR;
15335 }
15336
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015337 if (wifi_chip_type == DRIVER_WCN &&
15338 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
15339 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
15340 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
15341 if (wcn_sta_override_oci(dut, intf, oci_frametype,
15342 oci_freq)) {
15343 send_resp(dut, conn, SIGMA_ERROR,
15344 "errorCode,Failed to override OCI");
15345 return STATUS_SENT_ERROR;
15346 }
15347 return SUCCESS_SEND_STATUS;
15348 }
15349
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015350 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
15351 snprintf(buf, sizeof(buf),
15352 "SET oci_freq_override_eapol %d", oci_freq);
15353 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15354 snprintf(buf, sizeof(buf),
15355 "SET oci_freq_override_saquery_req %d",
15356 oci_freq);
15357 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15358 snprintf(buf, sizeof(buf),
15359 "SET oci_freq_override_saquery_resp %d",
15360 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015361 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
15362 snprintf(buf, sizeof(buf),
15363 "SET oci_freq_override_eapol_g2 %d",
15364 oci_freq);
15365 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15366 snprintf(buf, sizeof(buf),
15367 "SET oci_freq_override_ft_assoc %d",
15368 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015369 } else {
15370 send_resp(dut, conn, SIGMA_ERROR,
15371 "errorCode,Unsupported OCIFrameType");
15372 return STATUS_SENT_ERROR;
15373 }
15374 if (wpa_command(intf, buf) < 0) {
15375 send_resp(dut, conn, SIGMA_ERROR,
15376 "errorCode,Failed to set oci_freq_override");
15377 return STATUS_SENT_ERROR;
15378 }
15379 return SUCCESS_SEND_STATUS;
15380 }
15381
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015382 val = get_param(cmd, "IgnoreCSA");
15383 if (val && atoi(val) == 1) {
15384 if (wifi_chip_type == DRIVER_WCN) {
15385 if (wcn_sta_ignore_csa(dut, intf, 1)) {
15386 send_resp(dut, conn, SIGMA_ERROR,
15387 "errorCode,Failed to set ignore CSA");
15388 return STATUS_SENT_ERROR;
15389 }
15390 return SUCCESS_SEND_STATUS;
15391 }
15392 }
15393
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015394 val = get_param(cmd, "Deauth_Per_SAQueryResp");
15395 if (val && atoi(val) == 0) {
15396 if (wifi_chip_type == DRIVER_WCN) {
15397 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
15398 send_resp(dut, conn, SIGMA_ERROR,
15399 "errorCode,Failed to set ignore SA Query timeout");
15400 return STATUS_SENT_ERROR;
15401 }
15402 return SUCCESS_SEND_STATUS;
15403 }
15404 }
15405
Jouni Malinen6250cb02020-04-15 13:54:45 +030015406 send_resp(dut, conn, SIGMA_ERROR,
15407 "errorCode,Unsupported WPA3 rfeature");
15408 return STATUS_SENT_ERROR;
15409}
15410
15411
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015412static enum sigma_cmd_result
15413cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
15414 struct sigma_conn *conn, struct sigma_cmd *cmd)
15415{
15416 const char *val;
15417
15418 val = get_param(cmd, "DomainName_Domain");
15419 if (val) {
15420 if (strlen(val) >= sizeof(dut->qm_domain_name))
15421 return ERROR_SEND_STATUS;
15422
15423 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
15424 return SUCCESS_SEND_STATUS;
15425 }
15426
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053015427 val = get_param(cmd, "DSCPPolicy_PolicyID");
15428 if (val) {
15429 unsigned int i;
15430 int policy_id = atoi(val);
15431
15432 val = get_param(cmd, "DSCPPolicy_RequestType");
15433
15434 if (!policy_id || !val)
15435 return INVALID_SEND_STATUS;
15436
15437 if (dut->num_dscp_status >= ARRAY_SIZE(dut->dscp_status)) {
15438 send_resp(dut, conn, SIGMA_ERROR,
15439 "errorCode,DSCP status list full");
15440 return STATUS_SENT_ERROR;
15441 }
15442
15443 for (i = 0; i < dut->num_dscp_status; i++)
15444 if (dut->dscp_status[i].id == policy_id)
15445 break;
15446
15447 /* New policy configured */
15448 if (i == dut->num_dscp_status) {
15449 dut->dscp_status[i].id = policy_id;
15450 dut->num_dscp_status++;
15451 }
15452
15453 dut->dscp_status[i].status = strcasecmp(val, "Remove") ?
15454 DSCP_POLICY_SUCCESS : DSCP_POLICY_REJECT;
15455
15456 return SUCCESS_SEND_STATUS;
15457 }
15458
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015459 send_resp(dut, conn, SIGMA_ERROR,
15460 "errorCode,Unsupported QM rfeature");
15461 return STATUS_SENT_ERROR;
15462}
15463
15464
Jouni Malinenf7222712019-06-13 01:50:21 +030015465static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
15466 struct sigma_conn *conn,
15467 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015468{
15469 const char *intf = get_param(cmd, "Interface");
15470 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015471 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015472
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015473 if (!prog)
15474 prog = get_param(cmd, "Program");
15475
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015476 if (intf == NULL || prog == NULL)
15477 return -1;
15478
Ashwini Patil5acd7382017-04-13 15:55:04 +053015479 /* BSS Transition candidate list for BTM query */
15480 val = get_param(cmd, "Nebor_BSSID");
15481 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
15482 return 0;
15483
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015484 if (strcasecmp(prog, "TDLS") == 0)
15485 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
15486
15487 if (strcasecmp(prog, "VHT") == 0)
15488 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
15489
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015490 if (strcasecmp(prog, "HE") == 0)
15491 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
15492
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015493 if (strcasecmp(prog, "MBO") == 0) {
15494 val = get_param(cmd, "Cellular_Data_Cap");
15495 if (val &&
15496 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
15497 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053015498
15499 val = get_param(cmd, "Ch_Pref");
15500 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
15501 return 0;
15502
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015503 return 1;
15504 }
15505
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015506 if (strcasecmp(prog, "60GHz") == 0)
15507 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
15508
Jouni Malinen6250cb02020-04-15 13:54:45 +030015509 if (strcasecmp(prog, "WPA3") == 0)
15510 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015511 if (strcasecmp(prog, "QM") == 0)
15512 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030015513
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015514 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
15515 return 0;
15516}
15517
15518
Jouni Malinenf7222712019-06-13 01:50:21 +030015519static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
15520 struct sigma_conn *conn,
15521 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015522{
15523 const char *intf = get_param(cmd, "Interface");
15524 const char *mode = get_param(cmd, "Mode");
15525 int res;
15526
15527 if (intf == NULL || mode == NULL)
15528 return -1;
15529
15530 if (strcasecmp(mode, "On") == 0)
15531 res = wpa_command(intf, "SET radio_disabled 0");
15532 else if (strcasecmp(mode, "Off") == 0)
15533 res = wpa_command(intf, "SET radio_disabled 1");
15534 else
15535 return -1;
15536
15537 if (res) {
15538 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15539 "radio mode");
15540 return 0;
15541 }
15542
15543 return 1;
15544}
15545
15546
Jouni Malinenf7222712019-06-13 01:50:21 +030015547static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
15548 struct sigma_conn *conn,
15549 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015550{
15551 const char *intf = get_param(cmd, "Interface");
15552 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015553 const char *prog = get_param(cmd, "program");
15554 const char *powersave = get_param(cmd, "powersave");
15555 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015556
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015557 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015558 return -1;
15559
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015560 if (prog && strcasecmp(prog, "60GHz") == 0) {
15561 /*
15562 * The CAPI mode parameter does not exist in 60G
15563 * unscheduled PS.
15564 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080015565 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015566 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015567 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020015568 strcasecmp(prog, "HE") == 0) {
15569 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015570 } else {
15571 if (mode == NULL)
15572 return -1;
15573
15574 if (strcasecmp(mode, "On") == 0)
15575 res = set_ps(intf, dut, 1);
15576 else if (strcasecmp(mode, "Off") == 0)
15577 res = set_ps(intf, dut, 0);
15578 else
15579 return -1;
15580 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015581
15582 if (res) {
15583 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15584 "power save mode");
15585 return 0;
15586 }
15587
15588 return 1;
15589}
15590
15591
Jouni Malinenf7222712019-06-13 01:50:21 +030015592static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
15593 struct sigma_conn *conn,
15594 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015595{
15596 const char *intf = get_param(cmd, "Interface");
15597 const char *val, *bssid;
15598 int res;
15599 char *buf;
15600 size_t buf_len;
15601
15602 val = get_param(cmd, "BSSID_FILTER");
15603 if (val == NULL)
15604 return -1;
15605
15606 bssid = get_param(cmd, "BSSID_List");
15607 if (atoi(val) == 0 || bssid == NULL) {
15608 /* Disable BSSID filter */
15609 if (wpa_command(intf, "SET bssid_filter ")) {
15610 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
15611 "to disable BSSID filter");
15612 return 0;
15613 }
15614
15615 return 1;
15616 }
15617
15618 buf_len = 100 + strlen(bssid);
15619 buf = malloc(buf_len);
15620 if (buf == NULL)
15621 return -1;
15622
15623 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
15624 res = wpa_command(intf, buf);
15625 free(buf);
15626 if (res) {
15627 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
15628 "BSSID filter");
15629 return 0;
15630 }
15631
15632 return 1;
15633}
15634
15635
Jouni Malinenf7222712019-06-13 01:50:21 +030015636static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
15637 struct sigma_conn *conn,
15638 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015639{
15640 const char *intf = get_param(cmd, "Interface");
15641 const char *val;
15642
15643 /* TODO: ARP */
15644
15645 val = get_param(cmd, "HS2_CACHE_PROFILE");
15646 if (val && strcasecmp(val, "All") == 0)
15647 hs2_clear_credentials(intf);
15648
15649 return 1;
15650}
15651
15652
Jouni Malinenf7222712019-06-13 01:50:21 +030015653static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
15654 struct sigma_conn *conn,
15655 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015656{
15657 const char *intf = get_param(cmd, "Interface");
15658 const char *key_type = get_param(cmd, "KeyType");
15659 char buf[100], resp[200];
15660
15661 if (key_type == NULL)
15662 return -1;
15663
15664 if (strcasecmp(key_type, "GTK") == 0) {
15665 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
15666 strncmp(buf, "FAIL", 4) == 0) {
15667 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15668 "not fetch current GTK");
15669 return 0;
15670 }
15671 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
15672 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15673 return 0;
15674 } else {
15675 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
15676 "KeyType");
15677 return 0;
15678 }
15679
15680 return 1;
15681}
15682
15683
15684static int hs2_set_policy(struct sigma_dut *dut)
15685{
15686#ifdef ANDROID
15687 system("ip rule del prio 23000");
15688 if (system("ip rule add from all lookup main prio 23000") != 0) {
15689 sigma_dut_print(dut, DUT_MSG_ERROR,
15690 "Failed to run:ip rule add from all lookup main prio");
15691 return -1;
15692 }
15693 if (system("ip route flush cache") != 0) {
15694 sigma_dut_print(dut, DUT_MSG_ERROR,
15695 "Failed to run ip route flush cache");
15696 return -1;
15697 }
15698 return 1;
15699#else /* ANDROID */
15700 return 0;
15701#endif /* ANDROID */
15702}
15703
15704
Jouni Malinenf7222712019-06-13 01:50:21 +030015705static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
15706 struct sigma_conn *conn,
15707 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015708{
15709 const char *intf = get_param(cmd, "Interface");
15710 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030015711 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015712 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030015713 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015714 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
15715 int tries = 0;
15716 int ignore_blacklist = 0;
15717 const char *events[] = {
15718 "CTRL-EVENT-CONNECTED",
15719 "INTERWORKING-BLACKLISTED",
15720 "INTERWORKING-NO-MATCH",
15721 NULL
15722 };
15723
15724 start_sta_mode(dut);
15725
Jouni Malinen439352d2018-09-13 03:42:23 +030015726 if (band) {
15727 if (strcmp(band, "2.4") == 0) {
15728 wpa_command(intf, "SET setband 2G");
15729 } else if (strcmp(band, "5") == 0) {
15730 wpa_command(intf, "SET setband 5G");
15731 } else {
15732 send_resp(dut, conn, SIGMA_ERROR,
15733 "errorCode,Unsupported band");
15734 return 0;
15735 }
15736 }
15737
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015738 blacklisted[0] = '\0';
15739 if (val && atoi(val))
15740 ignore_blacklist = 1;
15741
15742try_again:
15743 ctrl = open_wpa_mon(intf);
15744 if (ctrl == NULL) {
15745 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15746 "wpa_supplicant monitor connection");
15747 return -2;
15748 }
15749
15750 tries++;
15751 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
15752 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
15753 "Interworking connection");
15754 wpa_ctrl_detach(ctrl);
15755 wpa_ctrl_close(ctrl);
15756 return 0;
15757 }
15758
15759 buf[0] = '\0';
15760 while (1) {
15761 char *pos;
15762 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15763 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
15764 if (!pos)
15765 break;
15766 pos += 25;
15767 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
15768 pos);
15769 if (!blacklisted[0])
15770 memcpy(blacklisted, pos, strlen(pos) + 1);
15771 }
15772
15773 if (ignore_blacklist && blacklisted[0]) {
15774 char *end;
15775 end = strchr(blacklisted, ' ');
15776 if (end)
15777 *end = '\0';
15778 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
15779 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030015780 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
15781 blacklisted);
15782 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015783 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
15784 wpa_ctrl_detach(ctrl);
15785 wpa_ctrl_close(ctrl);
15786 return 0;
15787 }
15788 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15789 buf, sizeof(buf));
15790 }
15791
15792 wpa_ctrl_detach(ctrl);
15793 wpa_ctrl_close(ctrl);
15794
15795 if (res < 0) {
15796 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15797 "connect");
15798 return 0;
15799 }
15800
15801 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
15802 strstr(buf, "INTERWORKING-BLACKLISTED")) {
15803 if (tries < 2) {
15804 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
15805 goto try_again;
15806 }
15807 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
15808 "matching credentials found");
15809 return 0;
15810 }
15811
15812 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15813 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15814 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15815 "get current BSSID/SSID");
15816 return 0;
15817 }
15818
15819 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
15820 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15821 hs2_set_policy(dut);
15822 return 0;
15823}
15824
15825
Jouni Malinenf7222712019-06-13 01:50:21 +030015826static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
15827 struct sigma_conn *conn,
15828 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015829{
15830 const char *intf = get_param(cmd, "Interface");
15831 const char *display = get_param(cmd, "Display");
15832 struct wpa_ctrl *ctrl;
15833 char buf[300], params[400], *pos;
15834 char bssid[20];
15835 int info_avail = 0;
15836 unsigned int old_timeout;
15837 int res;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015838 const char *events[] = { "RX-VENUE-URL", "ANQP-QUERY-DONE", NULL };
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015839
15840 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
15841 send_resp(dut, conn, SIGMA_ERROR,
15842 "ErrorCode,Could not get current BSSID");
15843 return 0;
15844 }
15845 ctrl = open_wpa_mon(intf);
15846 if (!ctrl) {
15847 sigma_dut_print(dut, DUT_MSG_ERROR,
15848 "Failed to open wpa_supplicant monitor connection");
15849 return -2;
15850 }
15851
15852 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
15853 wpa_command(intf, buf);
15854
15855 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
15856 if (res < 0) {
15857 send_resp(dut, conn, SIGMA_ERROR,
15858 "ErrorCode,Could not complete GAS query");
15859 goto fail;
15860 }
15861
15862 old_timeout = dut->default_timeout;
15863 dut->default_timeout = 2;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015864 for (;;) {
15865 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15866 if (res < 0)
15867 break;
15868 if (strstr(buf, "ANQP-QUERY-DONE") != NULL) {
15869 res = -1;
15870 break;
15871 }
15872 pos = strchr(buf, ' ');
15873 if (!pos)
15874 continue;
15875 pos++;
15876 pos = strchr(pos, ' ');
15877 if (!pos)
15878 continue;
15879 pos++;
15880
15881 if (strncmp(pos, "https://", 8) == 0)
15882 break;
15883
15884 sigma_dut_print(dut, DUT_MSG_DEBUG,
15885 "Ignore non-HTTPS venue URL: %s", pos);
15886 }
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015887 dut->default_timeout = old_timeout;
15888 if (res < 0)
15889 goto done;
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015890 info_avail = 1;
15891 snprintf(params, sizeof(params), "browser %s", pos);
15892
15893 if (display && strcasecmp(display, "Yes") == 0) {
15894 pid_t pid;
15895
15896 pid = fork();
15897 if (pid < 0) {
15898 perror("fork");
15899 return -1;
15900 }
15901
15902 if (pid == 0) {
15903 run_hs20_osu(dut, params);
15904 exit(0);
15905 }
15906 }
15907
15908done:
15909 snprintf(buf, sizeof(buf), "Info_available,%s",
15910 info_avail ? "Yes" : "No");
15911 send_resp(dut, conn, SIGMA_COMPLETE, buf);
15912fail:
15913 wpa_ctrl_detach(ctrl);
15914 wpa_ctrl_close(ctrl);
15915 return 0;
15916}
15917
15918
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015919static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
15920 struct sigma_conn *conn,
15921 const char *ifname,
15922 struct sigma_cmd *cmd)
15923{
15924 const char *val;
15925 int id;
15926
15927 id = add_cred(ifname);
15928 if (id < 0)
15929 return -2;
15930 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15931
15932 val = get_param(cmd, "prefer");
15933 if (val && atoi(val) > 0)
15934 set_cred(ifname, id, "priority", "1");
15935
15936 val = get_param(cmd, "REALM");
15937 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
15938 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15939 "realm");
15940 return 0;
15941 }
15942
15943 val = get_param(cmd, "HOME_FQDN");
15944 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
15945 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15946 "home_fqdn");
15947 return 0;
15948 }
15949
15950 val = get_param(cmd, "Username");
15951 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
15952 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15953 "username");
15954 return 0;
15955 }
15956
15957 val = get_param(cmd, "Password");
15958 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
15959 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15960 "password");
15961 return 0;
15962 }
15963
15964 val = get_param(cmd, "ROOT_CA");
15965 if (val) {
15966 char fname[200];
15967 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
15968#ifdef __linux__
15969 if (!file_exists(fname)) {
15970 char msg[300];
15971 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
15972 "file (%s) not found", fname);
15973 send_resp(dut, conn, SIGMA_ERROR, msg);
15974 return 0;
15975 }
15976#endif /* __linux__ */
15977 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
15978 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15979 "not set root CA");
15980 return 0;
15981 }
15982 }
15983
15984 return 1;
15985}
15986
15987
15988static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
15989{
15990 FILE *in, *out;
15991 char buf[500];
15992 int found = 0;
15993
15994 in = fopen("devdetail.xml", "r");
15995 if (in == NULL)
15996 return -1;
15997 out = fopen("devdetail.xml.tmp", "w");
15998 if (out == NULL) {
15999 fclose(in);
16000 return -1;
16001 }
16002
16003 while (fgets(buf, sizeof(buf), in)) {
16004 char *pos = strstr(buf, "<IMSI>");
16005 if (pos) {
16006 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
16007 imsi);
16008 pos += 6;
16009 *pos = '\0';
16010 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
16011 found++;
16012 } else {
16013 fprintf(out, "%s", buf);
16014 }
16015 }
16016
16017 fclose(out);
16018 fclose(in);
16019 if (found)
16020 rename("devdetail.xml.tmp", "devdetail.xml");
16021 else
16022 unlink("devdetail.xml.tmp");
16023
16024 return 0;
16025}
16026
16027
16028static int sta_add_credential_sim(struct sigma_dut *dut,
16029 struct sigma_conn *conn,
16030 const char *ifname, struct sigma_cmd *cmd)
16031{
16032 const char *val, *imsi = NULL;
16033 int id;
16034 char buf[200];
16035 int res;
16036 const char *pos;
16037 size_t mnc_len;
16038 char plmn_mcc[4];
16039 char plmn_mnc[4];
16040
16041 id = add_cred(ifname);
16042 if (id < 0)
16043 return -2;
16044 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16045
16046 val = get_param(cmd, "prefer");
16047 if (val && atoi(val) > 0)
16048 set_cred(ifname, id, "priority", "1");
16049
16050 val = get_param(cmd, "PLMN_MCC");
16051 if (val == NULL) {
16052 send_resp(dut, conn, SIGMA_ERROR,
16053 "errorCode,Missing PLMN_MCC");
16054 return 0;
16055 }
16056 if (strlen(val) != 3) {
16057 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
16058 return 0;
16059 }
16060 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
16061
16062 val = get_param(cmd, "PLMN_MNC");
16063 if (val == NULL) {
16064 send_resp(dut, conn, SIGMA_ERROR,
16065 "errorCode,Missing PLMN_MNC");
16066 return 0;
16067 }
16068 if (strlen(val) != 2 && strlen(val) != 3) {
16069 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
16070 return 0;
16071 }
16072 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
16073
16074 val = get_param(cmd, "IMSI");
16075 if (val == NULL) {
16076 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
16077 "IMSI");
16078 return 0;
16079 }
16080
16081 imsi = pos = val;
16082
16083 if (strncmp(plmn_mcc, pos, 3) != 0) {
16084 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
16085 return 0;
16086 }
16087 pos += 3;
16088
16089 mnc_len = strlen(plmn_mnc);
16090 if (mnc_len < 2) {
16091 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
16092 return 0;
16093 }
16094
16095 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
16096 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
16097 return 0;
16098 }
16099 pos += mnc_len;
16100
16101 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
16102 if (res < 0 || res >= (int) sizeof(buf))
16103 return -1;
16104 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
16105 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16106 "not set IMSI");
16107 return 0;
16108 }
16109
16110 val = get_param(cmd, "Password");
16111 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
16112 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16113 "not set password");
16114 return 0;
16115 }
16116
Jouni Malinen9a742ff2022-01-27 00:43:14 +020016117 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
16118 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016119 /*
16120 * Set provisioning_sp for the test cases where SIM/USIM
16121 * provisioning is used.
16122 */
16123 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
16124 "wi-fi.org") < 0) {
16125 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16126 "not set provisioning_sp");
16127 return 0;
16128 }
16129
16130 update_devdetail_imsi(dut, imsi);
16131 }
16132
16133 return 1;
16134}
16135
16136
16137static int sta_add_credential_cert(struct sigma_dut *dut,
16138 struct sigma_conn *conn,
16139 const char *ifname,
16140 struct sigma_cmd *cmd)
16141{
16142 const char *val;
16143 int id;
16144
16145 id = add_cred(ifname);
16146 if (id < 0)
16147 return -2;
16148 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16149
16150 val = get_param(cmd, "prefer");
16151 if (val && atoi(val) > 0)
16152 set_cred(ifname, id, "priority", "1");
16153
16154 val = get_param(cmd, "REALM");
16155 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
16156 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16157 "realm");
16158 return 0;
16159 }
16160
16161 val = get_param(cmd, "HOME_FQDN");
16162 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
16163 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16164 "home_fqdn");
16165 return 0;
16166 }
16167
16168 val = get_param(cmd, "Username");
16169 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
16170 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16171 "username");
16172 return 0;
16173 }
16174
16175 val = get_param(cmd, "clientCertificate");
16176 if (val) {
16177 char fname[200];
16178 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16179#ifdef __linux__
16180 if (!file_exists(fname)) {
16181 char msg[300];
16182 snprintf(msg, sizeof(msg),
16183 "ErrorCode,clientCertificate "
16184 "file (%s) not found", fname);
16185 send_resp(dut, conn, SIGMA_ERROR, msg);
16186 return 0;
16187 }
16188#endif /* __linux__ */
16189 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
16190 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16191 "not set client_cert");
16192 return 0;
16193 }
16194 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
16195 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16196 "not set private_key");
16197 return 0;
16198 }
16199 }
16200
16201 val = get_param(cmd, "ROOT_CA");
16202 if (val) {
16203 char fname[200];
16204 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16205#ifdef __linux__
16206 if (!file_exists(fname)) {
16207 char msg[300];
16208 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16209 "file (%s) not found", fname);
16210 send_resp(dut, conn, SIGMA_ERROR, msg);
16211 return 0;
16212 }
16213#endif /* __linux__ */
16214 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16215 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16216 "not set root CA");
16217 return 0;
16218 }
16219 }
16220
16221 return 1;
16222}
16223
16224
Jouni Malinenf7222712019-06-13 01:50:21 +030016225static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
16226 struct sigma_conn *conn,
16227 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016228{
16229 const char *intf = get_param(cmd, "Interface");
16230 const char *type;
16231
16232 start_sta_mode(dut);
16233
16234 type = get_param(cmd, "Type");
16235 if (!type)
16236 return -1;
16237
16238 if (strcasecmp(type, "uname_pwd") == 0)
16239 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
16240
16241 if (strcasecmp(type, "sim") == 0)
16242 return sta_add_credential_sim(dut, conn, intf, cmd);
16243
16244 if (strcasecmp(type, "cert") == 0)
16245 return sta_add_credential_cert(dut, conn, intf, cmd);
16246
16247 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
16248 "type");
16249 return 0;
16250}
16251
16252
Jouni Malinenf7222712019-06-13 01:50:21 +030016253static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
16254 struct sigma_conn *conn,
16255 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016256{
16257 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016258 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070016259 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053016260 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016261 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016262 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016263 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016264 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016265
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020016266 start_sta_mode(dut);
16267
Arif Hussain66a4af02019-02-07 15:04:51 -080016268 val = get_param(cmd, "GetParameter");
16269 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016270 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080016271 buf, sizeof(buf)) < 0) {
16272 sigma_dut_print(dut, DUT_MSG_ERROR,
16273 "Could not get ssid bssid");
16274 return ERROR_SEND_STATUS;
16275 }
16276
16277 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
16278 send_resp(dut, conn, SIGMA_COMPLETE, buf);
16279 return STATUS_SENT;
16280 }
16281
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016282 val = get_param(cmd, "HESSID");
16283 if (val) {
16284 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
16285 if (res < 0 || res >= (int) sizeof(buf))
16286 return -1;
16287 wpa_command(intf, buf);
16288 }
16289
16290 val = get_param(cmd, "ACCS_NET_TYPE");
16291 if (val) {
16292 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
16293 val);
16294 if (res < 0 || res >= (int) sizeof(buf))
16295 return -1;
16296 wpa_command(intf, buf);
16297 }
16298
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016299 if (get_param(cmd, "RxMac"))
16300 sta_set_scan_unicast_probe(dut, intf, 1);
16301
vamsi krishna89ad8c62017-09-19 12:51:18 +053016302 bssid = get_param(cmd, "Bssid");
16303 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016304 if (!bssid)
16305 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053016306
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016307 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
16308 dut->device_type == STA_testbed) {
16309 ssid = NULL;
16310 wildcard_ssid = 1;
16311 }
16312
vamsi krishna89ad8c62017-09-19 12:51:18 +053016313 if (ssid) {
16314 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
16315 send_resp(dut, conn, SIGMA_ERROR,
16316 "ErrorCode,Too long SSID");
16317 return 0;
16318 }
16319 ascii2hexstr(ssid, ssid_hex);
16320 }
16321
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016322 short_ssid = get_param(cmd, "ShortSSID");
16323 if (short_ssid) {
16324 uint32_t short_ssid_hex;
16325
16326 short_ssid_hex = strtoul(short_ssid, NULL, 16);
16327 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
16328 (((short_ssid_hex >> 8) & 0xFF) << 16) |
16329 (((short_ssid_hex >> 16) & 0xFF) << 8) |
16330 ((short_ssid_hex >> 24) & 0xFF);
16331
16332 res = snprintf(buf, sizeof(buf),
16333 "VENDOR_ELEM_ADD 14 ff053a%08x",
16334 short_ssid_hex);
16335 if (res < 0 || res >= (int) sizeof(buf) ||
16336 wpa_command(intf, buf)) {
16337 send_resp(dut, conn, SIGMA_ERROR,
16338 "errorCode,Failed to add short SSID");
16339 return STATUS_SENT_ERROR;
16340 }
16341 }
16342
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016343 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053016344 if (scan_freq) {
16345 if (strcasecmp(scan_freq, "2G") == 0)
16346 scan_freq = "2412-2462";
16347 else if (strcasecmp(scan_freq, "5G") == 0)
16348 scan_freq = "5180-5925";
16349 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016350
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016351 val = get_param(cmd, "WaitCompletion");
16352 if (val && atoi(val) == 1) {
16353 ctrl = open_wpa_mon(intf);
16354 if (!ctrl) {
16355 send_resp(dut, conn, SIGMA_ERROR,
16356 "errorCode,Failed to open monitor socket");
16357 return STATUS_SENT_ERROR;
16358 }
16359 }
16360
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016361 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053016362 bssid ? " bssid=": "",
16363 bssid ? bssid : "",
16364 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016365 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016366 wildcard_ssid ? " wildcard_ssid=1" : "",
16367 scan_freq ? " freq=" : "",
16368 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016369 if (res < 0 || res >= (int) sizeof(buf)) {
16370 send_resp(dut, conn, SIGMA_ERROR,
16371 "errorCode,Could not build scan command");
16372 status = STATUS_SENT_ERROR;
16373 goto remove_s_ssid;
16374 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053016375
Veerendranathdc581b52020-08-10 03:29:08 -070016376 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
16377 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
16378 sigma_dut_print(dut, DUT_MSG_DEBUG,
16379 "Scan request rejected with busy status, abort ongoing scan and try again");
16380 wpa_command(intf, "ABORT_SCAN");
16381 res = wpa_command(intf, buf);
16382 }
16383
16384 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016385 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
16386 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016387 status = STATUS_SENT_ERROR;
16388 } else {
16389 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016390 }
16391
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016392remove_s_ssid:
16393 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
16394 sigma_dut_print(dut, DUT_MSG_ERROR,
16395 "Failed to delete vendor element");
16396
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016397 if (ctrl) {
16398 if (status == SUCCESS_SEND_STATUS) {
16399 res = get_wpa_cli_event(dut, ctrl,
16400 "CTRL-EVENT-SCAN-RESULTS",
16401 buf, sizeof(buf));
16402 if (res < 0) {
16403 send_resp(dut, conn, SIGMA_ERROR,
16404 "ErrorCode,scan did not complete");
16405 status = STATUS_SENT_ERROR;
16406 }
16407 }
16408
16409 wpa_ctrl_detach(ctrl);
16410 wpa_ctrl_close(ctrl);
16411 }
16412
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016413 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016414}
16415
16416
Jouni Malinenf7222712019-06-13 01:50:21 +030016417static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
16418 struct sigma_conn *conn,
16419 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016420{
16421 const char *intf = get_param(cmd, "Interface");
16422 const char *bssid;
16423 char buf[4096], *pos;
16424 int freq, chan;
16425 char *ssid;
16426 char resp[100];
16427 int res;
16428 struct wpa_ctrl *ctrl;
16429
16430 bssid = get_param(cmd, "BSSID");
16431 if (!bssid) {
16432 send_resp(dut, conn, SIGMA_INVALID,
16433 "errorCode,BSSID argument is missing");
16434 return 0;
16435 }
16436
16437 ctrl = open_wpa_mon(intf);
16438 if (!ctrl) {
16439 sigma_dut_print(dut, DUT_MSG_ERROR,
16440 "Failed to open wpa_supplicant monitor connection");
16441 return -1;
16442 }
16443
16444 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
16445 send_resp(dut, conn, SIGMA_ERROR,
16446 "errorCode,Could not start scan");
16447 wpa_ctrl_detach(ctrl);
16448 wpa_ctrl_close(ctrl);
16449 return 0;
16450 }
16451
16452 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
16453 buf, sizeof(buf));
16454
16455 wpa_ctrl_detach(ctrl);
16456 wpa_ctrl_close(ctrl);
16457
16458 if (res < 0) {
16459 send_resp(dut, conn, SIGMA_ERROR,
16460 "errorCode,Scan did not complete");
16461 return 0;
16462 }
16463
16464 snprintf(buf, sizeof(buf), "BSS %s", bssid);
16465 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
16466 strncmp(buf, "id=", 3) != 0) {
16467 send_resp(dut, conn, SIGMA_ERROR,
16468 "errorCode,Specified BSSID not found");
16469 return 0;
16470 }
16471
16472 pos = strstr(buf, "\nfreq=");
16473 if (!pos) {
16474 send_resp(dut, conn, SIGMA_ERROR,
16475 "errorCode,Channel not found");
16476 return 0;
16477 }
16478 freq = atoi(pos + 6);
16479 chan = freq_to_channel(freq);
16480
16481 pos = strstr(buf, "\nssid=");
16482 if (!pos) {
16483 send_resp(dut, conn, SIGMA_ERROR,
16484 "errorCode,SSID not found");
16485 return 0;
16486 }
16487 ssid = pos + 6;
16488 pos = strchr(ssid, '\n');
16489 if (pos)
16490 *pos = '\0';
16491 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
16492 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16493 return 0;
16494}
16495
16496
Jouni Malinenf7222712019-06-13 01:50:21 +030016497static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
16498 struct sigma_conn *conn,
16499 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016500{
16501#ifdef __linux__
16502 struct timeval tv;
16503 struct tm tm;
16504 time_t t;
16505 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016506 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016507
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016508 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016509
16510 memset(&tm, 0, sizeof(tm));
16511 val = get_param(cmd, "seconds");
16512 if (val)
16513 tm.tm_sec = atoi(val);
16514 val = get_param(cmd, "minutes");
16515 if (val)
16516 tm.tm_min = atoi(val);
16517 val = get_param(cmd, "hours");
16518 if (val)
16519 tm.tm_hour = atoi(val);
16520 val = get_param(cmd, "date");
16521 if (val)
16522 tm.tm_mday = atoi(val);
16523 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016524 if (val) {
16525 v = atoi(val);
16526 if (v < 1 || v > 12) {
16527 send_resp(dut, conn, SIGMA_INVALID,
16528 "errorCode,Invalid month");
16529 return 0;
16530 }
16531 tm.tm_mon = v - 1;
16532 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016533 val = get_param(cmd, "year");
16534 if (val) {
16535 int year = atoi(val);
16536#ifdef ANDROID
16537 if (year > 2035)
16538 year = 2035; /* years beyond 2035 not supported */
16539#endif /* ANDROID */
16540 tm.tm_year = year - 1900;
16541 }
16542 t = mktime(&tm);
16543 if (t == (time_t) -1) {
16544 send_resp(dut, conn, SIGMA_ERROR,
16545 "errorCode,Invalid date or time");
16546 return 0;
16547 }
16548
16549 memset(&tv, 0, sizeof(tv));
16550 tv.tv_sec = t;
16551
16552 if (settimeofday(&tv, NULL) < 0) {
16553 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
16554 strerror(errno));
16555 send_resp(dut, conn, SIGMA_ERROR,
16556 "errorCode,Failed to set time");
16557 return 0;
16558 }
16559
16560 return 1;
16561#endif /* __linux__ */
16562
16563 return -1;
16564}
16565
16566
Jouni Malinenf7222712019-06-13 01:50:21 +030016567static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
16568 struct sigma_conn *conn,
16569 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016570{
16571 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016572 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016573 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016574 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016575 int res;
16576 struct wpa_ctrl *ctrl;
16577
16578 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016579 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016580
16581 val = get_param(cmd, "ProdESSAssoc");
16582 if (val)
16583 prod_ess_assoc = atoi(val);
16584
16585 kill_dhcp_client(dut, intf);
16586 if (start_dhcp_client(dut, intf) < 0)
16587 return -2;
16588
16589 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
16590 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16591 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016592 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016593 prod_ess_assoc ? "" : "-N",
16594 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016595 name ? "'" : "",
16596 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
16597 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016598
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053016599 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016600 if (run_hs20_osu(dut, buf) < 0) {
16601 FILE *f;
16602
16603 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
16604
16605 f = fopen("hs20-osu-client.res", "r");
16606 if (f) {
16607 char resp[400], res[300], *pos;
16608 if (!fgets(res, sizeof(res), f))
16609 res[0] = '\0';
16610 pos = strchr(res, '\n');
16611 if (pos)
16612 *pos = '\0';
16613 fclose(f);
16614 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
16615 res);
16616 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
16617 if (system(resp) != 0) {
16618 }
16619 snprintf(resp, sizeof(resp),
16620 "SSID,,BSSID,,failureReason,%s", res);
16621 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16622 return 0;
16623 }
16624
16625 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16626 return 0;
16627 }
16628
16629 if (!prod_ess_assoc)
16630 goto report;
16631
16632 ctrl = open_wpa_mon(intf);
16633 if (ctrl == NULL) {
16634 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16635 "wpa_supplicant monitor connection");
16636 return -1;
16637 }
16638
16639 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
16640 buf, sizeof(buf));
16641
16642 wpa_ctrl_detach(ctrl);
16643 wpa_ctrl_close(ctrl);
16644
16645 if (res < 0) {
16646 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
16647 "network after OSU");
16648 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16649 return 0;
16650 }
16651
16652report:
16653 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
16654 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
16655 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
16656 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16657 return 0;
16658 }
16659
16660 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
16661 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016662 return 0;
16663}
16664
16665
Jouni Malinenf7222712019-06-13 01:50:21 +030016666static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
16667 struct sigma_conn *conn,
16668 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016669{
16670 const char *val;
16671 int timeout = 120;
16672
16673 val = get_param(cmd, "PolicyUpdate");
16674 if (val == NULL || atoi(val) == 0)
16675 return 1; /* No operation requested */
16676
16677 val = get_param(cmd, "Timeout");
16678 if (val)
16679 timeout = atoi(val);
16680
16681 if (timeout) {
16682 /* TODO: time out the command and return
16683 * PolicyUpdateStatus,TIMEOUT if needed. */
16684 }
16685
16686 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
16687 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16688 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
16689 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
16690 return 0;
16691 }
16692
16693 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
16694 return 0;
16695}
16696
16697
Jouni Malinenf7222712019-06-13 01:50:21 +030016698static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
16699 struct sigma_conn *conn,
16700 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016701{
16702 struct wpa_ctrl *ctrl;
16703 const char *intf = get_param(cmd, "Interface");
16704 const char *bssid = get_param(cmd, "Bssid");
16705 const char *ssid = get_param(cmd, "SSID");
16706 const char *security = get_param(cmd, "Security");
16707 const char *passphrase = get_param(cmd, "Passphrase");
16708 const char *pin = get_param(cmd, "PIN");
16709 char buf[1000];
16710 char ssid_hex[200], passphrase_hex[200];
16711 const char *keymgmt, *cipher;
16712
16713 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016714 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016715
16716 if (!bssid) {
16717 send_resp(dut, conn, SIGMA_ERROR,
16718 "ErrorCode,Missing Bssid argument");
16719 return 0;
16720 }
16721
16722 if (!ssid) {
16723 send_resp(dut, conn, SIGMA_ERROR,
16724 "ErrorCode,Missing SSID argument");
16725 return 0;
16726 }
16727
16728 if (!security) {
16729 send_resp(dut, conn, SIGMA_ERROR,
16730 "ErrorCode,Missing Security argument");
16731 return 0;
16732 }
16733
16734 if (!passphrase) {
16735 send_resp(dut, conn, SIGMA_ERROR,
16736 "ErrorCode,Missing Passphrase argument");
16737 return 0;
16738 }
16739
16740 if (!pin) {
16741 send_resp(dut, conn, SIGMA_ERROR,
16742 "ErrorCode,Missing PIN argument");
16743 return 0;
16744 }
16745
vamsi krishna8c9c1562017-05-12 15:51:46 +053016746 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
16747 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016748 send_resp(dut, conn, SIGMA_ERROR,
16749 "ErrorCode,Too long SSID/passphrase");
16750 return 0;
16751 }
16752
16753 ctrl = open_wpa_mon(intf);
16754 if (ctrl == NULL) {
16755 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16756 "wpa_supplicant monitor connection");
16757 return -2;
16758 }
16759
16760 if (strcasecmp(security, "wpa2-psk") == 0) {
16761 keymgmt = "WPA2PSK";
16762 cipher = "CCMP";
16763 } else {
16764 wpa_ctrl_detach(ctrl);
16765 wpa_ctrl_close(ctrl);
16766 send_resp(dut, conn, SIGMA_ERROR,
16767 "ErrorCode,Unsupported Security value");
16768 return 0;
16769 }
16770
16771 ascii2hexstr(ssid, ssid_hex);
16772 ascii2hexstr(passphrase, passphrase_hex);
16773 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
16774 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
16775
16776 if (wpa_command(intf, buf) < 0) {
16777 wpa_ctrl_detach(ctrl);
16778 wpa_ctrl_close(ctrl);
16779 send_resp(dut, conn, SIGMA_ERROR,
16780 "ErrorCode,Failed to start registrar");
16781 return 0;
16782 }
16783
16784 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
16785 dut->er_oper_performed = 1;
16786
16787 return wps_connection_event(dut, conn, ctrl, intf, 0);
16788}
16789
16790
Jouni Malinenf7222712019-06-13 01:50:21 +030016791static enum sigma_cmd_result
16792cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
16793 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016794{
16795 struct wpa_ctrl *ctrl;
16796 const char *intf = get_param(cmd, "Interface");
16797 const char *bssid = get_param(cmd, "Bssid");
16798 char buf[100];
16799
16800 if (!bssid) {
16801 send_resp(dut, conn, SIGMA_ERROR,
16802 "ErrorCode,Missing Bssid argument");
16803 return 0;
16804 }
16805
16806 ctrl = open_wpa_mon(intf);
16807 if (ctrl == NULL) {
16808 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16809 "wpa_supplicant monitor connection");
16810 return -2;
16811 }
16812
16813 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
16814
16815 if (wpa_command(intf, buf) < 0) {
16816 wpa_ctrl_detach(ctrl);
16817 wpa_ctrl_close(ctrl);
16818 send_resp(dut, conn, SIGMA_ERROR,
16819 "ErrorCode,Failed to start registrar");
16820 return 0;
16821 }
16822
16823 return wps_connection_event(dut, conn, ctrl, intf, 0);
16824}
16825
16826
Jouni Malinenf7222712019-06-13 01:50:21 +030016827static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
16828 struct sigma_conn *conn,
16829 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053016830{
16831 struct wpa_ctrl *ctrl;
16832 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016833 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016834 const char *config_method = get_param(cmd, "WPSConfigMethod");
16835 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053016836 int res;
16837 char buf[256];
16838 const char *events[] = {
16839 "CTRL-EVENT-CONNECTED",
16840 "WPS-OVERLAP-DETECTED",
16841 "WPS-TIMEOUT",
16842 "WPS-FAIL",
16843 NULL
16844 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016845 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053016846
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016847 /* 60G WPS tests do not pass Interface parameter */
16848 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016849 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016850
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016851 if (dut->mode == SIGMA_MODE_AP)
16852 return ap_wps_registration(dut, conn, cmd);
16853
16854 if (config_method) {
16855 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
16856 * sta_wps_enter_pin before calling start_wps_registration. */
16857 if (strcasecmp(config_method, "PBC") == 0)
16858 dut->wps_method = WFA_CS_WPS_PBC;
16859 }
16860 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
16861 send_resp(dut, conn, SIGMA_ERROR,
16862 "ErrorCode,WPS parameters not yet set");
16863 return STATUS_SENT;
16864 }
16865
16866 /* Make sure WPS is enabled (also for STA mode) */
16867 dut->wps_disable = 0;
16868
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016869 if (dut->band == WPS_BAND_60G && network_mode &&
16870 strcasecmp(network_mode, "PBSS") == 0) {
16871 sigma_dut_print(dut, DUT_MSG_DEBUG,
16872 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016873 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016874 return -2;
16875 }
16876
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016877 if (dut->force_rsn_ie) {
16878 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
16879 dut->force_rsn_ie);
16880 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
16881 sigma_dut_print(dut, DUT_MSG_INFO,
16882 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020016883 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016884 }
16885 }
16886
vamsi krishna9b144002017-09-20 13:28:13 +053016887 ctrl = open_wpa_mon(intf);
16888 if (!ctrl) {
16889 sigma_dut_print(dut, DUT_MSG_ERROR,
16890 "Failed to open wpa_supplicant monitor connection");
16891 return -2;
16892 }
16893
16894 role = get_param(cmd, "WpsRole");
16895 if (!role) {
16896 send_resp(dut, conn, SIGMA_INVALID,
16897 "ErrorCode,WpsRole not provided");
16898 goto fail;
16899 }
16900
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016901 if (strcasecmp(role, "Enrollee") != 0) {
16902 /* Registrar role for STA not supported */
16903 send_resp(dut, conn, SIGMA_ERROR,
16904 "ErrorCode,Unsupported WpsRole value");
16905 goto fail;
16906 }
16907
16908 if (is_60g_sigma_dut(dut)) {
16909 if (dut->wps_method == WFA_CS_WPS_PBC)
16910 snprintf(buf, sizeof(buf), "WPS_PBC");
16911 else /* WFA_CS_WPS_PIN_KEYPAD */
16912 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
16913 dut->wps_pin);
16914 if (wpa_command(intf, buf) < 0) {
16915 send_resp(dut, conn, SIGMA_ERROR,
16916 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053016917 goto fail;
16918 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016919 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16920 if (res < 0) {
16921 send_resp(dut, conn, SIGMA_ERROR,
16922 "ErrorCode,WPS connection did not complete");
16923 goto fail;
16924 }
16925 if (strstr(buf, "WPS-TIMEOUT")) {
16926 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
16927 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16928 send_resp(dut, conn, SIGMA_COMPLETE,
16929 "WpsState,OverlapSession");
16930 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16931 send_resp(dut, conn, SIGMA_COMPLETE,
16932 "WpsState,Successful");
16933 } else {
16934 send_resp(dut, conn, SIGMA_COMPLETE,
16935 "WpsState,Failure");
16936 }
16937 } else {
16938 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053016939 if (wpa_command(intf, "WPS_PBC") < 0) {
16940 send_resp(dut, conn, SIGMA_ERROR,
16941 "ErrorCode,Failed to enable PBC");
16942 goto fail;
16943 }
16944 } else {
16945 /* TODO: PIN method */
16946 send_resp(dut, conn, SIGMA_ERROR,
16947 "ErrorCode,Unsupported WpsConfigMethod value");
16948 goto fail;
16949 }
16950 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16951 if (res < 0) {
16952 send_resp(dut, conn, SIGMA_ERROR,
16953 "ErrorCode,WPS connection did not complete");
16954 goto fail;
16955 }
16956 if (strstr(buf, "WPS-TIMEOUT")) {
16957 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
16958 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16959 send_resp(dut, conn, SIGMA_ERROR,
16960 "ErrorCode,OverlapSession");
16961 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16962 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
16963 } else {
16964 send_resp(dut, conn, SIGMA_ERROR,
16965 "ErrorCode,WPS operation failed");
16966 }
vamsi krishna9b144002017-09-20 13:28:13 +053016967 }
16968
16969fail:
16970 wpa_ctrl_detach(ctrl);
16971 wpa_ctrl_close(ctrl);
16972 return 0;
16973}
16974
16975
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016976static int req_intf(struct sigma_cmd *cmd)
16977{
16978 return get_param(cmd, "interface") == NULL ? -1 : 0;
16979}
16980
16981
16982void sta_register_cmds(void)
16983{
16984 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
16985 cmd_sta_get_ip_config);
16986 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
16987 cmd_sta_set_ip_config);
16988 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
16989 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
16990 cmd_sta_get_mac_address);
16991 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
16992 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
16993 cmd_sta_verify_ip_connection);
16994 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
16995 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
16996 cmd_sta_set_encryption);
16997 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
16998 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
16999 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
17000 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
17001 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
17002 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
17003 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
17004 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
17005 cmd_sta_set_eapakaprime);
17006 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
17007 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
17008 /* TODO: sta_set_ibss */
17009 /* TODO: sta_set_mode */
17010 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
17011 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
17012 /* TODO: sta_up_load */
17013 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
17014 cmd_sta_preset_testparameters);
17015 /* TODO: sta_set_system */
17016 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
17017 /* TODO: sta_set_rifs_test */
17018 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
17019 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
17020 /* TODO: sta_send_coexist_mgmt */
17021 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
17022 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
17023 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
17024 sigma_dut_reg_cmd("sta_reset_default", req_intf,
17025 cmd_sta_reset_default);
17026 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
17027 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
17028 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
17029 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
17030 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020017031 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017032 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
17033 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
17034 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
17035 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
17036 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030017037 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
17038 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017039 sigma_dut_reg_cmd("sta_add_credential", req_intf,
17040 cmd_sta_add_credential);
17041 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020017042 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017043 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
17044 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
17045 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
17046 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
17047 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
17048 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030017049 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017050 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
17051 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020017052 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053017053 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017054}