blob: 1a1cf1c2926e6c7efedd8fd395538fc640c0d2cd [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
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001597 /* TODO */
1598 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1599 "setting", val);
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301600#else /* ANDROID */
1601 char dns_cmd[200];
1602 int len;
1603
1604 if (system("sed -i '/nameserver/d' /etc/resolv.conf") != 0) {
1605 sigma_dut_print(dut, DUT_MSG_ERROR,
1606 "Failed to clear nameserver entries in /etc/resolv.conf");
1607 return ERROR_SEND_STATUS;
1608 }
1609
1610 len = snprintf(dns_cmd, sizeof(dns_cmd),
1611 "sed -i '1 i nameserver %s' /etc/resolv.conf", val);
1612 if (len < 0 || len >= sizeof(dns_cmd))
1613 return ERROR_SEND_STATUS;
1614
1615 sigma_dut_print(dut, DUT_MSG_DEBUG, "Running %s", dns_cmd);
1616 if (system(dns_cmd) != 0) {
1617 send_resp(dut, conn, SIGMA_ERROR,
1618 "ErrorCode,Failed to set primary-dns");
1619 return STATUS_SENT_ERROR;
1620 }
1621#endif /* ANDROID */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001622 }
1623
1624 val = get_param(cmd, "secondary-dns");
1625 if (val) {
1626 /* TODO */
1627 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1628 "setting", val);
1629 }
1630
1631 static_ip_file(4, ip, mask, gw);
1632
1633 return 1;
1634}
1635
1636
Jouni Malinenf7222712019-06-13 01:50:21 +03001637static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1638 struct sigma_conn *conn,
1639 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001640{
1641 /* const char *intf = get_param(cmd, "Interface"); */
1642 /* TODO: could report more details here */
1643 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1644 return 0;
1645}
1646
1647
Jouni Malinenf7222712019-06-13 01:50:21 +03001648static enum sigma_cmd_result cmd_sta_get_mac_address(struct sigma_dut *dut,
1649 struct sigma_conn *conn,
1650 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001651{
1652 /* const char *intf = get_param(cmd, "Interface"); */
1653 char addr[20], resp[50];
1654
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301655 if (dut->dev_role == DEVROLE_STA_CFON)
1656 return sta_cfon_get_mac_address(dut, conn, cmd);
1657
Jouni Malinen9540e012019-11-05 17:08:42 +02001658 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001659 if (get_wpa_status(get_station_ifname(dut), "address",
1660 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001661 return -2;
1662
1663 snprintf(resp, sizeof(resp), "mac,%s", addr);
1664 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1665 return 0;
1666}
1667
1668
Jouni Malinenf7222712019-06-13 01:50:21 +03001669static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1670 struct sigma_conn *conn,
1671 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001672{
1673 /* const char *intf = get_param(cmd, "Interface"); */
1674 int connected = 0;
1675 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001676 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001677 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001678 sigma_dut_print(dut, DUT_MSG_INFO,
1679 "Could not get interface %s status",
1680 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001681 return -2;
1682 }
1683
1684 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1685 if (strncmp(result, "COMPLETED", 9) == 0)
1686 connected = 1;
1687
1688 if (connected)
1689 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1690 else
1691 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1692
1693 return 0;
1694}
1695
1696
Jouni Malinenf7222712019-06-13 01:50:21 +03001697static enum sigma_cmd_result
1698cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1699 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001700{
1701 /* const char *intf = get_param(cmd, "Interface"); */
1702 const char *dst, *timeout;
1703 int wait_time = 90;
1704 char buf[100];
1705 int res;
1706
1707 dst = get_param(cmd, "destination");
1708 if (dst == NULL || !is_ip_addr(dst))
1709 return -1;
1710
1711 timeout = get_param(cmd, "timeout");
1712 if (timeout) {
1713 wait_time = atoi(timeout);
1714 if (wait_time < 1)
1715 wait_time = 1;
1716 }
1717
1718 /* TODO: force renewal of IP lease if DHCP is enabled */
1719
1720 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1721 res = system(buf);
1722 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1723 if (res == 0)
1724 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1725 else if (res == 256)
1726 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1727 else
1728 return -2;
1729
1730 return 0;
1731}
1732
1733
Jouni Malinenf7222712019-06-13 01:50:21 +03001734static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1735 struct sigma_conn *conn,
1736 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001737{
1738 /* const char *intf = get_param(cmd, "Interface"); */
1739 char bssid[20], resp[50];
1740
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001741 if (get_wpa_status(get_station_ifname(dut), "bssid",
1742 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001743 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001744
1745 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1746 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1747 return 0;
1748}
1749
1750
1751#ifdef __SAMSUNG__
1752static int add_use_network(const char *ifname)
1753{
1754 char buf[100];
1755
1756 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1757 wpa_command(ifname, buf);
1758 return 0;
1759}
1760#endif /* __SAMSUNG__ */
1761
1762
1763static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1764 const char *ifname, struct sigma_cmd *cmd)
1765{
1766 const char *ssid = get_param(cmd, "ssid");
1767 int id;
1768 const char *val;
1769
1770 if (ssid == NULL)
1771 return -1;
1772
1773 start_sta_mode(dut);
1774
1775#ifdef __SAMSUNG__
1776 add_use_network(ifname);
1777#endif /* __SAMSUNG__ */
1778
1779 id = add_network(ifname);
1780 if (id < 0)
1781 return -2;
1782 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1783
1784 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1785 return -2;
1786
1787 dut->infra_network_id = id;
1788 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1789
1790 val = get_param(cmd, "program");
1791 if (!val)
1792 val = get_param(cmd, "prog");
1793 if (val && strcasecmp(val, "hs2") == 0) {
1794 char buf[100];
1795 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1796 wpa_command(ifname, buf);
1797
1798 val = get_param(cmd, "prefer");
1799 if (val && atoi(val) > 0)
1800 set_network(ifname, id, "priority", "1");
1801 }
1802
1803 return id;
1804}
1805
1806
Jouni Malinenf7222712019-06-13 01:50:21 +03001807static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1808 struct sigma_conn *conn,
1809 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001810{
1811 const char *intf = get_param(cmd, "Interface");
1812 const char *ssid = get_param(cmd, "ssid");
1813 const char *type = get_param(cmd, "encpType");
1814 const char *ifname;
1815 char buf[200];
1816 int id;
1817
1818 if (intf == NULL || ssid == NULL)
1819 return -1;
1820
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001821 if (strcmp(intf, get_main_ifname(dut)) == 0)
1822 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001823 else
1824 ifname = intf;
1825
1826 id = add_network_common(dut, conn, ifname, cmd);
1827 if (id < 0)
1828 return id;
1829
1830 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1831 return -2;
1832
1833 if (type && strcasecmp(type, "wep") == 0) {
1834 const char *val;
1835 int i;
1836
1837 val = get_param(cmd, "activeKey");
1838 if (val) {
1839 int keyid;
1840 keyid = atoi(val);
1841 if (keyid < 1 || keyid > 4)
1842 return -1;
1843 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1844 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1845 return -2;
1846 }
1847
1848 for (i = 0; i < 4; i++) {
1849 snprintf(buf, sizeof(buf), "key%d", i + 1);
1850 val = get_param(cmd, buf);
1851 if (val == NULL)
1852 continue;
1853 snprintf(buf, sizeof(buf), "wep_key%d", i);
1854 if (set_network(ifname, id, buf, val) < 0)
1855 return -2;
1856 }
1857 }
1858
1859 return 1;
1860}
1861
1862
Jouni Malinene4fde732019-03-25 22:29:37 +02001863static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1864 int id, const char *val)
1865{
1866 char key_mgmt[200], *end, *pos;
1867 const char *in_pos = val;
1868
Jouni Malinen8179fee2019-03-28 03:19:47 +02001869 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001870 pos = key_mgmt;
1871 end = pos + sizeof(key_mgmt);
1872 while (*in_pos) {
1873 int res, akm = atoi(in_pos);
1874 const char *str;
1875
Jouni Malinen8179fee2019-03-28 03:19:47 +02001876 if (akm >= 0 && akm < 32)
1877 dut->akm_values |= 1 << akm;
1878
Jouni Malinene4fde732019-03-25 22:29:37 +02001879 switch (akm) {
1880 case AKM_WPA_EAP:
1881 str = "WPA-EAP";
1882 break;
1883 case AKM_WPA_PSK:
1884 str = "WPA-PSK";
1885 break;
1886 case AKM_FT_EAP:
1887 str = "FT-EAP";
1888 break;
1889 case AKM_FT_PSK:
1890 str = "FT-PSK";
1891 break;
1892 case AKM_EAP_SHA256:
1893 str = "WPA-EAP-SHA256";
1894 break;
1895 case AKM_PSK_SHA256:
1896 str = "WPA-PSK-SHA256";
1897 break;
1898 case AKM_SAE:
1899 str = "SAE";
1900 break;
1901 case AKM_FT_SAE:
1902 str = "FT-SAE";
1903 break;
1904 case AKM_SUITE_B:
1905 str = "WPA-EAP-SUITE-B-192";
1906 break;
1907 case AKM_FT_SUITE_B:
1908 str = "FT-EAP-SHA384";
1909 break;
1910 case AKM_FILS_SHA256:
1911 str = "FILS-SHA256";
1912 break;
1913 case AKM_FILS_SHA384:
1914 str = "FILS-SHA384";
1915 break;
1916 case AKM_FT_FILS_SHA256:
1917 str = "FT-FILS-SHA256";
1918 break;
1919 case AKM_FT_FILS_SHA384:
1920 str = "FT-FILS-SHA384";
1921 break;
1922 default:
1923 sigma_dut_print(dut, DUT_MSG_ERROR,
1924 "Unsupported AKMSuitetype %d", akm);
1925 return -1;
1926 }
1927
1928 res = snprintf(pos, end - pos, "%s%s",
1929 pos == key_mgmt ? "" : " ", str);
1930 if (res < 0 || res >= end - pos)
1931 return -1;
1932 pos += res;
1933
1934 in_pos = strchr(in_pos, ';');
1935 if (!in_pos)
1936 break;
1937 while (*in_pos == ';')
1938 in_pos++;
1939 }
1940 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1941 val, key_mgmt);
1942 return set_network(ifname, id, "key_mgmt", key_mgmt);
1943}
1944
1945
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001946static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1947 const char *ifname, struct sigma_cmd *cmd)
1948{
1949 const char *val;
1950 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001951 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001952 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301953 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001954
1955 id = add_network_common(dut, conn, ifname, cmd);
1956 if (id < 0)
1957 return id;
1958
Jouni Malinen47dcc952017-10-09 16:43:24 +03001959 val = get_param(cmd, "Type");
1960 owe = val && strcasecmp(val, "OWE") == 0;
1961
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001962 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001963 if (!val && owe)
1964 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001965 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001966 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1967 * this missing parameter and assume proto=WPA2. */
1968 if (set_network(ifname, id, "proto", "WPA2") < 0)
1969 return ERROR_SEND_STATUS;
1970 } else if (strcasecmp(val, "wpa") == 0 ||
1971 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001972 if (set_network(ifname, id, "proto", "WPA") < 0)
1973 return -2;
1974 } else if (strcasecmp(val, "wpa2") == 0 ||
1975 strcasecmp(val, "wpa2-psk") == 0 ||
1976 strcasecmp(val, "wpa2-ft") == 0 ||
1977 strcasecmp(val, "wpa2-sha256") == 0) {
1978 if (set_network(ifname, id, "proto", "WPA2") < 0)
1979 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301980 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1981 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001982 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1983 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001984 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301985 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001986 if (set_network(ifname, id, "proto", "WPA2") < 0)
1987 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001988 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001989 } else {
1990 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1991 return 0;
1992 }
1993
1994 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001995 if (val) {
1996 cipher_set = 1;
1997 if (strcasecmp(val, "tkip") == 0) {
1998 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1999 return -2;
2000 } else if (strcasecmp(val, "aes-ccmp") == 0) {
2001 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2002 return -2;
2003 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
2004 if (set_network(ifname, id, "pairwise",
2005 "CCMP TKIP") < 0)
2006 return -2;
2007 } else if (strcasecmp(val, "aes-gcmp") == 0) {
2008 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2009 return -2;
2010 if (set_network(ifname, id, "group", "GCMP") < 0)
2011 return -2;
2012 } else {
2013 send_resp(dut, conn, SIGMA_ERROR,
2014 "errorCode,Unrecognized encpType value");
2015 return 0;
2016 }
2017 }
2018
2019 val = get_param(cmd, "PairwiseCipher");
2020 if (val) {
2021 cipher_set = 1;
2022 /* TODO: Support space separated list */
2023 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2024 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
2025 return -2;
2026 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2027 if (set_network(ifname, id, "pairwise",
2028 "CCMP-256") < 0)
2029 return -2;
2030 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2031 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2032 return -2;
2033 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2034 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2035 return -2;
2036 } else {
2037 send_resp(dut, conn, SIGMA_ERROR,
2038 "errorCode,Unrecognized PairwiseCipher value");
2039 return 0;
2040 }
2041 }
2042
Jouni Malinen47dcc952017-10-09 16:43:24 +03002043 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03002044 send_resp(dut, conn, SIGMA_ERROR,
2045 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002046 return 0;
2047 }
Jouni Malinenad395a22017-09-01 21:13:46 +03002048
2049 val = get_param(cmd, "GroupCipher");
2050 if (val) {
2051 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2052 if (set_network(ifname, id, "group", "GCMP-256") < 0)
2053 return -2;
2054 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2055 if (set_network(ifname, id, "group", "CCMP-256") < 0)
2056 return -2;
2057 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2058 if (set_network(ifname, id, "group", "GCMP") < 0)
2059 return -2;
2060 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2061 if (set_network(ifname, id, "group", "CCMP") < 0)
2062 return -2;
2063 } else {
2064 send_resp(dut, conn, SIGMA_ERROR,
2065 "errorCode,Unrecognized GroupCipher value");
2066 return 0;
2067 }
2068 }
2069
Jouni Malinen7b239522017-09-14 21:37:18 +03002070 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03002071 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03002072 const char *cipher;
2073
2074 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2075 cipher = "BIP-GMAC-256";
2076 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2077 cipher = "BIP-CMAC-256";
2078 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2079 cipher = "BIP-GMAC-128";
2080 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2081 cipher = "AES-128-CMAC";
2082 } else {
2083 send_resp(dut, conn, SIGMA_INVALID,
2084 "errorCode,Unsupported GroupMgntCipher");
2085 return 0;
2086 }
2087 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
2088 send_resp(dut, conn, SIGMA_INVALID,
2089 "errorCode,Failed to set GroupMgntCipher");
2090 return 0;
2091 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002092 }
2093
Jouni Malinene4fde732019-03-25 22:29:37 +02002094 val = get_param(cmd, "AKMSuiteType");
2095 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2096 return ERROR_SEND_STATUS;
2097
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002098 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302099
2100 if (dut->program == PROGRAM_OCE) {
2101 dut->sta_pmf = STA_PMF_OPTIONAL;
2102 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2103 return -2;
2104 }
2105
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002106 val = get_param(cmd, "PMF");
2107 if (val) {
2108 if (strcasecmp(val, "Required") == 0 ||
2109 strcasecmp(val, "Forced_Required") == 0) {
2110 dut->sta_pmf = STA_PMF_REQUIRED;
2111 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2112 return -2;
2113 } else if (strcasecmp(val, "Optional") == 0) {
2114 dut->sta_pmf = STA_PMF_OPTIONAL;
2115 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2116 return -2;
2117 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002118 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002119 strcasecmp(val, "Forced_Disabled") == 0) {
2120 dut->sta_pmf = STA_PMF_DISABLED;
2121 } else {
2122 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2123 return 0;
2124 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302125 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002126 dut->sta_pmf = STA_PMF_REQUIRED;
2127 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2128 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002129 }
2130
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002131 val = get_param(cmd, "BeaconProtection");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05302132 if (val)
2133 dut->beacon_prot = atoi(val);
2134 if (dut->beacon_prot && set_network(ifname, id, "beacon_prot", "1") < 0)
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002135 return ERROR_SEND_STATUS;
2136
Veerendranath Jakkam54fd51c2020-12-21 01:36:04 +05302137 if (dut->ocvc && set_network(ifname, id, "ocv", "1") < 0)
2138 return ERROR_SEND_STATUS;
2139
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002140 return id;
2141}
2142
2143
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302144static int wcn_set_ignore_h2e_rsnxe(struct sigma_dut *dut, const char *intf,
2145 uint8_t cfg)
2146{
2147#ifdef NL80211_SUPPORT
2148 return wcn_wifi_test_config_set_u8(
2149 dut, intf,
2150 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE, cfg);
2151#else /* NL80211_SUPPORT */
2152 sigma_dut_print(dut, DUT_MSG_ERROR,
2153 "Ignore SAE H2E requirement mismatch can't be set without NL80211_SUPPORT defined");
2154 return -1;
2155#endif /* NL80211_SUPPORT */
2156}
2157
2158
Jouni Malinenf7222712019-06-13 01:50:21 +03002159static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2160 struct sigma_conn *conn,
2161 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002162{
2163 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002164 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002165 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002166 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002167 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002168 const char *ifname, *val, *alg;
2169 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002170 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002171 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002172
2173 if (intf == NULL)
2174 return -1;
2175
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002176 if (strcmp(intf, get_main_ifname(dut)) == 0)
2177 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002178 else
2179 ifname = intf;
2180
2181 id = set_wpa_common(dut, conn, ifname, cmd);
2182 if (id < 0)
2183 return id;
2184
2185 val = get_param(cmd, "keyMgmtType");
2186 alg = get_param(cmd, "micAlg");
2187
Jouni Malinen992a81e2017-08-22 13:57:47 +03002188 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002189 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002190 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2191 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002192 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002193 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2194 return -2;
2195 }
2196 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2197 sigma_dut_print(dut, DUT_MSG_ERROR,
2198 "Failed to clear sae_groups to default");
2199 return -2;
2200 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002201 if (!pmf) {
2202 dut->sta_pmf = STA_PMF_REQUIRED;
2203 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2204 return -2;
2205 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002206 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2207 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2208 if (set_network(ifname, id, "key_mgmt",
2209 "FT-SAE FT-PSK") < 0)
2210 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002211 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002212 if (set_network(ifname, id, "key_mgmt",
2213 "SAE WPA-PSK") < 0)
2214 return -2;
2215 }
2216 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2217 sigma_dut_print(dut, DUT_MSG_ERROR,
2218 "Failed to clear sae_groups to default");
2219 return -2;
2220 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002221 if (!pmf) {
2222 dut->sta_pmf = STA_PMF_OPTIONAL;
2223 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2224 return -2;
2225 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002226 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002227 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2228 return -2;
2229 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2230 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2231 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302232 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2233 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2234 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002235 } else if (!akm &&
2236 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2237 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002238 if (set_network(ifname, id, "key_mgmt",
2239 "WPA-PSK WPA-PSK-SHA256") < 0)
2240 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002241 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002242 if (set_network(ifname, id, "key_mgmt",
2243 "WPA-PSK WPA-PSK-SHA256") < 0)
2244 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002245 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002246 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2247 return -2;
2248 }
2249
2250 val = get_param(cmd, "passPhrase");
2251 if (val == NULL)
2252 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002253 if (type && strcasecmp(type, "SAE") == 0) {
2254 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2255 return -2;
2256 } else {
2257 if (set_network_quoted(ifname, id, "psk", val) < 0)
2258 return -2;
2259 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002260
Jouni Malinen78d10c42019-03-25 22:34:32 +02002261 val = get_param(cmd, "PasswordId");
2262 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2263 return ERROR_SEND_STATUS;
2264
Jouni Malinen992a81e2017-08-22 13:57:47 +03002265 val = get_param(cmd, "ECGroupID");
2266 if (val) {
Jouni Malinenb54f0df2019-12-12 01:57:29 +02002267 snprintf(buf, sizeof(buf), "SET sae_groups %s", val);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002268 if (wpa_command(ifname, buf) != 0) {
2269 sigma_dut_print(dut, DUT_MSG_ERROR,
2270 "Failed to clear sae_groups");
2271 return -2;
2272 }
2273 }
2274
Jouni Malinen68143132017-09-02 02:34:08 +03002275 val = get_param(cmd, "InvalidSAEElement");
2276 if (val) {
2277 free(dut->sae_commit_override);
2278 dut->sae_commit_override = strdup(val);
2279 }
2280
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002281 val = get_param(cmd, "PMKID_Include");
2282 if (val) {
2283 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2284 get_enable_disable(val));
2285 wpa_command(intf, buf);
2286 }
2287
Jouni Malineneeb43d32019-12-06 17:40:07 +02002288 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2289 if (val) {
2290 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2291 get_enable_disable(val));
2292 wpa_command(intf, buf);
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302293 if (get_driver_type(dut) == DRIVER_WCN)
2294 wcn_set_ignore_h2e_rsnxe(dut, intf,
2295 get_enable_disable(val));
Jouni Malineneeb43d32019-12-06 17:40:07 +02002296 }
2297
Jouni Malinenf2348d22019-12-07 11:52:55 +02002298 val = get_param(cmd, "ECGroupID_RGE");
2299 if (val) {
2300 snprintf(buf, sizeof(buf), "SET extra_sae_rejected_groups %s",
2301 val);
2302 wpa_command(intf, buf);
2303 }
2304
Jouni Malinen99e55022019-12-07 13:59:41 +02002305 val = get_param(cmd, "RSNXE_Content");
2306 if (val) {
2307 const char *param;
2308
2309 if (strncasecmp(val, "AssocReq:", 9) == 0) {
2310 val += 9;
2311 param = "rsnxe_override_assoc";
2312 } else if (strncasecmp(val, "EapolM2:", 8) == 0) {
2313 val += 8;
2314 param = "rsnxe_override_eapol";
2315 } else {
2316 send_resp(dut, conn, SIGMA_ERROR,
2317 "errorCode,Unsupported RSNXE_Content value");
2318 return STATUS_SENT_ERROR;
2319 }
2320 snprintf(buf, sizeof(buf), "SET %s %s", param, val);
2321 wpa_command(intf, buf);
2322 }
2323
Jouni Malinen11e55212019-11-22 21:46:59 +02002324 val = get_param(cmd, "sae_pwe");
2325 if (val) {
2326 if (strcasecmp(val, "h2e") == 0) {
2327 dut->sae_pwe = SAE_PWE_H2E;
Jouni Malinen7244a412019-12-07 11:54:10 +02002328 } else if (strcasecmp(val, "loop") == 0 ||
2329 strcasecmp(val, "looping") == 0) {
Jouni Malinen11e55212019-11-22 21:46:59 +02002330 dut->sae_pwe = SAE_PWE_LOOP;
2331 } else {
2332 send_resp(dut, conn, SIGMA_ERROR,
2333 "errorCode,Unsupported sae_pwe value");
2334 return STATUS_SENT_ERROR;
2335 }
2336 }
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302337
2338 val = get_param(cmd, "Clear_RSNXE");
2339 if (val && strcmp(val, "1") == 0 &&
2340 (wpa_command(intf, "SET rsnxe_override_assoc ") ||
2341 wpa_command(intf, "SET rsnxe_override_eapol "))) {
2342 send_resp(dut, conn, SIGMA_ERROR,
2343 "errorCode,Failed to clear RSNXE");
Jouni Malinenb11498c2020-08-03 11:05:53 +03002344 return STATUS_SENT_ERROR;
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302345 }
2346
Jouni Malinenc0078772020-03-04 21:23:16 +02002347 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2348 sae_pwe = 3;
2349 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002350 sae_pwe = 0;
2351 else if (dut->sae_pwe == SAE_PWE_H2E)
2352 sae_pwe = 1;
2353 else if (dut->sae_h2e_default)
2354 sae_pwe = 2;
2355 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2356 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2357 return ERROR_SEND_STATUS;
2358
Veerendranath Jakkam0316be12020-06-23 20:11:41 +05302359 val = get_param(cmd, "sae_pk");
2360 if (val && strcmp(val, "0") == 0 &&
2361 set_network(ifname, id, "sae_pk", "2") < 0)
2362 return ERROR_SEND_STATUS;
2363
Veerendranath Jakkama9177042020-08-10 00:14:03 +05302364 val = get_param(cmd, "sae_pk_only");
2365 if (val && strcmp(val, "1") == 0 &&
2366 set_network(ifname, id, "sae_pk", "1") < 0)
2367 return ERROR_SEND_STATUS;
2368
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002369 if (dut->program == PROGRAM_60GHZ && network_mode &&
2370 strcasecmp(network_mode, "PBSS") == 0 &&
2371 set_network(ifname, id, "pbss", "1") < 0)
2372 return -2;
2373
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002374 return 1;
2375}
2376
2377
Jouni Malinen8ac93452019-08-14 15:19:13 +03002378static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2379 struct sigma_conn *conn,
2380 const char *ifname, int id)
2381{
2382 char buf[200];
2383
2384 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2385 if (!file_exists(buf))
2386 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2387 if (!file_exists(buf))
2388 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2389 if (!file_exists(buf)) {
2390 char msg[300];
2391
2392 snprintf(msg, sizeof(msg),
2393 "ErrorCode,trustedRootCA system store (%s) not found",
2394 buf);
2395 send_resp(dut, conn, SIGMA_ERROR, msg);
2396 return STATUS_SENT_ERROR;
2397 }
2398
2399 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2400 return ERROR_SEND_STATUS;
2401
2402 return SUCCESS_SEND_STATUS;
2403}
2404
2405
2406static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2407 struct sigma_conn *conn,
2408 const char *ifname, int id,
2409 const char *val)
2410{
2411 char buf[200];
2412#ifdef ANDROID
2413 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2414 int length;
2415#endif /* ANDROID */
2416
2417 if (strcmp(val, "DEFAULT") == 0)
2418 return set_trust_root_system(dut, conn, ifname, id);
2419
2420#ifdef ANDROID
2421 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2422 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2423 if (length > 0) {
2424 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2425 buf);
2426 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2427 goto ca_cert_selected;
2428 }
2429#endif /* ANDROID */
2430
2431 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2432#ifdef __linux__
2433 if (!file_exists(buf)) {
2434 char msg[300];
2435
2436 snprintf(msg, sizeof(msg),
2437 "ErrorCode,trustedRootCA file (%s) not found", buf);
2438 send_resp(dut, conn, SIGMA_ERROR, msg);
2439 return STATUS_SENT_ERROR;
2440 }
2441#endif /* __linux__ */
2442#ifdef ANDROID
2443ca_cert_selected:
2444#endif /* ANDROID */
2445 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2446 return ERROR_SEND_STATUS;
2447
2448 return SUCCESS_SEND_STATUS;
2449}
2450
2451
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002452static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302453 const char *ifname, int username_identity,
2454 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002455{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002456 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002457 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002458 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002459 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002460 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002461
2462 id = set_wpa_common(dut, conn, ifname, cmd);
2463 if (id < 0)
2464 return id;
2465
2466 val = get_param(cmd, "keyMgmtType");
2467 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302468 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002469 trust_root = get_param(cmd, "trustedRootCA");
2470 domain = get_param(cmd, "Domain");
2471 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002472
Jouni Malinenad395a22017-09-01 21:13:46 +03002473 if (val && strcasecmp(val, "SuiteB") == 0) {
2474 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2475 0)
2476 return -2;
2477 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002478 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2479 return -2;
2480 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2481 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2482 return -2;
2483 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2484 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2485 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002486 } else if (!akm &&
2487 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2488 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002489 if (set_network(ifname, id, "key_mgmt",
2490 "WPA-EAP WPA-EAP-SHA256") < 0)
2491 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302492 } else if (akm && atoi(akm) == 14) {
2493 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2494 dut->sta_pmf == STA_PMF_REQUIRED) {
2495 if (set_network(ifname, id, "key_mgmt",
2496 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2497 return -2;
2498 } else {
2499 if (set_network(ifname, id, "key_mgmt",
2500 "WPA-EAP FILS-SHA256") < 0)
2501 return -2;
2502 }
2503
Jouni Malinen8179fee2019-03-28 03:19:47 +02002504 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302505 } else if (akm && atoi(akm) == 15) {
2506 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2507 dut->sta_pmf == STA_PMF_REQUIRED) {
2508 if (set_network(ifname, id, "key_mgmt",
2509 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2510 return -2;
2511 } else {
2512 if (set_network(ifname, id, "key_mgmt",
2513 "WPA-EAP FILS-SHA384") < 0)
2514 return -2;
2515 }
2516
Jouni Malinen8179fee2019-03-28 03:19:47 +02002517 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002518 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002519 if (set_network(ifname, id, "key_mgmt",
2520 "WPA-EAP WPA-EAP-SHA256") < 0)
2521 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002522 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002523 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2524 return -2;
2525 }
2526
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002527 if (trust_root) {
2528 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2529 !domain_suffix) {
2530 send_resp(dut, conn, SIGMA_ERROR,
2531 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2532 return STATUS_SENT_ERROR;
2533 }
2534 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002535 if (res != SUCCESS_SEND_STATUS)
2536 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002537 }
2538
Jouni Malinen53264f62019-05-03 13:04:40 +03002539 val = get_param(cmd, "ServerCert");
2540 if (val) {
2541 FILE *f;
2542 char *result = NULL, *pos;
2543
2544 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2545 val);
2546 f = fopen(buf, "r");
2547 if (f) {
2548 result = fgets(buf, sizeof(buf), f);
2549 fclose(f);
2550 }
2551 if (!result) {
2552 snprintf(buf2, sizeof(buf2),
2553 "ErrorCode,ServerCert hash could not be read from %s",
2554 buf);
2555 send_resp(dut, conn, SIGMA_ERROR, buf2);
2556 return STATUS_SENT_ERROR;
2557 }
2558 pos = strchr(buf, '\n');
2559 if (pos)
2560 *pos = '\0';
Jouni Malinen0572a742020-10-08 13:53:25 +03002561 pos = strchr(buf, '\r');
2562 if (pos)
2563 *pos = '\0';
Jouni Malinen53264f62019-05-03 13:04:40 +03002564 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2565 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2566 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002567
2568 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2569 if (file_exists(buf)) {
2570 sigma_dut_print(dut, DUT_MSG_DEBUG,
2571 "TOD policy enabled for the configured ServerCert hash");
2572 dut->sta_tod_policy = 1;
2573 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002574 }
2575
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002576 if (domain &&
2577 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002578 return ERROR_SEND_STATUS;
2579
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002580 if (domain_suffix &&
2581 set_network_quoted(ifname, id, "domain_suffix_match",
2582 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002583 return ERROR_SEND_STATUS;
2584
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302585 if (username_identity) {
2586 val = get_param(cmd, "username");
2587 if (val) {
2588 if (set_network_quoted(ifname, id, "identity", val) < 0)
2589 return -2;
2590 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002591
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302592 val = get_param(cmd, "password");
2593 if (val) {
2594 if (set_network_quoted(ifname, id, "password", val) < 0)
2595 return -2;
2596 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002597 }
2598
Jouni Malinen8179fee2019-03-28 03:19:47 +02002599 if (dut->akm_values &
2600 ((1 << AKM_FILS_SHA256) |
2601 (1 << AKM_FILS_SHA384) |
2602 (1 << AKM_FT_FILS_SHA256) |
2603 (1 << AKM_FT_FILS_SHA384)))
2604 erp = 1;
2605 if (erp && set_network(ifname, id, "erp", "1") < 0)
2606 return ERROR_SEND_STATUS;
2607
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002608 dut->sta_associate_wait_connect = 1;
2609
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002610 return id;
2611}
2612
2613
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002614static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2615{
2616 const char *val;
2617
2618 if (!cipher)
2619 return 0;
2620
2621 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2622 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2623 else if (strcasecmp(cipher,
2624 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2625 val = "ECDHE-RSA-AES256-GCM-SHA384";
2626 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2627 val = "DHE-RSA-AES256-GCM-SHA384";
2628 else if (strcasecmp(cipher,
2629 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2630 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2631 else
2632 return -1;
2633
2634 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2635 set_network_quoted(ifname, id, "phase1", "");
2636
2637 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2638}
2639
2640
Jouni Malinenf7222712019-06-13 01:50:21 +03002641static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2642 struct sigma_conn *conn,
2643 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002644{
2645 const char *intf = get_param(cmd, "Interface");
2646 const char *ifname, *val;
2647 int id;
2648 char buf[200];
2649#ifdef ANDROID
2650 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2651 int length;
2652 int jb_or_newer = 0;
2653 char prop[PROPERTY_VALUE_MAX];
2654#endif /* ANDROID */
2655
2656 if (intf == NULL)
2657 return -1;
2658
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002659 if (strcmp(intf, get_main_ifname(dut)) == 0)
2660 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002661 else
2662 ifname = intf;
2663
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302664 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002665 if (id < 0)
2666 return id;
2667
2668 if (set_network(ifname, id, "eap", "TLS") < 0)
2669 return -2;
2670
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302671 if (!get_param(cmd, "username") &&
2672 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002673 "wifi-user@wifilabs.local") < 0)
2674 return -2;
2675
2676 val = get_param(cmd, "clientCertificate");
2677 if (val == NULL)
2678 return -1;
2679#ifdef ANDROID
2680 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2681 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2682 if (length < 0) {
2683 /*
2684 * JB started reporting keystore type mismatches, so retry with
2685 * the GET_PUBKEY command if the generic GET fails.
2686 */
2687 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2688 buf, kvalue);
2689 }
2690
2691 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2692 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2693 if (strncmp(prop, "4.0", 3) != 0)
2694 jb_or_newer = 1;
2695 } else
2696 jb_or_newer = 1; /* assume newer */
2697
2698 if (jb_or_newer && length > 0) {
2699 sigma_dut_print(dut, DUT_MSG_INFO,
2700 "Use Android keystore [%s]", buf);
2701 if (set_network(ifname, id, "engine", "1") < 0)
2702 return -2;
2703 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2704 return -2;
2705 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2706 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2707 return -2;
2708 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2709 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2710 return -2;
2711 return 1;
2712 } else if (length > 0) {
2713 sigma_dut_print(dut, DUT_MSG_INFO,
2714 "Use Android keystore [%s]", buf);
2715 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2716 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2717 return -2;
2718 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2719 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2720 return -2;
2721 return 1;
2722 }
2723#endif /* ANDROID */
2724
2725 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2726#ifdef __linux__
2727 if (!file_exists(buf)) {
2728 char msg[300];
2729 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2730 "(%s) not found", buf);
2731 send_resp(dut, conn, SIGMA_ERROR, msg);
2732 return -3;
2733 }
2734#endif /* __linux__ */
2735 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2736 return -2;
2737 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2738 return -2;
2739
2740 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2741 return -2;
2742
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002743 val = get_param(cmd, "keyMgmtType");
2744 if (val && strcasecmp(val, "SuiteB") == 0) {
2745 val = get_param(cmd, "CertType");
2746 if (val && strcasecmp(val, "RSA") == 0) {
2747 if (set_network_quoted(ifname, id, "phase1",
2748 "tls_suiteb=1") < 0)
2749 return -2;
2750 } else {
2751 if (set_network_quoted(ifname, id, "openssl_ciphers",
2752 "SUITEB192") < 0)
2753 return -2;
2754 }
2755
2756 val = get_param(cmd, "TLSCipher");
2757 if (set_tls_cipher(ifname, id, val) < 0) {
2758 send_resp(dut, conn, SIGMA_ERROR,
2759 "ErrorCode,Unsupported TLSCipher value");
2760 return -3;
2761 }
2762 }
2763
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002764 return 1;
2765}
2766
2767
Jouni Malinenf7222712019-06-13 01:50:21 +03002768static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2769 struct sigma_conn *conn,
2770 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002771{
2772 const char *intf = get_param(cmd, "Interface");
2773 const char *ifname;
2774 int id;
2775
2776 if (intf == NULL)
2777 return -1;
2778
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002779 if (strcmp(intf, get_main_ifname(dut)) == 0)
2780 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002781 else
2782 ifname = intf;
2783
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302784 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002785 if (id < 0)
2786 return id;
2787
2788 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2789 send_resp(dut, conn, SIGMA_ERROR,
2790 "errorCode,Failed to set TTLS method");
2791 return 0;
2792 }
2793
2794 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2795 send_resp(dut, conn, SIGMA_ERROR,
2796 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2797 return 0;
2798 }
2799
2800 return 1;
2801}
2802
2803
Jouni Malinenf7222712019-06-13 01:50:21 +03002804static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2805 struct sigma_conn *conn,
2806 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002807{
2808 const char *intf = get_param(cmd, "Interface");
2809 const char *ifname;
2810 int id;
2811
2812 if (intf == NULL)
2813 return -1;
2814
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002815 if (strcmp(intf, get_main_ifname(dut)) == 0)
2816 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002817 else
2818 ifname = intf;
2819
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302820 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002821 if (id < 0)
2822 return id;
2823
2824 if (set_network(ifname, id, "eap", "SIM") < 0)
2825 return -2;
2826
2827 return 1;
2828}
2829
2830
Jouni Malinenf7222712019-06-13 01:50:21 +03002831static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2832 struct sigma_conn *conn,
2833 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002834{
2835 const char *intf = get_param(cmd, "Interface");
2836 const char *ifname, *val;
2837 int id;
2838 char buf[100];
2839
2840 if (intf == NULL)
2841 return -1;
2842
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002843 if (strcmp(intf, get_main_ifname(dut)) == 0)
2844 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002845 else
2846 ifname = intf;
2847
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302848 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002849 if (id < 0)
2850 return id;
2851
2852 if (set_network(ifname, id, "eap", "PEAP") < 0)
2853 return -2;
2854
2855 val = get_param(cmd, "innerEAP");
2856 if (val) {
2857 if (strcasecmp(val, "MSCHAPv2") == 0) {
2858 if (set_network_quoted(ifname, id, "phase2",
2859 "auth=MSCHAPV2") < 0)
2860 return -2;
2861 } else if (strcasecmp(val, "GTC") == 0) {
2862 if (set_network_quoted(ifname, id, "phase2",
2863 "auth=GTC") < 0)
2864 return -2;
2865 } else
2866 return -1;
2867 }
2868
2869 val = get_param(cmd, "peapVersion");
2870 if (val) {
2871 int ver = atoi(val);
2872 if (ver < 0 || ver > 1)
2873 return -1;
2874 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2875 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2876 return -2;
2877 }
2878
2879 return 1;
2880}
2881
2882
Jouni Malinenf7222712019-06-13 01:50:21 +03002883static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2884 struct sigma_conn *conn,
2885 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002886{
2887 const char *intf = get_param(cmd, "Interface");
2888 const char *ifname, *val;
2889 int id;
2890 char buf[100];
2891
2892 if (intf == NULL)
2893 return -1;
2894
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002895 if (strcmp(intf, get_main_ifname(dut)) == 0)
2896 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002897 else
2898 ifname = intf;
2899
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302900 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002901 if (id < 0)
2902 return id;
2903
2904 if (set_network(ifname, id, "eap", "FAST") < 0)
2905 return -2;
2906
2907 val = get_param(cmd, "innerEAP");
2908 if (val) {
2909 if (strcasecmp(val, "MSCHAPV2") == 0) {
2910 if (set_network_quoted(ifname, id, "phase2",
2911 "auth=MSCHAPV2") < 0)
2912 return -2;
2913 } else if (strcasecmp(val, "GTC") == 0) {
2914 if (set_network_quoted(ifname, id, "phase2",
2915 "auth=GTC") < 0)
2916 return -2;
2917 } else
2918 return -1;
2919 }
2920
2921 val = get_param(cmd, "validateServer");
2922 if (val) {
2923 /* TODO */
2924 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2925 "validateServer=%s", val);
2926 }
2927
2928 val = get_param(cmd, "pacFile");
2929 if (val) {
2930 snprintf(buf, sizeof(buf), "blob://%s", val);
2931 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2932 return -2;
2933 }
2934
2935 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2936 0)
2937 return -2;
2938
2939 return 1;
2940}
2941
2942
Jouni Malinenf7222712019-06-13 01:50:21 +03002943static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2944 struct sigma_conn *conn,
2945 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002946{
2947 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302948 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002949 const char *ifname;
2950 int id;
2951
2952 if (intf == NULL)
2953 return -1;
2954
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002955 if (strcmp(intf, get_main_ifname(dut)) == 0)
2956 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002957 else
2958 ifname = intf;
2959
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302960 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002961 if (id < 0)
2962 return id;
2963
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302964 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2965 * hexadecimal).
2966 */
2967 if (username && username[0] == '6') {
2968 if (set_network(ifname, id, "eap", "AKA'") < 0)
2969 return -2;
2970 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002971 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302972 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002973
2974 return 1;
2975}
2976
2977
Jouni Malinenf7222712019-06-13 01:50:21 +03002978static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2979 struct sigma_conn *conn,
2980 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002981{
2982 const char *intf = get_param(cmd, "Interface");
2983 const char *ifname;
2984 int id;
2985
2986 if (intf == NULL)
2987 return -1;
2988
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002989 if (strcmp(intf, get_main_ifname(dut)) == 0)
2990 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002991 else
2992 ifname = intf;
2993
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302994 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002995 if (id < 0)
2996 return id;
2997
2998 if (set_network(ifname, id, "eap", "AKA'") < 0)
2999 return -2;
3000
3001 return 1;
3002}
3003
3004
3005static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
3006 struct sigma_cmd *cmd)
3007{
3008 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003009 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003010 const char *ifname;
3011 int id;
3012
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003013 if (strcmp(intf, get_main_ifname(dut)) == 0)
3014 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003015 else
3016 ifname = intf;
3017
3018 id = add_network_common(dut, conn, ifname, cmd);
3019 if (id < 0)
3020 return id;
3021
3022 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
3023 return -2;
3024
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003025 if (dut->program == PROGRAM_60GHZ && network_mode &&
3026 strcasecmp(network_mode, "PBSS") == 0 &&
3027 set_network(ifname, id, "pbss", "1") < 0)
3028 return -2;
3029
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003030 return 1;
3031}
3032
3033
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003034static enum sigma_cmd_result sta_set_owe(struct sigma_dut *dut,
3035 struct sigma_conn *conn,
3036 struct sigma_cmd *cmd)
Jouni Malinen47dcc952017-10-09 16:43:24 +03003037{
3038 const char *intf = get_param(cmd, "Interface");
3039 const char *ifname, *val;
3040 int id;
3041
3042 if (intf == NULL)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003043 return INVALID_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003044
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003045 if (strcmp(intf, get_main_ifname(dut)) == 0)
3046 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003047 else
3048 ifname = intf;
3049
3050 id = set_wpa_common(dut, conn, ifname, cmd);
3051 if (id < 0)
3052 return id;
3053
3054 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003055 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003056
Hu Wangdd5eed22020-07-16 12:18:03 +08003057 if (dut->owe_ptk_workaround &&
3058 set_network(ifname, id, "owe_ptk_workaround", "1") < 0) {
3059 sigma_dut_print(dut, DUT_MSG_ERROR,
3060 "Failed to set owe_ptk_workaround to 1");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003061 return ERROR_SEND_STATUS;
Hu Wangdd5eed22020-07-16 12:18:03 +08003062 }
3063
Jouni Malinen47dcc952017-10-09 16:43:24 +03003064 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003065 if (val && strcmp(val, "0") == 0) {
3066 if (wpa_command(ifname,
3067 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
3068 sigma_dut_print(dut, DUT_MSG_ERROR,
3069 "Failed to set OWE DH Param element override");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003070 return ERROR_SEND_STATUS;
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003071 }
Hu Wangdd5eed22020-07-16 12:18:03 +08003072 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03003073 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08003074 "Failed to set owe_group");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003075 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003076 }
3077
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003078 return SUCCESS_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003079}
3080
3081
Jouni Malinenf7222712019-06-13 01:50:21 +03003082static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
3083 struct sigma_conn *conn,
3084 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003085{
3086 const char *type = get_param(cmd, "Type");
3087
3088 if (type == NULL) {
3089 send_resp(dut, conn, SIGMA_ERROR,
3090 "ErrorCode,Missing Type argument");
3091 return 0;
3092 }
3093
3094 if (strcasecmp(type, "OPEN") == 0)
3095 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003096 if (strcasecmp(type, "OWE") == 0)
3097 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03003098 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03003099 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03003100 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003101 return cmd_sta_set_psk(dut, conn, cmd);
3102 if (strcasecmp(type, "EAPTLS") == 0)
3103 return cmd_sta_set_eaptls(dut, conn, cmd);
3104 if (strcasecmp(type, "EAPTTLS") == 0)
3105 return cmd_sta_set_eapttls(dut, conn, cmd);
3106 if (strcasecmp(type, "EAPPEAP") == 0)
3107 return cmd_sta_set_peap(dut, conn, cmd);
3108 if (strcasecmp(type, "EAPSIM") == 0)
3109 return cmd_sta_set_eapsim(dut, conn, cmd);
3110 if (strcasecmp(type, "EAPFAST") == 0)
3111 return cmd_sta_set_eapfast(dut, conn, cmd);
3112 if (strcasecmp(type, "EAPAKA") == 0)
3113 return cmd_sta_set_eapaka(dut, conn, cmd);
3114 if (strcasecmp(type, "EAPAKAPRIME") == 0)
3115 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08003116 if (strcasecmp(type, "wep") == 0)
3117 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003118
3119 send_resp(dut, conn, SIGMA_ERROR,
3120 "ErrorCode,Unsupported Type value");
3121 return 0;
3122}
3123
3124
3125int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
3126{
3127#ifdef __linux__
3128 /* special handling for ath6kl */
3129 char path[128], fname[128], *pos;
3130 ssize_t res;
3131 FILE *f;
3132
Jouni Malinene39cd562019-05-29 23:39:56 +03003133 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3134 intf);
3135 if (res < 0 || res >= sizeof(fname))
3136 return 0;
3137 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003138 if (res < 0)
3139 return 0; /* not ath6kl */
3140
3141 if (res >= (int) sizeof(path))
3142 res = sizeof(path) - 1;
3143 path[res] = '\0';
3144 pos = strrchr(path, '/');
3145 if (pos == NULL)
3146 pos = path;
3147 else
3148 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003149 res = snprintf(fname, sizeof(fname),
3150 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3151 "create_qos", pos);
3152 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003153 return 0; /* not ath6kl */
3154
3155 if (uapsd) {
3156 f = fopen(fname, "w");
3157 if (f == NULL)
3158 return -1;
3159
3160 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3161 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3162 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3163 "20000 0\n");
3164 fclose(f);
3165 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003166 res = snprintf(fname, sizeof(fname),
3167 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3168 "delete_qos", pos);
3169 if (res < 0 || res >= sizeof(fname))
3170 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003171
3172 f = fopen(fname, "w");
3173 if (f == NULL)
3174 return -1;
3175
3176 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3177 fprintf(f, "2 4\n");
3178 fclose(f);
3179 }
3180#endif /* __linux__ */
3181
3182 return 0;
3183}
3184
3185
Jouni Malinenf7222712019-06-13 01:50:21 +03003186static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3187 struct sigma_conn *conn,
3188 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003189{
3190 const char *intf = get_param(cmd, "Interface");
3191 /* const char *ssid = get_param(cmd, "ssid"); */
3192 const char *val;
3193 int max_sp_len = 4;
3194 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3195 char buf[100];
3196 int ret1, ret2;
3197
3198 val = get_param(cmd, "maxSPLength");
3199 if (val) {
3200 max_sp_len = atoi(val);
3201 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3202 max_sp_len != 4)
3203 return -1;
3204 }
3205
3206 val = get_param(cmd, "acBE");
3207 if (val)
3208 ac_be = atoi(val);
3209
3210 val = get_param(cmd, "acBK");
3211 if (val)
3212 ac_bk = atoi(val);
3213
3214 val = get_param(cmd, "acVI");
3215 if (val)
3216 ac_vi = atoi(val);
3217
3218 val = get_param(cmd, "acVO");
3219 if (val)
3220 ac_vo = atoi(val);
3221
3222 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3223
3224 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3225 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3226 ret1 = wpa_command(intf, buf);
3227
3228 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3229 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3230 ret2 = wpa_command(intf, buf);
3231
3232 if (ret1 && ret2) {
3233 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3234 "UAPSD parameters.");
3235 return -2;
3236 }
3237
3238 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3239 send_resp(dut, conn, SIGMA_ERROR,
3240 "ErrorCode,Failed to set ath6kl QoS parameters");
3241 return 0;
3242 }
3243
3244 return 1;
3245}
3246
3247
Jouni Malinenf7222712019-06-13 01:50:21 +03003248static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3249 struct sigma_conn *conn,
3250 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003251{
3252 char buf[1000];
3253 const char *intf = get_param(cmd, "Interface");
3254 const char *grp = get_param(cmd, "Group");
3255 const char *act = get_param(cmd, "Action");
3256 const char *tid = get_param(cmd, "Tid");
3257 const char *dir = get_param(cmd, "Direction");
3258 const char *psb = get_param(cmd, "Psb");
3259 const char *up = get_param(cmd, "Up");
3260 const char *fixed = get_param(cmd, "Fixed");
3261 const char *size = get_param(cmd, "Size");
3262 const char *msize = get_param(cmd, "Maxsize");
3263 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3264 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3265 const char *inact = get_param(cmd, "Inactivity");
3266 const char *sus = get_param(cmd, "Suspension");
3267 const char *mindr = get_param(cmd, "Mindatarate");
3268 const char *meandr = get_param(cmd, "Meandatarate");
3269 const char *peakdr = get_param(cmd, "Peakdatarate");
3270 const char *phyrate = get_param(cmd, "Phyrate");
3271 const char *burstsize = get_param(cmd, "Burstsize");
3272 const char *sba = get_param(cmd, "Sba");
3273 int direction;
3274 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003275 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003276 int fixed_int;
3277 int psb_ts;
3278
3279 if (intf == NULL || grp == NULL || act == NULL )
3280 return -1;
3281
3282 if (strcasecmp(act, "addts") == 0) {
3283 if (tid == NULL || dir == NULL || psb == NULL ||
3284 up == NULL || fixed == NULL || size == NULL)
3285 return -1;
3286
3287 /*
3288 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3289 * possible values, but WMM-AC and V-E test scripts use "UP,
3290 * "DOWN", and "BIDI".
3291 */
3292 if (strcasecmp(dir, "uplink") == 0 ||
3293 strcasecmp(dir, "up") == 0) {
3294 direction = 0;
3295 } else if (strcasecmp(dir, "downlink") == 0 ||
3296 strcasecmp(dir, "down") == 0) {
3297 direction = 1;
3298 } else if (strcasecmp(dir, "bidi") == 0) {
3299 direction = 2;
3300 } else {
3301 sigma_dut_print(dut, DUT_MSG_ERROR,
3302 "Direction %s not supported", dir);
3303 return -1;
3304 }
3305
3306 if (strcasecmp(psb, "legacy") == 0) {
3307 psb_ts = 0;
3308 } else if (strcasecmp(psb, "uapsd") == 0) {
3309 psb_ts = 1;
3310 } else {
3311 sigma_dut_print(dut, DUT_MSG_ERROR,
3312 "PSB %s not supported", psb);
3313 return -1;
3314 }
3315
3316 if (atoi(tid) < 0 || atoi(tid) > 7) {
3317 sigma_dut_print(dut, DUT_MSG_ERROR,
3318 "TID %s not supported", tid);
3319 return -1;
3320 }
3321
3322 if (strcasecmp(fixed, "true") == 0) {
3323 fixed_int = 1;
3324 } else {
3325 fixed_int = 0;
3326 }
3327
Peng Xu93319622017-10-04 17:58:16 -07003328 if (sba)
3329 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003330
3331 dut->dialog_token++;
3332 handle = 7000 + dut->dialog_token;
3333
3334 /*
3335 * size: convert to hex
3336 * maxsi: convert to hex
3337 * mindr: convert to hex
3338 * meandr: convert to hex
3339 * peakdr: convert to hex
3340 * burstsize: convert to hex
3341 * phyrate: convert to hex
3342 * sba: convert to hex with modification
3343 * minsi: convert to integer
3344 * sus: convert to integer
3345 * inact: convert to integer
3346 * maxsi: convert to integer
3347 */
3348
3349 /*
3350 * The Nominal MSDU Size field is 2 octets long and contains an
3351 * unsigned integer that specifies the nominal size, in octets,
3352 * of MSDUs belonging to the traffic under this traffic
3353 * specification and is defined in Figure 16. If the Fixed
3354 * subfield is set to 1, then the size of the MSDU is fixed and
3355 * is indicated by the Size Subfield. If the Fixed subfield is
3356 * set to 0, then the size of the MSDU might not be fixed and
3357 * the Size indicates the nominal MSDU size.
3358 *
3359 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3360 * and specifies the excess allocation of time (and bandwidth)
3361 * over and above the stated rates required to transport an MSDU
3362 * belonging to the traffic in this TSPEC. This field is
3363 * represented as an unsigned binary number with an implicit
3364 * binary point after the leftmost 3 bits. For example, an SBA
3365 * of 1.75 is represented as 0x3800. This field is included to
3366 * account for retransmissions. As such, the value of this field
3367 * must be greater than unity.
3368 */
3369
3370 snprintf(buf, sizeof(buf),
3371 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3372 " 0x%X 0x%X 0x%X"
3373 " 0x%X 0x%X 0x%X"
3374 " 0x%X %d %d %d %d"
3375 " %d %d",
3376 intf, handle, tid, direction, psb_ts, up,
3377 (unsigned int) ((fixed_int << 15) | atoi(size)),
3378 msize ? atoi(msize) : 0,
3379 mindr ? atoi(mindr) : 0,
3380 meandr ? atoi(meandr) : 0,
3381 peakdr ? atoi(peakdr) : 0,
3382 burstsize ? atoi(burstsize) : 0,
3383 phyrate ? atoi(phyrate) : 0,
3384 sba ? ((unsigned int) (((int) sba_fv << 13) |
3385 (int)((sba_fv - (int) sba_fv) *
3386 8192))) : 0,
3387 minsi ? atoi(minsi) : 0,
3388 sus ? atoi(sus) : 0,
3389 0, 0,
3390 inact ? atoi(inact) : 0,
3391 maxsi ? atoi(maxsi) : 0);
3392
3393 if (system(buf) != 0) {
3394 sigma_dut_print(dut, DUT_MSG_ERROR,
3395 "iwpriv addtspec request failed");
3396 send_resp(dut, conn, SIGMA_ERROR,
3397 "errorCode,Failed to execute addTspec command");
3398 return 0;
3399 }
3400
3401 sigma_dut_print(dut, DUT_MSG_INFO,
3402 "iwpriv addtspec request send");
3403
3404 /* Mapping handle to a TID */
3405 dut->tid_to_handle[atoi(tid)] = handle;
3406 } else if (strcasecmp(act, "delts") == 0) {
3407 if (tid == NULL)
3408 return -1;
3409
3410 if (atoi(tid) < 0 || atoi(tid) > 7) {
3411 sigma_dut_print(dut, DUT_MSG_ERROR,
3412 "TID %s not supported", tid);
3413 send_resp(dut, conn, SIGMA_ERROR,
3414 "errorCode,Unsupported TID");
3415 return 0;
3416 }
3417
3418 handle = dut->tid_to_handle[atoi(tid)];
3419
3420 if (handle < 7000 || handle > 7255) {
3421 /* Invalid handle ie no mapping for that TID */
3422 sigma_dut_print(dut, DUT_MSG_ERROR,
3423 "handle-> %d not found", handle);
3424 }
3425
3426 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3427 intf, handle);
3428
3429 if (system(buf) != 0) {
3430 sigma_dut_print(dut, DUT_MSG_ERROR,
3431 "iwpriv deltspec request failed");
3432 send_resp(dut, conn, SIGMA_ERROR,
3433 "errorCode,Failed to execute delTspec command");
3434 return 0;
3435 }
3436
3437 sigma_dut_print(dut, DUT_MSG_INFO,
3438 "iwpriv deltspec request send");
3439
3440 dut->tid_to_handle[atoi(tid)] = 0;
3441 } else {
3442 sigma_dut_print(dut, DUT_MSG_ERROR,
3443 "Action type %s not supported", act);
3444 send_resp(dut, conn, SIGMA_ERROR,
3445 "errorCode,Unsupported Action");
3446 return 0;
3447 }
3448
3449 return 1;
3450}
3451
3452
vamsi krishna52e16f92017-08-29 12:37:34 +05303453static int find_network(struct sigma_dut *dut, const char *ssid)
3454{
3455 char list[4096];
3456 char *pos;
3457
3458 sigma_dut_print(dut, DUT_MSG_DEBUG,
3459 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003460 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303461 list, sizeof(list)) < 0)
3462 return -1;
3463 pos = strstr(list, ssid);
3464 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3465 return -1;
3466
3467 while (pos > list && pos[-1] != '\n')
3468 pos--;
3469 dut->infra_network_id = atoi(pos);
3470 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3471 return 0;
3472}
3473
3474
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303475/**
3476 * enum qca_sta_helper_config_params - This helper enum defines the config
3477 * parameters which can be delivered to sta.
3478 */
3479enum qca_sta_helper_config_params {
3480 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE */
3481 STA_SET_RSNIE,
3482
3483 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC */
3484 STA_SET_LDPC,
3485
3486 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC */
3487 STA_SET_TX_STBC,
3488
3489 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC */
3490 STA_SET_RX_STBC,
3491
3492 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION */
3493 STA_SET_TX_MSDU,
3494
3495 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION */
3496 STA_SET_RX_MSDU,
Shivani Baranwal2a572842021-09-16 12:27:15 +05303497
3498 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH */
3499 STA_SET_CHAN_WIDTH,
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303500
3501 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS */
3502 STA_SET_FT_DS,
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303503};
3504
3505
3506static int sta_config_params(struct sigma_dut *dut, const char *intf,
3507 enum qca_sta_helper_config_params config_cmd,
3508 int value)
Sunil Dutt44595082018-02-12 19:41:45 +05303509{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303510#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05303511 struct nl_msg *msg;
3512 int ret;
3513 struct nlattr *params;
3514 int ifindex;
3515
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303516 ifindex = if_nametoindex(intf);
3517 if (ifindex == 0) {
3518 sigma_dut_print(dut, DUT_MSG_ERROR,
3519 "%s: Interface %s does not exist",
3520 __func__, intf);
3521 return -1;
3522 }
3523
Sunil Dutt44595082018-02-12 19:41:45 +05303524 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3525 NL80211_CMD_VENDOR)) ||
3526 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3527 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3528 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3529 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303530 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)))
3531 goto fail;
3532
3533 switch (config_cmd) {
3534 case STA_SET_RSNIE:
3535 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, value))
3536 goto fail;
3537 break;
3538 case STA_SET_LDPC:
3539 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC, value))
3540 goto fail;
3541 break;
3542 case STA_SET_TX_STBC:
3543 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC, value))
3544 goto fail;
3545 break;
3546 case STA_SET_RX_STBC:
3547 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC, value))
3548 goto fail;
3549 break;
3550 case STA_SET_TX_MSDU:
3551 if (nla_put_u8(msg,
3552 QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION,
3553 value))
3554 goto fail;
3555 break;
3556 case STA_SET_RX_MSDU:
3557 if (nla_put_u8(msg,
3558 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION,
3559 value))
3560 goto fail;
3561 break;
Shivani Baranwal2a572842021-09-16 12:27:15 +05303562 case STA_SET_CHAN_WIDTH:
3563 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
3564 value))
3565 goto fail;
3566 break;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303567 case STA_SET_FT_DS:
3568 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS,
3569 value))
3570 goto fail;
3571 break;
Sunil Dutt44595082018-02-12 19:41:45 +05303572 }
3573 nla_nest_end(msg, params);
3574
3575 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3576 if (ret) {
3577 sigma_dut_print(dut, DUT_MSG_ERROR,
3578 "%s: err in send_and_recv_msgs, ret=%d",
3579 __func__, ret);
3580 return ret;
3581 }
3582
3583 return 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303584
3585fail:
3586 sigma_dut_print(dut, DUT_MSG_ERROR,
3587 "%s: err in adding vendor_cmd and vendor_data",
3588 __func__);
3589 nlmsg_free(msg);
Sunil Dutt44595082018-02-12 19:41:45 +05303590#endif /* NL80211_SUPPORT */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303591 return -1;
3592}
Sunil Dutt44595082018-02-12 19:41:45 +05303593
3594
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303595void free_dscp_policy_table(struct sigma_dut *dut)
3596{
3597 struct dscp_policy_data *dscp_policy;
3598
3599 while (dut->dscp_policy_table) {
3600 dscp_policy = dut->dscp_policy_table;
3601 dut->dscp_policy_table = dscp_policy->next;
3602 free(dscp_policy);
3603 }
3604}
3605
3606
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303607static char * protocol_to_str(int proto)
3608{
3609 switch (proto) {
3610 case 6:
3611 return "tcp";
3612 case 17:
3613 return "udp";
3614 case 50:
3615 return "esp";
3616 default:
3617 return "unknown";
3618 }
3619}
3620
3621
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303622static int delete_nft_table(struct sigma_dut *dut, const char *table,
3623 const char *ip_type)
3624{
3625 int res;
3626 char cmd[200];
3627
3628 res = snprintf(cmd, sizeof(cmd), "nft delete table %s %s_%s", ip_type,
3629 table, ip_type);
3630 if (snprintf_error(sizeof(cmd), res)) {
3631 sigma_dut_print(dut, DUT_MSG_ERROR,
3632 "Failed to create delete table command");
3633 return -1;
3634 }
3635
3636 if (system(cmd) != 0) {
3637 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3638 return -1;
3639 }
3640
3641 return 0;
3642}
3643
3644
3645static int remove_nft_rule(struct sigma_dut *dut, int policy_id,
3646 enum ip_version ip_ver)
3647{
3648 int res;
3649 char table[50];
3650
3651 res = snprintf(table, sizeof(table), "wifi_%s_dscp_policy_%d",
3652 dut->station_ifname, policy_id);
3653 if (snprintf_error(sizeof(table), res)) {
3654 sigma_dut_print(dut, DUT_MSG_INFO,
3655 "Failed to create table name for policy %d",
3656 policy_id);
3657 return -1;
3658 }
3659
3660
3661 if (ip_ver == IPV6)
3662 return delete_nft_table(dut, table, "ip6");
3663 else
3664 return delete_nft_table(dut, table, "ip");
3665}
3666
3667
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303668static int remove_iptable_rule(struct sigma_dut *dut,
3669 struct dscp_policy_data *dscp_policy)
3670{
3671 char ip_cmd[1000];
3672 char *pos;
3673 int ret, len;
3674 enum ip_version ip_ver = dscp_policy->ip_version;
3675
3676 pos = ip_cmd;
3677 len = sizeof(ip_cmd);
3678
3679 ret = snprintf(pos, len,
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05303680 "%s -t mangle -D OUTPUT -o %s",
3681#ifdef ANDROID
3682 ip_ver == IPV6 ? "/system/bin/ip6tables" : "/system/bin/iptables",
3683#else /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303684 ip_ver == IPV6 ? "ip6tables" : "iptables",
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05303685#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303686 dut->station_ifname);
3687 if (snprintf_error(len, ret)) {
3688 sigma_dut_print(dut, DUT_MSG_INFO,
3689 "Failed to create delete iptables command %s",
3690 ip_cmd);
3691 return -1;
3692 }
3693
3694 pos += ret;
3695 len -= ret;
3696
3697 if (strlen(dscp_policy->src_ip)) {
3698 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
3699 if (snprintf_error(len, ret)) {
3700 sigma_dut_print(dut, DUT_MSG_INFO,
3701 "Error in adding src_ip %s in delete command",
3702 dscp_policy->src_ip);
3703 return -1;
3704 }
3705 pos += ret;
3706 len -= ret;
3707 }
3708
3709 if (strlen(dscp_policy->dst_ip)) {
3710 ret = snprintf(pos, len, " -d %s",
3711 dscp_policy->dst_ip);
3712 if (snprintf_error(len, ret)) {
3713 sigma_dut_print(dut, DUT_MSG_INFO,
3714 "Error in adding dst_ip %s in delete cmd",
3715 dscp_policy->dst_ip);
3716 return -1;
3717 }
3718 pos += ret;
3719 len -= ret;
3720 }
3721
3722 if (dscp_policy->src_port || dscp_policy->dst_port ||
3723 (dscp_policy->start_port && dscp_policy->end_port)) {
3724 ret = snprintf(pos, len, " -p %s",
3725 protocol_to_str(dscp_policy->protocol));
3726 if (snprintf_error(len, ret)) {
3727 sigma_dut_print(dut, DUT_MSG_INFO,
3728 "Error in adding protocol %d in delete command",
3729 dscp_policy->protocol);
3730 return -1;
3731 }
3732 pos += ret;
3733 len -= ret;
3734 }
3735
3736 if (dscp_policy->src_port) {
3737 ret = snprintf(pos, len, " --sport %d",
3738 dscp_policy->src_port);
3739 if (snprintf_error(len, ret)) {
3740 sigma_dut_print(dut, DUT_MSG_INFO,
3741 "Error in adding src_port %d in delete command",
3742 dscp_policy->src_port);
3743 return -1;
3744 }
3745 pos += ret;
3746 len -= ret;
3747 }
3748
3749 if (dscp_policy->dst_port) {
3750 ret = snprintf(pos, len, " --dport %d",
3751 dscp_policy->dst_port);
3752 if (snprintf_error(len, ret)) {
3753 sigma_dut_print(dut, DUT_MSG_INFO,
3754 "Error in adding dst_port %d in delete command",
3755 dscp_policy->dst_port);
3756 return -1;
3757 }
3758 pos += ret;
3759 len -= ret;
3760 }
3761
3762 if (dscp_policy->start_port && dscp_policy->end_port) {
3763 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
3764 dscp_policy->start_port,
3765 dscp_policy->end_port);
3766 if (snprintf_error(len, ret)) {
3767 sigma_dut_print(dut, DUT_MSG_INFO,
3768 "Error in adding start:end port %d:%d in delete command",
3769 dscp_policy->start_port,
3770 dscp_policy->end_port);
3771 return -1;
3772 }
3773 pos += ret;
3774 len -= ret;
3775 }
3776
3777 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
3778 dscp_policy->dscp);
3779 if (snprintf_error(len, ret)) {
3780 sigma_dut_print(dut, DUT_MSG_INFO,
3781 "Error in adding dscp %0x in delete command",
3782 dscp_policy->dscp);
3783 return -1;
3784 }
3785 ret = system(ip_cmd);
3786 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
3787 ip_cmd, ret);
3788
3789 return ret;
3790}
3791
3792
3793static int remove_dscp_policy_rule(struct sigma_dut *dut,
3794 struct dscp_policy_data *dscp_policy)
3795{
3796 return dut->dscp_use_iptables ? remove_iptable_rule(dut, dscp_policy) :
3797 remove_nft_rule(dut, dscp_policy->policy_id,
3798 dscp_policy->ip_version);
3799}
3800
3801
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303802static int create_nft_table(struct sigma_dut *dut, int policy_id,
3803 const char *table_name, enum ip_version ip_ver)
3804{
3805 char cmd[200];
3806 int res;
3807
3808 res = snprintf(cmd, sizeof(cmd), "nft add table %s %s",
3809 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3810 if (snprintf_error(sizeof(cmd), res)) {
3811 sigma_dut_print(dut, DUT_MSG_INFO,
3812 "Failed to add rule to create table for policy id %d",
3813 policy_id);
3814 return -1;
3815 }
3816
3817 if (system(cmd) != 0) {
3818 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3819 return -1;
3820 }
3821
3822 res = snprintf(cmd, sizeof(cmd),
3823 "nft add chain %s %s OUTPUT { type filter hook output priority 0 \\; }",
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 chain for table = %s",
3828 table_name);
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 return 0;
3838}
3839
3840
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303841static int remove_dscp_policy(struct sigma_dut *dut, u8 policy_id)
3842{
3843 struct dscp_policy_data *dscp_policy = dut->dscp_policy_table;
3844 struct dscp_policy_data *prev = NULL;
3845
3846 while (dscp_policy) {
3847 if (dscp_policy->policy_id == policy_id)
3848 break;
3849
3850 prev = dscp_policy;
3851 dscp_policy = dscp_policy->next;
3852 }
3853
3854 /*
3855 * Consider remove request for a policy id which does not exist as
3856 * success.
3857 */
3858 if (!dscp_policy)
3859 return 0;
3860
3861 if (strlen(dscp_policy->domain_name) == 0 &&
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303862 remove_dscp_policy_rule(dut, dscp_policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303863 return -1;
3864
3865 if (prev)
3866 prev->next = dscp_policy->next;
3867 else
3868 dut->dscp_policy_table = dscp_policy->next;
3869
3870 free(dscp_policy);
3871 return 0;
3872}
3873
3874
3875static int add_nft_rule(struct sigma_dut *dut,
3876 struct dscp_policy_data *dscp_policy)
3877{
3878 char nft_cmd[1000], ip[4], table_name[100];
3879 char *pos;
3880 int ret, len, policy_id = dscp_policy->policy_id;
3881 enum ip_version ip_ver = dscp_policy->ip_version;
3882
3883 if (ip_ver == IPV6)
3884 strlcpy(ip, "ip6", sizeof(ip));
3885 else
3886 strlcpy(ip, "ip", sizeof(ip));
3887
3888 ret = snprintf(table_name, sizeof(table_name),
3889 "wifi_%s_dscp_policy_%d_%s",
3890 dut->station_ifname, policy_id, ip);
3891 if (snprintf_error(sizeof(table_name), ret))
3892 return -1;
3893
3894 if (create_nft_table(dut, policy_id, table_name, ip_ver)) {
3895 sigma_dut_print(dut, DUT_MSG_INFO,
3896 "Failed to create nft table");
3897 return -1;
3898 }
3899
3900 pos = nft_cmd;
3901 len = sizeof(nft_cmd);
3902
3903 ret = snprintf(pos, len,
3904 "nft add rule %s %s OUTPUT oifname \"%s\"",
3905 ip, table_name, dut->station_ifname);
3906 if (snprintf_error(len, ret)) {
3907 sigma_dut_print(dut, DUT_MSG_INFO,
3908 "Failed to create nft cmd %s", nft_cmd);
3909 return -1;
3910 }
3911
3912 pos += ret;
3913 len -= ret;
3914
3915 if (strlen(dscp_policy->src_ip)) {
3916 ret = snprintf(pos, len, " %s saddr %s", ip,
3917 dscp_policy->src_ip);
3918 if (snprintf_error(len, ret))
3919 return -1;
3920
3921 pos += ret;
3922 len -= ret;
3923 }
3924
3925 if (strlen(dscp_policy->dst_ip)) {
3926 ret = snprintf(pos, len, " %s daddr %s", ip,
3927 dscp_policy->dst_ip);
3928 if (snprintf_error(len, ret))
3929 return -1;
3930
3931 pos += ret;
3932 len -= ret;
3933 }
3934
3935 if (dscp_policy->src_port) {
3936 ret = snprintf(pos, len, " %s sport %d",
3937 protocol_to_str(dscp_policy->protocol),
3938 dscp_policy->src_port);
3939 if (snprintf_error(len, ret))
3940 return -1;
3941
3942 pos += ret;
3943 len -= ret;
3944 }
3945
3946 if (dscp_policy->dst_port) {
3947 ret = snprintf(pos, len, " %s dport %d",
3948 protocol_to_str(dscp_policy->protocol),
3949 dscp_policy->dst_port);
3950 if (snprintf_error(len, ret))
3951 return -1;
3952
3953 pos += ret;
3954 len -= ret;
3955 }
3956
3957 if (dscp_policy->start_port && dscp_policy->end_port) {
3958 ret = snprintf(pos, len, " %s dport %d-%d",
3959 protocol_to_str(dscp_policy->protocol),
3960 dscp_policy->start_port,
3961 dscp_policy->end_port);
3962 if (snprintf_error(len, ret))
3963 return -1;
3964
3965 pos += ret;
3966 len -= ret;
3967 }
3968
3969 ret = snprintf(pos, len, " counter %s dscp set 0x%0x", ip,
3970 dscp_policy->dscp);
3971 if (snprintf_error(len, ret))
3972 return -1;
3973
3974 ret = system(nft_cmd);
3975 sigma_dut_print(dut, DUT_MSG_INFO, "nft rule: %s err: %d",
3976 nft_cmd, ret);
3977
3978 return ret;
3979}
3980
3981
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303982static int add_iptable_rule(struct sigma_dut *dut,
3983 struct dscp_policy_data *dscp_policy)
3984{
3985 char ip_cmd[1000];
3986 char *pos;
3987 int ret, len;
3988 enum ip_version ip_ver = dscp_policy->ip_version;
3989 struct dscp_policy_data *active_policy = dut->dscp_policy_table;
3990 int ipv4_rule_num = 1, ipv6_rule_num = 1;
3991
3992 pos = ip_cmd;
3993 len = sizeof(ip_cmd);
3994
3995 /*
3996 * DSCP target in the mangle table doesn't stop processing of rules
3997 * so to make sure the most granular rule is applied last, add the new
3998 * rules in granularity increasing order.
3999 */
4000 while (active_policy) {
4001 /*
4002 * Domain name rules are managed in sigma_dut thus don't count
4003 * them while counting the number of active rules.
4004 */
4005 if (strlen(active_policy->domain_name)) {
4006 active_policy = active_policy->next;
4007 continue;
4008 }
4009
4010 if (active_policy->granularity_score >
4011 dscp_policy->granularity_score)
4012 break;
4013
4014 if (active_policy->ip_version == IPV6)
4015 ipv6_rule_num++;
4016 else
4017 ipv4_rule_num++;
4018
4019 active_policy = active_policy->next;
4020 }
4021
4022 ret = snprintf(pos, len,
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304023 "%s -t mangle -I OUTPUT %d -o %s",
4024#ifdef ANDROID
4025 ip_ver == IPV6 ? "/system/bin/ip6tables" : "/system/bin/iptables",
4026#else /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304027 ip_ver == IPV6 ? "ip6tables" : "iptables",
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304028#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304029 ip_ver == IPV6 ? ipv6_rule_num : ipv4_rule_num,
4030 dut->station_ifname);
4031 if (snprintf_error(len, ret)) {
4032 sigma_dut_print(dut, DUT_MSG_INFO,
4033 "Failed to create iptables command %s", ip_cmd);
4034 return -1;
4035 }
4036
4037 pos += ret;
4038 len -= ret;
4039
4040 if (strlen(dscp_policy->src_ip)) {
4041 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
4042 if (snprintf_error(len, ret)) {
4043 sigma_dut_print(dut, DUT_MSG_INFO,
4044 "Error in adding src_ip %s",
4045 dscp_policy->src_ip);
4046 return -1;
4047 }
4048 pos += ret;
4049 len -= ret;
4050 }
4051
4052 if (strlen(dscp_policy->dst_ip)) {
4053 ret = snprintf(pos, len, " -d %s", dscp_policy->dst_ip);
4054 if (snprintf_error(len, ret)) {
4055 sigma_dut_print(dut, DUT_MSG_INFO,
4056 "Error in adding dst_ip %s",
4057 dscp_policy->dst_ip);
4058 return -1;
4059 }
4060 pos += ret;
4061 len -= ret;
4062 }
4063
4064 if (dscp_policy->src_port || dscp_policy->dst_port ||
4065 (dscp_policy->start_port && dscp_policy->end_port)) {
4066 ret = snprintf(pos, len, " -p %s",
4067 protocol_to_str(dscp_policy->protocol));
4068 if (snprintf_error(len, ret)) {
4069 sigma_dut_print(dut, DUT_MSG_INFO,
4070 "Error in adding protocol %d in add command",
4071 dscp_policy->protocol);
4072 return -1;
4073 }
4074 pos += ret;
4075 len -= ret;
4076 }
4077
4078 if (dscp_policy->src_port) {
4079 ret = snprintf(pos, len, " --sport %d", dscp_policy->src_port);
4080 if (snprintf_error(len, ret)) {
4081 sigma_dut_print(dut, DUT_MSG_INFO,
4082 "Error in adding src_port %d",
4083 dscp_policy->src_port);
4084 return -1;
4085 }
4086 pos += ret;
4087 len -= ret;
4088 }
4089
4090 if (dscp_policy->dst_port) {
4091 ret = snprintf(pos, len, " --dport %d", dscp_policy->dst_port);
4092 if (snprintf_error(len, ret)) {
4093 sigma_dut_print(dut, DUT_MSG_INFO,
4094 "Error in adding dst_port %d",
4095 dscp_policy->dst_port);
4096 return -1;
4097 }
4098 pos += ret;
4099 len -= ret;
4100 }
4101
4102 if (dscp_policy->start_port && dscp_policy->end_port) {
4103 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
4104 dscp_policy->start_port, dscp_policy->end_port);
4105 if (snprintf_error(len, ret)) {
4106 sigma_dut_print(dut, DUT_MSG_INFO,
4107 "Error in adding start:end port %d:%d",
4108 dscp_policy->start_port,
4109 dscp_policy->end_port);
4110 return -1;
4111 }
4112 pos += ret;
4113 len -= ret;
4114 }
4115
4116 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
4117 dscp_policy->dscp);
4118 if (snprintf_error(len, ret)) {
4119 sigma_dut_print(dut, DUT_MSG_INFO,
4120 "Error in adding dscp %0x", dscp_policy->dscp);
4121 return -1;
4122 }
4123 ret = system(ip_cmd);
4124 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
4125 ip_cmd, ret);
4126
4127 return ret;
4128}
4129
4130
4131static int add_dscp_policy_rule(struct sigma_dut *dut,
4132 struct dscp_policy_data *dscp_policy)
4133{
4134 return dut->dscp_use_iptables ? add_iptable_rule(dut, dscp_policy) :
4135 add_nft_rule(dut, dscp_policy);
4136}
4137
4138
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304139static void clear_all_dscp_policies(struct sigma_dut *dut)
4140{
4141 free_dscp_policy_table(dut);
4142
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304143 if (dut->dscp_use_iptables) {
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304144#ifdef ANDROID
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304145 if (system("/system/bin/iptables -t mangle -F && /system/bin/iptables -t mangle -X") != 0 ||
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304146 system("/system/bin/ip6tables -t mangle -F && /system/bin/ip6tables -t mangle -X") != 0)
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304147 sigma_dut_print(dut, DUT_MSG_ERROR,
4148 "iptables: Failed to flush DSCP policy");
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304149#else /* ANDROID */
4150 if (system("iptables -t mangle -F && iptables -t mangle -X") != 0 ||
4151 system("ip6tables -t mangle -F && ip6tables -t mangle -X") != 0)
4152 sigma_dut_print(dut, DUT_MSG_ERROR,
4153 "iptables: Failed to flush DSCP policy");
4154#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304155 } else {
4156 if (system("nft flush ruleset") != 0)
4157 sigma_dut_print(dut, DUT_MSG_ERROR,
4158 "nftables: Failed to flush DSCP policy");
4159 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304160}
4161
4162
4163static int send_dscp_response(struct sigma_dut *dut,
4164 struct dscp_policy_status *status_list,
4165 int num_status)
4166{
4167 int rem_len, ret;
4168 char buf[200] = "", *pos, cmd[256];
4169
4170 pos = buf;
4171 rem_len = sizeof(buf);
4172
4173 ret = snprintf(pos, rem_len, " solicited");
4174 if (snprintf_error(rem_len, ret)) {
4175 sigma_dut_print(dut, DUT_MSG_ERROR,
4176 "Failed to write DSCP policy response command");
4177 return -1;
4178 }
4179 pos += ret;
4180 rem_len -= ret;
4181
4182 for (int i = 0; i < num_status; i++) {
4183 ret = snprintf(pos, rem_len, " policy_id=%d status=%d",
4184 status_list[i].id, status_list[i].status);
4185 if (snprintf_error(rem_len, ret)) {
4186 sigma_dut_print(dut, DUT_MSG_ERROR,
4187 "Failed to wite DSCP policy response");
4188 return -1;
4189 }
4190
4191 pos += ret;
4192 rem_len -= ret;
4193 }
4194
4195 ret = snprintf(cmd, sizeof(cmd), "DSCP_RESP%s", buf);
4196 if (snprintf_error(sizeof(cmd), ret)) {
4197 sigma_dut_print(dut, DUT_MSG_ERROR,
4198 "Failed to create DSCP Policy Response frame");
4199 return -1;
4200 }
4201
4202 if (wpa_command(dut->station_ifname, cmd) != 0) {
4203 sigma_dut_print(dut, DUT_MSG_ERROR,
4204 "Failed to send DSCP Policy Response frame");
4205 return -1;
4206 }
4207
4208 sigma_dut_print(dut, DUT_MSG_DEBUG,
4209 "DSCP Policy Response frame sent: %s", cmd);
4210 return 0;
4211}
4212
4213
4214#ifdef ANDROID
4215static void thread_cancel_handler(int sig)
4216{
4217 if (sig == SIGUSR1)
4218 pthread_exit(0);
4219}
4220#endif /* ANDROID */
4221
4222
4223static void * mon_dscp_policies(void *ptr)
4224{
4225 struct sigma_dut *dut = ptr;
4226 int ret, policy_id;
4227 struct wpa_ctrl *ctrl;
4228 char buf[4096], *pos, *end;
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304229 struct dscp_policy_data *policy = NULL, *current_policy, *prev_policy;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304230 struct dscp_policy_status status_list[10];
4231 int num_status = 0;
4232 const char *events[] = {
4233 "CTRL-EVENT-DISCONNECTED",
4234 "CTRL-EVENT-DSCP-POLICY",
4235 NULL
4236 };
4237#ifdef ANDROID
4238 struct sigaction actions;
4239#endif /* ANDROID */
4240
4241 ctrl = open_wpa_mon(get_station_ifname(dut));
4242 if (!ctrl) {
4243 sigma_dut_print(dut, DUT_MSG_ERROR,
4244 "Failed to open wpa_supplicant monitor connection");
4245 return NULL;
4246 }
4247
4248#ifdef ANDROID
4249 memset(&actions, 0, sizeof(actions));
4250 sigemptyset(&actions.sa_mask);
4251 actions.sa_flags = 0;
4252 actions.sa_handler = thread_cancel_handler;
4253 if (sigaction(SIGUSR1, &actions, NULL) == -1) {
4254 sigma_dut_print(dut, DUT_MSG_ERROR,
4255 "Failed to register exit handler for %s",
4256 __func__);
4257 wpa_ctrl_detach(ctrl);
4258 wpa_ctrl_close(ctrl);
4259 return NULL;
4260 }
4261#endif /* ANDROID */
4262
4263 while (1) {
4264 ret = get_wpa_cli_events_timeout(dut, ctrl, events,
4265 buf, sizeof(buf), 0);
4266
4267 if (ret || strlen(buf) == 0) {
4268 sigma_dut_print(dut, DUT_MSG_INFO,
4269 "Did not receive any event");
4270 continue;
4271 }
4272
4273 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4274 clear_all_dscp_policies(dut);
4275 break;
4276 }
4277
4278 if (strstr(buf, "request_start")) {
4279 num_status = 0;
4280 if (strstr(buf, "clear_all"))
4281 clear_all_dscp_policies(dut);
4282 continue;
4283 }
4284
4285 if (strstr(buf, "request_end")) {
4286 send_dscp_response(dut, status_list, num_status);
4287 continue;
4288 }
4289
4290 if (!strstr(buf, "add") && !strstr(buf, "remove") &&
4291 !strstr(buf, "reject")) {
4292 sigma_dut_print(dut, DUT_MSG_DEBUG, "Ignore event: %s",
4293 buf);
4294 continue;
4295 }
4296
4297 pos = strstr(buf, "policy_id=");
4298 if (!pos) {
4299 sigma_dut_print(dut, DUT_MSG_INFO,
4300 "Policy id not present");
4301 continue;
4302 }
4303 policy_id = atoi(pos + 10);
4304
4305 if (num_status >= ARRAY_SIZE(status_list)) {
4306 sigma_dut_print(dut, DUT_MSG_INFO,
4307 "Max policies allowed per DSCP request reached. Drop policy id %d request",
4308 policy_id);
4309 continue;
4310 }
4311 status_list[num_status].id = policy_id;
4312
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05304313 if (dut->reject_dscp_policies) {
4314 status_list[num_status].status =
4315 dut->dscp_reject_resp_code;
4316 num_status++;
4317 continue;
4318 }
4319
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304320 if (strstr(buf, "reject"))
4321 goto reject;
4322
4323 /*
4324 * In case of "add" also if policy with same policy id exist it
4325 * shall be removed. So always call remove_dscp_policy().
4326 */
4327 if (remove_dscp_policy(dut, policy_id))
4328 goto reject;
4329
4330 if (strstr(buf, "remove"))
4331 goto success;
4332
4333 policy = malloc(sizeof(*policy));
4334 if (!policy)
4335 goto reject;
4336
4337 memset(policy, 0, sizeof(*policy));
4338
4339 policy->policy_id = policy_id;
4340
4341 pos = strstr(buf, "dscp=");
4342 if (!pos) {
4343 sigma_dut_print(dut, DUT_MSG_ERROR,
4344 "DSCP info not present");
4345 goto reject;
4346 }
4347 policy->dscp = atoi(pos + 5);
4348
4349 pos = strstr(buf, "ip_version=");
4350 if (!pos) {
4351 sigma_dut_print(dut, DUT_MSG_ERROR,
4352 "IP version info not present");
4353 goto reject;
4354 }
4355 policy->ip_version = atoi(pos + 11);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304356 if (policy->ip_version)
4357 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304358
4359 pos = strstr(buf, "domain_name=");
4360 if (pos) {
4361 pos += 12;
4362 end = strchr(pos, ' ');
4363 if (!end)
4364 end = pos + strlen(pos);
4365
4366 if (end - pos >= (int) sizeof(policy->domain_name))
4367 goto reject;
4368
4369 memcpy(policy->domain_name, pos, end - pos);
4370 policy->domain_name[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304371 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304372 }
4373
4374 pos = strstr(buf, "start_port=");
4375 if (pos) {
4376 pos += 11;
4377 policy->start_port = atoi(pos);
4378 }
4379
4380 pos = strstr(buf, "end_port=");
4381 if (pos) {
4382 pos += 9;
4383 policy->end_port = atoi(pos);
4384 }
4385
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304386 if (policy->start_port && policy->end_port)
4387 policy->granularity_score++;
4388
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304389 pos = strstr(buf, "src_ip=");
4390 if (pos) {
4391 pos += 7;
4392 end = strchr(pos, ' ');
4393 if (!end)
4394 end = pos + strlen(pos);
4395
4396 if (end - pos >= (int) sizeof(policy->src_ip))
4397 goto reject;
4398
4399 memcpy(policy->src_ip, pos, end - pos);
4400 policy->src_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304401 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304402 }
4403
4404 pos = strstr(buf, "dst_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->dst_ip))
4412 goto reject;
4413
4414 memcpy(policy->dst_ip, pos, end - pos);
4415 policy->dst_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, "src_port=");
4420 if (pos) {
4421 pos += 9;
4422 policy->src_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304423 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304424 }
4425
4426 pos = strstr(buf, "dst_port=");
4427 if (pos) {
4428 pos += 9;
4429 policy->dst_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304430 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304431 }
4432
4433 pos = strstr(buf, "protocol=");
4434 if (pos) {
4435 pos += 9;
4436 policy->protocol = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304437 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304438 }
4439
4440 /*
4441 * Skip adding nft rules for doman name policies.
4442 * Domain name rules are applied in sigma_dut itself.
4443 */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304444 if (!strlen(policy->domain_name) &&
4445 add_dscp_policy_rule(dut, policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304446 goto reject;
4447
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304448 /*
4449 * Add the new policy in policy table in granularity increasing
4450 * order.
4451 */
4452 current_policy = dut->dscp_policy_table;
4453 prev_policy = NULL;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304454
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304455 while (current_policy) {
4456 if (current_policy->granularity_score >
4457 policy->granularity_score)
4458 break;
4459
4460 prev_policy = current_policy;
4461 current_policy = current_policy->next;
4462 }
4463
4464 if (prev_policy)
4465 prev_policy->next = policy;
4466 else
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304467 dut->dscp_policy_table = policy;
4468
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304469 policy->next = current_policy;
4470
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304471success:
4472 status_list[num_status].status = DSCP_POLICY_SUCCESS;
4473 num_status++;
4474 policy = NULL;
4475 continue;
4476reject:
4477 status_list[num_status].status = DSCP_POLICY_REJECT;
4478 num_status++;
4479 free(policy);
4480 policy = NULL;
4481 }
4482
4483 free_dscp_policy_table(dut);
4484 wpa_ctrl_detach(ctrl);
4485 wpa_ctrl_close(ctrl);
4486
4487 pthread_exit(0);
4488 return NULL;
4489}
4490
4491
4492static void start_dscp_policy_mon_thread(struct sigma_dut *dut)
4493{
4494 /* Create event thread */
4495 pthread_create(&dut->dscp_policy_mon_thread, NULL, &mon_dscp_policies,
4496 (void *) dut);
4497}
4498
4499
4500void stop_dscp_policy_mon_thread(struct sigma_dut *dut)
4501{
4502 if (dut->dscp_policy_mon_thread) {
4503#ifdef ANDROID
4504 /* pthread_cancel not supported in Android */
4505 pthread_kill(dut->dscp_policy_mon_thread, SIGUSR1);
4506#else /* ANDROID */
4507 pthread_cancel(dut->dscp_policy_mon_thread);
4508#endif /* ANDROID */
4509 dut->dscp_policy_mon_thread = 0;
4510 }
4511}
4512
4513
Jouni Malinenf7222712019-06-13 01:50:21 +03004514static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
4515 struct sigma_conn *conn,
4516 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004517{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304518#ifdef NL80211_SUPPORT
4519 const char *intf = get_param(cmd, "Interface");
4520#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004521 const char *ssid = get_param(cmd, "ssid");
4522 const char *wps_param = get_param(cmd, "WPS");
4523 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03004524 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004525 const char *network_mode = get_param(cmd, "network_mode");
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304526 const char *ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004527 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03004528 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004529 int e;
4530 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
4531 struct wpa_ctrl *ctrl = NULL;
4532 int num_network_not_found = 0;
4533 int num_disconnected = 0;
4534 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004535
4536 if (ssid == NULL)
4537 return -1;
4538
Jouni Malinen37d5c692019-08-19 16:56:55 +03004539 dut->server_cert_tod = 0;
4540
Jouni Malinen3c367e82017-06-23 17:01:47 +03004541 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05304542#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004543 if (get_driver_type(dut) == DRIVER_WCN) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304544 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Sunil Dutt44595082018-02-12 19:41:45 +05304545 dut->config_rsnie = 1;
4546 }
4547#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03004548 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
4549 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004550 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03004551 send_resp(dut, conn, SIGMA_ERROR,
4552 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
4553 return 0;
4554 }
4555 }
4556
Jouni Malinen68143132017-09-02 02:34:08 +03004557 if (dut->sae_commit_override) {
4558 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
4559 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004560 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03004561 send_resp(dut, conn, SIGMA_ERROR,
4562 "ErrorCode,Failed to set SAE commit override");
4563 return 0;
4564 }
4565 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304566#ifdef ANDROID
4567 if (dut->fils_hlp)
4568 process_fils_hlp(dut);
4569#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03004570
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004571 if (wps_param &&
4572 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
4573 wps = 1;
4574
4575 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004576 if (dut->program == PROGRAM_60GHZ && network_mode &&
4577 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004578 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004579 "pbss", "1") < 0)
4580 return -2;
4581
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004582 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
4583 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
4584 "parameters not yet set");
4585 return 0;
4586 }
4587 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004588 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004589 return -2;
4590 } else {
4591 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
4592 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004593 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004594 return -2;
4595 }
4596 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05304597 if (strcmp(ssid, dut->infra_ssid) == 0) {
4598 sigma_dut_print(dut, DUT_MSG_DEBUG,
4599 "sta_associate for the most recently added network");
4600 } else if (find_network(dut, ssid) < 0) {
4601 sigma_dut_print(dut, DUT_MSG_DEBUG,
4602 "sta_associate for a previously stored network profile");
4603 send_resp(dut, conn, SIGMA_ERROR,
4604 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004605 return 0;
4606 }
4607
4608 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004609 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004610 "bssid", bssid) < 0) {
4611 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4612 "Invalid bssid argument");
4613 return 0;
4614 }
4615
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304616 if ((dut->program == PROGRAM_WPA3 &&
4617 dut->sta_associate_wait_connect) ||
4618 dut->program == PROGRAM_QM) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004619 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004620 if (!ctrl)
4621 return ERROR_SEND_STATUS;
4622 }
4623
Jouni Malinen46a19b62017-06-23 14:31:27 +03004624 extra[0] = '\0';
4625 if (chan)
4626 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02004627 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03004628 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
4629 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004630 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004631 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
4632 "network id %d on %s",
4633 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004634 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004635 ret = ERROR_SEND_STATUS;
4636 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004637 }
4638 }
4639
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004640 if (!ctrl)
4641 return SUCCESS_SEND_STATUS;
4642
4643 /* Wait for connection result to be able to store server certificate
4644 * hash for trust root override testing
4645 * (dev_exec_action,ServerCertTrust). */
4646
4647 for (e = 0; e < 20; e++) {
4648 const char *events[] = {
4649 "CTRL-EVENT-EAP-PEER-CERT",
4650 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
4651 "CTRL-EVENT-DISCONNECTED",
4652 "CTRL-EVENT-CONNECTED",
4653 "CTRL-EVENT-NETWORK-NOT-FOUND",
4654 NULL
4655 };
4656 char buf[1024];
4657 int res;
4658
4659 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
4660 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02004661 send_resp(dut, conn, SIGMA_COMPLETE,
4662 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004663 ret = STATUS_SENT_ERROR;
4664 break;
4665 }
4666 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
4667 buf);
4668
4669 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
4670 strstr(buf, " depth=0")) {
4671 char *pos = strstr(buf, " hash=");
4672
4673 if (pos) {
4674 char *end;
4675
Jouni Malinen34b19cb2019-08-16 16:37:17 +03004676 if (strstr(buf, " tod=1"))
4677 tod = 1;
4678 else if (strstr(buf, " tod=2"))
4679 tod = 2;
4680 else
4681 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004682 sigma_dut_print(dut, DUT_MSG_DEBUG,
4683 "Server certificate TOD policy: %d",
4684 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03004685 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004686
4687 pos += 6;
4688 end = strchr(pos, ' ');
4689 if (end)
4690 *end = '\0';
4691 strlcpy(dut->server_cert_hash, pos,
4692 sizeof(dut->server_cert_hash));
4693 sigma_dut_print(dut, DUT_MSG_DEBUG,
4694 "Server certificate hash: %s",
4695 dut->server_cert_hash);
4696 }
4697 }
4698
4699 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
4700 send_resp(dut, conn, SIGMA_COMPLETE,
4701 "Result,TLS server certificate validation failed");
4702 ret = STATUS_SENT_ERROR;
4703 break;
4704 }
4705
4706 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
4707 num_network_not_found++;
4708
4709 if (num_network_not_found > 2) {
4710 send_resp(dut, conn, SIGMA_COMPLETE,
4711 "Result,Network not found");
4712 ret = STATUS_SENT_ERROR;
4713 break;
4714 }
4715 }
4716
4717 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4718 num_disconnected++;
4719
4720 if (num_disconnected > 2) {
4721 send_resp(dut, conn, SIGMA_COMPLETE,
4722 "Result,Connection failed");
4723 ret = STATUS_SENT_ERROR;
4724 break;
4725 }
4726 }
4727
4728 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
4729 if (tod >= 0) {
4730 sigma_dut_print(dut, DUT_MSG_DEBUG,
4731 "Network profile TOD policy update: %d -> %d",
4732 dut->sta_tod_policy, tod);
4733 dut->sta_tod_policy = tod;
4734 }
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304735 if (dut->program == PROGRAM_QM) {
4736 unsigned char iface_mac_addr[ETH_ALEN];
4737 char ipv6[100];
4738
4739 if (get_hwaddr(ifname, iface_mac_addr) < 0) {
4740 sigma_dut_print(dut, DUT_MSG_ERROR,
4741 "%s: get_hwaddr %s failed",
4742 __func__, ifname);
4743 ret = ERROR_SEND_STATUS;
4744 break;
4745 }
4746
4747 convert_mac_addr_to_ipv6_lladdr(iface_mac_addr,
4748 ipv6,
4749 sizeof(ipv6));
4750
4751 if (set_ipv6_addr(dut, ipv6, "64", ifname) !=
4752 0) {
4753 ret = ERROR_SEND_STATUS;
4754 break;
4755 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304756 start_dscp_policy_mon_thread(dut);
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304757 }
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004758 break;
4759 }
4760 }
4761done:
4762 if (ctrl) {
4763 wpa_ctrl_detach(ctrl);
4764 wpa_ctrl_close(ctrl);
4765 }
4766 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004767}
4768
4769
4770static int run_hs20_osu(struct sigma_dut *dut, const char *params)
4771{
4772 char buf[500], cmd[200];
4773 int res;
4774
4775 /* Use hs20-osu-client file at the current dir, if found; otherwise use
4776 * default path */
4777 res = snprintf(cmd, sizeof(cmd),
4778 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
4779 file_exists("./hs20-osu-client") ?
4780 "./hs20-osu-client" : "hs20-osu-client",
4781 sigma_wpas_ctrl,
4782 dut->summary_log ? "-s " : "",
4783 dut->summary_log ? dut->summary_log : "");
4784 if (res < 0 || res >= (int) sizeof(cmd))
4785 return -1;
4786
4787 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
4788 if (res < 0 || res >= (int) sizeof(buf))
4789 return -1;
4790 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
4791
4792 if (system(buf) != 0) {
4793 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
4794 return -1;
4795 }
4796 sigma_dut_print(dut, DUT_MSG_DEBUG,
4797 "Completed hs20-osu-client operation");
4798
4799 return 0;
4800}
4801
4802
4803static int download_ppsmo(struct sigma_dut *dut,
4804 struct sigma_conn *conn,
4805 const char *intf,
4806 struct sigma_cmd *cmd)
4807{
4808 const char *name, *path, *val;
4809 char url[500], buf[600], fbuf[100];
4810 char *fqdn = NULL;
4811
4812 name = get_param(cmd, "FileName");
4813 path = get_param(cmd, "FilePath");
4814 if (name == NULL || path == NULL)
4815 return -1;
4816
4817 if (strcasecmp(path, "VendorSpecific") == 0) {
4818 snprintf(url, sizeof(url), "PPS/%s", name);
4819 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
4820 "from the device (%s)", url);
4821 if (!file_exists(url)) {
4822 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
4823 "PPS MO file does not exist");
4824 return 0;
4825 }
4826 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
4827 if (system(buf) != 0) {
4828 send_resp(dut, conn, SIGMA_ERROR,
4829 "errorCode,Failed to copy PPS MO");
4830 return 0;
4831 }
4832 } else if (strncasecmp(path, "http:", 5) != 0 &&
4833 strncasecmp(path, "https:", 6) != 0) {
4834 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4835 "Unsupported FilePath value");
4836 return 0;
4837 } else {
4838 snprintf(url, sizeof(url), "%s/%s", path, name);
4839 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
4840 url);
4841 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
4842 remove("pps-tnds.xml");
4843 if (system(buf) != 0) {
4844 send_resp(dut, conn, SIGMA_ERROR,
4845 "errorCode,Failed to download PPS MO");
4846 return 0;
4847 }
4848 }
4849
4850 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
4851 send_resp(dut, conn, SIGMA_ERROR,
4852 "errorCode,Failed to parse downloaded PPSMO");
4853 return 0;
4854 }
4855 unlink("pps-tnds.xml");
4856
4857 val = get_param(cmd, "managementTreeURI");
4858 if (val) {
4859 const char *pos, *end;
4860 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
4861 val);
4862 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
4863 send_resp(dut, conn, SIGMA_ERROR,
4864 "errorCode,Invalid managementTreeURI prefix");
4865 return 0;
4866 }
4867 pos = val + 8;
4868 end = strchr(pos, '/');
4869 if (end == NULL ||
4870 strcmp(end, "/PerProviderSubscription") != 0) {
4871 send_resp(dut, conn, SIGMA_ERROR,
4872 "errorCode,Invalid managementTreeURI postfix");
4873 return 0;
4874 }
4875 if (end - pos >= (int) sizeof(fbuf)) {
4876 send_resp(dut, conn, SIGMA_ERROR,
4877 "errorCode,Too long FQDN in managementTreeURI");
4878 return 0;
4879 }
4880 memcpy(fbuf, pos, end - pos);
4881 fbuf[end - pos] = '\0';
4882 fqdn = fbuf;
4883 sigma_dut_print(dut, DUT_MSG_INFO,
4884 "FQDN from managementTreeURI: %s", fqdn);
4885 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
4886 FILE *f = fopen("pps-fqdn", "r");
4887 if (f) {
4888 if (fgets(fbuf, sizeof(fbuf), f)) {
4889 fbuf[sizeof(fbuf) - 1] = '\0';
4890 fqdn = fbuf;
4891 sigma_dut_print(dut, DUT_MSG_DEBUG,
4892 "Use FQDN %s", fqdn);
4893 }
4894 fclose(f);
4895 }
4896 }
4897
4898 if (fqdn == NULL) {
4899 send_resp(dut, conn, SIGMA_ERROR,
4900 "errorCode,No FQDN specified");
4901 return 0;
4902 }
4903
4904 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4905 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
4906 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4907
4908 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
4909 if (rename("pps.xml", buf) < 0) {
4910 send_resp(dut, conn, SIGMA_ERROR,
4911 "errorCode,Could not move PPS MO");
4912 return 0;
4913 }
4914
4915 if (strcasecmp(path, "VendorSpecific") == 0) {
4916 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
4917 fqdn);
4918 if (system(buf)) {
4919 send_resp(dut, conn, SIGMA_ERROR,
4920 "errorCode,Failed to copy OSU CA cert");
4921 return 0;
4922 }
4923
4924 snprintf(buf, sizeof(buf),
4925 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
4926 fqdn);
4927 if (system(buf)) {
4928 send_resp(dut, conn, SIGMA_ERROR,
4929 "errorCode,Failed to copy AAA CA cert");
4930 return 0;
4931 }
4932 } else {
4933 snprintf(buf, sizeof(buf),
4934 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
4935 fqdn, fqdn);
4936 if (run_hs20_osu(dut, buf) < 0) {
4937 send_resp(dut, conn, SIGMA_ERROR,
4938 "errorCode,Failed to download OSU CA cert");
4939 return 0;
4940 }
4941
4942 snprintf(buf, sizeof(buf),
4943 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
4944 fqdn, fqdn);
4945 if (run_hs20_osu(dut, buf) < 0) {
4946 sigma_dut_print(dut, DUT_MSG_INFO,
4947 "Failed to download AAA CA cert");
4948 }
4949 }
4950
4951 if (file_exists("next-client-cert.pem")) {
4952 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
4953 if (rename("next-client-cert.pem", buf) < 0) {
4954 send_resp(dut, conn, SIGMA_ERROR,
4955 "errorCode,Could not move client certificate");
4956 return 0;
4957 }
4958 }
4959
4960 if (file_exists("next-client-key.pem")) {
4961 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
4962 if (rename("next-client-key.pem", buf) < 0) {
4963 send_resp(dut, conn, SIGMA_ERROR,
4964 "errorCode,Could not move client key");
4965 return 0;
4966 }
4967 }
4968
4969 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
4970 if (run_hs20_osu(dut, buf) < 0) {
4971 send_resp(dut, conn, SIGMA_ERROR,
4972 "errorCode,Failed to configure credential from "
4973 "PPSMO");
4974 return 0;
4975 }
4976
4977 return 1;
4978}
4979
4980
4981static int download_cert(struct sigma_dut *dut,
4982 struct sigma_conn *conn,
4983 const char *intf,
4984 struct sigma_cmd *cmd)
4985{
4986 const char *name, *path;
4987 char url[500], buf[600];
4988
4989 name = get_param(cmd, "FileName");
4990 path = get_param(cmd, "FilePath");
4991 if (name == NULL || path == NULL)
4992 return -1;
4993
4994 if (strcasecmp(path, "VendorSpecific") == 0) {
4995 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
4996 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
4997 "certificate from the device (%s)", url);
4998 if (!file_exists(url)) {
4999 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
5000 "certificate file does not exist");
5001 return 0;
5002 }
5003 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
5004 if (system(buf) != 0) {
5005 send_resp(dut, conn, SIGMA_ERROR,
5006 "errorCode,Failed to copy client "
5007 "certificate");
5008 return 0;
5009 }
5010
5011 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
5012 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
5013 "private key from the device (%s)", url);
5014 if (!file_exists(url)) {
5015 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
5016 "private key file does not exist");
5017 return 0;
5018 }
5019 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
5020 if (system(buf) != 0) {
5021 send_resp(dut, conn, SIGMA_ERROR,
5022 "errorCode,Failed to copy client key");
5023 return 0;
5024 }
5025 } else if (strncasecmp(path, "http:", 5) != 0 &&
5026 strncasecmp(path, "https:", 6) != 0) {
5027 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
5028 "Unsupported FilePath value");
5029 return 0;
5030 } else {
5031 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
5032 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
5033 "certificate/key from %s", url);
5034 snprintf(buf, sizeof(buf),
5035 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
5036 if (system(buf) != 0) {
5037 send_resp(dut, conn, SIGMA_ERROR,
5038 "errorCode,Failed to download client "
5039 "certificate");
5040 return 0;
5041 }
5042
5043 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
5044 {
5045 send_resp(dut, conn, SIGMA_ERROR,
5046 "errorCode,Failed to copy client key");
5047 return 0;
5048 }
5049 }
5050
5051 return 1;
5052}
5053
5054
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005055static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
5056 struct sigma_conn *conn,
5057 struct sigma_cmd *cmd)
5058{
5059 const char *val;
5060 const char *intf = get_param(cmd, "interface");
5061
5062 if (!intf)
5063 return -1;
5064
5065 val = get_param(cmd, "WscIEFragment");
5066 if (val && strcasecmp(val, "enable") == 0) {
5067 sigma_dut_print(dut, DUT_MSG_DEBUG,
5068 "Enable WSC IE fragmentation");
5069
5070 dut->wsc_fragment = 1;
5071 /* set long attributes to force fragmentation */
5072 if (wpa_command(intf, "SET device_name "
5073 WPS_LONG_DEVICE_NAME) < 0)
5074 return -2;
5075 if (wpa_command(intf, "SET manufacturer "
5076 WPS_LONG_MANUFACTURER) < 0)
5077 return -2;
5078 if (wpa_command(intf, "SET model_name "
5079 WPS_LONG_MODEL_NAME) < 0)
5080 return -2;
5081 if (wpa_command(intf, "SET model_number "
5082 WPS_LONG_MODEL_NUMBER) < 0)
5083 return -2;
5084 if (wpa_command(intf, "SET serial_number "
5085 WPS_LONG_SERIAL_NUMBER) < 0)
5086 return -2;
5087 }
5088
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005089 val = get_param(cmd, "RSN_IE");
5090 if (val) {
5091 if (strcasecmp(val, "disable") == 0)
5092 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
5093 else if (strcasecmp(val, "enable") == 0)
5094 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
5095 }
5096
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02005097 val = get_param(cmd, "WpsVersion");
5098 if (val)
5099 dut->wps_forced_version = get_wps_forced_version(dut, val);
5100
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005101 val = get_param(cmd, "WscEAPFragment");
5102 if (val && strcasecmp(val, "enable") == 0)
5103 dut->eap_fragment = 1;
5104
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005105 return 1;
5106}
5107
5108
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005109static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
5110 struct sigma_conn *conn,
5111 const char *intf,
5112 struct sigma_cmd *cmd)
5113{
5114 const char *val;
5115
5116 val = get_param(cmd, "FileType");
5117 if (val && strcasecmp(val, "PPSMO") == 0)
5118 return download_ppsmo(dut, conn, intf, cmd);
5119 if (val && strcasecmp(val, "CERT") == 0)
5120 return download_cert(dut, conn, intf, cmd);
5121 if (val) {
5122 send_resp(dut, conn, SIGMA_ERROR,
5123 "ErrorCode,Unsupported FileType");
5124 return 0;
5125 }
5126
5127 return 1;
5128}
5129
5130
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305131static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
5132 struct sigma_conn *conn,
5133 const char *intf,
5134 struct sigma_cmd *cmd)
5135{
5136 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305137 char buf[1000];
5138 char text[20];
5139 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305140
5141 val = get_param(cmd, "OCESupport");
5142 if (val && strcasecmp(val, "Disable") == 0) {
5143 if (wpa_command(intf, "SET oce 0") < 0) {
5144 send_resp(dut, conn, SIGMA_ERROR,
5145 "ErrorCode,Failed to disable OCE");
5146 return 0;
5147 }
5148 } else if (val && strcasecmp(val, "Enable") == 0) {
5149 if (wpa_command(intf, "SET oce 1") < 0) {
5150 send_resp(dut, conn, SIGMA_ERROR,
5151 "ErrorCode,Failed to enable OCE");
5152 return 0;
5153 }
5154 }
5155
vamsi krishnaa2799492017-12-05 14:28:01 +05305156 val = get_param(cmd, "FILScap");
5157 if (val && (atoi(val) == 1)) {
5158 if (wpa_command(intf, "SET disable_fils 0") < 0) {
5159 send_resp(dut, conn, SIGMA_ERROR,
5160 "ErrorCode,Failed to enable FILS");
5161 return 0;
5162 }
5163 } else if (val && (atoi(val) == 0)) {
5164 if (wpa_command(intf, "SET disable_fils 1") < 0) {
5165 send_resp(dut, conn, SIGMA_ERROR,
5166 "ErrorCode,Failed to disable FILS");
5167 return 0;
5168 }
5169 }
5170
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305171 val = get_param(cmd, "FILSHLP");
5172 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005173 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305174 sizeof(text)) < 0)
5175 return -2;
5176 hwaddr_aton(text, addr);
5177 snprintf(buf, sizeof(buf),
5178 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
5179 "080045100140000040004011399e00000000ffffffff00440043"
5180 "012cb30001010600fd4f46410000000000000000000000000000"
5181 "000000000000"
5182 "%02x%02x%02x%02x%02x%02x"
5183 "0000000000000000000000000000000000000000000000000000"
5184 "0000000000000000000000000000000000000000000000000000"
5185 "0000000000000000000000000000000000000000000000000000"
5186 "0000000000000000000000000000000000000000000000000000"
5187 "0000000000000000000000000000000000000000000000000000"
5188 "0000000000000000000000000000000000000000000000000000"
5189 "0000000000000000000000000000000000000000000000000000"
5190 "0000000000000000000000000000000000000000638253633501"
5191 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
5192 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
5193 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
5194 if (wpa_command(intf, buf)) {
5195 send_resp(dut, conn, SIGMA_ERROR,
5196 "ErrorCode,Failed to add HLP");
5197 return 0;
5198 }
5199 dut->fils_hlp = 1;
5200 }
5201
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305202 return 1;
5203}
5204
5205
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005206static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
5207 const char *val)
5208{
5209 int counter = 0;
5210 char token[50];
5211 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305212 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005213
Peng Xub8fc5cc2017-05-10 17:27:28 -07005214 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005215 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305216 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005217 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005218 if (strcmp(result, "disable") == 0)
5219 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
5220 else
5221 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305222 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005223 counter++;
5224 }
5225}
5226
5227
5228static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
5229 const char *val)
5230{
5231 char buf[100];
5232
5233 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
5234 if (system(buf) != 0) {
5235 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
5236 }
5237}
5238
5239
5240static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5241 const char *val)
5242{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005243 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005244 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005245 }
5246}
5247
5248
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005249static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5250 const char *val)
5251{
5252#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005253 int wmmenable = 1;
5254
5255 if (val &&
5256 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
5257 wmmenable = 0;
5258
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305259 return wcn_wifi_test_config_set_u8(
5260 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
5261 wmmenable);
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005262#else /* NL80211_SUPPORT */
5263 sigma_dut_print(dut, DUT_MSG_ERROR,
5264 "WMM cannot be changed without NL80211_SUPPORT defined");
5265 return -1;
5266#endif /* NL80211_SUPPORT */
5267}
5268
5269
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005270static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
5271 const char *val)
5272{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005273 int sgi20;
5274
5275 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5276
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005277 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005278}
5279
5280
5281static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
5282 const char *val)
5283{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305284 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005285
5286 /* Disable Tx Beam forming when using a fixed rate */
5287 ath_disable_txbf(dut, intf);
5288
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305289 v = atoi(val);
5290 if (v < 0 || v > 32) {
5291 sigma_dut_print(dut, DUT_MSG_ERROR,
5292 "Invalid Fixed MCS rate: %d", v);
5293 return;
5294 }
5295 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005296
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005297 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005298
5299 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005300 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005301}
5302
5303
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005304static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
5305 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005306{
5307 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305308 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005309
5310 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
5311 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
5312 else
5313 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5314
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305315 ret = system(buf);
5316#ifdef NL80211_SUPPORT
5317 if (ret) {
5318 int value = (strcasecmp(val, "Enable") == 0) ? 2 : 1;
5319
5320 ret = sta_config_params(dut, intf, STA_SET_TX_MSDU, value);
5321 ret |= sta_config_params(dut, intf, STA_SET_RX_MSDU, value);
5322 }
5323#endif /* NL80211_SUPPORT */
5324 if (ret)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005325 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
5326}
5327
5328
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005329static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
5330 int ampdu)
5331{
5332 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005333 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005334
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005335 if (ampdu)
5336 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005337 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
5338 if (system(buf) != 0) {
5339 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
5340 return -1;
5341 }
5342
5343 return 0;
5344}
5345
5346
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005347static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5348 const char *val)
5349{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005350 run_iwpriv(dut, intf, "tx_stbc %s", val);
5351 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005352}
5353
5354
5355static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
5356 const char *val)
5357{
5358 char buf[60];
5359
Peng Xucc317ed2017-05-18 16:44:37 -07005360 if (strcmp(val, "160") == 0) {
5361 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
5362 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005363 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5364 } else if (strcmp(val, "40") == 0) {
5365 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
5366 } else if (strcmp(val, "20") == 0) {
5367 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
5368 } else if (strcasecmp(val, "Auto") == 0) {
5369 buf[0] = '\0';
5370 } else {
5371 sigma_dut_print(dut, DUT_MSG_ERROR,
5372 "WIDTH/CTS_WIDTH value not supported");
5373 return -1;
5374 }
5375
5376 if (buf[0] != '\0' && system(buf) != 0) {
5377 sigma_dut_print(dut, DUT_MSG_ERROR,
5378 "Failed to set WIDTH/CTS_WIDTH");
5379 return -1;
5380 }
5381
5382 return 0;
5383}
5384
5385
5386int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
5387 const char *intf, const char *val)
5388{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005389 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005390 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005391 dut->chwidth = 0;
5392 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005393 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005394 dut->chwidth = 0;
5395 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005396 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005397 dut->chwidth = 1;
5398 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005399 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005400 dut->chwidth = 2;
5401 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005402 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005403 dut->chwidth = 3;
5404 } else {
5405 send_resp(dut, conn, SIGMA_ERROR,
5406 "ErrorCode,WIDTH not supported");
5407 return -1;
5408 }
5409
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005410 return 0;
5411}
5412
5413
5414static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
5415 const char *val)
5416{
5417 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07005418 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005419
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005420 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005421 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005422 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005423 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005424 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005425 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005426 } else {
5427 sigma_dut_print(dut, DUT_MSG_ERROR,
5428 "SP_STREAM value not supported");
5429 return -1;
5430 }
5431
5432 if (system(buf) != 0) {
5433 sigma_dut_print(dut, DUT_MSG_ERROR,
5434 "Failed to set SP_STREAM");
5435 return -1;
5436 }
5437
Arif Hussainac6c5112018-05-25 17:34:00 -07005438 dut->sta_nss = sta_nss;
5439
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005440 return 0;
5441}
5442
5443
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305444static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5445 const char *val)
5446{
5447 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305448 int ret;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305449
5450 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305451 ret = system(buf);
5452#ifdef NL80211_SUPPORT
5453 if (ret)
5454 ret = sta_config_params(dut, intf, STA_SET_TX_STBC,
5455 strcmp(val, "0") == 0 ? 0 : 1);
5456#endif /* NL80211_SUPPORT */
5457 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305458 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
5459
5460 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305461 ret = system(buf);
5462#ifdef NL80211_SUPPORT
5463 if (ret)
5464 ret = sta_config_params(dut, intf, STA_SET_RX_STBC,
5465 strcmp(val, "0") == 0 ? 0 : 1);
5466#endif /* NL80211_SUPPORT */
5467 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305468 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
5469}
5470
5471
Ashwini Patil68d02cd2017-01-10 15:39:16 +05305472static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
5473 struct sigma_conn *conn,
5474 const char *intf, int capa)
5475{
5476 char buf[32];
5477
5478 if (capa > 0 && capa < 4) {
5479 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
5480 if (wpa_command(intf, buf) < 0) {
5481 send_resp(dut, conn, SIGMA_ERROR,
5482 "ErrorCode, Failed to set cellular data capability");
5483 return 0;
5484 }
5485 return 1;
5486 }
5487
5488 sigma_dut_print(dut, DUT_MSG_ERROR,
5489 "Invalid Cellular data capability: %d", capa);
5490 send_resp(dut, conn, SIGMA_INVALID,
5491 "ErrorCode,Invalid cellular data capability");
5492 return 0;
5493}
5494
5495
Ashwini Patil9183fdb2017-04-13 16:58:25 +05305496static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
5497 const char *intf, const char *val)
5498{
5499 if (strcasecmp(val, "Disable") == 0) {
5500 if (wpa_command(intf, "SET roaming 0") < 0) {
5501 send_resp(dut, conn, SIGMA_ERROR,
5502 "ErrorCode,Failed to disable roaming");
5503 return 0;
5504 }
5505 return 1;
5506 }
5507
5508 if (strcasecmp(val, "Enable") == 0) {
5509 if (wpa_command(intf, "SET roaming 1") < 0) {
5510 send_resp(dut, conn, SIGMA_ERROR,
5511 "ErrorCode,Failed to enable roaming");
5512 return 0;
5513 }
5514 return 1;
5515 }
5516
5517 sigma_dut_print(dut, DUT_MSG_ERROR,
5518 "Invalid value provided for roaming: %s", val);
5519 send_resp(dut, conn, SIGMA_INVALID,
5520 "ErrorCode,Unknown value provided for Roaming");
5521 return 0;
5522}
5523
5524
Ashwini Patila75de5a2017-04-13 16:35:05 +05305525static int mbo_set_assoc_disallow(struct sigma_dut *dut,
5526 struct sigma_conn *conn,
5527 const char *intf, const char *val)
5528{
5529 if (strcasecmp(val, "Disable") == 0) {
5530 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
5531 send_resp(dut, conn, SIGMA_ERROR,
5532 "ErrorCode,Failed to disable Assoc_disallow");
5533 return 0;
5534 }
5535 return 1;
5536 }
5537
5538 if (strcasecmp(val, "Enable") == 0) {
5539 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
5540 send_resp(dut, conn, SIGMA_ERROR,
5541 "ErrorCode,Failed to enable Assoc_disallow");
5542 return 0;
5543 }
5544 return 1;
5545 }
5546
5547 sigma_dut_print(dut, DUT_MSG_ERROR,
5548 "Invalid value provided for Assoc_disallow: %s", val);
5549 send_resp(dut, conn, SIGMA_INVALID,
5550 "ErrorCode,Unknown value provided for Assoc_disallow");
5551 return 0;
5552}
5553
5554
Ashwini Patilc63161e2017-04-13 16:30:23 +05305555static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
5556 const char *intf, const char *val)
5557{
5558 if (strcasecmp(val, "Reject") == 0) {
5559 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
5560 send_resp(dut, conn, SIGMA_ERROR,
5561 "ErrorCode,Failed to Reject BTM Request");
5562 return 0;
5563 }
5564 return 1;
5565 }
5566
5567 if (strcasecmp(val, "Accept") == 0) {
5568 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
5569 send_resp(dut, conn, SIGMA_ERROR,
5570 "ErrorCode,Failed to Accept BTM Request");
5571 return 0;
5572 }
5573 return 1;
5574 }
5575
5576 sigma_dut_print(dut, DUT_MSG_ERROR,
5577 "Invalid value provided for BSS_Transition: %s", val);
5578 send_resp(dut, conn, SIGMA_INVALID,
5579 "ErrorCode,Unknown value provided for BSS_Transition");
5580 return 0;
5581}
5582
5583
Ashwini Patil00402582017-04-13 12:29:39 +05305584static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
5585 struct sigma_conn *conn,
5586 const char *intf,
5587 struct sigma_cmd *cmd)
5588{
5589 const char *ch, *pref, *op_class, *reason;
5590 char buf[120];
5591 int len, ret;
5592
5593 pref = get_param(cmd, "Ch_Pref");
5594 if (!pref)
5595 return 1;
5596
5597 if (strcasecmp(pref, "clear") == 0) {
5598 free(dut->non_pref_ch_list);
5599 dut->non_pref_ch_list = NULL;
5600 } else {
5601 op_class = get_param(cmd, "Ch_Op_Class");
5602 if (!op_class) {
5603 send_resp(dut, conn, SIGMA_INVALID,
5604 "ErrorCode,Ch_Op_Class not provided");
5605 return 0;
5606 }
5607
5608 ch = get_param(cmd, "Ch_Pref_Num");
5609 if (!ch) {
5610 send_resp(dut, conn, SIGMA_INVALID,
5611 "ErrorCode,Ch_Pref_Num not provided");
5612 return 0;
5613 }
5614
5615 reason = get_param(cmd, "Ch_Reason_Code");
5616 if (!reason) {
5617 send_resp(dut, conn, SIGMA_INVALID,
5618 "ErrorCode,Ch_Reason_Code not provided");
5619 return 0;
5620 }
5621
5622 if (!dut->non_pref_ch_list) {
5623 dut->non_pref_ch_list =
5624 calloc(1, NON_PREF_CH_LIST_SIZE);
5625 if (!dut->non_pref_ch_list) {
5626 send_resp(dut, conn, SIGMA_ERROR,
5627 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
5628 return 0;
5629 }
5630 }
5631 len = strlen(dut->non_pref_ch_list);
5632 ret = snprintf(dut->non_pref_ch_list + len,
5633 NON_PREF_CH_LIST_SIZE - len,
5634 " %s:%s:%s:%s", op_class, ch, pref, reason);
5635 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
5636 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
5637 dut->non_pref_ch_list);
5638 } else {
5639 sigma_dut_print(dut, DUT_MSG_ERROR,
5640 "snprintf failed for non_pref_list, ret = %d",
5641 ret);
5642 send_resp(dut, conn, SIGMA_ERROR,
5643 "ErrorCode,snprintf failed");
5644 free(dut->non_pref_ch_list);
5645 dut->non_pref_ch_list = NULL;
5646 return 0;
5647 }
5648 }
5649
5650 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
5651 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
5652 if (ret < 0 || ret >= (int) sizeof(buf)) {
5653 sigma_dut_print(dut, DUT_MSG_DEBUG,
5654 "snprintf failed for set non_pref_chan, ret: %d",
5655 ret);
5656 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
5657 return 0;
5658 }
5659
5660 if (wpa_command(intf, buf) < 0) {
5661 send_resp(dut, conn, SIGMA_ERROR,
5662 "ErrorCode,Failed to set non-preferred channel list");
5663 return 0;
5664 }
5665
5666 return 1;
5667}
5668
5669
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005670#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005671
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005672static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
5673 uint8_t cfg)
5674{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305675 return wcn_wifi_test_config_set_u8(
5676 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
5677 cfg);
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005678}
5679
5680
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005681static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
5682 enum he_fragmentation_val frag)
5683{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305684 return wcn_wifi_test_config_set_u8(
5685 dut, intf,
5686 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION, frag);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005687}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005688
5689
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08005690int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
5691 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005692{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305693 return wcn_wifi_test_config_set_u8(
5694 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF, ltf);
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005695}
5696
5697
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005698static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
5699 int noack, enum qca_wlan_ac_type ac)
5700{
5701 struct nl_msg *msg;
5702 int ret = 0;
5703 struct nlattr *params;
5704 int ifindex;
5705
5706 ifindex = if_nametoindex(intf);
5707 if (ifindex == 0) {
5708 sigma_dut_print(dut, DUT_MSG_ERROR,
5709 "%s: Index for interface %s failed",
5710 __func__, intf);
5711 return -1;
5712 }
5713
5714 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5715 NL80211_CMD_VENDOR)) ||
5716 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5717 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5718 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5719 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5720 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5721 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
5722 noack) ||
5723 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
5724 ac)) {
5725 sigma_dut_print(dut, DUT_MSG_ERROR,
5726 "%s: err in adding vendor_cmd and vendor_data",
5727 __func__);
5728 nlmsg_free(msg);
5729 return -1;
5730 }
5731 nla_nest_end(msg, params);
5732
5733 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5734 if (ret) {
5735 sigma_dut_print(dut, DUT_MSG_ERROR,
5736 "%s: err in send_and_recv_msgs, ret=%d",
5737 __func__, ret);
5738 }
5739 return ret;
5740}
5741
5742
5743static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
5744 const char *val)
5745{
5746 int noack, ret;
5747 char token[100];
5748 char *result;
5749 char *saveptr;
5750 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
5751
5752 strlcpy(token, val, sizeof(token));
5753 token[sizeof(token) - 1] = '\0';
5754 result = strtok_r(token, ":", &saveptr);
5755 while (result) {
5756 noack = strcasecmp(result, "Disable") != 0;
5757 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
5758 if (ret) {
5759 sigma_dut_print(dut, DUT_MSG_ERROR,
5760 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
5761 ac, ret);
5762 }
5763 result = strtok_r(NULL, ":", &saveptr);
5764 ac++;
5765 }
5766}
5767
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305768
5769static int nlvendor_sta_set_phymode(struct sigma_dut *dut, const char *intf,
5770 enum qca_wlan_vendor_phy_mode val)
5771{
5772 struct nl_msg *msg;
5773 struct nlattr *params;
5774 int ifindex, ret;
5775
5776 ifindex = if_nametoindex(intf);
5777 if (ifindex == 0) {
5778 sigma_dut_print(dut, DUT_MSG_ERROR,
5779 "%s: Index for interface %s not found",
5780 __func__, intf);
5781 return -1;
5782 }
5783
5784 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5785 NL80211_CMD_VENDOR);
5786 if (!msg) {
5787 sigma_dut_print(dut, DUT_MSG_ERROR,
5788 "%s: err in adding vendor_cmd", __func__);
5789 return -1;
5790 }
5791
5792 if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5793 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5794 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION)) {
5795 sigma_dut_print(dut, DUT_MSG_ERROR,
5796 "%s: err in adding vendor_attr", __func__);
5797 nlmsg_free(msg);
5798 return -1;
5799 }
5800
5801 params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
5802 if (!params || nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE,
5803 val)) {
5804 sigma_dut_print(dut, DUT_MSG_ERROR,
5805 "%s: err in adding vendor_data", __func__);
5806 nlmsg_free(msg);
5807 return -1;
5808 }
5809
5810 nla_nest_end(msg, params);
5811 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5812 if (ret) {
5813 sigma_dut_print(dut, DUT_MSG_ERROR,
5814 "%s: err in send_and_recv_msgs, ret=%d (%s)",
5815 __func__, ret, strerror(-ret));
5816 return ret;
5817 }
5818
5819 return 0;
5820}
5821
5822
5823static enum qca_wlan_vendor_phy_mode get_qca_vendor_phymode(const char *val)
5824{
5825 if (strcmp(val, "11a") == 0) {
5826 /* IEEE80211_MODE_11A */
5827 return QCA_WLAN_VENDOR_PHY_MODE_11A;
5828 }
5829
5830 if (strcmp(val, "11g") == 0) {
5831 /* IEEE80211_MODE_11G */
5832 return QCA_WLAN_VENDOR_PHY_MODE_11G;
5833 }
5834
5835 if (strcmp(val, "11b") == 0) {
5836 /* IEEE80211_MODE_11B */
5837 return QCA_WLAN_VENDOR_PHY_MODE_11B;
5838 }
5839
5840 if (strcmp(val, "11n") == 0 ||
5841 strcmp(val, "11nl") == 0 ||
5842 strcmp(val, "11nl(nabg)") == 0) {
5843 /* IEEE80211_MODE_11AGN */
5844 return QCA_WLAN_VENDOR_PHY_MODE_11AGN;
5845 }
5846
5847 if (strcmp(val, "11ng") == 0) {
5848 /* IEEE80211_MODE_11NG_HT40 */
5849 return QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40;
5850 }
5851
5852 if (strcmp(val, "AC") == 0 ||
5853 strcasecmp(val, "11AC") == 0) {
5854 /* IEEE80211_MODE_11AC_VHT80 */
5855 return QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80;
5856 }
5857
5858 if (strcmp(val, "11na") == 0 ||
5859 strcasecmp(val, "11an") == 0) {
5860 /* IEEE80211_MODE_11NA_HT40 */
5861 return QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40;
5862 }
5863
5864 if (strcmp(val, "11ax") == 0 ||
5865 strcmp(val, "auto") == 0) {
5866 /* IEEE80211_MODE_AUTO */
5867 return QCA_WLAN_VENDOR_PHY_MODE_AUTO;
5868 }
5869
5870 return -1;
5871}
5872
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005873#endif /* NL80211_SUPPORT */
5874
5875
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305876static int get_phymode(const char *val)
5877{
5878 if (strcmp(val, "11a") == 0)
5879 return 1; /* IEEE80211_MODE_11A */
5880 if (strcmp(val, "11g") == 0)
5881 return 3; /* IEEE80211_MODE_11G */
5882 if (strcmp(val, "11b") == 0)
5883 return 2; /* IEEE80211_MODE_11B */
5884 if (strcmp(val, "11n") == 0 ||
5885 strcmp(val, "11nl") == 0 ||
5886 strcmp(val, "11nl(nabg)") == 0)
5887 return 22; /* IEEE80211_MODE_11AGN */
5888 if (strcmp(val, "11ng") == 0)
5889 return 13; /* IEEE80211_MODE_11NG_HT40 */
5890 if (strcmp(val, "AC") == 0 ||
5891 strcasecmp(val, "11AC") == 0)
5892 return 19; /* IEEE80211_MODE_11AC_VHT80 */
5893 if (strcmp(val, "11na") == 0 ||
5894 strcasecmp(val, "11an") == 0)
5895 return 14; /* IEEE80211_MODE_11NA_HT40 */
5896 if (strcmp(val, "11ax") == 0 ||
5897 strcmp(val, "auto") == 0)
5898 return 0; /* IEEE80211_MODE_AUTO */
5899 return -1;
5900}
5901
5902
5903static void sta_set_phymode(struct sigma_dut *dut, const char *intf,
5904 const char *val)
5905{
5906 char buf[100];
5907 int len, phymode;
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305908#ifdef NL80211_SUPPORT
5909 enum qca_wlan_vendor_phy_mode qca_phymode;
5910
5911 qca_phymode = get_qca_vendor_phymode(val);
5912 if (qca_phymode == -1) {
5913 sigma_dut_print(dut, DUT_MSG_DEBUG,
5914 "Ignoring mode change for mode: %s",
5915 val);
5916 return;
5917 }
5918
5919 if (nlvendor_sta_set_phymode(dut, intf, qca_phymode) == 0)
5920 return;
5921#endif /* NL80211_SUPPORT */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305922
5923 phymode = get_phymode(val);
5924 if (phymode == -1) {
5925 sigma_dut_print(dut, DUT_MSG_DEBUG,
5926 "Ignoring mode change for mode: %s",
5927 val);
5928 return;
5929 }
5930
5931 len = snprintf(buf, sizeof(buf), "iwpriv %s setphymode %d", intf,
5932 phymode);
5933 if (len < 0 || len >= sizeof(buf)) {
5934 sigma_dut_print(dut, DUT_MSG_ERROR,
5935 "Failed to set phymode");
5936 return;
5937 }
5938
5939 if (system(buf) != 0)
5940 sigma_dut_print(dut, DUT_MSG_ERROR,
5941 "iwpriv setting of phymode failed");
5942}
5943
5944
Jouni Malinenf7222712019-06-13 01:50:21 +03005945static enum sigma_cmd_result
5946cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
5947 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005948{
5949 const char *intf = get_param(cmd, "Interface");
5950 const char *val;
5951
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005952 val = get_param(cmd, "FT_DS");
5953 if (val) {
5954 if (strcasecmp(val, "Enable") == 0) {
5955 dut->sta_ft_ds = 1;
5956 } else if (strcasecmp(val, "Disable") == 0) {
5957 dut->sta_ft_ds = 0;
5958 } else {
5959 send_resp(dut, conn, SIGMA_ERROR,
5960 "errorCode,Unsupported value for FT_DS");
5961 return STATUS_SENT_ERROR;
5962 }
Shivani Baranwal7aa48602021-09-29 10:53:38 +05305963 if (get_driver_type(dut) == DRIVER_WCN &&
5964 sta_config_params(dut, intf, STA_SET_FT_DS,
5965 dut->sta_ft_ds) != 0) {
5966 send_resp(dut, conn, SIGMA_ERROR,
5967 "errorCode,Failed to enable/disable FT_DS");
5968 return STATUS_SENT_ERROR;
5969 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005970 }
5971
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005972 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03005973 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
5974 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005975 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
5976 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005977
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005978 if (val && strcasecmp(val, "LOC") == 0)
5979 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02005980 if (val && strcasecmp(val, "60GHZ") == 0) {
5981 val = get_param(cmd, "WPS");
5982 if (val && strcasecmp(val, "disable") == 0) {
5983 dut->wps_disable = 1;
5984 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
5985 } else {
5986 /* wps_disable can have other value from the previous
5987 * test, so make sure it has the correct value.
5988 */
5989 dut->wps_disable = 0;
5990 }
5991
5992 val = get_param(cmd, "P2P");
5993 if (val && strcasecmp(val, "disable") == 0)
5994 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
5995 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005996
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005997 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
5998 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
5999
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006000#ifdef ANDROID_NAN
6001 if (val && strcasecmp(val, "NAN") == 0)
6002 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
6003#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006004#ifdef MIRACAST
6005 if (val && (strcasecmp(val, "WFD") == 0 ||
6006 strcasecmp(val, "DisplayR2") == 0))
6007 return miracast_preset_testparameters(dut, conn, cmd);
6008#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006009
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07006010 if (val &&
6011 (strcasecmp(val, "MBO") == 0 || strcasecmp(val, "HE") == 0)) {
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306012 val = get_param(cmd, "Cellular_Data_Cap");
6013 if (val &&
6014 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
6015 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05306016
6017 val = get_param(cmd, "Ch_Pref");
6018 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
6019 return 0;
6020
Ashwini Patilc63161e2017-04-13 16:30:23 +05306021 val = get_param(cmd, "BSS_Transition");
6022 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
6023 return 0;
6024
Ashwini Patila75de5a2017-04-13 16:35:05 +05306025 val = get_param(cmd, "Assoc_Disallow");
6026 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
6027 return 0;
6028
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306029 val = get_param(cmd, "Roaming");
6030 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
6031 return 0;
6032
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306033 return 1;
6034 }
6035
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306036 if (val && strcasecmp(val, "OCE") == 0)
6037 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
6038
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006039#if 0
6040 val = get_param(cmd, "Supplicant");
6041 if (val && strcasecmp(val, "Default") != 0) {
6042 send_resp(dut, conn, SIGMA_ERROR,
6043 "ErrorCode,Only default(Vendor) supplicant "
6044 "supported");
6045 return 0;
6046 }
6047#endif
6048
6049 val = get_param(cmd, "RTS");
6050 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006051 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006052 case DRIVER_ATHEROS:
6053 ath_sta_set_rts(dut, intf, val);
6054 break;
6055 default:
6056#if 0
6057 send_resp(dut, conn, SIGMA_ERROR,
6058 "ErrorCode,Setting RTS not supported");
6059 return 0;
6060#else
6061 sigma_dut_print(dut, DUT_MSG_DEBUG,
6062 "Setting RTS not supported");
6063 break;
6064#endif
6065 }
6066 }
6067
6068#if 0
6069 val = get_param(cmd, "FRGMNT");
6070 if (val) {
6071 /* TODO */
6072 send_resp(dut, conn, SIGMA_ERROR,
6073 "ErrorCode,Setting FRGMNT not supported");
6074 return 0;
6075 }
6076#endif
6077
6078#if 0
6079 val = get_param(cmd, "Preamble");
6080 if (val) {
6081 /* TODO: Long/Short */
6082 send_resp(dut, conn, SIGMA_ERROR,
6083 "ErrorCode,Setting Preamble not supported");
6084 return 0;
6085 }
6086#endif
6087
6088 val = get_param(cmd, "Mode");
6089 if (val) {
6090 if (strcmp(val, "11b") == 0 ||
6091 strcmp(val, "11g") == 0 ||
6092 strcmp(val, "11a") == 0 ||
6093 strcmp(val, "11n") == 0 ||
6094 strcmp(val, "11ng") == 0 ||
6095 strcmp(val, "11nl") == 0 ||
6096 strcmp(val, "11nl(nabg)") == 0 ||
6097 strcmp(val, "AC") == 0 ||
6098 strcmp(val, "11AC") == 0 ||
6099 strcmp(val, "11ac") == 0 ||
6100 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08006101 strcmp(val, "11an") == 0 ||
6102 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006103 /* STA supports all modes by default */
6104 } else {
6105 send_resp(dut, conn, SIGMA_ERROR,
6106 "ErrorCode,Setting Mode not supported");
6107 return 0;
6108 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006109
6110 /* Change the mode only in case of testbed for HE program
6111 * and for 11a and 11g modes only. */
6112 if (dut->program == PROGRAM_HE &&
6113 dut->device_type == STA_testbed) {
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05306114 sta_set_phymode(dut, intf, val);
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006115 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006116 }
6117
6118 val = get_param(cmd, "wmm");
6119 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006120 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006121 case DRIVER_ATHEROS:
6122 ath_sta_set_wmm(dut, intf, val);
6123 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08006124 case DRIVER_WCN:
6125 wcn_sta_set_wmm(dut, intf, val);
6126 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006127 default:
6128 sigma_dut_print(dut, DUT_MSG_DEBUG,
6129 "Setting wmm not supported");
6130 break;
6131 }
6132 }
6133
6134 val = get_param(cmd, "Powersave");
6135 if (val) {
6136 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006137 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306138 if (set_power_save_wcn(dut, intf, 2) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006139 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006140 }
6141
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006142 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006143 "P2P_SET ps 0") < 0)
6144 return -2;
6145 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006146 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6147 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006148 } else if (strcmp(val, "1") == 0 ||
6149 strcasecmp(val, "PSPoll") == 0 ||
6150 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006151 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306152 if (set_power_save_wcn(dut, intf, 1) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006153 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006154 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006155 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006156 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006157 /* Enable PS-Poll test mode */
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 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006160 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006161 "P2P_SET ps 99") < 0)
6162 return -2;
6163 } else if (strcmp(val, "2") == 0 ||
6164 strcasecmp(val, "Fast") == 0) {
6165 /* TODO */
6166 send_resp(dut, conn, SIGMA_ERROR,
6167 "ErrorCode,Powersave=Fast not supported");
6168 return 0;
6169 } else if (strcmp(val, "3") == 0 ||
6170 strcasecmp(val, "PSNonPoll") == 0) {
6171 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006172 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6173 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006174
6175 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006176 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006177 "P2P_SET ps 1") < 0)
6178 return -2;
6179 } else
6180 return -1;
6181 }
6182
6183 val = get_param(cmd, "NoAck");
6184 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006185 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006186 case DRIVER_ATHEROS:
6187 ath_sta_set_noack(dut, intf, val);
6188 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08006189#ifdef NL80211_SUPPORT
6190 case DRIVER_WCN:
6191 wcn_sta_set_noack(dut, intf, val);
6192 break;
6193#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006194 default:
6195 send_resp(dut, conn, SIGMA_ERROR,
6196 "ErrorCode,Setting NoAck not supported");
6197 return 0;
6198 }
6199 }
6200
6201 val = get_param(cmd, "IgnoreChswitchProhibit");
6202 if (val) {
6203 /* TODO: Enabled/disabled */
6204 if (strcasecmp(val, "Enabled") == 0) {
6205 send_resp(dut, conn, SIGMA_ERROR,
6206 "ErrorCode,Enabling IgnoreChswitchProhibit "
6207 "not supported");
6208 return 0;
6209 }
6210 }
6211
6212 val = get_param(cmd, "TDLS");
6213 if (val) {
6214 if (strcasecmp(val, "Disabled") == 0) {
6215 if (wpa_command(intf, "SET tdls_disabled 1")) {
6216 send_resp(dut, conn, SIGMA_ERROR,
6217 "ErrorCode,Failed to disable TDLS");
6218 return 0;
6219 }
6220 } else if (strcasecmp(val, "Enabled") == 0) {
6221 if (wpa_command(intf, "SET tdls_disabled 0")) {
6222 send_resp(dut, conn, SIGMA_ERROR,
6223 "ErrorCode,Failed to enable TDLS");
6224 return 0;
6225 }
6226 } else {
6227 send_resp(dut, conn, SIGMA_ERROR,
6228 "ErrorCode,Unsupported TDLS value");
6229 return 0;
6230 }
6231 }
6232
6233 val = get_param(cmd, "TDLSmode");
6234 if (val) {
6235 if (strcasecmp(val, "Default") == 0) {
6236 wpa_command(intf, "SET tdls_testing 0");
6237 } else if (strcasecmp(val, "APProhibit") == 0) {
6238 if (wpa_command(intf, "SET tdls_testing 0x400")) {
6239 send_resp(dut, conn, SIGMA_ERROR,
6240 "ErrorCode,Failed to enable ignore "
6241 "APProhibit TDLS mode");
6242 return 0;
6243 }
6244 } else if (strcasecmp(val, "HiLoMac") == 0) {
6245 /* STA should respond with TDLS setup req for a TDLS
6246 * setup req */
6247 if (wpa_command(intf, "SET tdls_testing 0x80")) {
6248 send_resp(dut, conn, SIGMA_ERROR,
6249 "ErrorCode,Failed to enable HiLoMac "
6250 "TDLS mode");
6251 return 0;
6252 }
6253 } else if (strcasecmp(val, "WeakSecurity") == 0) {
6254 /*
6255 * Since all security modes are enabled by default when
6256 * Sigma control is used, there is no need to do
6257 * anything here.
6258 */
6259 } else if (strcasecmp(val, "ExistLink") == 0) {
6260 /*
6261 * Since we allow new TDLS Setup Request even if there
6262 * is an existing link, nothing needs to be done for
6263 * this.
6264 */
6265 } else {
6266 /* TODO:
6267 * ExistLink: STA should send TDLS setup req even if
6268 * direct link already exists
6269 */
6270 send_resp(dut, conn, SIGMA_ERROR,
6271 "ErrorCode,Unsupported TDLSmode value");
6272 return 0;
6273 }
6274 }
6275
6276 val = get_param(cmd, "FakePubKey");
6277 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
6278 send_resp(dut, conn, SIGMA_ERROR,
6279 "ErrorCode,Failed to enable FakePubKey");
6280 return 0;
6281 }
6282
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08006283#ifdef NL80211_SUPPORT
6284 val = get_param(cmd, "FrgmntSupport");
6285 if (val) {
6286 if (strcasecmp(val, "Enable") == 0) {
6287 if (sta_set_he_fragmentation(dut, intf,
6288 HE_FRAG_LEVEL1)) {
6289 send_resp(dut, conn, SIGMA_ERROR,
6290 "ErrorCode,Failed to enable HE Fragmentation");
6291 return 0;
6292 }
6293 } else if (strcasecmp(val, "Disable") == 0) {
6294 if (sta_set_he_fragmentation(dut, intf,
6295 HE_FRAG_DISABLE)) {
6296 send_resp(dut, conn, SIGMA_ERROR,
6297 "ErrorCode,Failed to disable HE Fragmentation");
6298 return 0;
6299 }
6300 }
6301 }
6302#endif /* NL80211_SUPPORT */
6303
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306304 val = get_param(cmd, "IncludeMSCSDescriptor");
6305 if (val && strcasecmp(val, "1") == 0) {
6306 char buf[128];
6307 int len;
6308
6309 len = snprintf(buf, sizeof(buf),
Veerendranath Jakkam62cde372020-08-19 18:03:06 +05306310 "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=60000 frame_classifier=045F%032x",
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306311 0);
6312
6313 if (len < 0 || len >= sizeof(buf)) {
6314 sigma_dut_print(dut, DUT_MSG_ERROR,
6315 "Failed to build MSCS Descriptor IE");
6316 return ERROR_SEND_STATUS;
6317 }
6318
6319 if (wpa_command(intf, buf) != 0) {
6320 send_resp(dut, conn, SIGMA_ERROR,
6321 "ErrorCode,Failed to include MSCS descriptor");
6322 return STATUS_SENT_ERROR;
6323 }
6324 }
6325
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306326 val = get_param(cmd, "SCSSupport");
6327 if (val) {
6328 char buf[30];
6329 int disable_scs, len;
6330
6331 if (strcasecmp(val, "Enable") == 0) {
6332 disable_scs = 0;
6333 } else if (strcasecmp(val, "Disable") == 0) {
6334 disable_scs = 1;
6335 } else {
6336 sigma_dut_print(dut, DUT_MSG_ERROR,
6337 "Invalid SCSsupport parameter");
6338 return INVALID_SEND_STATUS;
6339 }
6340
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306341 if (disable_scs || dut->prev_disable_scs_support) {
6342 len = snprintf(buf, sizeof(buf),
6343 "SET disable_scs_support %d",
6344 disable_scs);
6345 if (len < 0 || len >= sizeof(buf) ||
6346 wpa_command(intf, buf) != 0) {
6347 send_resp(dut, conn, SIGMA_ERROR,
6348 "ErrorCode,Failed to update SCS support");
6349 return STATUS_SENT_ERROR;
6350 }
6351 dut->prev_disable_scs_support = disable_scs;
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306352 }
6353 }
6354
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306355 val = get_param(cmd, "MSCSSupport");
6356 if (val) {
6357 char buf[30];
6358 int disable_mscs, len;
6359
6360 if (strcasecmp(val, "Enable") == 0) {
6361 disable_mscs = 0;
6362 } else if (strcasecmp(val, "Disable") == 0) {
6363 disable_mscs = 1;
6364 } else {
6365 sigma_dut_print(dut, DUT_MSG_ERROR,
6366 "Invalid MSCSsupport parameter");
6367 return INVALID_SEND_STATUS;
6368 }
6369
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306370 if (disable_mscs || dut->prev_disable_mscs_support) {
6371 len = snprintf(buf, sizeof(buf),
6372 "SET disable_mscs_support %d",
6373 disable_mscs);
6374 if (len < 0 || len >= sizeof(buf) ||
6375 wpa_command(intf, buf) != 0) {
6376 send_resp(dut, conn, SIGMA_ERROR,
6377 "ErrorCode,Failed to update MSCS support");
6378 return STATUS_SENT_ERROR;
6379 }
6380 dut->prev_disable_mscs_support = disable_mscs;
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306381 }
6382 }
6383
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05306384 val = get_param(cmd, "DSCPPolicyCapability");
6385 if (val) {
6386 char buf[35];
6387 int len;
6388
6389 if (strcasecmp(val, "Enable") == 0) {
6390 len = snprintf(buf, sizeof(buf),
6391 "SET enable_dscp_policy_capa 1");
6392 } else if (strcasecmp(val, "Disable") == 0) {
6393 len = snprintf(buf, sizeof(buf),
6394 "SET enable_dscp_policy_capa 0");
6395 } else {
6396 sigma_dut_print(dut, DUT_MSG_ERROR,
6397 "Invalid DSCP policy parameter");
6398 return INVALID_SEND_STATUS;
6399 }
6400
6401 if (len < 0 || len >= sizeof(buf) ||
6402 wpa_command(intf, buf) != 0) {
6403 send_resp(dut, conn, SIGMA_ERROR,
6404 "ErrorCode,Failed to update DSCP policy capability");
6405 return STATUS_SENT_ERROR;
6406 }
6407 }
6408
6409 val = get_param(cmd, "DSCPPolicyRespParams");
6410 if (val) {
6411 if (strcasecmp(val, "RejectAll") == 0) {
6412 dut->reject_dscp_policies = 1;
6413 dut->dscp_reject_resp_code = DSCP_POLICY_REJECT;
6414 } else if (strcasecmp(val, "AcceptAll") == 0) {
6415 dut->reject_dscp_policies = 0;
6416 }
6417 }
6418
6419 val = get_param(cmd, "DSCPPolicyResp_StatusCode");
6420 if (val)
6421 dut->dscp_reject_resp_code = atoi(val);
6422
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006423 return 1;
6424}
6425
6426
6427static const char * ath_get_radio_name(const char *radio_name)
6428{
6429 if (radio_name == NULL)
6430 return "wifi0";
6431 if (strcmp(radio_name, "wifi1") == 0)
6432 return "wifi1";
6433 if (strcmp(radio_name, "wifi2") == 0)
6434 return "wifi2";
6435 return "wifi0";
6436}
6437
6438
6439static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
6440 const char *val)
6441{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006442 unsigned int vht_mcsmap = 0;
6443 int txchainmask = 0;
6444 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6445
6446 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6447 if (dut->testbed_flag_txsp == 1) {
6448 vht_mcsmap = 0xfffc;
6449 dut->testbed_flag_txsp = 0;
6450 } else {
6451 vht_mcsmap = 0xfffe;
6452 }
6453 txchainmask = 1;
6454 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6455 if (dut->testbed_flag_txsp == 1) {
6456 vht_mcsmap = 0xfff0;
6457 dut->testbed_flag_txsp = 0;
6458 } else {
6459 vht_mcsmap = 0xfffa;
6460 }
6461 txchainmask = 3;
6462 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6463 if (dut->testbed_flag_txsp == 1) {
6464 vht_mcsmap = 0xffc0;
6465 dut->testbed_flag_txsp = 0;
6466 } else {
6467 vht_mcsmap = 0xffea;
6468 }
6469 txchainmask = 7;
6470 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6471 if (dut->testbed_flag_txsp == 1) {
6472 vht_mcsmap = 0xff00;
6473 dut->testbed_flag_txsp = 0;
6474 } else {
6475 vht_mcsmap = 0xffaa;
6476 }
6477 txchainmask = 15;
6478 } else {
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 }
6486
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006487 if (txchainmask)
6488 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006489
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006490 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006491}
6492
6493
6494static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
6495 const char *val)
6496{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006497 unsigned int vht_mcsmap = 0;
6498 int rxchainmask = 0;
6499 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6500
6501 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6502 if (dut->testbed_flag_rxsp == 1) {
6503 vht_mcsmap = 0xfffc;
6504 dut->testbed_flag_rxsp = 0;
6505 } else {
6506 vht_mcsmap = 0xfffe;
6507 }
6508 rxchainmask = 1;
6509 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6510 if (dut->testbed_flag_rxsp == 1) {
6511 vht_mcsmap = 0xfff0;
6512 dut->testbed_flag_rxsp = 0;
6513 } else {
6514 vht_mcsmap = 0xfffa;
6515 }
6516 rxchainmask = 3;
6517 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6518 if (dut->testbed_flag_rxsp == 1) {
6519 vht_mcsmap = 0xffc0;
6520 dut->testbed_flag_rxsp = 0;
6521 } else {
6522 vht_mcsmap = 0xffea;
6523 }
6524 rxchainmask = 7;
6525 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6526 if (dut->testbed_flag_rxsp == 1) {
6527 vht_mcsmap = 0xff00;
6528 dut->testbed_flag_rxsp = 0;
6529 } else {
6530 vht_mcsmap = 0xffaa;
6531 }
6532 rxchainmask = 15;
6533 } else {
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 }
6541
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006542 if (rxchainmask)
6543 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006544
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006545 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006546}
6547
6548
6549void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
6550{
6551 if (strcasecmp(val, "enable") == 0) {
6552 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
6553 != 0) {
6554 sigma_dut_print(dut, DUT_MSG_ERROR,
6555 "Disable BB_VHTSIGB_CRC_CALC failed");
6556 }
6557
6558 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
6559 != 0) {
6560 sigma_dut_print(dut, DUT_MSG_ERROR,
6561 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6562 }
6563 } else {
6564 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
6565 != 0) {
6566 sigma_dut_print(dut, DUT_MSG_ERROR,
6567 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6568 }
6569
6570 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
6571 != 0) {
6572 sigma_dut_print(dut, DUT_MSG_ERROR,
6573 "Enable BB_VHTSIGB_CRC_CALC failed");
6574 }
6575 }
6576}
6577
6578
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006579static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
6580 const char *val)
6581{
6582 char buf[60];
6583
Shivani Baranwal2a572842021-09-16 12:27:15 +05306584#ifdef NL80211_SUPPORT
6585 enum nl80211_chan_width qca_channel_width;
6586
6587 if (strcmp(val, "20") == 0) {
6588 qca_channel_width = NL80211_CHAN_WIDTH_20;
6589 dut->chwidth = 0;
6590 } else if (strcmp(val, "40") == 0) {
6591 qca_channel_width = NL80211_CHAN_WIDTH_40;
6592 dut->chwidth = 1;
6593 } else if (strcmp(val, "80") == 0) {
6594 qca_channel_width = NL80211_CHAN_WIDTH_80;
6595 dut->chwidth = 2;
6596 } else if (strcmp(val, "160") == 0) {
6597 qca_channel_width = NL80211_CHAN_WIDTH_160;
6598 dut->chwidth = 3;
6599 } else if (strcasecmp(val, "Auto") == 0) {
6600 return 0;
6601 } else {
6602 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6603 val);
6604 return -1;
6605 }
6606 if (sta_config_params(dut, intf, STA_SET_CHAN_WIDTH,
6607 qca_channel_width) == 0)
6608 return 0;
6609#endif /* NL80211_SUPPORT */
6610
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006611 if (strcmp(val, "20") == 0) {
6612 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
6613 dut->chwidth = 0;
6614 } else if (strcmp(val, "40") == 0) {
6615 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
6616 dut->chwidth = 1;
6617 } else if (strcmp(val, "80") == 0) {
6618 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
6619 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05306620 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006621 buf[0] = '\0';
6622 } else {
6623 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6624 val);
6625 return -1;
6626 }
6627
6628 if (buf[0] != '\0' && system(buf) != 0) {
6629 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
6630 return -1;
6631 }
6632
6633 return 0;
6634}
6635
6636
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006637static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
6638 const char *intf, int addbareject)
6639{
6640#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306641 return wcn_wifi_test_config_set_u8(
6642 dut, intf,
6643 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
6644 !addbareject);
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006645#else /* NL80211_SUPPORT */
6646 sigma_dut_print(dut, DUT_MSG_ERROR,
6647 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
6648 return -1;
6649#endif /* NL80211_SUPPORT */
6650}
6651
6652
6653static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
6654 int addbareject)
6655{
6656 int ret;
6657
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006658 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006659 case DRIVER_WCN:
6660 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
6661 if (ret) {
6662 sigma_dut_print(dut, DUT_MSG_ERROR,
6663 "nlvendor_sta_set_addba_reject failed, ret:%d",
6664 ret);
6665 return ret;
6666 }
6667 break;
6668 default:
6669 sigma_dut_print(dut, DUT_MSG_ERROR,
6670 "errorCode,Unsupported ADDBA_REJECT with the current driver");
6671 ret = -1;
6672 break;
6673 }
6674
6675 return ret;
6676}
6677
6678
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006679static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
6680 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006681{
6682#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306683 return wcn_wifi_test_config_set_u8(
6684 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
6685 enable);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006686#else /* NL80211_SUPPORT */
6687 sigma_dut_print(dut, DUT_MSG_ERROR,
6688 "Disable addba not possible without NL80211_SUPPORT defined");
6689 return -1;
6690#endif /* NL80211_SUPPORT */
6691}
6692
6693
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306694#ifdef NL80211_SUPPORT
6695static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6696{
6697 struct nl_msg *msg;
6698 int ret = 0;
6699 int ifindex;
6700
6701 ifindex = if_nametoindex(intf);
6702 if (ifindex == 0) {
6703 sigma_dut_print(dut, DUT_MSG_ERROR,
6704 "%s: Index for interface %s failed",
6705 __func__, intf);
6706 return -1;
6707 }
6708
6709 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6710 NL80211_CMD_SET_WIPHY)) ||
6711 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
6712 sigma_dut_print(dut, DUT_MSG_ERROR,
6713 "%s: err in adding RTS threshold",
6714 __func__);
6715 nlmsg_free(msg);
6716 return -1;
6717 }
6718
6719 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6720 if (ret) {
6721 sigma_dut_print(dut, DUT_MSG_ERROR,
6722 "%s: err in send_and_recv_msgs, ret=%d",
6723 __func__, ret);
6724 }
6725 return ret;
6726}
6727#endif /* NL80211_SUPPORT */
6728
6729
6730static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6731{
6732 char buf[100];
6733
6734#ifdef NL80211_SUPPORT
6735 if (nl80211_sta_set_rts(dut, intf, val) == 0)
6736 return 0;
6737 sigma_dut_print(dut, DUT_MSG_DEBUG,
6738 "Fall back to using iwconfig for setting RTS threshold");
6739#endif /* NL80211_SUPPORT */
6740
6741 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
6742 if (system(buf) != 0) {
6743 sigma_dut_print(dut, DUT_MSG_ERROR,
6744 "Failed to set RTS threshold %d", val);
6745 return -1;
6746 }
6747 return 0;
6748}
6749
6750
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006751static enum sigma_cmd_result
6752cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
6753 struct sigma_conn *conn, struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006754{
6755 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006756 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006757 char buf[128];
6758 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006759
6760 val = get_param(cmd, "40_INTOLERANT");
6761 if (val) {
6762 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6763 /* TODO: iwpriv ht40intol through wpa_supplicant */
6764 send_resp(dut, conn, SIGMA_ERROR,
6765 "ErrorCode,40_INTOLERANT not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006766 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006767 }
6768 }
6769
6770 val = get_param(cmd, "ADDBA_REJECT");
6771 if (val) {
6772 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6773 /* reject any ADDBA with status "decline" */
6774 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006775 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006776 } else {
6777 /* accept ADDBA */
6778 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006779 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006780 }
6781 }
6782
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006783 if (addbareject >= 0 &&
6784 sta_set_addba_reject(dut, intf, addbareject) < 0) {
6785 send_resp(dut, conn, SIGMA_ERROR,
6786 "ErrorCode,set addba_reject failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006787 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006788 }
6789
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006790 val = get_param(cmd, "AMPDU");
6791 if (val) {
6792 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6793 /* enable AMPDU Aggregation */
6794 if (ampdu == 0) {
6795 send_resp(dut, conn, SIGMA_ERROR,
6796 "ErrorCode,Mismatch in "
6797 "addba_reject/ampdu - "
6798 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006799 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006800 }
6801 ampdu = 1;
6802 } else {
6803 /* disable AMPDU Aggregation */
6804 if (ampdu == 1) {
6805 send_resp(dut, conn, SIGMA_ERROR,
6806 "ErrorCode,Mismatch in "
6807 "addba_reject/ampdu - "
6808 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006809 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006810 }
6811 ampdu = 0;
6812 }
6813 }
6814
6815 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006816 int ret;
6817
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006818 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
6819 ampdu ? "Enabling" : "Disabling");
6820 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07006821 if (wpa_command(intf, buf) < 0 &&
6822 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006823 send_resp(dut, conn, SIGMA_ERROR,
6824 "ErrorCode,set aggr failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006825 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006826 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006827
6828 if (ampdu == 0) {
6829 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006830 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006831 if (ret) {
6832 sigma_dut_print(dut, DUT_MSG_ERROR,
6833 "Failed to disable addba, ret:%d",
6834 ret);
6835 }
6836 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006837 }
6838
6839 val = get_param(cmd, "AMSDU");
6840 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006841 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006842 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006843 case DRIVER_WCN:
6844 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006845 break;
6846 default:
6847 if (strcmp(val, "1") == 0 ||
6848 strcasecmp(val, "Enable") == 0) {
6849 /* Enable AMSDU Aggregation */
6850 send_resp(dut, conn, SIGMA_ERROR,
6851 "ErrorCode,AMSDU aggregation not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006852 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006853 }
6854 break;
6855 }
6856 }
6857
6858 val = get_param(cmd, "STBC_RX");
6859 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006860 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006861 case DRIVER_ATHEROS:
6862 ath_sta_set_stbc(dut, intf, val);
6863 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05306864 case DRIVER_WCN:
6865 wcn_sta_set_stbc(dut, intf, val);
6866 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006867 default:
6868 send_resp(dut, conn, SIGMA_ERROR,
6869 "ErrorCode,STBC_RX not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006870 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006871 }
6872 }
6873
6874 val = get_param(cmd, "WIDTH");
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_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006878 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006879 send_resp(dut, conn, SIGMA_ERROR,
6880 "ErrorCode,Failed to set WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006881 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006882 }
6883 break;
6884 case DRIVER_ATHEROS:
6885 if (ath_set_width(dut, conn, intf, val) < 0)
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006886 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006887 break;
6888 default:
6889 sigma_dut_print(dut, DUT_MSG_ERROR,
6890 "Setting WIDTH not supported");
6891 break;
6892 }
6893 }
6894
6895 val = get_param(cmd, "SMPS");
6896 if (val) {
6897 /* TODO: Dynamic/0, Static/1, No Limit/2 */
6898 send_resp(dut, conn, SIGMA_ERROR,
6899 "ErrorCode,SMPS not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006900 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006901 }
6902
6903 val = get_param(cmd, "TXSP_STREAM");
6904 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006905 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006906 case DRIVER_WCN:
6907 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6908 send_resp(dut, conn, SIGMA_ERROR,
6909 "ErrorCode,Failed to set TXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006910 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006911 }
6912 break;
6913 case DRIVER_ATHEROS:
6914 ath_sta_set_txsp_stream(dut, intf, val);
6915 break;
6916 default:
6917 sigma_dut_print(dut, DUT_MSG_ERROR,
6918 "Setting TXSP_STREAM not supported");
6919 break;
6920 }
6921 }
6922
6923 val = get_param(cmd, "RXSP_STREAM");
6924 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006925 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006926 case DRIVER_WCN:
6927 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6928 send_resp(dut, conn, SIGMA_ERROR,
6929 "ErrorCode,Failed to set RXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006930 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006931 }
6932 break;
6933 case DRIVER_ATHEROS:
6934 ath_sta_set_rxsp_stream(dut, intf, val);
6935 break;
6936 default:
6937 sigma_dut_print(dut, DUT_MSG_ERROR,
6938 "Setting RXSP_STREAM not supported");
6939 break;
6940 }
6941 }
6942
6943 val = get_param(cmd, "DYN_BW_SGNL");
6944 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006945 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006946 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08006947 if (strcasecmp(val, "enable") == 0) {
6948 snprintf(buf, sizeof(buf),
6949 "iwpriv %s cwmenable 1", intf);
6950 if (system(buf) != 0) {
6951 sigma_dut_print(dut, DUT_MSG_ERROR,
6952 "iwpriv cwmenable 1 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006953 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006954 }
6955 } else if (strcasecmp(val, "disable") == 0) {
6956 snprintf(buf, sizeof(buf),
6957 "iwpriv %s cwmenable 0", intf);
6958 if (system(buf) != 0) {
6959 sigma_dut_print(dut, DUT_MSG_ERROR,
6960 "iwpriv cwmenable 0 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006961 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006962 }
6963 } else {
6964 sigma_dut_print(dut, DUT_MSG_ERROR,
6965 "Unsupported DYN_BW_SGL");
6966 }
6967
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006968 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
6969 if (system(buf) != 0) {
6970 sigma_dut_print(dut, DUT_MSG_ERROR,
6971 "Failed to set cts_cbw in DYN_BW_SGNL");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006972 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006973 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006974 break;
6975 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07006976 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006977 ath_config_dyn_bw_sig(dut, intf, val);
6978 break;
6979 default:
6980 sigma_dut_print(dut, DUT_MSG_ERROR,
6981 "Failed to set DYN_BW_SGNL");
6982 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006983 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006984 }
6985
6986 val = get_param(cmd, "RTS_FORCE");
6987 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07006988 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006989 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306990 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02006991 sigma_dut_print(dut, DUT_MSG_ERROR,
6992 "Failed to set RTS_FORCE 64");
6993 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03006994 res = snprintf(buf, sizeof(buf),
6995 "wifitool %s beeliner_fw_test 100 1",
6996 intf);
6997 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08006998 sigma_dut_print(dut, DUT_MSG_ERROR,
6999 "wifitool beeliner_fw_test 100 1 failed");
7000 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007001 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307002 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007003 sigma_dut_print(dut, DUT_MSG_ERROR,
7004 "Failed to set RTS_FORCE 2347");
7005 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007006 } else {
7007 send_resp(dut, conn, SIGMA_ERROR,
7008 "ErrorCode,RTS_FORCE value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007009 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007010 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007011 }
7012
7013 val = get_param(cmd, "CTS_WIDTH");
7014 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007015 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007016 case DRIVER_WCN:
7017 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
7018 send_resp(dut, conn, SIGMA_ERROR,
7019 "ErrorCode,Failed to set CTS_WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007020 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007021 }
7022 break;
7023 case DRIVER_ATHEROS:
7024 ath_set_cts_width(dut, intf, val);
7025 break;
7026 default:
7027 sigma_dut_print(dut, DUT_MSG_ERROR,
7028 "Setting CTS_WIDTH not supported");
7029 break;
7030 }
7031 }
7032
7033 val = get_param(cmd, "BW_SGNL");
7034 if (val) {
7035 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007036 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007037 } else if (strcasecmp(val, "Disable") == 0) {
7038 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007039 } else {
7040 send_resp(dut, conn, SIGMA_ERROR,
7041 "ErrorCode,BW_SGNL value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007042 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007043 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007044 }
7045
7046 val = get_param(cmd, "Band");
7047 if (val) {
7048 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
7049 /* STA supports all bands by default */
7050 } else {
7051 send_resp(dut, conn, SIGMA_ERROR,
7052 "ErrorCode,Unsupported Band");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007053 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007054 }
7055 }
7056
7057 val = get_param(cmd, "zero_crc");
7058 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007059 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007060 case DRIVER_ATHEROS:
7061 ath_set_zero_crc(dut, val);
7062 break;
7063 default:
7064 break;
7065 }
7066 }
7067
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007068 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007069}
7070
7071
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007072static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7073{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007074 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007075#ifdef __linux__
7076 case DRIVER_WIL6210:
7077 return wil6210_set_force_mcs(dut, force, mcs);
7078#endif /* __linux__ */
7079 default:
7080 sigma_dut_print(dut, DUT_MSG_ERROR,
7081 "Unsupported sta_set_force_mcs with the current driver");
7082 return -1;
7083 }
7084}
7085
7086
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007087static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
7088{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007089 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007090#ifdef __linux__
7091 case DRIVER_WIL6210:
7092 return wil6210_force_rsn_ie(dut, state);
7093#endif /* __linux__ */
7094 default:
7095 sigma_dut_print(dut, DUT_MSG_ERROR,
7096 "Unsupported sta_60g_force_rsn_ie with the current driver");
7097 return -1;
7098 }
7099}
7100
7101
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007102static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
7103 struct sigma_cmd *cmd)
7104{
7105 const char *val;
7106 char buf[100];
7107
7108 val = get_param(cmd, "MSDUSize");
7109 if (val) {
7110 int mtu;
7111
7112 dut->amsdu_size = atoi(val);
7113 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
7114 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
7115 sigma_dut_print(dut, DUT_MSG_ERROR,
7116 "MSDUSize %d is above max %d or below min %d",
7117 dut->amsdu_size,
7118 IEEE80211_MAX_DATA_LEN_DMG,
7119 IEEE80211_SNAP_LEN_DMG);
7120 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007121 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007122 }
7123
7124 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
7125 sigma_dut_print(dut, DUT_MSG_DEBUG,
7126 "Setting amsdu_size to %d", mtu);
7127 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007128 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007129
7130 if (system(buf) != 0) {
7131 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7132 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007133 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007134 }
7135 }
7136
7137 val = get_param(cmd, "BAckRcvBuf");
7138 if (val) {
7139 dut->back_rcv_buf = atoi(val);
7140 if (dut->back_rcv_buf == 0) {
7141 sigma_dut_print(dut, DUT_MSG_ERROR,
7142 "Failed to convert %s or value is 0",
7143 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007144 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007145 }
7146
7147 sigma_dut_print(dut, DUT_MSG_DEBUG,
7148 "Setting BAckRcvBuf to %s", val);
7149 }
7150
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007151 val = get_param(cmd, "MCS_FixedRate");
7152 if (val) {
7153 if (sta_set_force_mcs(dut, 1, atoi(val))) {
7154 sigma_dut_print(dut, DUT_MSG_ERROR,
7155 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007156 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007157 }
7158 }
7159
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007160 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007161}
7162
7163
7164static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
7165 struct sigma_cmd *cmd)
7166{
7167 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007168 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007169 const char *val;
7170 char buf[100];
7171
7172 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007173 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007174 if (wpa_command(ifname, "PING") != 0) {
7175 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007176 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007177 }
7178
7179 wpa_command(ifname, "FLUSH");
7180 net_id = add_network_common(dut, conn, ifname, cmd);
7181 if (net_id < 0) {
7182 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
7183 return net_id;
7184 }
7185
7186 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
7187 if (set_network(ifname, net_id, "mode", "2") < 0) {
7188 sigma_dut_print(dut, DUT_MSG_ERROR,
7189 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007190 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007191 }
7192
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02007193 if (set_network(ifname, net_id, "pbss", "1") < 0)
7194 return -2;
7195
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007196 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007197 "Supplicant set network with mode 2. network_id %d",
7198 net_id);
7199
7200 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
7201 sigma_dut_print(dut, DUT_MSG_INFO,
7202 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007203 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007204 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007205
7206 val = get_param(cmd, "Security");
7207 if (val && strcasecmp(val, "OPEN") == 0) {
7208 dut->ap_key_mgmt = AP_OPEN;
7209 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
7210 sigma_dut_print(dut, DUT_MSG_ERROR,
7211 "Failed to set supplicant to %s security",
7212 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007213 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007214 }
7215 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
7216 dut->ap_key_mgmt = AP_WPA2_PSK;
7217 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
7218 sigma_dut_print(dut, DUT_MSG_ERROR,
7219 "Failed to set supplicant to %s security",
7220 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007221 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007222 }
7223
7224 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
7225 sigma_dut_print(dut, DUT_MSG_ERROR,
7226 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007227 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007228 }
7229 } else if (val) {
7230 sigma_dut_print(dut, DUT_MSG_ERROR,
7231 "Requested Security %s is not supported on 60GHz",
7232 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007233 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007234 }
7235
7236 val = get_param(cmd, "Encrypt");
7237 if (val && strcasecmp(val, "AES-GCMP") == 0) {
7238 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
7239 sigma_dut_print(dut, DUT_MSG_ERROR,
7240 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007241 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007242 }
7243 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
7244 sigma_dut_print(dut, DUT_MSG_ERROR,
7245 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007246 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007247 }
7248 } else if (val) {
7249 sigma_dut_print(dut, DUT_MSG_ERROR,
7250 "Requested Encrypt %s is not supported on 60 GHz",
7251 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007252 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007253 }
7254
7255 val = get_param(cmd, "PSK");
7256 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
7257 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
7258 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007259 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007260 }
7261
7262 /* Convert 60G channel to freq */
7263 switch (dut->ap_channel) {
7264 case 1:
7265 val = "58320";
7266 break;
7267 case 2:
7268 val = "60480";
7269 break;
7270 case 3:
7271 val = "62640";
7272 break;
7273 default:
7274 sigma_dut_print(dut, DUT_MSG_ERROR,
7275 "Failed to configure channel %d. Not supported",
7276 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007277 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007278 }
7279
7280 if (set_network(ifname, net_id, "frequency", val) < 0) {
7281 sigma_dut_print(dut, DUT_MSG_ERROR,
7282 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007283 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007284 }
7285
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02007286 if (dut->eap_fragment) {
7287 sigma_dut_print(dut, DUT_MSG_DEBUG,
7288 "Set EAP fragment size to 128 bytes.");
7289 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
7290 return ERROR_SEND_STATUS;
7291 }
7292
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007293 sigma_dut_print(dut, DUT_MSG_DEBUG,
7294 "Supplicant set network with frequency");
7295
7296 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
7297 if (wpa_command(ifname, buf) < 0) {
7298 sigma_dut_print(dut, DUT_MSG_INFO,
7299 "Failed to select network id %d on %s",
7300 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007301 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007302 }
7303
7304 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
7305
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007306 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007307}
7308
7309
Lior David67543f52017-01-03 19:04:22 +02007310static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
7311{
7312 char buf[128], fname[128];
7313 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03007314 int res;
Lior David67543f52017-01-03 19:04:22 +02007315
7316 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
7317 sigma_dut_print(dut, DUT_MSG_ERROR,
7318 "failed to get wil6210 debugfs dir");
7319 return -1;
7320 }
7321
Jouni Malinen3aa72862019-05-29 23:14:51 +03007322 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
7323 if (res < 0 || res >= sizeof(fname))
7324 return -1;
Lior David67543f52017-01-03 19:04:22 +02007325 f = fopen(fname, "w");
7326 if (!f) {
7327 sigma_dut_print(dut, DUT_MSG_ERROR,
7328 "failed to open: %s", fname);
7329 return -1;
7330 }
7331
7332 fprintf(f, "%d\n", abft_len);
7333 fclose(f);
7334
7335 return 0;
7336}
7337
7338
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02007339int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
7340 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02007341{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007342 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02007343 case DRIVER_WIL6210:
7344 return wil6210_set_abft_len(dut, abft_len);
7345 default:
7346 sigma_dut_print(dut, DUT_MSG_ERROR,
7347 "set abft_len not supported");
7348 return -1;
7349 }
7350}
7351
7352
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007353static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
7354 struct sigma_cmd *cmd)
7355{
7356 const char *val;
Lior David67543f52017-01-03 19:04:22 +02007357 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007358
7359 if (dut->dev_role != DEVROLE_PCP) {
7360 send_resp(dut, conn, SIGMA_INVALID,
7361 "ErrorCode,Invalid DevRole");
7362 return 0;
7363 }
7364
7365 val = get_param(cmd, "SSID");
7366 if (val) {
7367 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
7368 send_resp(dut, conn, SIGMA_INVALID,
7369 "ErrorCode,Invalid SSID");
7370 return -1;
7371 }
7372
Peng Xub8fc5cc2017-05-10 17:27:28 -07007373 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007374 }
7375
7376 val = get_param(cmd, "CHANNEL");
7377 if (val) {
7378 const char *pos;
7379
7380 dut->ap_channel = atoi(val);
7381 pos = strchr(val, ';');
7382 if (pos) {
7383 pos++;
7384 dut->ap_channel_1 = atoi(pos);
7385 }
7386 }
7387
7388 switch (dut->ap_channel) {
7389 case 1:
7390 case 2:
7391 case 3:
7392 break;
7393 default:
7394 sigma_dut_print(dut, DUT_MSG_ERROR,
7395 "Channel %d is not supported", dut->ap_channel);
7396 send_resp(dut, conn, SIGMA_ERROR,
7397 "Requested channel is not supported");
7398 return -1;
7399 }
7400
7401 val = get_param(cmd, "BCNINT");
7402 if (val)
7403 dut->ap_bcnint = atoi(val);
7404
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007405 val = get_param(cmd, "AllocType");
7406 if (val) {
7407 send_resp(dut, conn, SIGMA_ERROR,
7408 "ErrorCode,AllocType is not supported yet");
7409 return -1;
7410 }
7411
7412 val = get_param(cmd, "PercentBI");
7413 if (val) {
7414 send_resp(dut, conn, SIGMA_ERROR,
7415 "ErrorCode,PercentBI is not supported yet");
7416 return -1;
7417 }
7418
7419 val = get_param(cmd, "CBAPOnly");
7420 if (val) {
7421 send_resp(dut, conn, SIGMA_ERROR,
7422 "ErrorCode,CBAPOnly is not supported yet");
7423 return -1;
7424 }
7425
7426 val = get_param(cmd, "AMPDU");
7427 if (val) {
7428 if (strcasecmp(val, "Enable") == 0)
7429 dut->ap_ampdu = 1;
7430 else if (strcasecmp(val, "Disable") == 0)
7431 dut->ap_ampdu = 2;
7432 else {
7433 send_resp(dut, conn, SIGMA_ERROR,
7434 "ErrorCode,AMPDU value is not Enable nor Disabled");
7435 return -1;
7436 }
7437 }
7438
7439 val = get_param(cmd, "AMSDU");
7440 if (val) {
7441 if (strcasecmp(val, "Enable") == 0)
7442 dut->ap_amsdu = 1;
7443 else if (strcasecmp(val, "Disable") == 0)
7444 dut->ap_amsdu = 2;
7445 }
7446
7447 val = get_param(cmd, "NumMSDU");
7448 if (val) {
7449 send_resp(dut, conn, SIGMA_ERROR,
7450 "ErrorCode, NumMSDU is not supported yet");
7451 return -1;
7452 }
7453
7454 val = get_param(cmd, "ABFTLRang");
7455 if (val) {
7456 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02007457 "ABFTLRang parameter %s", val);
7458 if (strcmp(val, "Gt1") == 0)
7459 abft_len = 2; /* 2 slots in this case */
7460 }
7461
7462 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
7463 send_resp(dut, conn, SIGMA_ERROR,
7464 "ErrorCode, Can't set ABFT length");
7465 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007466 }
7467
7468 if (sta_pcp_start(dut, conn, cmd) < 0) {
7469 send_resp(dut, conn, SIGMA_ERROR,
7470 "ErrorCode, Can't start PCP role");
7471 return -1;
7472 }
7473
7474 return sta_set_60g_common(dut, conn, cmd);
7475}
7476
7477
7478static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
7479 struct sigma_cmd *cmd)
7480{
7481 const char *val = get_param(cmd, "DiscoveryMode");
7482
7483 if (dut->dev_role != DEVROLE_STA) {
7484 send_resp(dut, conn, SIGMA_INVALID,
7485 "ErrorCode,Invalid DevRole");
7486 return 0;
7487 }
7488
7489 if (val) {
7490 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
7491 /* Ignore Discovery mode till Driver expose API. */
7492#if 0
7493 if (strcasecmp(val, "1") == 0) {
7494 send_resp(dut, conn, SIGMA_INVALID,
7495 "ErrorCode,DiscoveryMode 1 not supported");
7496 return 0;
7497 }
7498
7499 if (strcasecmp(val, "0") == 0) {
7500 /* OK */
7501 } else {
7502 send_resp(dut, conn, SIGMA_INVALID,
7503 "ErrorCode,DiscoveryMode not supported");
7504 return 0;
7505 }
7506#endif
7507 }
7508
7509 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007510 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007511 return sta_set_60g_common(dut, conn, cmd);
7512}
7513
7514
Jouni Malinenf7222712019-06-13 01:50:21 +03007515static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
7516 struct sigma_conn *conn,
7517 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007518{
7519 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02007520 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05307521
Jouni Malinened77e672018-01-10 16:45:13 +02007522 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08007523 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02007524 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05307525 wpa_command(intf, "DISCONNECT");
7526 return 1;
7527 }
7528
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007529 disconnect_station(dut);
7530 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
7531 * due to cached results. */
7532 wpa_command(intf, "SET ignore_old_scan_res 1");
7533 wpa_command(intf, "BSS_FLUSH");
7534 return 1;
7535}
7536
7537
Jouni Malinenf7222712019-06-13 01:50:21 +03007538static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
7539 struct sigma_conn *conn,
7540 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007541{
7542 const char *intf = get_param(cmd, "Interface");
7543 const char *bssid = get_param(cmd, "bssid");
7544 const char *val = get_param(cmd, "CHANNEL");
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007545 const char *freq_val = get_param(cmd, "ChnlFreq");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007546 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307547 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05307548 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007549 int res;
7550 int chan = 0;
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007551 int freq = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007552 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05307553 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007554 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007555
7556 if (bssid == NULL) {
7557 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
7558 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007559 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007560 }
7561
7562 if (val)
7563 chan = atoi(val);
7564
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007565 if (freq_val)
7566 freq = atoi(freq_val);
7567
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007568 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
7569 /* The current network may be from sta_associate or
7570 * sta_hs2_associate
7571 */
7572 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
7573 0 ||
7574 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007575 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007576 }
7577
7578 ctrl = open_wpa_mon(intf);
7579 if (ctrl == NULL) {
7580 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7581 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007582 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007583 }
7584
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007585 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05307586 sizeof(result)) < 0 ||
7587 strncmp(result, "COMPLETED", 9) != 0) {
7588 sigma_dut_print(dut, DUT_MSG_DEBUG,
7589 "sta_reassoc: Not connected");
7590 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007591 } else if (dut->sta_ft_ds) {
7592 sigma_dut_print(dut, DUT_MSG_DEBUG,
7593 "sta_reassoc: Use FT-over-DS");
7594 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05307595 }
7596
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307597 if (dut->rsne_override) {
7598#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007599 if (get_driver_type(dut) == DRIVER_WCN &&
7600 dut->config_rsnie == 0) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05307601 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307602 dut->config_rsnie = 1;
7603 }
7604#endif /* NL80211_SUPPORT */
7605 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
7606 dut->rsne_override);
7607 if (wpa_command(intf, buf) < 0) {
7608 send_resp(dut, conn, SIGMA_ERROR,
7609 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
7610 return 0;
7611 }
7612 }
7613
Shivani Baranwal7aa48602021-09-29 10:53:38 +05307614 if (ft_ds && get_driver_type(dut) != DRIVER_WCN) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007615 if (chan || freq) {
7616 if (!freq)
7617 freq = channel_to_freq(dut, chan);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007618 if (!freq) {
7619 sigma_dut_print(dut, DUT_MSG_ERROR,
7620 "Invalid channel number provided: %d",
7621 chan);
7622 send_resp(dut, conn, SIGMA_INVALID,
7623 "ErrorCode,Invalid channel number");
7624 goto close_mon_conn;
7625 }
7626 res = snprintf(buf, sizeof(buf),
7627 "SCAN TYPE=ONLY freq=%d", freq);
7628 } else {
7629 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7630 }
7631 if (res < 0 || res >= (int) sizeof(buf)) {
7632 send_resp(dut, conn, SIGMA_ERROR,
7633 "ErrorCode,snprintf failed");
7634 goto close_mon_conn;
7635 }
7636 if (wpa_command(intf, buf) < 0) {
7637 sigma_dut_print(dut, DUT_MSG_INFO,
7638 "Failed to start scan");
7639 send_resp(dut, conn, SIGMA_ERROR,
7640 "ErrorCode,scan failed");
7641 goto close_mon_conn;
7642 }
7643
7644 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7645 buf, sizeof(buf));
7646 if (res < 0) {
7647 sigma_dut_print(dut, DUT_MSG_INFO,
7648 "Scan did not complete");
7649 send_resp(dut, conn, SIGMA_ERROR,
7650 "ErrorCode,scan did not complete");
7651 goto close_mon_conn;
7652 }
7653
7654 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
7655 if (res > 0 && res < (int) sizeof(buf))
7656 res = wpa_command(intf, buf);
7657
7658 if (res < 0 || res >= (int) sizeof(buf)) {
7659 send_resp(dut, conn, SIGMA_ERROR,
7660 "errorCode,FT_DS command failed");
7661 status = STATUS_SENT_ERROR;
7662 goto close_mon_conn;
7663 }
7664 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007665 if (chan || freq) {
7666 if (!freq)
7667 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05307668 if (!freq) {
7669 sigma_dut_print(dut, DUT_MSG_ERROR,
7670 "Invalid channel number provided: %d",
7671 chan);
7672 send_resp(dut, conn, SIGMA_INVALID,
7673 "ErrorCode,Invalid channel number");
7674 goto close_mon_conn;
7675 }
7676 res = snprintf(buf, sizeof(buf),
7677 "SCAN TYPE=ONLY freq=%d", freq);
7678 } else {
7679 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7680 }
7681 if (res < 0 || res >= (int) sizeof(buf)) {
7682 send_resp(dut, conn, SIGMA_ERROR,
7683 "ErrorCode,snprintf failed");
7684 goto close_mon_conn;
7685 }
7686 if (wpa_command(intf, buf) < 0) {
7687 sigma_dut_print(dut, DUT_MSG_INFO,
7688 "Failed to start scan");
7689 send_resp(dut, conn, SIGMA_ERROR,
7690 "ErrorCode,scan failed");
7691 goto close_mon_conn;
7692 }
7693
7694 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7695 buf, sizeof(buf));
7696 if (res < 0) {
7697 sigma_dut_print(dut, DUT_MSG_INFO,
7698 "Scan did not complete");
7699 send_resp(dut, conn, SIGMA_ERROR,
7700 "ErrorCode,scan did not complete");
7701 goto close_mon_conn;
7702 }
7703
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007704 if (set_network(intf, dut->infra_network_id, "bssid", "any")
7705 < 0) {
7706 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7707 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007708 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05307709 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007710 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307711 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007712 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307713 if (res < 0 || res >= (int) sizeof(buf) ||
7714 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007715 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307716 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05307717 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007718 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007719 sigma_dut_print(dut, DUT_MSG_INFO,
7720 "sta_reassoc: Run %s successful", buf);
7721 } else if (wpa_command(intf, "REASSOCIATE")) {
7722 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
7723 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05307724 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007725 }
7726
7727 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
7728 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05307729 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007730 send_resp(dut, conn, SIGMA_ERROR,
7731 "errorCode,Connection did not complete");
7732 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05307733 goto close_mon_conn;
7734 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007735 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007736
Ashwini Patil467efef2017-05-25 12:18:27 +05307737close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007738 wpa_ctrl_detach(ctrl);
7739 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05307740 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007741}
7742
7743
7744static void hs2_clear_credentials(const char *intf)
7745{
7746 wpa_command(intf, "REMOVE_CRED all");
7747}
7748
7749
Lior Davidcc88b562017-01-03 18:52:09 +02007750#ifdef __linux__
7751static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
7752 unsigned int *aid)
7753{
Lior David0fe101e2017-03-09 16:09:50 +02007754 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02007755
Lior David0fe101e2017-03-09 16:09:50 +02007756 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02007757}
7758#endif /* __linux__ */
7759
7760
7761static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
7762 unsigned int *aid)
7763{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007764 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02007765#ifdef __linux__
7766 case DRIVER_WIL6210:
7767 return wil6210_get_aid(dut, bssid, aid);
7768#endif /* __linux__ */
7769 default:
7770 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
7771 return -1;
7772 }
7773}
7774
7775
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007776static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7777 struct sigma_cmd *cmd)
7778{
7779 char buf[MAX_CMD_LEN];
7780 char bss_list[MAX_CMD_LEN];
7781 const char *parameter = get_param(cmd, "Parameter");
7782
7783 if (parameter == NULL)
7784 return -1;
7785
Lior Davidcc88b562017-01-03 18:52:09 +02007786 if (strcasecmp(parameter, "AID") == 0) {
7787 unsigned int aid = 0;
7788 char bssid[20];
7789
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007790 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02007791 bssid, sizeof(bssid)) < 0) {
7792 sigma_dut_print(dut, DUT_MSG_ERROR,
7793 "could not get bssid");
7794 return -2;
7795 }
7796
7797 if (sta_get_aid_60g(dut, bssid, &aid))
7798 return -2;
7799
7800 snprintf(buf, sizeof(buf), "aid,%d", aid);
7801 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
7802 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7803 return 0;
7804 }
7805
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007806 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
7807 char *bss_line;
7808 char *bss_id = NULL;
7809 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307810 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007811
7812 if (ifname == NULL) {
7813 sigma_dut_print(dut, DUT_MSG_INFO,
7814 "For get DiscoveredDevList need Interface name.");
7815 return -1;
7816 }
7817
7818 /*
7819 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
7820 * of BSSIDs in "bssid=<BSSID>\n"
7821 */
7822 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
7823 bss_list,
7824 sizeof(bss_list)) < 0) {
7825 sigma_dut_print(dut, DUT_MSG_ERROR,
7826 "Failed to get bss list");
7827 return -1;
7828 }
7829
7830 sigma_dut_print(dut, DUT_MSG_DEBUG,
7831 "bss list for ifname:%s is:%s",
7832 ifname, bss_list);
7833
7834 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307835 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007836 while (bss_line) {
7837 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
7838 bss_id) {
7839 int len;
7840
7841 len = snprintf(buf + strlen(buf),
7842 sizeof(buf) - strlen(buf),
7843 ",%s", bss_id);
7844 free(bss_id);
7845 bss_id = NULL;
7846 if (len < 0) {
7847 sigma_dut_print(dut,
7848 DUT_MSG_ERROR,
7849 "Failed to read BSSID");
7850 send_resp(dut, conn, SIGMA_ERROR,
7851 "ErrorCode,Failed to read BSS ID");
7852 return 0;
7853 }
7854
7855 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
7856 sigma_dut_print(dut,
7857 DUT_MSG_ERROR,
7858 "Response buf too small for list");
7859 send_resp(dut, conn,
7860 SIGMA_ERROR,
7861 "ErrorCode,Response buf too small for list");
7862 return 0;
7863 }
7864 }
7865
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307866 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007867 }
7868
7869 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
7870 buf);
7871 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7872 return 0;
7873 }
7874
7875 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7876 return 0;
7877}
7878
7879
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007880static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
7881 struct sigma_cmd *cmd)
7882{
7883 char buf[MAX_CMD_LEN];
7884 const char *parameter = get_param(cmd, "Parameter");
7885
7886 if (!parameter)
7887 return -1;
7888
7889 if (strcasecmp(parameter, "RSSI") == 0) {
7890 char rssi[10];
7891
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007892 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007893 rssi, sizeof(rssi)) < 0) {
7894 sigma_dut_print(dut, DUT_MSG_ERROR,
7895 "Could not get RSSI");
7896 return -2;
7897 }
7898
7899 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
7900 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
7901 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7902 return 0;
7903 }
7904
7905 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7906 return 0;
7907}
7908
7909
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05307910#ifdef NL80211_SUPPORT
7911
7912struct station_info {
7913 uint64_t filled;
7914 uint32_t beacon_mic_error_count;
7915 uint32_t beacon_replay_count;
7916};
7917
7918
7919static int qca_get_sta_info_handler(struct nl_msg *msg, void *arg)
7920{
7921 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7922 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7923 struct station_info *data = arg;
7924 struct nlattr *info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
7925 static struct nla_policy info_policy[
7926 QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = {
7927 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT] = {
7928 .type = NLA_U32
7929 },
7930 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT] = {
7931 .type = NLA_U32
7932 },
7933 };
7934
7935 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7936 genlmsg_attrlen(gnlh, 0), NULL);
7937
7938 if (!tb[NL80211_ATTR_VENDOR_DATA])
7939 return NL_SKIP;
7940
7941 if (nla_parse_nested(info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
7942 tb[NL80211_ATTR_VENDOR_DATA], info_policy)) {
7943 return NL_SKIP;
7944 }
7945
7946 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]) {
7947 data->filled |=
7948 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT);
7949 data->beacon_mic_error_count =
7950 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]);
7951 }
7952
7953 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]) {
7954 data->filled |=
7955 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT);
7956 data->beacon_replay_count =
7957 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]);
7958 }
7959
7960 return NL_SKIP;
7961}
7962
7963
7964static int qca_nl80211_get_sta_info(struct sigma_dut *dut, const char *intf,
7965 struct station_info *sta_data)
7966{
7967 struct nl_msg *msg;
7968 int ifindex, ret;
7969
7970 ifindex = if_nametoindex(intf);
7971 if (ifindex == 0) {
7972 sigma_dut_print(dut, DUT_MSG_ERROR,
7973 "%s: Index for interface %s not found",
7974 __func__, intf);
7975 return -1;
7976 }
7977
7978 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7979 NL80211_CMD_VENDOR)) ||
7980 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7981 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7982 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7983 QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
7984 sigma_dut_print(dut, DUT_MSG_ERROR,
7985 "%s: err in adding vendor_cmd", __func__);
7986 nlmsg_free(msg);
7987 return -1;
7988 }
7989
7990 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg,
7991 qca_get_sta_info_handler, sta_data);
7992 if (ret) {
7993 sigma_dut_print(dut, DUT_MSG_ERROR,
7994 "%s: err in send_and_recv_msgs, ret=%d",
7995 __func__, ret);
7996 }
7997 return ret;
7998}
7999#endif /* NL80211_SUPPORT */
8000
8001
8002static int get_bip_mic_error_count(struct sigma_dut *dut,
8003 const char *ifname,
8004 unsigned int *count)
8005{
8006#ifdef NL80211_SUPPORT
8007 struct station_info sta_data;
8008#endif /* NL80211_SUPPORT */
8009
8010 if (get_driver_type(dut) != DRIVER_WCN) {
8011 sigma_dut_print(dut, DUT_MSG_ERROR,
8012 "BIP MIC error count not supported");
8013 return -1;
8014 }
8015
8016#ifdef NL80211_SUPPORT
8017 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8018 !(sta_data.filled &
8019 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT))) {
8020 sigma_dut_print(dut, DUT_MSG_ERROR,
8021 "BIP MIC error count fetching failed");
8022 return -1;
8023 }
8024
8025 *count = sta_data.beacon_mic_error_count;
8026 return 0;
8027#else /* NL80211_SUPPORT */
8028 sigma_dut_print(dut, DUT_MSG_ERROR,
8029 "BIP MIC error count cannot be fetched without NL80211_SUPPORT defined");
8030 return -1;
8031#endif /* NL80211_SUPPORT */
8032}
8033
8034
8035static int get_cmac_replay_count(struct sigma_dut *dut, const char *ifname,
8036 unsigned int *count)
8037{
8038#ifdef NL80211_SUPPORT
8039 struct station_info sta_data;
8040#endif /* NL80211_SUPPORT */
8041
8042 if (get_driver_type(dut) != DRIVER_WCN) {
8043 sigma_dut_print(dut, DUT_MSG_ERROR,
8044 "CMAC reply count not supported");
8045 return -1;
8046 }
8047
8048#ifdef NL80211_SUPPORT
8049 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8050 !(sta_data.filled &
8051 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT))) {
8052 sigma_dut_print(dut, DUT_MSG_ERROR,
8053 "CMAC replay count fetching failed");
8054 return -1;
8055 }
8056
8057 *count = sta_data.beacon_replay_count;
8058 return 0;
8059#else /* NL80211_SUPPORT */
8060 sigma_dut_print(dut, DUT_MSG_ERROR,
8061 "CMAC replay count cannot be fetched without NL80211_SUPPORT defined");
8062 return -1;
8063#endif /* NL80211_SUPPORT */
8064}
8065
8066
8067static enum sigma_cmd_result sta_get_parameter_wpa3(struct sigma_dut *dut,
8068 struct sigma_conn *conn,
8069 struct sigma_cmd *cmd)
8070{
8071 char buf[MAX_CMD_LEN];
8072 const char *ifname = get_param(cmd, "interface");
8073 const char *parameter = get_param(cmd, "Parameter");
8074 unsigned int val;
8075
8076 if (!ifname || !parameter)
8077 return INVALID_SEND_STATUS;
8078
8079 if (strcasecmp(parameter, "BIPMICErrors") == 0) {
8080 if (get_bip_mic_error_count(dut, ifname, &val)) {
8081 send_resp(dut, conn, SIGMA_ERROR,
8082 "ErrorCode,Failed to get BIPMICErrors");
8083 return STATUS_SENT_ERROR;
8084 }
8085 snprintf(buf, sizeof(buf), "BIPMICErrors,%d", val);
8086 sigma_dut_print(dut, DUT_MSG_INFO, "BIPMICErrors %s", buf);
8087 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8088 return STATUS_SENT;
8089 }
8090
8091 if (strcasecmp(parameter, "CMACReplays") == 0) {
8092 if (get_cmac_replay_count(dut, ifname, &val)) {
8093 send_resp(dut, conn, SIGMA_ERROR,
8094 "ErrorCode,Failed to get CMACReplays");
8095 return STATUS_SENT_ERROR;
8096 }
8097 snprintf(buf, sizeof(buf), "CMACReplays,%d", val);
8098 sigma_dut_print(dut, DUT_MSG_INFO, "CMACReplays %s", buf);
8099 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8100 return STATUS_SENT;
8101 }
8102
8103 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8104 return STATUS_SENT_ERROR;
8105}
8106
8107
Jouni Malinenca0abd32020-02-09 20:18:10 +02008108static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
8109 struct sigma_conn *conn,
8110 struct sigma_cmd *cmd)
8111{
8112 const char *intf = get_param(cmd, "Interface");
8113 char buf[4096], bssid[20], resp[200], *pos, *tmp;
8114
8115 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
8116 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8117 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
8118 send_resp(dut, conn, SIGMA_ERROR,
8119 "ErrorCode,PMKSA_GET not supported");
8120 return STATUS_SENT_ERROR;
8121 }
8122
8123 if (strncmp(buf, "FAIL", 4) == 0 ||
8124 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
8125 send_resp(dut, conn, SIGMA_ERROR,
8126 "ErrorCode,Could not find current network");
8127 return STATUS_SENT_ERROR;
8128 }
8129
8130 pos = buf;
8131 while (pos) {
8132 if (strncmp(pos, bssid, 17) == 0) {
8133 pos = strchr(pos, ' ');
8134 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308135 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008136 pos++;
8137 pos = strchr(pos, ' ');
8138 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308139 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008140 pos++;
8141 tmp = strchr(pos, ' ');
8142 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308143 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008144 *tmp = '\0';
8145 break;
8146 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02008147 pos = strchr(pos, '\n');
8148 if (pos)
8149 pos++;
8150 }
8151
8152 if (!pos) {
8153 send_resp(dut, conn, SIGMA_ERROR,
8154 "ErrorCode,PMK not available");
8155 return STATUS_SENT_ERROR;
8156 }
8157
8158 snprintf(resp, sizeof(resp), "PMK,%s", pos);
8159 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8160 return STATUS_SENT;
8161}
8162
8163
Jouni Malinenf7222712019-06-13 01:50:21 +03008164static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
8165 struct sigma_conn *conn,
8166 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008167{
8168 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02008169 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008170
Jouni Malinenca0abd32020-02-09 20:18:10 +02008171 if (!parameter)
8172 return INVALID_SEND_STATUS;
8173
8174 if (strcasecmp(parameter, "PMK") == 0)
8175 return sta_get_pmk(dut, conn, cmd);
8176
8177 if (!program)
8178 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008179
8180 if (strcasecmp(program, "P2PNFC") == 0)
8181 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
8182
8183 if (strcasecmp(program, "60ghz") == 0)
8184 return sta_get_parameter_60g(dut, conn, cmd);
8185
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07008186 if (strcasecmp(program, "he") == 0)
8187 return sta_get_parameter_he(dut, conn, cmd);
8188
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008189#ifdef ANDROID_NAN
8190 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07008191 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008192#endif /* ANDROID_NAN */
8193
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008194#ifdef MIRACAST
8195 if (strcasecmp(program, "WFD") == 0 ||
8196 strcasecmp(program, "DisplayR2") == 0)
8197 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
8198#endif /* MIRACAST */
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05308199 if (strcasecmp(program, "WPA3") == 0)
8200 return sta_get_parameter_wpa3(dut, conn, cmd);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008201
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008202 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8203 return 0;
8204}
8205
8206
8207static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
8208 const char *type)
8209{
8210 char buf[100];
8211
8212 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008213 run_iwpriv(dut, intf, "chwidth 2");
8214 run_iwpriv(dut, intf, "mode 11ACVHT80");
8215 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008216 }
8217
8218 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008219 run_iwpriv(dut, intf, "chwidth 0");
8220 run_iwpriv(dut, intf, "mode 11naht40");
8221 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008222 }
8223
8224 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008225 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008226
8227 /* Reset CTS width */
8228 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
8229 intf);
8230 if (system(buf) != 0) {
8231 sigma_dut_print(dut, DUT_MSG_ERROR,
8232 "wifitool %s beeliner_fw_test 54 0 failed",
8233 intf);
8234 }
8235
8236 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008237 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008238
8239 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
8240 if (system(buf) != 0) {
8241 sigma_dut_print(dut, DUT_MSG_ERROR,
8242 "iwpriv rts failed");
8243 }
8244 }
8245
8246 if (type && strcasecmp(type, "Testbed") == 0) {
8247 dut->testbed_flag_txsp = 1;
8248 dut->testbed_flag_rxsp = 1;
8249 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008250 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008251
8252 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008253 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008254
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008255 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008256
8257 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008258 run_iwpriv(dut, intf, "tx_stbc 0");
8259 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008260
8261 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008262 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008263 }
8264
8265 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008266 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07008267 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008268
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008269 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008270 }
8271}
8272
8273
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008274#ifdef NL80211_SUPPORT
8275static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
8276 enum he_mcs_config mcs)
8277{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308278 return wcn_wifi_test_config_set_u8(
8279 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS, mcs);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008280}
8281#endif /* NL80211_SUPPORT */
8282
8283
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008284static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
8285 const char *intf, int enable)
8286{
8287#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308288 return wcn_wifi_test_config_set_u8(
8289 dut, intf,
8290 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
8291 enable);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008292#else /* NL80211_SUPPORT */
8293 sigma_dut_print(dut, DUT_MSG_ERROR,
8294 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
8295 return -1;
8296#endif /* NL80211_SUPPORT */
8297}
8298
8299
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008300static int sta_set_heconfig_and_wep_tkip(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, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
8306 enable);
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008307#else /* NL80211_SUPPORT */
8308 sigma_dut_print(dut, DUT_MSG_ERROR,
8309 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
8310 return -1;
8311#endif /* NL80211_SUPPORT */
8312}
8313
8314
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008315#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008316
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008317static int sta_set_he_testbed_def(struct sigma_dut *dut,
8318 const char *intf, int cfg)
8319{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308320 return wcn_wifi_test_config_set_u8(
8321 dut, intf,
8322 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
8323 cfg);
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008324}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008325
8326
8327static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
8328{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308329 return wcn_wifi_test_config_set_u8(
8330 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
8331 cfg);
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008332}
8333
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008334#endif /* NL80211_SUPPORT */
8335
8336
Qiwei Caib6806972020-01-15 13:52:11 +08008337int sta_set_addba_buf_size(struct sigma_dut *dut,
8338 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008339{
8340#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308341 return wcn_wifi_test_config_set_u16(
8342 dut, intf,
8343 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE, bufsize);
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008344#else /* NL80211_SUPPORT */
8345 sigma_dut_print(dut, DUT_MSG_ERROR,
8346 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
8347 return -1;
8348#endif /* NL80211_SUPPORT */
8349}
8350
8351
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008352static int sta_set_scan_unicast_probe(struct sigma_dut *dut,
8353 const char *intf, int val)
8354{
8355#ifdef NL80211_SUPPORT
8356 return wcn_wifi_test_config_set_u8(
8357 dut, intf,
8358 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA,
8359 val);
8360#else /* NL80211_SUPPORT */
8361 sigma_dut_print(dut, DUT_MSG_ERROR,
8362 "Unicast RA in Probe Request frame cannot be set without NL80211_SUPPORT defined");
8363 return -1;
8364#endif /* NL80211_SUPPORT */
8365}
8366
8367
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07008368static int sta_set_rx_ctrl_multi_bss(struct sigma_dut *dut, const char *intf,
8369 int enable)
8370{
8371#ifdef NL80211_SUPPORT
8372 return wcn_wifi_test_config_set_u8(
8373 dut, intf,
8374 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS,
8375 enable);
8376#else /* NL80211_SUPPORT */
8377 sigma_dut_print(dut, DUT_MSG_ERROR,
8378 "Rx ctrl frame to Multi-BSS cannot be changed without NL80211_SUPPORT defined");
8379 return -1;
8380#endif /* NL80211_SUPPORT */
8381}
8382
8383
8384static int sta_set_bcast_twt_support(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_BCAST_TWT_SUPPORT,
8391 enable);
8392#else /* NL80211_SUPPORT */
8393 sigma_dut_print(dut, DUT_MSG_ERROR,
8394 "BCAST TWT cannot be changed without NL80211_SUPPORT defined");
8395 return -1;
8396#endif /* NL80211_SUPPORT */
8397}
8398
8399
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008400static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
8401 int enable)
8402{
8403#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308404 return wcn_wifi_test_config_set_u8(
8405 dut, intf,
8406 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
8407 enable);
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008408#else /* NL80211_SUPPORT */
8409 sigma_dut_print(dut, DUT_MSG_ERROR,
8410 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
8411 return -1;
8412#endif /* NL80211_SUPPORT */
8413}
8414
8415
Arif Hussain9765f7d2018-07-03 08:28:26 -07008416static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
8417 int val)
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_HE_TX_BEAMFORMEE_NSTS,
8423 val);
Arif Hussain9765f7d2018-07-03 08:28:26 -07008424#else /* NL80211_SUPPORT */
8425 sigma_dut_print(dut, DUT_MSG_ERROR,
8426 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
8427 return -1;
8428#endif /* NL80211_SUPPORT */
8429}
8430
8431
Arif Hussain68d23f52018-07-11 13:39:08 -07008432#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008433static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
8434 enum qca_wlan_he_mac_padding_dur val)
8435{
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_MAC_PADDING_DUR, val);
Arif Hussain68d23f52018-07-11 13:39:08 -07008439}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008440#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008441
8442
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008443static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
8444 int val)
8445{
8446#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308447 return wcn_wifi_test_config_set_u8(
8448 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
8449 val);
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008450#else /* NL80211_SUPPORT */
8451 sigma_dut_print(dut, DUT_MSG_ERROR,
8452 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
8453 return -1;
8454#endif /* NL80211_SUPPORT */
8455}
8456
8457
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008458static int sta_set_mgmt_data_tx_disable_cfg(struct sigma_dut *dut,
8459 const char *intf, int val)
8460{
8461#ifdef NL80211_SUPPORT
8462 return wcn_wifi_test_config_set_u8(
8463 dut, intf,
8464 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX,
8465 val);
8466#else /* NL80211_SUPPORT */
8467 sigma_dut_print(dut, DUT_MSG_ERROR,
8468 "Tx disable config cannot be set without NL80211_SUPPORT defined");
8469 return -1;
8470#endif /* NL80211_SUPPORT */
8471}
8472
8473
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -07008474static int sta_set_keep_alive_data_cfg(struct sigma_dut *dut, const char *intf,
8475 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_KEEP_ALIVE_FRAME_TYPE,
8481 val);
8482#else /* NL80211_SUPPORT */
8483 sigma_dut_print(dut, DUT_MSG_ERROR,
8484 "Keep alive data type cannot be set without NL80211_SUPPORT defined");
8485 return -1;
8486#endif /* NL80211_SUPPORT */
8487}
8488
8489
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008490#ifdef NL80211_SUPPORT
8491static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
8492{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308493 return wcn_wifi_test_config_set_flag(
8494 dut, intf,
8495 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG);
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008496}
8497#endif /* NL80211_SUPPORT */
8498
8499
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008500static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
8501 int val)
8502{
8503#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308504 return wcn_wifi_test_config_set_u8(
8505 dut, intf,
8506 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA, val);
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008507#else /* NL80211_SUPPORT */
8508 sigma_dut_print(dut, DUT_MSG_ERROR,
8509 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
8510 return -1;
8511#endif /* NL80211_SUPPORT */
8512}
8513
8514
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008515static int sta_set_er_su_ppdu_type_tx(struct sigma_dut *dut, const char *intf,
8516 int val)
8517{
8518#ifdef NL80211_SUPPORT
8519 return wcn_wifi_test_config_set_u8(
8520 dut, intf,
8521 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE, val);
8522#else /* NL80211_SUPPORT */
8523 sigma_dut_print(dut, DUT_MSG_ERROR,
8524 "ER-SU PPDU type cannot be set without NL80211_SUPPORT defined");
8525 return -1;
8526#endif /* NL80211_SUPPORT */
8527}
8528
8529
8530static int sta_set_ru_242_tone_tx(struct sigma_dut *dut, const char *intf,
8531 int val)
8532{
8533#ifdef NL80211_SUPPORT
8534 return wcn_wifi_test_config_set_u8(
8535 dut, intf,
8536 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX, val);
8537#else /* NL80211_SUPPORT */
8538 sigma_dut_print(dut, DUT_MSG_ERROR,
8539 "RU 242 tone cannot be set without NL80211_SUPPORT defined");
8540 return -1;
8541#endif /* NL80211_SUPPORT */
8542}
8543
8544
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008545static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
8546 int val)
8547{
8548#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308549 return wcn_wifi_test_config_set_u8(
8550 dut, intf,
8551 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP, val);
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008552#else /* NL80211_SUPPORT */
8553 sigma_dut_print(dut, DUT_MSG_ERROR,
8554 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
8555 return -1;
8556#endif /* NL80211_SUPPORT */
8557}
8558
8559
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008560#ifdef NL80211_SUPPORT
8561
8562struct features_info {
8563 unsigned char flags[8];
8564 size_t flags_len;
8565};
8566
8567static int features_info_handler(struct nl_msg *msg, void *arg)
8568{
8569 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8570 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8571 struct features_info *info = arg;
8572 struct nlattr *nl_vend, *attr;
8573
8574 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8575 genlmsg_attrlen(gnlh, 0), NULL);
8576
8577 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
8578 if (nl_vend) {
8579 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
8580
8581 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
8582 nla_data(nl_vend), nla_len(nl_vend), NULL);
8583
8584 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
8585 if (attr) {
8586 int len = nla_len(attr);
8587
Vamsi Krishna79a91132021-08-16 21:40:22 +05308588 if (info && len <= sizeof(info->flags)) {
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008589 memcpy(info->flags, nla_data(attr), len);
8590 info->flags_len = len;
8591 }
8592 }
8593 }
8594
8595 return NL_SKIP;
8596}
8597
8598
8599static int check_feature(enum qca_wlan_vendor_features feature,
8600 struct features_info *info)
8601{
8602 size_t idx = feature / 8;
8603
Vamsi Krishna79a91132021-08-16 21:40:22 +05308604 if (!info)
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008605 return 0;
8606
8607 return (idx < info->flags_len) &&
8608 (info->flags[idx] & BIT(feature % 8));
8609}
8610
8611#endif /* NL80211_SUPPORT */
8612
8613
8614static void sta_get_twt_feature_async_supp(struct sigma_dut *dut,
8615 const char *intf)
8616{
8617#ifdef NL80211_SUPPORT
8618 struct nl_msg *msg;
8619 struct features_info info = { 0 };
8620 int ifindex, ret;
8621
8622 ifindex = if_nametoindex(intf);
8623 if (ifindex == 0) {
8624 sigma_dut_print(dut, DUT_MSG_ERROR,
8625 "%s: Index for interface %s failed",
8626 __func__, intf);
8627 return;
8628 }
8629
8630 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8631 NL80211_CMD_VENDOR)) ||
8632 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8633 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8634 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8635 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
8636 sigma_dut_print(dut, DUT_MSG_ERROR,
8637 "%s: err in adding vendor_cmd and vendor_data",
8638 __func__);
8639 nlmsg_free(msg);
8640 return;
8641 }
8642
8643 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, features_info_handler,
8644 &info);
8645 if (ret) {
8646 sigma_dut_print(dut, DUT_MSG_ERROR,
8647 "%s: err in send_and_recv_msgs, ret=%d",
8648 __func__, ret);
8649 return;
8650 }
8651
8652 if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info))
8653 dut->sta_async_twt_supp = 1;
8654 else
8655 dut->sta_async_twt_supp = 0;
8656
8657 sigma_dut_print(dut, DUT_MSG_DEBUG,
8658 "%s: sta_async_twt_supp %d",
8659 __func__, dut->sta_async_twt_supp);
8660#else /* NL80211_SUPPORT */
8661 sigma_dut_print(dut, DUT_MSG_INFO,
8662 "TWT async supp get cannot be done without NL80211_SUPPORT defined");
8663 dut->sta_async_twt_supp = 0;
8664#endif /* NL80211_SUPPORT */
8665}
8666
8667
Arif Hussain480d5f42019-03-12 14:40:42 -07008668static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
8669 int val)
8670{
8671#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308672 return wcn_wifi_test_config_set_u8(
8673 dut, intf,
8674 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT, val);
Arif Hussain480d5f42019-03-12 14:40:42 -07008675#else /* NL80211_SUPPORT */
8676 sigma_dut_print(dut, DUT_MSG_ERROR,
8677 "TWT Request cannot be changed without NL80211_SUPPORT defined");
8678 return -1;
8679#endif /* NL80211_SUPPORT */
8680}
8681
8682
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07008683static int sta_set_bss_max_idle_period(struct sigma_dut *dut, const char *intf,
8684 int val)
8685{
8686#ifdef NL80211_SUPPORT
8687 return wcn_wifi_test_config_set_u16(
8688 dut, intf,
8689 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD, val);
8690#else /* NL80211_SUPPORT */
8691 sigma_dut_print(dut, DUT_MSG_ERROR,
8692 "BSS max idle period cannot be set without NL80211_SUPPORT defined");
8693 return -1;
8694#endif /* NL80211_SUPPORT */
8695}
8696
8697
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07008698static int sta_set_bss_max_idle_support(struct sigma_dut *dut, const char *intf,
8699 int val)
8700{
8701#ifdef NL80211_SUPPORT
8702 return wcn_wifi_test_config_set_u8(
8703 dut, intf,
8704 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE,
8705 val);
8706#else /* NL80211_SUPPORT */
8707 sigma_dut_print(dut, DUT_MSG_ERROR,
8708 "BSS max idle support cannot be set without NL80211_SUPPORT defined");
8709 return -1;
8710#endif /* NL80211_SUPPORT */
8711}
8712
8713
Srinivas Girigowda0525e292020-11-12 13:28:21 -08008714static int sta_set_fullbw_ulmumimo(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_FULL_BW_UL_MU_MIMO, val);
8721#else /* NL80211_SUPPORT */
8722 sigma_dut_print(dut, DUT_MSG_ERROR,
8723 "Full BW UL MU MIMO cannot be changed without NL80211_SUPPORT defined");
8724 return -1;
8725#endif /* NL80211_SUPPORT */
8726}
8727
8728
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07008729static int sta_set_punctured_preamble_rx(struct sigma_dut *dut,
8730 const char *intf, int val)
8731{
8732#ifdef NL80211_SUPPORT
8733 return wcn_wifi_test_config_set_u8(
8734 dut, intf,
8735 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX,
8736 val);
8737#else /* NL80211_SUPPORT */
8738 sigma_dut_print(dut, DUT_MSG_ERROR,
8739 "Punctured preamble Rx cannot be set without NL80211_SUPPORT defined");
8740 return -1;
8741#endif /* NL80211_SUPPORT */
8742}
8743
8744
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -08008745int wcn_set_he_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8746{
8747 #ifdef NL80211_SUPPORT
8748 struct nlattr *attr;
8749 struct nlattr *attr1;
8750 int ifindex, ret;
8751 struct nl_msg *msg;
8752
8753 ifindex = if_nametoindex(intf);
8754 if (ifindex == 0) {
8755 sigma_dut_print(dut, DUT_MSG_ERROR,
8756 "%s: Index for interface %s failed",
8757 __func__, intf);
8758 return -1;
8759 }
8760
8761 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8762 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8763 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8764 sigma_dut_print(dut, DUT_MSG_ERROR,
8765 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8766 __func__);
8767 nlmsg_free(msg);
8768 return -1;
8769 }
8770
8771 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting HE GI %d",
8772 __func__, gi_val);
8773
8774 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8775 if (!attr1) {
8776 sigma_dut_print(dut, DUT_MSG_ERROR,
8777 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8778 __func__);
8779 nlmsg_free(msg);
8780 return -1;
8781 }
8782 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8783 nla_nest_end(msg, attr1);
8784
8785 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8786 if (!attr1) {
8787 sigma_dut_print(dut, DUT_MSG_ERROR,
8788 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8789 __func__);
8790 nlmsg_free(msg);
8791 return -1;
8792 }
8793 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8794 nla_nest_end(msg, attr1);
8795
8796 nla_nest_end(msg, attr);
8797 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8798 if (ret) {
8799 sigma_dut_print(dut, DUT_MSG_ERROR,
8800 "%s: send_and_recv_msgs failed, ret=%d",
8801 __func__, ret);
8802 }
8803 return ret;
8804#else /* NL80211_SUPPORT */
8805 return -1;
8806#endif /* NL80211_SUPPORT */
8807}
8808
8809
8810static int sta_set_vht_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8811{
8812 #ifdef NL80211_SUPPORT
8813 struct nlattr *attr;
8814 struct nlattr *attr1;
8815 int ifindex, ret;
8816 struct nl_msg *msg;
8817
8818 ifindex = if_nametoindex(intf);
8819 if (ifindex == 0) {
8820 sigma_dut_print(dut, DUT_MSG_ERROR,
8821 "%s: Index for interface %s failed",
8822 __func__, intf);
8823 return -1;
8824 }
8825
8826 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8827 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8828 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8829 sigma_dut_print(dut, DUT_MSG_ERROR,
8830 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8831 __func__);
8832 nlmsg_free(msg);
8833 return -1;
8834 }
8835
8836 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting VHT GI %d",
8837 __func__, gi_val);
8838
8839 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8840 if (!attr1) {
8841 sigma_dut_print(dut, DUT_MSG_ERROR,
8842 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8843 __func__);
8844 nlmsg_free(msg);
8845 return -1;
8846 }
8847 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8848 nla_nest_end(msg, attr1);
8849
8850 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8851 if (!attr1) {
8852 sigma_dut_print(dut, DUT_MSG_ERROR,
8853 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8854 __func__);
8855 nlmsg_free(msg);
8856 return -1;
8857 }
8858 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8859 nla_nest_end(msg, attr1);
8860 nla_nest_end(msg, attr);
8861
8862 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8863 if (ret) {
8864 sigma_dut_print(dut, DUT_MSG_ERROR,
8865 "%s: send_and_recv_msgs failed, ret=%d",
8866 __func__, ret);
8867 }
8868 return ret;
8869#else /* NL80211_SUPPORT */
8870 return -1;
8871#endif /* NL80211_SUPPORT */
8872}
8873
8874
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008875static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
8876 const char *type)
8877{
8878 char buf[60];
8879
8880 if (dut->program == PROGRAM_HE) {
8881 /* resetting phymode to auto in case of HE program */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05308882 sta_set_phymode(dut, intf, "auto");
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008883
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07008884 /* reset the rate to Auto rate */
8885 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
8886 intf);
8887 if (system(buf) != 0) {
8888 sigma_dut_print(dut, DUT_MSG_ERROR,
8889 "iwpriv %s set_11ax_rate 0xff failed",
8890 intf);
8891 }
8892
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07008893 /* reset the LDPC setting */
8894 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
8895 if (system(buf) != 0) {
8896 sigma_dut_print(dut, DUT_MSG_ERROR,
8897 "iwpriv %s ldpc 1 failed", intf);
8898 }
8899
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008900 /* reset the power save setting */
Vinita S. Malooa8b62722020-04-23 01:45:41 +05308901 set_power_save_wcn(dut, intf, 2);
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008902
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008903 /* remove all network profiles */
8904 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008905
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008906 /* Configure ADDBA Req/Rsp buffer size to be 64 */
8907 sta_set_addba_buf_size(dut, intf, 64);
8908
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008909 if (dut->sta_async_twt_supp == -1)
8910 sta_get_twt_feature_async_supp(dut, intf);
8911
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008912 sta_set_scan_unicast_probe(dut, intf, 0);
8913
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008914#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008915 /* Reset the device HE capabilities to its default supported
8916 * configuration. */
8917 sta_set_he_testbed_def(dut, intf, 0);
8918
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008919 /* Disable noackpolicy for all AC */
8920 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
8921 sigma_dut_print(dut, DUT_MSG_ERROR,
8922 "Disable of noackpolicy for all AC failed");
8923 }
8924#endif /* NL80211_SUPPORT */
8925
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08008926 /* Enable WMM by default */
8927 if (wcn_sta_set_wmm(dut, intf, "on")) {
8928 sigma_dut_print(dut, DUT_MSG_ERROR,
8929 "Enable of WMM in sta_reset_default_wcn failed");
8930 }
8931
8932 /* Disable ADDBA_REJECT by default */
8933 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
8934 sigma_dut_print(dut, DUT_MSG_ERROR,
8935 "Disable of addba_reject in sta_reset_default_wcn failed");
8936 }
8937
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08008938 /* Enable sending of ADDBA by default */
8939 if (nlvendor_config_send_addba(dut, intf, 1)) {
8940 sigma_dut_print(dut, DUT_MSG_ERROR,
8941 "Enable sending of ADDBA in sta_reset_default_wcn failed");
8942 }
8943
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08008944 /* Enable AMPDU by default */
8945 iwpriv_sta_set_ampdu(dut, intf, 1);
8946
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008947#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08008948 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008949 sigma_dut_print(dut, DUT_MSG_ERROR,
8950 "Set LTF config to default in sta_reset_default_wcn failed");
8951 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07008952
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08008953 /* set the beamformee NSTS(maximum number of
8954 * space-time streams) to default DUT config
8955 */
8956 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07008957 sigma_dut_print(dut, DUT_MSG_ERROR,
8958 "Failed to set BeamformeeSTS");
8959 }
Arif Hussain68d23f52018-07-11 13:39:08 -07008960
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008961 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, 0)) {
8962 sigma_dut_print(dut, DUT_MSG_ERROR,
8963 "Failed to reset mgmt/data Tx disable config");
8964 }
8965
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008966 if (sta_set_mac_padding_duration(
8967 dut, intf,
8968 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008969 sigma_dut_print(dut, DUT_MSG_ERROR,
8970 "Failed to set MAC padding duration");
8971 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008972
8973 if (sta_set_mu_edca_override(dut, intf, 0)) {
8974 sigma_dut_print(dut, DUT_MSG_ERROR,
8975 "ErrorCode,Failed to set MU EDCA override disable");
8976 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008977
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008978 if (sta_set_ru_242_tone_tx(dut, intf, 0)) {
8979 sigma_dut_print(dut, DUT_MSG_ERROR,
8980 "Failed to set RU 242 tone Tx");
8981 }
8982
8983 if (sta_set_er_su_ppdu_type_tx(dut, intf, 0)) {
8984 sigma_dut_print(dut, DUT_MSG_ERROR,
8985 "Failed to set ER-SU PPDU type Tx");
8986 }
8987
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008988 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
8989 sigma_dut_print(dut, DUT_MSG_ERROR,
8990 "Failed to set OM ctrl supp");
8991 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008992
8993 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
8994 sigma_dut_print(dut, DUT_MSG_ERROR,
8995 "Failed to set Tx SU PPDU enable");
8996 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008997
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008998 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
8999 sigma_dut_print(dut, DUT_MSG_ERROR,
9000 "failed to send TB PPDU Tx cfg");
9001 }
9002
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009003 if (sta_set_he_om_ctrl_reset(dut, intf)) {
9004 sigma_dut_print(dut, DUT_MSG_ERROR,
9005 "Failed to set OM ctrl reset");
9006 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009007
9008 /* +HTC-HE support default on */
9009 if (sta_set_he_htc_supp(dut, intf, 1)) {
9010 sigma_dut_print(dut, DUT_MSG_ERROR,
9011 "Setting of +HTC-HE support failed");
9012 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009013#endif /* NL80211_SUPPORT */
9014
Arif Hussain8d5b27b2018-05-14 14:31:03 -07009015 if (sta_set_tx_beamformee(dut, intf, 1)) {
9016 sigma_dut_print(dut, DUT_MSG_ERROR,
9017 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
9018 }
9019
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009020 wpa_command(intf, "SET oce 1");
9021
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009022 /* Set nss to 1 and MCS 0-7 in case of testbed */
9023 if (type && strcasecmp(type, "Testbed") == 0) {
9024#ifdef NL80211_SUPPORT
9025 int ret;
9026#endif /* NL80211_SUPPORT */
9027
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009028 wpa_command(intf, "SET oce 0");
9029
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009030 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
9031 if (system(buf) != 0) {
9032 sigma_dut_print(dut, DUT_MSG_ERROR,
9033 "iwpriv %s nss failed", intf);
9034 }
9035
9036#ifdef NL80211_SUPPORT
9037 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
9038 if (ret) {
9039 sigma_dut_print(dut, DUT_MSG_ERROR,
9040 "Setting of MCS failed, ret:%d",
9041 ret);
9042 }
9043#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08009044
9045 /* Disable STBC as default */
9046 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08009047
9048 /* Disable AMSDU as default */
9049 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009050
9051#ifdef NL80211_SUPPORT
9052 /* HE fragmentation default off */
9053 if (sta_set_he_fragmentation(dut, intf,
9054 HE_FRAG_DISABLE)) {
9055 sigma_dut_print(dut, DUT_MSG_ERROR,
9056 "Setting of HE fragmentation failed");
9057 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009058
9059 /* set the beamformee NSTS(maximum number of
9060 * space-time streams) to default testbed config
9061 */
9062 if (sta_set_beamformee_sts(dut, intf, 3)) {
9063 sigma_dut_print(dut, DUT_MSG_ERROR,
9064 "Failed to set BeamformeeSTS");
9065 }
9066
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07009067 if (sta_set_punctured_preamble_rx(dut, intf, 0)) {
9068 sigma_dut_print(dut, DUT_MSG_ERROR,
9069 "Failed to reset PreamblePunctRx support");
9070 }
9071
Kiran Kumar Lokere727687f2021-06-24 00:35:49 -07009072 if (sta_set_bss_max_idle_period(dut, intf, 0)) {
9073 sigma_dut_print(dut, DUT_MSG_ERROR,
9074 "Failed to reset BSS max idle period");
9075 }
9076
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009077 /* +HTC-HE support default off */
9078 if (sta_set_he_htc_supp(dut, intf, 0)) {
9079 sigma_dut_print(dut, DUT_MSG_ERROR,
9080 "Setting of +HTC-HE support failed");
9081 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08009082
9083 /* Set device HE capabilities to testbed default
9084 * configuration. */
9085 if (sta_set_he_testbed_def(dut, intf, 1)) {
9086 sigma_dut_print(dut, DUT_MSG_DEBUG,
9087 "Failed to set HE defaults");
9088 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08009089
9090 /* Disable VHT support in 2.4 GHz for testbed */
9091 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009092#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08009093
9094 /* Enable WEP/TKIP with HE capability in testbed */
9095 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
9096 sigma_dut_print(dut, DUT_MSG_ERROR,
9097 "Enabling HE config with WEP/TKIP failed");
9098 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009099 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009100
9101 /* Defaults in case of DUT */
9102 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07009103 /* Enable STBC by default */
9104 wcn_sta_set_stbc(dut, intf, "1");
9105
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009106 /* set nss to 2 */
9107 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
9108 if (system(buf) != 0) {
9109 sigma_dut_print(dut, DUT_MSG_ERROR,
9110 "iwpriv %s nss 2 failed", intf);
9111 }
Arif Hussainac6c5112018-05-25 17:34:00 -07009112 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009113
9114#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07009115 /* Set HE_MCS to 0-11 */
9116 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009117 sigma_dut_print(dut, DUT_MSG_ERROR,
9118 "Setting of MCS failed");
9119 }
9120#endif /* NL80211_SUPPORT */
9121
9122 /* Disable WEP/TKIP with HE capability in DUT */
9123 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
9124 sigma_dut_print(dut, DUT_MSG_ERROR,
9125 "Enabling HE config with WEP/TKIP failed");
9126 }
9127 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009128 }
9129}
9130
9131
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309132static int sta_set_client_privacy(struct sigma_dut *dut,
9133 struct sigma_conn *conn, const char *intf,
9134 int enable)
9135{
9136 if (enable &&
9137 (wpa_command(intf, "SET mac_addr 1") < 0 ||
9138 wpa_command(intf, "SET rand_addr_lifetime 1") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309139 (wpa_command(intf, "MAC_RAND_SCAN enable=1 all") < 0 &&
9140 wpa_command(intf, "SET preassoc_mac_addr 1") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309141 wpa_command(intf, "SET gas_rand_mac_addr 1") < 0 ||
9142 wpa_command(intf, "SET gas_rand_addr_lifetime 1") < 0))
9143 return -1;
9144
9145 if (!enable &&
9146 (wpa_command(intf, "SET mac_addr 0") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309147 (wpa_command(intf, "MAC_RAND_SCAN enable=0 all") < 0 &&
9148 wpa_command(intf, "SET preassoc_mac_addr 0") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309149 wpa_command(intf, "SET gas_rand_mac_addr 0") < 0))
9150 return -1;
9151
9152 dut->client_privacy = enable;
9153 return 0;
9154}
9155
9156
Jouni Malinenf7222712019-06-13 01:50:21 +03009157static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
9158 struct sigma_conn *conn,
9159 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009160{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009161 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009162 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009163 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009164 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309165 const char *dev_role = get_param(cmd, "DevRole");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309166 char resp[20];
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309167 char buf[100];
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309168 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009169
Jouni Malinenb21f0542019-11-04 17:53:38 +02009170 if (dut->station_ifname_2g &&
9171 strcmp(dut->station_ifname_2g, intf) == 0)
9172 dut->use_5g = 0;
9173 else if (dut->station_ifname_5g &&
9174 strcmp(dut->station_ifname_5g, intf) == 0)
9175 dut->use_5g = 1;
9176
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009177 if (!program)
9178 program = get_param(cmd, "prog");
9179 dut->program = sigma_program_to_enum(program);
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05309180
9181 if (dut->program == PROGRAM_WFD && dut->user_config_timeout)
9182 dut->default_timeout = dut->user_config_timeout;
9183
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009184 dut->device_type = STA_unknown;
9185 type = get_param(cmd, "type");
9186 if (type && strcasecmp(type, "Testbed") == 0)
9187 dut->device_type = STA_testbed;
9188 if (type && strcasecmp(type, "DUT") == 0)
9189 dut->device_type = STA_dut;
9190
9191 if (dut->program == PROGRAM_TDLS) {
9192 /* Clear TDLS testing mode */
9193 wpa_command(intf, "SET tdls_disabled 0");
9194 wpa_command(intf, "SET tdls_testing 0");
9195 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009196 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05309197 /* Enable the WCN driver in TDLS Explicit trigger mode
9198 */
9199 wpa_command(intf, "SET tdls_external_control 0");
9200 wpa_command(intf, "SET tdls_trigger_control 0");
9201 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009202 }
9203
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009204#ifdef MIRACAST
9205 if (dut->program == PROGRAM_WFD ||
9206 dut->program == PROGRAM_DISPLAYR2)
9207 miracast_sta_reset_default(dut, conn, cmd);
9208#endif /* MIRACAST */
9209
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009210 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009211 case DRIVER_ATHEROS:
9212 sta_reset_default_ath(dut, intf, type);
9213 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009214 case DRIVER_WCN:
9215 sta_reset_default_wcn(dut, intf, type);
9216 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009217 default:
9218 break;
9219 }
9220
9221#ifdef ANDROID_NAN
9222 if (dut->program == PROGRAM_NAN)
9223 nan_cmd_sta_reset_default(dut, conn, cmd);
9224#endif /* ANDROID_NAN */
9225
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05309226 if (dut->program == PROGRAM_LOC &&
9227 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
9228 return ERROR_SEND_STATUS;
9229
Jouni Malinenba630452018-06-22 11:49:59 +03009230 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009231 unlink("SP/wi-fi.org/pps.xml");
9232 if (system("rm -r SP/*") != 0) {
9233 }
9234 unlink("next-client-cert.pem");
9235 unlink("next-client-key.pem");
9236 }
9237
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009238 /* For WPS program of the 60 GHz band the band type needs to be saved */
9239 if (dut->program == PROGRAM_WPS) {
9240 if (band && strcasecmp(band, "60GHz") == 0) {
9241 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009242 /* For 60 GHz enable WPS for WPS TCs */
9243 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009244 } else {
9245 dut->band = WPS_BAND_NON_60G;
9246 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009247 } else if (dut->program == PROGRAM_60GHZ) {
9248 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
9249 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009250 }
9251
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02009252 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009253 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009254 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009255
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009256 sigma_dut_print(dut, DUT_MSG_INFO,
9257 "WPS 60 GHz program, wps_disable = %d",
9258 dut->wps_disable);
9259
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009260 if (!dev_role) {
9261 send_resp(dut, conn, SIGMA_ERROR,
9262 "errorCode,Missing DevRole argument");
9263 return 0;
9264 }
9265
9266 if (strcasecmp(dev_role, "STA") == 0)
9267 dut->dev_role = DEVROLE_STA;
9268 else if (strcasecmp(dev_role, "PCP") == 0)
9269 dut->dev_role = DEVROLE_PCP;
9270 else {
9271 send_resp(dut, conn, SIGMA_ERROR,
9272 "errorCode,Unknown DevRole");
9273 return 0;
9274 }
9275
9276 if (dut->device_type == STA_unknown) {
9277 sigma_dut_print(dut, DUT_MSG_ERROR,
9278 "Device type is not STA testbed or DUT");
9279 send_resp(dut, conn, SIGMA_ERROR,
9280 "errorCode,Unknown device type");
9281 return 0;
9282 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009283
9284 sigma_dut_print(dut, DUT_MSG_DEBUG,
9285 "Setting msdu_size to MAX: 7912");
9286 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009287 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009288
9289 if (system(buf) != 0) {
9290 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9291 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009292 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009293 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009294
9295 if (sta_set_force_mcs(dut, 0, 1)) {
9296 sigma_dut_print(dut, DUT_MSG_ERROR,
9297 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009298 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009299 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009300 }
9301
9302 wpa_command(intf, "WPS_ER_STOP");
9303 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05309304 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009305 wpa_command(intf, "SET radio_disabled 0");
9306
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02009307 dut->wps_forced_version = 0;
9308
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009309 if (dut->wsc_fragment) {
9310 dut->wsc_fragment = 0;
9311 wpa_command(intf, "SET device_name Test client");
9312 wpa_command(intf, "SET manufacturer ");
9313 wpa_command(intf, "SET model_name ");
9314 wpa_command(intf, "SET model_number ");
9315 wpa_command(intf, "SET serial_number ");
9316 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02009317 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
9318 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
9319 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
9320 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009321
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009322 if (dut->tmp_mac_addr && dut->set_macaddr) {
9323 dut->tmp_mac_addr = 0;
9324 if (system(dut->set_macaddr) != 0) {
9325 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
9326 "temporary MAC address");
9327 }
9328 }
9329
9330 set_ps(intf, dut, 0);
9331
Jouni Malinenba630452018-06-22 11:49:59 +03009332 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
9333 dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009334 wpa_command(intf, "SET interworking 1");
9335 wpa_command(intf, "SET hs20 1");
9336 }
9337
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009338 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03009339 dut->program == PROGRAM_HS2_R3 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009340 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009341 wpa_command(intf, "SET pmf 1");
9342 } else {
9343 wpa_command(intf, "SET pmf 0");
9344 }
9345
9346 hs2_clear_credentials(intf);
9347 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
9348 wpa_command(intf, "SET access_network_type 15");
9349
9350 static_ip_file(0, NULL, NULL, NULL);
9351 kill_dhcp_client(dut, intf);
9352 clear_ip_addr(dut, intf);
9353
9354 dut->er_oper_performed = 0;
9355 dut->er_oper_bssid[0] = '\0';
9356
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009357 if (dut->program == PROGRAM_LOC) {
9358 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009359 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009360 }
9361
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07009362 if (dut->program == PROGRAM_MBO || dut->program == PROGRAM_HE) {
Ashwini Patil00402582017-04-13 12:29:39 +05309363 free(dut->non_pref_ch_list);
9364 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309365 free(dut->btm_query_cand_list);
9366 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05309367 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05309368 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05309369 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05309370 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05309371 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05309372 }
9373
Jouni Malinen3c367e82017-06-23 17:01:47 +03009374 free(dut->rsne_override);
9375 dut->rsne_override = NULL;
9376
Jouni Malinen68143132017-09-02 02:34:08 +03009377 free(dut->sae_commit_override);
9378 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03009379 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02009380 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03009381
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009382 dut->sta_associate_wait_connect = 0;
9383 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03009384 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009385 dut->sta_tod_policy = 0;
9386
Jouni Malinend86e5822017-08-29 03:55:32 +03009387 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02009388 free(dut->dpp_peer_uri);
9389 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02009390 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02009391 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03009392 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinend86e5822017-08-29 03:55:32 +03009393
Jouni Malinenfac9cad2017-10-10 18:35:55 +03009394 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
9395
vamsi krishnaa2799492017-12-05 14:28:01 +05309396 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309397 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05309398 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05309399 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
9400 dut->fils_hlp = 0;
9401#ifdef ANDROID
9402 hlp_thread_cleanup(dut);
9403#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05309404 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309405
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309406 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309407 wpa_command(intf, "SET interworking 1");
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309408 wpa_command(intf, "SET enable_dscp_policy_capa 1");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05309409 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309410 dut->reject_dscp_policies = 0;
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +05309411 dut->num_dscp_status = 0;
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309412 snprintf(buf, sizeof(buf),
9413 "ip -6 route replace fe80::/64 dev %s table local",
9414 intf);
9415 if (system(buf) != 0)
9416 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
9417 buf);
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05309418
9419 stop_dscp_policy_mon_thread(dut);
9420 clear_all_dscp_policies(dut);
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309421 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309422
Jouni Malinen8179fee2019-03-28 03:19:47 +02009423 dut->akm_values = 0;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05309424
9425#ifdef NL80211_SUPPORT
9426 if (get_driver_type(dut) == DRIVER_WCN)
9427 sta_config_params(dut, intf, STA_SET_FT_DS, 0);
9428#endif /* NL80211_SUPPORT */
9429
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03009430 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02009431
Sunil Dutt076081f2018-02-05 19:45:50 +05309432#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009433 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05309434 dut->config_rsnie == 1) {
9435 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309436 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05309437 }
9438#endif /* NL80211_SUPPORT */
9439
Sunil Duttfebf8a82018-02-09 18:50:13 +05309440 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
9441 dut->dev_role = DEVROLE_STA_CFON;
9442 return sta_cfon_reset_default(dut, conn, cmd);
9443 }
9444
Jouni Malinen439352d2018-09-13 03:42:23 +03009445 wpa_command(intf, "SET setband AUTO");
9446
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309447 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
9448 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
9449
9450 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
9451 sizeof(resp));
9452 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
9453
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309454 if (sta_set_client_privacy(dut, conn, intf,
9455 dut->program == PROGRAM_WPA3 &&
9456 dut->device_type == STA_dut &&
9457 dut->client_privacy_default)) {
9458 sigma_dut_print(dut, DUT_MSG_ERROR,
9459 "Failed to set client privacy functionality");
9460 /* sta_reset_default command is not really supposed to fail,
9461 * so allow this to continue. */
9462 }
9463
Veerendranath Jakkamca239592021-10-11 20:48:00 +05309464 if (get_driver_type(dut) == DRIVER_WCN)
9465 wcn_set_ignore_h2e_rsnxe(dut, intf, 0);
9466
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05309467 dut->saquery_oci_freq = 0;
Shivani Baranwalebde8f62021-10-19 12:26:02 +05309468 dut->prev_disable_scs_support = 0;
9469 dut->prev_disable_mscs_support = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309470
Sunil Duttfebf8a82018-02-09 18:50:13 +05309471 if (dut->program != PROGRAM_VHT)
9472 return cmd_sta_p2p_reset(dut, conn, cmd);
9473
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08009474 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009475}
9476
9477
Jouni Malinenf7222712019-06-13 01:50:21 +03009478static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
9479 struct sigma_conn *conn,
9480 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009481{
9482 const char *program = get_param(cmd, "Program");
9483
9484 if (program == NULL)
9485 return -1;
9486#ifdef ANDROID_NAN
9487 if (strcasecmp(program, "NAN") == 0)
9488 return nan_cmd_sta_get_events(dut, conn, cmd);
9489#endif /* ANDROID_NAN */
9490 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9491 return 0;
9492}
9493
9494
Jouni Malinen82905202018-04-29 17:20:10 +03009495static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
9496 struct sigma_cmd *cmd)
9497{
9498 const char *url = get_param(cmd, "url");
9499 const char *method = get_param(cmd, "method");
9500 pid_t pid;
9501 int status;
9502
9503 if (!url || !method)
9504 return -1;
9505
9506 /* TODO: Add support for method,post */
9507 if (strcasecmp(method, "get") != 0) {
9508 send_resp(dut, conn, SIGMA_ERROR,
9509 "ErrorCode,Unsupported method");
9510 return 0;
9511 }
9512
9513 pid = fork();
9514 if (pid < 0) {
9515 perror("fork");
9516 return -1;
9517 }
9518
9519 if (pid == 0) {
9520 char * argv[5] = { "wget", "-O", "/dev/null",
9521 (char *) url, NULL };
9522
9523 execv("/usr/bin/wget", argv);
9524 perror("execv");
9525 exit(0);
9526 return -1;
9527 }
9528
9529 if (waitpid(pid, &status, 0) < 0) {
9530 perror("waitpid");
9531 return -1;
9532 }
9533
9534 if (WIFEXITED(status)) {
9535 const char *errmsg;
9536
9537 if (WEXITSTATUS(status) == 0)
9538 return 1;
9539 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
9540 WEXITSTATUS(status));
9541 switch (WEXITSTATUS(status)) {
9542 case 4:
9543 errmsg = "errmsg,Network failure";
9544 break;
9545 case 8:
9546 errmsg = "errmsg,Server issued an error response";
9547 break;
9548 default:
9549 errmsg = "errmsg,Unknown failure from wget";
9550 break;
9551 }
9552 send_resp(dut, conn, SIGMA_ERROR, errmsg);
9553 return 0;
9554 }
9555
9556 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
9557 return 0;
9558}
9559
9560
Jouni Malinenf7222712019-06-13 01:50:21 +03009561static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
9562 struct sigma_conn *conn,
9563 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009564{
9565 const char *program = get_param(cmd, "Prog");
9566
Jouni Malinen82905202018-04-29 17:20:10 +03009567 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009568 return -1;
9569#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03009570 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009571 return nan_cmd_sta_exec_action(dut, conn, cmd);
9572#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03009573
9574 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009575 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03009576
9577 if (get_param(cmd, "url"))
9578 return sta_exec_action_url(dut, conn, cmd);
9579
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009580 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9581 return 0;
9582}
9583
9584
Jouni Malinenf7222712019-06-13 01:50:21 +03009585static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
9586 struct sigma_conn *conn,
9587 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009588{
9589 const char *intf = get_param(cmd, "Interface");
9590 const char *val, *mcs32, *rate;
9591
9592 val = get_param(cmd, "GREENFIELD");
9593 if (val) {
9594 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
9595 /* Enable GD */
9596 send_resp(dut, conn, SIGMA_ERROR,
9597 "ErrorCode,GF not supported");
9598 return 0;
9599 }
9600 }
9601
9602 val = get_param(cmd, "SGI20");
9603 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009604 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009605 case DRIVER_ATHEROS:
9606 ath_sta_set_sgi(dut, intf, val);
9607 break;
9608 default:
9609 send_resp(dut, conn, SIGMA_ERROR,
9610 "ErrorCode,SGI20 not supported");
9611 return 0;
9612 }
9613 }
9614
9615 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
9616 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
9617 if (mcs32 && rate) {
9618 /* TODO */
9619 send_resp(dut, conn, SIGMA_ERROR,
9620 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
9621 return 0;
9622 } else if (mcs32 && !rate) {
9623 /* TODO */
9624 send_resp(dut, conn, SIGMA_ERROR,
9625 "ErrorCode,MCS32 not supported");
9626 return 0;
9627 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009628 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009629 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07009630 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009631 ath_sta_set_11nrates(dut, intf, rate);
9632 break;
9633 default:
9634 send_resp(dut, conn, SIGMA_ERROR,
9635 "ErrorCode,MCS32_FIXEDRATE not supported");
9636 return 0;
9637 }
9638 }
9639
9640 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9641}
9642
9643
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009644static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
9645 int mcs_config)
9646{
9647#ifdef NL80211_SUPPORT
9648 int ret;
9649
9650 switch (mcs_config) {
9651 case HE_80_MCS0_7:
9652 case HE_80_MCS0_9:
9653 case HE_80_MCS0_11:
9654 ret = sta_set_he_mcs(dut, intf, mcs_config);
9655 if (ret) {
9656 sigma_dut_print(dut, DUT_MSG_ERROR,
9657 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
9658 mcs_config, ret);
9659 }
9660 break;
9661 default:
9662 sigma_dut_print(dut, DUT_MSG_ERROR,
9663 "cmd_set_max_he_mcs: Invalid mcs %d",
9664 mcs_config);
9665 break;
9666 }
9667#else /* NL80211_SUPPORT */
9668 sigma_dut_print(dut, DUT_MSG_ERROR,
9669 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
9670#endif /* NL80211_SUPPORT */
9671}
9672
9673
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009674struct wait_event {
9675 struct sigma_dut *dut;
9676 int cmd;
9677 unsigned int twt_op;
9678};
9679
9680#ifdef NL80211_SUPPORT
9681
9682static int twt_event_handler(struct nl_msg *msg, void *arg)
9683{
9684 struct wait_event *wait = arg;
9685 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9686 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9687 uint32_t subcmd;
9688 uint8_t *data = NULL;
9689 size_t len = 0;
9690 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
9691 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
9692 int cmd_id;
9693 unsigned char val;
9694
9695 if (!wait)
9696 return NL_SKIP;
9697
9698 if (gnlh->cmd != NL80211_CMD_VENDOR) {
9699 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9700 "%s: NL cmd is not vendor %d", __func__,
9701 gnlh->cmd);
9702 return NL_SKIP;
9703 }
9704
9705 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9706 genlmsg_attrlen(gnlh, 0), NULL);
9707
9708 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
9709 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9710 "%s: vendor ID not found", __func__);
9711 return NL_SKIP;
9712 }
9713 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
9714
9715 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
9716 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9717 "%s: Not a TWT_cmd %d", __func__, subcmd);
9718 return NL_SKIP;
9719 }
9720 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9721 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
9722 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
9723 } else {
9724 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9725 "%s: vendor data not present", __func__);
9726 return NL_SKIP;
9727 }
9728 if (!data || !len) {
9729 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9730 "Invalid vendor data or len");
9731 return NL_SKIP;
9732 }
9733 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
9734 "event data len %ld", len);
9735 hex_dump(wait->dut, data, len);
9736 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
9737 (struct nlattr *) data, len, NULL)) {
9738 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9739 "vendor data parse error");
9740 return NL_SKIP;
9741 }
9742
9743 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
9744 if (val != wait->twt_op) {
9745 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9746 "Invalid TWT operation, expected %d, rcvd %d",
9747 wait->twt_op, val);
9748 return NL_SKIP;
9749 }
9750 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
9751 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
9752 NULL)) {
9753 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9754 "nla_parse failed for TWT event");
9755 return NL_SKIP;
9756 }
9757
9758 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
9759 if (!twt_status[cmd_id]) {
9760 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9761 "%s TWT resp status missing", __func__);
9762 wait->cmd = -1;
9763 } else {
9764 val = nla_get_u8(twt_status[cmd_id]);
9765 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
9766 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9767 "%s TWT resp status %d", __func__, val);
9768 wait->cmd = -1;
9769 } else {
9770 wait->cmd = 1;
9771 }
9772 }
9773
9774 return NL_SKIP;
9775}
9776
9777
9778static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
9779 unsigned int timeout)
9780{
9781 fd_set read_fd_set;
9782 int retval;
9783 int sock_fd;
9784 struct timeval time_out;
9785
9786 time_out.tv_sec = timeout;
9787 time_out.tv_usec = 0;
9788
9789 FD_ZERO(&read_fd_set);
9790
9791 if (!sock)
9792 return -1;
9793
9794 sock_fd = nl_socket_get_fd(sock);
9795 FD_SET(sock_fd, &read_fd_set);
9796
9797 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
9798
9799 if (retval == 0)
9800 sigma_dut_print(dut, DUT_MSG_ERROR,
9801 "%s: TWT event response timedout", __func__);
9802
9803 if (retval < 0)
9804 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
9805 __func__, retval);
9806
9807 return retval;
9808}
9809
9810
9811#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
9812
9813static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
9814{
9815 struct nl_cb *cb;
9816 int err_code = 0, select_retval = 0;
9817 struct wait_event wait_info;
9818
9819 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
9820 if (!cb) {
9821 sigma_dut_print(dut, DUT_MSG_ERROR,
9822 "event callback not found");
9823 return ERROR_SEND_STATUS;
9824 }
9825
9826 wait_info.cmd = 0;
9827 wait_info.dut = dut;
9828 wait_info.twt_op = twt_op;
9829
9830 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
9831
9832 while (!wait_info.cmd) {
9833 select_retval = wait_on_nl_socket(
9834 dut->nl_ctx->event_sock, dut,
9835 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
9836
9837 if (select_retval > 0) {
9838 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
9839 if (err_code < 0) {
9840 sigma_dut_print(dut, DUT_MSG_ERROR,
9841 "%s: nl rcv failed, err_code %d",
9842 __func__, err_code);
9843 break;
9844 }
9845 } else {
9846 sigma_dut_print(dut, DUT_MSG_ERROR,
9847 "%s: wait on socket failed %d",
9848 __func__, select_retval);
9849 err_code = 1;
9850 break;
9851 }
9852
9853 }
9854 nl_cb_put(cb);
9855
9856 if (wait_info.cmd < 0)
9857 err_code = 1;
9858
9859 sigma_dut_print(dut, DUT_MSG_DEBUG,
9860 "%s: rcvd cmd %d, err_code %d, s_ret %d",
9861 __func__, wait_info.cmd, err_code, select_retval);
9862
9863 return err_code;
9864}
9865
9866#endif /* NL80211_SUPPORT */
9867
9868
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009869static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
9870 struct sigma_cmd *cmd)
9871{
9872#ifdef NL80211_SUPPORT
9873 struct nlattr *attr, *attr1;
9874 struct nl_msg *msg;
9875 int ifindex, ret;
9876 const char *intf = get_param(cmd, "Interface");
9877
9878 ifindex = if_nametoindex(intf);
9879 if (ifindex == 0) {
9880 sigma_dut_print(dut, DUT_MSG_ERROR,
9881 "%s: Index for interface %s failed",
9882 __func__, intf);
9883 return ERROR_SEND_STATUS;
9884 }
9885
9886 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9887 NL80211_CMD_VENDOR)) ||
9888 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9889 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9890 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9891 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9892 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9893 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9894 QCA_WLAN_TWT_SUSPEND) ||
9895 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07009896 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009897 sigma_dut_print(dut, DUT_MSG_ERROR,
9898 "%s: err in adding vendor_cmd and vendor_data",
9899 __func__);
9900 nlmsg_free(msg);
9901 return ERROR_SEND_STATUS;
9902 }
9903 nla_nest_end(msg, attr1);
9904 nla_nest_end(msg, attr);
9905
9906 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9907 if (ret) {
9908 sigma_dut_print(dut, DUT_MSG_ERROR,
9909 "%s: err in send_and_recv_msgs, ret=%d",
9910 __func__, ret);
9911 }
9912
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009913 if (!dut->sta_async_twt_supp)
9914 return ret;
9915
9916 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009917#else /* NL80211_SUPPORT */
9918 sigma_dut_print(dut, DUT_MSG_ERROR,
9919 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9920 return ERROR_SEND_STATUS;
9921#endif /* NL80211_SUPPORT */
9922}
9923
9924
9925static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
9926 struct sigma_cmd *cmd,
9927 unsigned int suspend_duration)
9928{
9929#ifdef NL80211_SUPPORT
9930 struct nlattr *attr, *attr1;
9931 struct nl_msg *msg;
9932 int ifindex, ret;
9933 const char *intf = get_param(cmd, "Interface");
9934 int next_twt_size = 1;
9935
9936 ifindex = if_nametoindex(intf);
9937 if (ifindex == 0) {
9938 sigma_dut_print(dut, DUT_MSG_ERROR,
9939 "%s: Index for interface %s failed",
9940 __func__, intf);
9941 return ERROR_SEND_STATUS;
9942 }
9943
9944 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9945 NL80211_CMD_VENDOR)) ||
9946 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9947 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9948 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9949 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9950 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9951 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9952 QCA_WLAN_TWT_NUDGE) ||
9953 !(attr1 = nla_nest_start(msg,
9954 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
9955 (suspend_duration &&
9956 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
9957 suspend_duration)) ||
9958 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009959 next_twt_size) ||
9960 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009961 sigma_dut_print(dut, DUT_MSG_ERROR,
9962 "%s: err in adding vendor_cmd and vendor_data",
9963 __func__);
9964 nlmsg_free(msg);
9965 return ERROR_SEND_STATUS;
9966 }
9967 nla_nest_end(msg, attr1);
9968 nla_nest_end(msg, attr);
9969
9970 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9971 if (ret) {
9972 sigma_dut_print(dut, DUT_MSG_ERROR,
9973 "%s: err in send_and_recv_msgs, ret=%d",
9974 __func__, ret);
9975 }
9976
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009977 if (!dut->sta_async_twt_supp)
9978 return ret;
9979
9980 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009981#else /* NL80211_SUPPORT */
9982 sigma_dut_print(dut, DUT_MSG_ERROR,
9983 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9984 return ERROR_SEND_STATUS;
9985#endif /* NL80211_SUPPORT */
9986}
9987
9988
9989static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
9990 struct sigma_conn *conn,
9991 struct sigma_cmd *cmd)
9992{
9993 const char *val;
9994
9995 val = get_param(cmd, "TWT_SuspendDuration");
9996 if (val) {
9997 unsigned int suspend_duration;
9998
9999 suspend_duration = atoi(val);
10000 suspend_duration = suspend_duration * 1000 * 1000;
10001 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
10002 }
10003
10004 return sta_twt_send_suspend(dut, conn, cmd);
10005}
10006
10007
10008static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
10009 struct sigma_cmd *cmd)
10010{
10011#ifdef NL80211_SUPPORT
10012 struct nlattr *attr, *attr1;
10013 struct nl_msg *msg;
10014 int ifindex, ret;
10015 const char *intf = get_param(cmd, "Interface");
10016 int next2_twt_size = 1;
10017 unsigned int resume_duration = 0;
10018 const char *val;
10019
10020 ifindex = if_nametoindex(intf);
10021 if (ifindex == 0) {
10022 sigma_dut_print(dut, DUT_MSG_ERROR,
10023 "%s: Index for interface %s failed",
10024 __func__, intf);
10025 return ERROR_SEND_STATUS;
10026 }
10027
10028 val = get_param(cmd, "TWT_ResumeDuration");
10029 if (val) {
10030 resume_duration = atoi(val);
10031 resume_duration = resume_duration * 1000 * 1000;
10032 }
10033
10034 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10035 NL80211_CMD_VENDOR)) ||
10036 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10037 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10038 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10039 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10040 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10041 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10042 QCA_WLAN_TWT_RESUME) ||
10043 !(attr1 = nla_nest_start(msg,
10044 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10045 (resume_duration &&
10046 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
10047 resume_duration)) ||
10048 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
10049 next2_twt_size)) {
10050 sigma_dut_print(dut, DUT_MSG_ERROR,
10051 "%s: err in adding vendor_cmd and vendor_data",
10052 __func__);
10053 nlmsg_free(msg);
10054 return ERROR_SEND_STATUS;
10055 }
10056 nla_nest_end(msg, attr1);
10057 nla_nest_end(msg, attr);
10058
10059 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10060 if (ret) {
10061 sigma_dut_print(dut, DUT_MSG_ERROR,
10062 "%s: err in send_and_recv_msgs, ret=%d",
10063 __func__, ret);
10064 }
10065
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010066 if (!dut->sta_async_twt_supp)
10067 return ret;
10068
10069 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010070#else /* NL80211_SUPPORT */
10071 sigma_dut_print(dut, DUT_MSG_ERROR,
10072 "TWT resume cannot be done without NL80211_SUPPORT defined");
10073 return ERROR_SEND_STATUS;
10074#endif /* NL80211_SUPPORT */
10075}
10076
10077
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010078#define TWT_REQUEST_CMD 0
10079#define TWT_SUGGEST_CMD 1
10080#define TWT_DEMAND_CMD 2
10081
Arif Hussain480d5f42019-03-12 14:40:42 -070010082static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
10083 struct sigma_cmd *cmd)
10084{
10085#ifdef NL80211_SUPPORT
10086 struct nlattr *params;
10087 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010088 struct nl_msg *msg;
10089 int ifindex, ret;
10090 const char *val;
10091 const char *intf = get_param(cmd, "Interface");
10092 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
10093 wake_interval_mantissa = 512;
10094 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010095 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010096 int bcast_twt = 0;
10097 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -070010098
10099 ifindex = if_nametoindex(intf);
10100 if (ifindex == 0) {
10101 sigma_dut_print(dut, DUT_MSG_ERROR,
10102 "%s: Index for interface %s failed",
10103 __func__, intf);
10104 return -1;
10105 }
10106
10107 val = get_param(cmd, "FlowType");
10108 if (val) {
10109 flow_type = atoi(val);
10110 if (flow_type != 0 && flow_type != 1) {
10111 sigma_dut_print(dut, DUT_MSG_ERROR,
10112 "TWT: Invalid FlowType %d", flow_type);
10113 return -1;
10114 }
10115 }
10116
10117 val = get_param(cmd, "TWT_Trigger");
10118 if (val) {
10119 twt_trigger = atoi(val);
10120 if (twt_trigger != 0 && twt_trigger != 1) {
10121 sigma_dut_print(dut, DUT_MSG_ERROR,
10122 "TWT: Invalid TWT_Trigger %d",
10123 twt_trigger);
10124 return -1;
10125 }
10126 }
10127
10128 val = get_param(cmd, "Protection");
10129 if (val) {
10130 protection = atoi(val);
10131 if (protection != 0 && protection != 1) {
10132 sigma_dut_print(dut, DUT_MSG_ERROR,
10133 "TWT: Invalid Protection %d",
10134 protection);
10135 return -1;
10136 }
10137 }
10138
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010139 val = get_param(cmd, "SetupCommand");
10140 if (val) {
10141 cmd_type = atoi(val);
10142 if (cmd_type == TWT_REQUEST_CMD)
10143 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
10144 else if (cmd_type == TWT_SUGGEST_CMD)
10145 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
10146 else if (cmd_type == TWT_DEMAND_CMD)
10147 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
10148 else
10149 sigma_dut_print(dut, DUT_MSG_ERROR,
10150 "Default suggest is used for cmd %d",
10151 cmd_type);
10152 }
10153
Arif Hussain480d5f42019-03-12 14:40:42 -070010154 val = get_param(cmd, "TargetWakeTime");
10155 if (val)
10156 target_wake_time = atoi(val);
10157
10158 val = get_param(cmd, "WakeIntervalMantissa");
10159 if (val)
10160 wake_interval_mantissa = atoi(val);
10161
10162 val = get_param(cmd, "WakeIntervalExp");
10163 if (val)
10164 wake_interval_exp = atoi(val);
10165
10166 val = get_param(cmd, "NominalMinWakeDur");
10167 if (val)
10168 nominal_min_wake_dur = atoi(val);
10169
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010170 val = get_param(cmd, "BTWT_ID");
10171 if (val) {
10172 bcast_twt_id = atoi(val);
10173 bcast_twt = 1;
10174 }
10175
10176 val = get_param(cmd, "BTWT_Persistence");
10177 if (val) {
10178 bcast_twt_persis = atoi(val);
10179 bcast_twt = 1;
10180 }
10181
10182 val = get_param(cmd, "BTWT_Recommendation");
10183 if (val) {
10184 bcast_twt_recommdn = atoi(val);
10185 bcast_twt = 1;
10186 }
10187
10188 if (bcast_twt)
10189 sigma_dut_print(dut, DUT_MSG_DEBUG,
10190 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
10191 bcast_twt_id, bcast_twt_recommdn,
10192 bcast_twt_persis);
10193
Arif Hussain480d5f42019-03-12 14:40:42 -070010194 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10195 NL80211_CMD_VENDOR)) ||
10196 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10197 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10198 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010199 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010200 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010201 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10202 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010203 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010204 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010205 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
10206 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010207 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010208 (twt_trigger &&
10209 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010210 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
10211 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010212 (protection &&
10213 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010214 (bcast_twt &&
10215 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10216 (bcast_twt &&
10217 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10218 bcast_twt_id)) ||
10219 (bcast_twt &&
10220 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
10221 bcast_twt_persis)) ||
10222 (bcast_twt &&
10223 nla_put_u8(msg,
10224 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
10225 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010226 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
10227 target_wake_time) ||
10228 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
10229 nominal_min_wake_dur) ||
10230 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
10231 wake_interval_mantissa)) {
10232 sigma_dut_print(dut, DUT_MSG_ERROR,
10233 "%s: err in adding vendor_cmd and vendor_data",
10234 __func__);
10235 nlmsg_free(msg);
10236 return -1;
10237 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010238 nla_nest_end(msg, params);
10239 nla_nest_end(msg, attr);
10240
10241 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10242 if (ret) {
10243 sigma_dut_print(dut, DUT_MSG_ERROR,
10244 "%s: err in send_and_recv_msgs, ret=%d",
10245 __func__, ret);
10246 }
10247
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010248 if (!dut->sta_async_twt_supp)
10249 return ret;
10250
10251 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -070010252#else /* NL80211_SUPPORT */
10253 sigma_dut_print(dut, DUT_MSG_ERROR,
10254 "TWT request cannot be done without NL80211_SUPPORT defined");
10255 return -1;
10256#endif /* NL80211_SUPPORT */
10257}
10258
10259
10260static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
10261 struct sigma_cmd *cmd)
10262{
10263 #ifdef NL80211_SUPPORT
10264 struct nlattr *params;
10265 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010266 int ifindex, ret;
10267 struct nl_msg *msg;
10268 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010269 int bcast_twt = 0;
10270 int bcast_twt_id = 0;
10271 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -070010272
10273 ifindex = if_nametoindex(intf);
10274 if (ifindex == 0) {
10275 sigma_dut_print(dut, DUT_MSG_ERROR,
10276 "%s: Index for interface %s failed",
10277 __func__, intf);
10278 return -1;
10279 }
10280
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010281 val = get_param(cmd, "BTWT_ID");
10282 if (val) {
10283 bcast_twt_id = atoi(val);
10284 bcast_twt = 1;
10285 }
10286
Arif Hussain480d5f42019-03-12 14:40:42 -070010287 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10288 NL80211_CMD_VENDOR)) ||
10289 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10290 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10291 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010292 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010293 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010294 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10295 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010296 !(params = nla_nest_start(
10297 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010298 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010299 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
10300 (bcast_twt &&
10301 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10302 (bcast_twt &&
10303 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10304 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -070010305 sigma_dut_print(dut, DUT_MSG_ERROR,
10306 "%s: err in adding vendor_cmd and vendor_data",
10307 __func__);
10308 nlmsg_free(msg);
10309 return -1;
10310 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010311 nla_nest_end(msg, params);
10312 nla_nest_end(msg, attr);
10313
10314 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10315 if (ret) {
10316 sigma_dut_print(dut, DUT_MSG_ERROR,
10317 "%s: err in send_and_recv_msgs, ret=%d",
10318 __func__, ret);
10319 }
10320
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010321 if (!dut->sta_async_twt_supp)
10322 return ret;
10323
10324 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -070010325#else /* NL80211_SUPPORT */
10326 sigma_dut_print(dut, DUT_MSG_ERROR,
10327 "TWT teardown cannot be done without NL80211_SUPPORT defined");
10328 return -1;
10329#endif /* NL80211_SUPPORT */
10330}
10331
10332
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080010333static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
10334 struct sigma_cmd *cmd)
10335{
10336#ifdef NL80211_SUPPORT
10337 struct nlattr *params;
10338 struct nlattr *attr;
10339 struct nlattr *attr1;
10340 struct nl_msg *msg;
10341 int ifindex, ret;
10342 const char *val;
10343 const char *intf = get_param(cmd, "Interface");
10344 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
10345 ulmu_data_dis = 0;
10346
10347 ifindex = if_nametoindex(intf);
10348 if (ifindex == 0) {
10349 sigma_dut_print(dut, DUT_MSG_ERROR,
10350 "%s: Index for interface %s failed",
10351 __func__, intf);
10352 return -1;
10353 }
10354 val = get_param(cmd, "OMCtrl_RxNSS");
10355 if (val)
10356 rx_nss = atoi(val);
10357
10358 val = get_param(cmd, "OMCtrl_ChnlWidth");
10359 if (val)
10360 ch_bw = atoi(val);
10361
10362 val = get_param(cmd, "OMCtrl_ULMUDisable");
10363 if (val)
10364 ulmu_dis = atoi(val);
10365
10366 val = get_param(cmd, "OMCtrl_TxNSTS");
10367 if (val)
10368 tx_nsts = atoi(val);
10369
10370 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
10371 if (val)
10372 ulmu_data_dis = atoi(val);
10373
10374 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10375 NL80211_CMD_VENDOR)) ||
10376 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10377 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10378 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10379 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10380 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10381 !(params = nla_nest_start(
10382 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
10383 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10384 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
10385 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
10386 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
10387 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
10388 ulmu_data_dis) ||
10389 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
10390 ulmu_dis)) {
10391 sigma_dut_print(dut, DUT_MSG_ERROR,
10392 "%s: err in adding vendor_cmd and vendor_data",
10393 __func__);
10394 nlmsg_free(msg);
10395 return -1;
10396 }
10397 nla_nest_end(msg, attr1);
10398 nla_nest_end(msg, params);
10399 nla_nest_end(msg, attr);
10400
10401 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10402 if (ret) {
10403 sigma_dut_print(dut, DUT_MSG_ERROR,
10404 "%s: err in send_and_recv_msgs, ret=%d",
10405 __func__, ret);
10406 }
10407
10408 return ret;
10409#else /* NL80211_SUPPORT */
10410 sigma_dut_print(dut, DUT_MSG_ERROR,
10411 "OMI TX cannot be processed without NL80211_SUPPORT defined");
10412 return -1;
10413#endif /* NL80211_SUPPORT */
10414}
10415
10416
Jouni Malinen224e3902021-06-09 16:41:27 +030010417static enum sigma_cmd_result
10418cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10419 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010420{
10421 const char *intf = get_param(cmd, "Interface");
10422 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -070010423 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010424 int tkip = -1;
10425 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010426 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010427
Arif Hussaina37e9552018-06-20 17:05:59 -070010428 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010429 val = get_param(cmd, "SGI80");
10430 if (val) {
10431 int sgi80;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010432 enum nl80211_txrate_gi gi_val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010433
10434 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010435 if (sgi80)
10436 gi_val = NL80211_TXRATE_FORCE_LGI;
10437 else
10438 gi_val = NL80211_TXRATE_FORCE_SGI;
10439 if (sta_set_vht_gi(dut, intf, (u8) gi_val)) {
10440 sigma_dut_print(dut, DUT_MSG_INFO,
10441 "sta_set_vht_gi failed, using iwpriv");
10442 run_iwpriv(dut, intf, "shortgi %d", sgi80);
10443 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010444 }
10445
10446 val = get_param(cmd, "TxBF");
10447 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010448 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010449 case DRIVER_WCN:
10450 if (sta_set_tx_beamformee(dut, intf, 1)) {
10451 send_resp(dut, conn, SIGMA_ERROR,
10452 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010453 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010454 }
10455 break;
10456 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010457 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010458 send_resp(dut, conn, SIGMA_ERROR,
10459 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010460 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010461 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010462 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010463 send_resp(dut, conn, SIGMA_ERROR,
10464 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010465 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010466 }
10467 break;
10468 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010469 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010470 "Unsupported driver type");
10471 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010472 }
10473 }
10474
10475 val = get_param(cmd, "MU_TxBF");
10476 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010477 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010478 case DRIVER_ATHEROS:
10479 ath_sta_set_txsp_stream(dut, intf, "1SS");
10480 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010481 run_iwpriv(dut, intf, "vhtmubfee 1");
10482 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +053010483 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010484 case DRIVER_WCN:
10485 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
10486 send_resp(dut, conn, SIGMA_ERROR,
10487 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +030010488 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010489 }
Sunil Duttae9e5d12018-06-29 11:50:47 +053010490 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010491 default:
10492 sigma_dut_print(dut, DUT_MSG_ERROR,
10493 "Setting SP_STREAM not supported");
10494 break;
10495 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010496 }
10497
10498 val = get_param(cmd, "LDPC");
10499 if (val) {
10500 int ldpc;
10501
10502 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010503 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
10504 if (iwpriv_status)
10505 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010506 }
10507
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010508 val = get_param(cmd, "BCC");
10509 if (val) {
10510 int bcc;
10511
10512 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10513 /* use LDPC iwpriv itself to set bcc coding, bcc coding
10514 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010515 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
10516 if (iwpriv_status)
10517 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010518 }
10519
Arif Hussain7b47d2d2018-05-09 10:44:02 -070010520 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
10521 if (val && dut->sta_nss == 1)
10522 cmd_set_max_he_mcs(dut, intf, atoi(val));
10523
10524 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
10525 if (val && dut->sta_nss == 2)
10526 cmd_set_max_he_mcs(dut, intf, atoi(val));
10527
Arif Hussainac6c5112018-05-25 17:34:00 -070010528 val = get_param(cmd, "MCS_FixedRate");
10529 if (val) {
10530#ifdef NL80211_SUPPORT
10531 int mcs, ratecode = 0;
10532 enum he_mcs_config mcs_config;
10533 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +030010534 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -070010535
10536 ratecode = (0x07 & dut->sta_nss) << 5;
10537 mcs = atoi(val);
10538 /* Add the MCS to the ratecode */
10539 if (mcs >= 0 && mcs <= 11) {
10540 ratecode += mcs;
10541 if (dut->device_type == STA_testbed &&
10542 mcs > 7 && mcs <= 11) {
10543 if (mcs <= 9)
10544 mcs_config = HE_80_MCS0_9;
10545 else
10546 mcs_config = HE_80_MCS0_11;
10547 ret = sta_set_he_mcs(dut, intf, mcs_config);
10548 if (ret) {
10549 sigma_dut_print(dut, DUT_MSG_ERROR,
10550 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10551 mcs, mcs_config, ret);
10552 }
10553 }
10554 snprintf(buf, sizeof(buf),
10555 "iwpriv %s set_11ax_rate 0x%03x",
10556 intf, ratecode);
10557 if (system(buf) != 0) {
10558 sigma_dut_print(dut, DUT_MSG_ERROR,
10559 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
10560 ratecode);
10561 }
10562 } else {
10563 sigma_dut_print(dut, DUT_MSG_ERROR,
10564 "MCS_FixedRate: HE MCS %d not supported",
10565 mcs);
10566 }
10567#else /* NL80211_SUPPORT */
10568 sigma_dut_print(dut, DUT_MSG_ERROR,
10569 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
10570#endif /* NL80211_SUPPORT */
10571 }
10572
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010573 val = get_param(cmd, "opt_md_notif_ie");
10574 if (val) {
10575 char *result = NULL;
10576 char delim[] = ";";
10577 char token[30];
10578 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010579 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010580
Peng Xub8fc5cc2017-05-10 17:27:28 -070010581 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010582 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010583
10584 /* Extract the NSS information */
10585 if (result) {
10586 value = atoi(result);
10587 switch (value) {
10588 case 1:
10589 config_val = 1;
10590 break;
10591 case 2:
10592 config_val = 3;
10593 break;
10594 case 3:
10595 config_val = 7;
10596 break;
10597 case 4:
10598 config_val = 15;
10599 break;
10600 default:
10601 config_val = 3;
10602 break;
10603 }
10604
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010605 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
10606 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010607
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010608 }
10609
10610 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010611 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010612 if (result) {
10613 value = atoi(result);
10614 switch (value) {
10615 case 20:
10616 config_val = 0;
10617 break;
10618 case 40:
10619 config_val = 1;
10620 break;
10621 case 80:
10622 config_val = 2;
10623 break;
10624 case 160:
10625 config_val = 3;
10626 break;
10627 default:
10628 config_val = 2;
10629 break;
10630 }
10631
10632 dut->chwidth = config_val;
10633
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010634 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010635 }
10636
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010637 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010638 }
10639
10640 val = get_param(cmd, "nss_mcs_cap");
10641 if (val) {
10642 int nss, mcs;
10643 char token[20];
10644 char *result = NULL;
10645 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010646 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010647
Peng Xub8fc5cc2017-05-10 17:27:28 -070010648 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010649 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010650 if (!result) {
10651 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010652 "NSS not specified");
10653 send_resp(dut, conn, SIGMA_ERROR,
10654 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010655 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010656 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010657 nss = atoi(result);
10658
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010659 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -070010660 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010661
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010662 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010663 if (result == NULL) {
10664 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010665 "MCS not specified");
10666 send_resp(dut, conn, SIGMA_ERROR,
10667 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010668 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010669 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010670 result = strtok_r(result, "-", &saveptr);
10671 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010672 if (!result) {
10673 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010674 "MCS not specified");
10675 send_resp(dut, conn, SIGMA_ERROR,
10676 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010677 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010678 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010679 mcs = atoi(result);
10680
Arif Hussaina37e9552018-06-20 17:05:59 -070010681 if (program && strcasecmp(program, "HE") == 0) {
10682#ifdef NL80211_SUPPORT
10683 enum he_mcs_config mcs_config;
10684 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010685
Arif Hussaina37e9552018-06-20 17:05:59 -070010686 if (mcs >= 0 && mcs <= 7) {
10687 mcs_config = HE_80_MCS0_7;
10688 } else if (mcs > 7 && mcs <= 9) {
10689 mcs_config = HE_80_MCS0_9;
10690 } else if (mcs > 9 && mcs <= 11) {
10691 mcs_config = HE_80_MCS0_11;
10692 } else {
10693 sigma_dut_print(dut, DUT_MSG_ERROR,
10694 "nss_mcs_cap: HE: Invalid mcs: %d",
10695 mcs);
10696 send_resp(dut, conn, SIGMA_ERROR,
10697 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010698 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010699 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010700
10701 ret = sta_set_he_mcs(dut, intf, mcs_config);
10702 if (ret) {
10703 sigma_dut_print(dut, DUT_MSG_ERROR,
10704 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
10705 mcs_config, ret);
10706 send_resp(dut, conn, SIGMA_ERROR,
10707 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010708 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010709 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010710#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010711 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010712 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
10713#endif /* NL80211_SUPPORT */
10714 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010715 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -070010716
10717 switch (nss) {
10718 case 1:
10719 switch (mcs) {
10720 case 7:
10721 vht_mcsmap = 0xfffc;
10722 break;
10723 case 8:
10724 vht_mcsmap = 0xfffd;
10725 break;
10726 case 9:
10727 vht_mcsmap = 0xfffe;
10728 break;
10729 default:
10730 vht_mcsmap = 0xfffe;
10731 break;
10732 }
10733 break;
10734 case 2:
10735 switch (mcs) {
10736 case 7:
10737 vht_mcsmap = 0xfff0;
10738 break;
10739 case 8:
10740 vht_mcsmap = 0xfff5;
10741 break;
10742 case 9:
10743 vht_mcsmap = 0xfffa;
10744 break;
10745 default:
10746 vht_mcsmap = 0xfffa;
10747 break;
10748 }
10749 break;
10750 case 3:
10751 switch (mcs) {
10752 case 7:
10753 vht_mcsmap = 0xffc0;
10754 break;
10755 case 8:
10756 vht_mcsmap = 0xffd5;
10757 break;
10758 case 9:
10759 vht_mcsmap = 0xffea;
10760 break;
10761 default:
10762 vht_mcsmap = 0xffea;
10763 break;
10764 }
10765 break;
10766 default:
10767 vht_mcsmap = 0xffea;
10768 break;
10769 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010770 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010771 }
10772 }
10773
10774 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
10775
10776 val = get_param(cmd, "Vht_tkip");
10777 if (val)
10778 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10779
10780 val = get_param(cmd, "Vht_wep");
10781 if (val)
10782 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10783
10784 if (tkip != -1 || wep != -1) {
10785 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010786 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010787 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010788 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010789 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +030010790 send_resp(dut, conn, SIGMA_ERROR,
10791 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
10792 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010793 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010794 }
10795
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -070010796 val = get_param(cmd, "TWTSchedSTASupport");
10797 if (val) {
10798 int set_val;
10799
10800 switch (get_driver_type(dut)) {
10801 case DRIVER_WCN:
10802 if (strcasecmp(val, "Enable") == 0) {
10803 set_val = 1;
10804 } else if (strcasecmp(val, "Disable") == 0) {
10805 set_val = 0;
10806 } else {
10807 send_resp(dut, conn, SIGMA_ERROR,
10808 "ErrorCode,Invalid TWTSchedSTASupport");
10809 return STATUS_SENT_ERROR;
10810 }
10811
10812 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
10813 send_resp(dut, conn, SIGMA_ERROR,
10814 "ErrorCode,Failed to set TWTSchedSTASupport");
10815 return STATUS_SENT_ERROR;
10816 }
10817 break;
10818 default:
10819 sigma_dut_print(dut, DUT_MSG_ERROR,
10820 "Setting TWTSchedSTASupport not supported");
10821 break;
10822 }
10823 }
10824
10825 val = get_param(cmd, "MBSSID_RxCtrl");
10826 if (val) {
10827 int set_val;
10828
10829 switch (get_driver_type(dut)) {
10830 case DRIVER_WCN:
10831 if (strcasecmp(val, "Enable") == 0) {
10832 set_val = 1;
10833 } else if (strcasecmp(val, "Disable") == 0) {
10834 set_val = 0;
10835 } else {
10836 send_resp(dut, conn, SIGMA_ERROR,
10837 "ErrorCode,Invalid MBSSID_RxCtrl");
10838 return STATUS_SENT_ERROR;
10839 }
10840
10841 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
10842 send_resp(dut, conn, SIGMA_ERROR,
10843 "ErrorCode,Failed to set MBSSID_RxCtrl");
10844 return STATUS_SENT_ERROR;
10845 }
10846 break;
10847 default:
10848 sigma_dut_print(dut, DUT_MSG_ERROR,
10849 "Setting MBSSID_RxCtrl not supported");
10850 break;
10851 }
10852 }
10853
Arif Hussain55f00da2018-07-03 08:28:26 -070010854 val = get_param(cmd, "txBandwidth");
10855 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010856 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -070010857 case DRIVER_WCN:
10858 if (wcn_sta_set_width(dut, intf, val) < 0) {
10859 send_resp(dut, conn, SIGMA_ERROR,
10860 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010861 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010862 }
10863 break;
10864 case DRIVER_ATHEROS:
10865 if (ath_set_width(dut, conn, intf, val) < 0) {
10866 send_resp(dut, conn, SIGMA_ERROR,
10867 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010868 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010869 }
10870 break;
10871 default:
10872 sigma_dut_print(dut, DUT_MSG_ERROR,
10873 "Setting txBandwidth not supported");
10874 break;
10875 }
10876 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010877
Arif Hussain9765f7d2018-07-03 08:28:26 -070010878 val = get_param(cmd, "BeamformeeSTS");
10879 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010880 if (sta_set_tx_beamformee(dut, intf, 1)) {
10881 send_resp(dut, conn, SIGMA_ERROR,
10882 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010883 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010884 }
10885
Arif Hussain9765f7d2018-07-03 08:28:26 -070010886 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
10887 send_resp(dut, conn, SIGMA_ERROR,
10888 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010889 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -070010890 }
10891 }
10892
Arif Hussain68d23f52018-07-11 13:39:08 -070010893 val = get_param(cmd, "Trig_MAC_Padding_Dur");
10894 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010895#ifdef NL80211_SUPPORT
10896 enum qca_wlan_he_mac_padding_dur set_val;
10897
10898 switch (atoi(val)) {
10899 case 16:
10900 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
10901 break;
10902 case 8:
10903 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
10904 break;
10905 default:
10906 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
10907 break;
10908 }
10909 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -070010910 send_resp(dut, conn, SIGMA_ERROR,
10911 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +030010912 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -070010913 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010914#else /* NL80211_SUPPORT */
10915 sigma_dut_print(dut, DUT_MSG_ERROR,
10916 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
10917#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -070010918 }
10919
Arif Hussain480d5f42019-03-12 14:40:42 -070010920 val = get_param(cmd, "TWT_ReqSupport");
10921 if (val) {
10922 int set_val;
10923
10924 if (strcasecmp(val, "Enable") == 0) {
10925 set_val = 1;
10926 } else if (strcasecmp(val, "Disable") == 0) {
10927 set_val = 0;
10928 } else {
10929 send_resp(dut, conn, SIGMA_ERROR,
10930 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010931 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010932 }
10933
10934 if (sta_set_twt_req_support(dut, intf, set_val)) {
10935 sigma_dut_print(dut, DUT_MSG_ERROR,
10936 "Failed to set TWT req support %d",
10937 set_val);
10938 send_resp(dut, conn, SIGMA_ERROR,
10939 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010940 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010941 }
10942 }
10943
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -070010944 val = get_param(cmd, "PreamblePunctRx");
10945 if (val && get_driver_type(dut) == DRIVER_WCN) {
10946 int set_val;
10947
10948 if (strcasecmp(val, "Enable") == 0) {
10949 set_val = 1;
10950 } else if (strcasecmp(val, "Disable") == 0) {
10951 set_val = 0;
10952 } else {
10953 send_resp(dut, conn, SIGMA_ERROR,
10954 "ErrorCode,Invalid PreamblePunctRx");
10955 return STATUS_SENT_ERROR;
10956 }
10957
10958 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
10959 sigma_dut_print(dut, DUT_MSG_ERROR,
10960 "Failed to set PreamblePunctRx support %d",
10961 set_val);
10962 send_resp(dut, conn, SIGMA_ERROR,
10963 "ErrorCode,Failed to set PreamblePunctRx");
10964 return STATUS_SENT_ERROR;
10965 }
10966 }
10967
Srinivas Girigowda0525e292020-11-12 13:28:21 -080010968 val = get_param(cmd, "FullBW_ULMUMIMO");
10969 if (val) {
10970 int set_val;
10971
10972 if (strcasecmp(val, "Enable") == 0) {
10973 set_val = 1;
10974 } else if (strcasecmp(val, "Disable") == 0) {
10975 set_val = 0;
10976 } else {
10977 send_resp(dut, conn, SIGMA_ERROR,
10978 "ErrorCode,Invalid FullBW_ULMUMIMO");
10979 return STATUS_SENT_ERROR;
10980 }
10981
10982 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
10983 sigma_dut_print(dut, DUT_MSG_ERROR,
10984 "Failed to set FullBW_ULMUMIMO %d",
10985 set_val);
10986 send_resp(dut, conn, SIGMA_ERROR,
10987 "ErrorCode,Failed to set FullBW_ULMUMIMO");
10988 return STATUS_SENT_ERROR;
10989 }
10990 }
10991
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010992 val = get_param(cmd, "TWTInfoFrameTx");
10993 if (val) {
10994 if (strcasecmp(val, "Enable") == 0) {
10995 /* No-op */
10996 } else if (strcasecmp(val, "Disable") == 0) {
10997 /* No-op */
10998 } else {
10999 send_resp(dut, conn, SIGMA_ERROR,
11000 "ErrorCode,Invalid TWTInfoFrameTx");
11001 return STATUS_SENT_ERROR;
11002 }
11003 }
11004
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011005 val = get_param(cmd, "MU_EDCA");
11006 if (val && (strcasecmp(val, "Override") == 0)) {
11007 if (sta_set_mu_edca_override(dut, intf, 1)) {
11008 send_resp(dut, conn, SIGMA_ERROR,
11009 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +030011010 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011011 }
11012 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011013
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070011014 val = get_param(cmd, "PPDUTxType");
11015 if (val && strcasecmp(val, "ER-SU") == 0) {
11016 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
11017 send_resp(dut, conn, SIGMA_ERROR,
11018 "ErrorCode,Failed to set ER-SU PPDU type Tx");
11019 return STATUS_SENT_ERROR;
11020 }
11021 }
11022
11023 val = get_param(cmd, "RUAllocTone");
11024 if (val && strcasecmp(val, "242") == 0) {
11025 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
11026 send_resp(dut, conn, SIGMA_ERROR,
11027 "ErrorCode,Failed to set RU 242 tone Tx");
11028 return STATUS_SENT_ERROR;
11029 }
11030 }
11031
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011032 val = get_param(cmd, "OMControl");
11033 if (val) {
11034 int set_val = 1;
11035
11036 if (strcasecmp(val, "Enable") == 0)
11037 set_val = 1;
11038 else if (strcasecmp(val, "Disable") == 0)
11039 set_val = 0;
11040
11041 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
11042 send_resp(dut, conn, SIGMA_ERROR,
11043 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +030011044 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011045 }
11046 }
11047
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -070011048 val = get_param(cmd, "BSSMaxIdlePeriod");
11049 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
11050 send_resp(dut, conn, SIGMA_ERROR,
11051 "ErrorCode,Failed to set BSS max idle period");
11052 return STATUS_SENT_ERROR;
11053 }
11054
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -070011055 val = get_param(cmd, "BSS_max_idle");
11056 if (val) {
11057 int set_val = 0;
11058
11059 if (strcasecmp(val, "Enable") == 0)
11060 set_val = 1;
11061 else if (strcasecmp(val, "Disable") == 0)
11062 set_val = 0;
11063 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
11064 send_resp(dut, conn, SIGMA_ERROR,
11065 "ErrorCode,Failed to set BSS max idle support");
11066 return STATUS_SENT_ERROR;
11067 }
11068 }
11069
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011070 val = get_param(cmd, "ADDBAResp_BufSize");
11071 if (val) {
11072 int buf_size;
11073
11074 if (strcasecmp(val, "gt64") == 0)
11075 buf_size = 256;
11076 else
11077 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011078 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011079 sta_set_addba_buf_size(dut, intf, buf_size)) {
11080 send_resp(dut, conn, SIGMA_ERROR,
11081 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011082 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011083 }
11084 }
11085
11086 val = get_param(cmd, "ADDBAReq_BufSize");
11087 if (val) {
11088 int buf_size;
11089
11090 if (strcasecmp(val, "gt64") == 0)
11091 buf_size = 256;
11092 else
11093 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011094 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011095 sta_set_addba_buf_size(dut, intf, buf_size)) {
11096 send_resp(dut, conn, SIGMA_ERROR,
11097 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011098 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011099 }
11100 }
11101
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011102 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11103}
11104
11105
11106static int sta_set_wireless_60g(struct sigma_dut *dut,
11107 struct sigma_conn *conn,
11108 struct sigma_cmd *cmd)
11109{
11110 const char *dev_role = get_param(cmd, "DevRole");
11111
11112 if (!dev_role) {
11113 send_resp(dut, conn, SIGMA_INVALID,
11114 "ErrorCode,DevRole not specified");
11115 return 0;
11116 }
11117
11118 if (strcasecmp(dev_role, "PCP") == 0)
11119 return sta_set_60g_pcp(dut, conn, cmd);
11120 if (strcasecmp(dev_role, "STA") == 0)
11121 return sta_set_60g_sta(dut, conn, cmd);
11122 send_resp(dut, conn, SIGMA_INVALID,
11123 "ErrorCode,DevRole not supported");
11124 return 0;
11125}
11126
11127
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011128static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
11129 struct sigma_cmd *cmd)
11130{
11131 int status;
11132 const char *intf = get_param(cmd, "Interface");
11133 const char *val = get_param(cmd, "DevRole");
11134
11135 if (val && strcasecmp(val, "STA-CFON") == 0) {
11136 status = sta_cfon_set_wireless(dut, conn, cmd);
11137 if (status)
11138 return status;
11139 }
11140 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11141}
11142
11143
Jouni Malinen67433fc2020-06-26 22:50:33 +030011144static enum sigma_cmd_result
11145sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
11146 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011147{
11148 const char *intf = get_param(cmd, "Interface");
11149 const char *val;
11150
11151 val = get_param(cmd, "ocvc");
11152 if (val)
11153 dut->ocvc = atoi(val);
11154
Jouni Malinen67433fc2020-06-26 22:50:33 +030011155 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +053011156 if (val && dut->client_privacy != atoi(val) &&
11157 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
11158 send_resp(dut, conn, SIGMA_ERROR,
11159 "errorCode,Failed to configure random MAC address use");
11160 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +030011161 }
11162
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011163 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11164}
11165
11166
Jouni Malinenf7222712019-06-13 01:50:21 +030011167static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
11168 struct sigma_conn *conn,
11169 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011170{
11171 const char *val;
11172
11173 val = get_param(cmd, "Program");
11174 if (val) {
11175 if (strcasecmp(val, "11n") == 0)
11176 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080011177 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011178 return cmd_sta_set_wireless_vht(dut, conn, cmd);
11179 if (strcasecmp(val, "60ghz") == 0)
11180 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011181 if (strcasecmp(val, "OCE") == 0)
11182 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020011183 /* sta_set_wireless in WPS program is only used for 60G */
11184 if (is_60g_sigma_dut(dut))
11185 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011186 if (strcasecmp(val, "WPA3") == 0)
11187 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011188 send_resp(dut, conn, SIGMA_ERROR,
11189 "ErrorCode,Program value not supported");
11190 } else {
11191 send_resp(dut, conn, SIGMA_ERROR,
11192 "ErrorCode,Program argument not available");
11193 }
11194
11195 return 0;
11196}
11197
11198
11199static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
11200 int tid)
11201{
11202 char buf[100];
11203 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
11204
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053011205 if (tid < 0 ||
11206 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
11207 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
11208 return;
11209 }
11210
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011211 /*
11212 * Two ways to ensure that addba request with a
11213 * non zero TID could be sent out. EV 117296
11214 */
11215 snprintf(buf, sizeof(buf),
11216 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
11217 tid);
11218 if (system(buf) != 0) {
11219 sigma_dut_print(dut, DUT_MSG_ERROR,
11220 "Ping did not send out");
11221 }
11222
11223 snprintf(buf, sizeof(buf),
11224 "iwconfig %s | grep Access | awk '{print $6}' > %s",
11225 intf, VI_QOS_TMP_FILE);
11226 if (system(buf) != 0)
11227 return;
11228
11229 snprintf(buf, sizeof(buf),
11230 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
11231 intf, VI_QOS_TMP_FILE);
11232 if (system(buf) != 0)
11233 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
11234
11235 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
11236 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
11237 if (system(buf) != 0) {
11238 sigma_dut_print(dut, DUT_MSG_ERROR,
11239 "VI_QOS_TEMP_FILE generation error failed");
11240 }
11241 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11242 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11243 if (system(buf) != 0) {
11244 sigma_dut_print(dut, DUT_MSG_ERROR,
11245 "VI_QOS_FILE generation failed");
11246 }
11247
11248 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11249 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11250 if (system(buf) != 0) {
11251 sigma_dut_print(dut, DUT_MSG_ERROR,
11252 "VI_QOS_FILE generation failed");
11253 }
11254
11255 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
11256 if (system(buf) != 0) {
11257 }
11258}
11259
11260
11261static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11262 struct sigma_cmd *cmd)
11263{
11264 const char *intf = get_param(cmd, "Interface");
11265 const char *val;
11266 int tid = 0;
11267 char buf[100];
11268
11269 val = get_param(cmd, "TID");
11270 if (val) {
11271 tid = atoi(val);
11272 if (tid)
11273 ath_sta_inject_frame(dut, intf, tid);
11274 }
11275
11276 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011277 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011278
11279 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
11280 if (system(buf) != 0) {
11281 sigma_dut_print(dut, DUT_MSG_ERROR,
11282 "wifitool senddelba failed");
11283 }
11284
11285 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
11286 if (system(buf) != 0) {
11287 sigma_dut_print(dut, DUT_MSG_ERROR,
11288 "wifitool sendaddba failed");
11289 }
11290
11291 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11292
11293 return 1;
11294}
11295
11296
Lior David9981b512017-01-20 13:16:40 +020011297#ifdef __linux__
11298
11299static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
11300 int agg_size)
11301{
11302 char dir[128], buf[128];
11303 FILE *f;
11304 regex_t re;
11305 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030011306 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020011307
11308 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
11309 sigma_dut_print(dut, DUT_MSG_ERROR,
11310 "failed to get wil6210 debugfs dir");
11311 return -1;
11312 }
11313
Jouni Malinen3aa72862019-05-29 23:14:51 +030011314 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
11315 if (res < 0 || res >= sizeof(buf))
11316 return -1;
Lior David9981b512017-01-20 13:16:40 +020011317 f = fopen(buf, "r");
11318 if (!f) {
11319 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011320 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030011321 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
11322 if (res < 0 || res >= sizeof(buf))
11323 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011324 f = fopen(buf, "r");
11325 if (!f) {
11326 sigma_dut_print(dut, DUT_MSG_ERROR,
11327 "failed to open: %s", buf);
11328 return -1;
11329 }
Lior David9981b512017-01-20 13:16:40 +020011330 }
11331
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011332 /* can be either VRING tx... or RING... */
11333 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020011334 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
11335 goto out;
11336 }
11337
11338 /* find TX VRING for the mac address */
11339 found = 0;
11340 while (fgets(buf, sizeof(buf), f)) {
11341 if (strcasestr(buf, dest_mac)) {
11342 found = 1;
11343 break;
11344 }
11345 }
11346
11347 if (!found) {
11348 sigma_dut_print(dut, DUT_MSG_ERROR,
11349 "no TX VRING for %s", dest_mac);
11350 goto out;
11351 }
11352
11353 /* extract VRING ID, "VRING tx_<id> = {" */
11354 if (!fgets(buf, sizeof(buf), f)) {
11355 sigma_dut_print(dut, DUT_MSG_ERROR,
11356 "no VRING start line for %s", dest_mac);
11357 goto out;
11358 }
11359
11360 rc = regexec(&re, buf, 2, m, 0);
11361 regfree(&re);
11362 if (rc || m[1].rm_so < 0) {
11363 sigma_dut_print(dut, DUT_MSG_ERROR,
11364 "no VRING TX ID for %s", dest_mac);
11365 goto out;
11366 }
11367 buf[m[1].rm_eo] = 0;
11368 vring_id = atoi(&buf[m[1].rm_so]);
11369
11370 /* send the addba command */
11371 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011372 res = snprintf(buf, sizeof(buf), "%s/back", dir);
11373 if (res < 0 || res >= sizeof(buf))
11374 return -1;
Lior David9981b512017-01-20 13:16:40 +020011375 f = fopen(buf, "w");
11376 if (!f) {
11377 sigma_dut_print(dut, DUT_MSG_ERROR,
11378 "failed to open: %s", buf);
11379 return -1;
11380 }
11381
11382 fprintf(f, "add %d %d\n", vring_id, agg_size);
11383
11384 ret = 0;
11385
11386out:
11387 fclose(f);
11388
11389 return ret;
11390}
11391
11392
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011393int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11394 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011395{
11396 const char *val;
11397 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011398
11399 val = get_param(cmd, "TID");
11400 if (val) {
11401 tid = atoi(val);
11402 if (tid != 0) {
11403 sigma_dut_print(dut, DUT_MSG_ERROR,
11404 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
11405 tid);
11406 }
11407 }
11408
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011409 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011410 if (!val) {
11411 sigma_dut_print(dut, DUT_MSG_ERROR,
11412 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011413 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011414 }
11415
Lior David9981b512017-01-20 13:16:40 +020011416 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011417 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011418
11419 return 1;
11420}
11421
Lior David9981b512017-01-20 13:16:40 +020011422#endif /* __linux__ */
11423
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011424
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011425static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11426 struct sigma_cmd *cmd)
11427{
11428#ifdef NL80211_SUPPORT
11429 const char *intf = get_param(cmd, "Interface");
11430 const char *val;
11431 int tid = -1;
11432 int bufsize = 64;
11433 struct nl_msg *msg;
11434 int ret = 0;
11435 struct nlattr *params;
11436 int ifindex;
11437
11438 val = get_param(cmd, "TID");
11439 if (val)
11440 tid = atoi(val);
11441
11442 if (tid == -1) {
11443 send_resp(dut, conn, SIGMA_ERROR,
11444 "ErrorCode,sta_send_addba tid invalid");
11445 return 0;
11446 }
11447
11448 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11449
11450 ifindex = if_nametoindex(intf);
11451 if (ifindex == 0) {
11452 sigma_dut_print(dut, DUT_MSG_ERROR,
11453 "%s: Index for interface %s failed",
11454 __func__, intf);
11455 send_resp(dut, conn, SIGMA_ERROR,
11456 "ErrorCode,sta_send_addba interface invalid");
11457 return 0;
11458 }
11459
11460 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11461 NL80211_CMD_VENDOR)) ||
11462 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
11463 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
11464 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
11465 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
11466 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
11467 nla_put_u8(msg,
11468 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
11469 QCA_WLAN_ADD_BA) ||
11470 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
11471 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070011472 nla_put_u16(msg,
11473 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
11474 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011475 sigma_dut_print(dut, DUT_MSG_ERROR,
11476 "%s: err in adding vendor_cmd and vendor_data",
11477 __func__);
11478 nlmsg_free(msg);
11479 send_resp(dut, conn, SIGMA_ERROR,
11480 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
11481 return 0;
11482 }
11483 nla_nest_end(msg, params);
11484
11485 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11486 if (ret) {
11487 sigma_dut_print(dut, DUT_MSG_ERROR,
11488 "%s: err in send_and_recv_msgs, ret=%d",
11489 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053011490 if (ret == -EOPNOTSUPP)
11491 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011492 send_resp(dut, conn, SIGMA_ERROR,
11493 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
11494 return 0;
11495 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011496#else /* NL80211_SUPPORT */
11497 sigma_dut_print(dut, DUT_MSG_ERROR,
11498 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011499#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053011500
11501 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011502}
11503
11504
Jouni Malinenf7222712019-06-13 01:50:21 +030011505static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
11506 struct sigma_conn *conn,
11507 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011508{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011509 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011510 case DRIVER_ATHEROS:
11511 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011512 case DRIVER_WCN:
11513 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020011514#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011515 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011516 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020011517#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011518 default:
11519 /*
11520 * There is no driver specific implementation for other drivers.
11521 * Ignore the command and report COMPLETE since the following
11522 * throughput test operation will end up sending ADDBA anyway.
11523 */
11524 return 1;
11525 }
11526}
11527
11528
11529int inject_eth_frame(int s, const void *data, size_t len,
11530 unsigned short ethtype, char *dst, char *src)
11531{
11532 struct iovec iov[4] = {
11533 {
11534 .iov_base = dst,
11535 .iov_len = ETH_ALEN,
11536 },
11537 {
11538 .iov_base = src,
11539 .iov_len = ETH_ALEN,
11540 },
11541 {
11542 .iov_base = &ethtype,
11543 .iov_len = sizeof(unsigned short),
11544 },
11545 {
11546 .iov_base = (void *) data,
11547 .iov_len = len,
11548 }
11549 };
11550 struct msghdr msg = {
11551 .msg_name = NULL,
11552 .msg_namelen = 0,
11553 .msg_iov = iov,
11554 .msg_iovlen = 4,
11555 .msg_control = NULL,
11556 .msg_controllen = 0,
11557 .msg_flags = 0,
11558 };
11559
11560 return sendmsg(s, &msg, 0);
11561}
11562
11563#if defined(__linux__) || defined(__QNXNTO__)
11564
11565int inject_frame(int s, const void *data, size_t len, int encrypt)
11566{
11567#define IEEE80211_RADIOTAP_F_WEP 0x04
11568#define IEEE80211_RADIOTAP_F_FRAG 0x08
11569 unsigned char rtap_hdr[] = {
11570 0x00, 0x00, /* radiotap version */
11571 0x0e, 0x00, /* radiotap length */
11572 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
11573 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
11574 0x00, /* padding */
11575 0x00, 0x00, /* RX and TX flags to indicate that */
11576 0x00, 0x00, /* this is the injected frame directly */
11577 };
11578 struct iovec iov[2] = {
11579 {
11580 .iov_base = &rtap_hdr,
11581 .iov_len = sizeof(rtap_hdr),
11582 },
11583 {
11584 .iov_base = (void *) data,
11585 .iov_len = len,
11586 }
11587 };
11588 struct msghdr msg = {
11589 .msg_name = NULL,
11590 .msg_namelen = 0,
11591 .msg_iov = iov,
11592 .msg_iovlen = 2,
11593 .msg_control = NULL,
11594 .msg_controllen = 0,
11595 .msg_flags = 0,
11596 };
11597
11598 if (encrypt)
11599 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
11600
11601 return sendmsg(s, &msg, 0);
11602}
11603
11604
11605int open_monitor(const char *ifname)
11606{
11607#ifdef __QNXNTO__
11608 struct sockaddr_dl ll;
11609 int s;
11610
11611 memset(&ll, 0, sizeof(ll));
11612 ll.sdl_family = AF_LINK;
11613 ll.sdl_index = if_nametoindex(ifname);
11614 if (ll.sdl_index == 0) {
11615 perror("if_nametoindex");
11616 return -1;
11617 }
11618 s = socket(PF_INET, SOCK_RAW, 0);
11619#else /* __QNXNTO__ */
11620 struct sockaddr_ll ll;
11621 int s;
11622
11623 memset(&ll, 0, sizeof(ll));
11624 ll.sll_family = AF_PACKET;
11625 ll.sll_ifindex = if_nametoindex(ifname);
11626 if (ll.sll_ifindex == 0) {
11627 perror("if_nametoindex");
11628 return -1;
11629 }
11630 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
11631#endif /* __QNXNTO__ */
11632 if (s < 0) {
11633 perror("socket[PF_PACKET,SOCK_RAW]");
11634 return -1;
11635 }
11636
11637 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
11638 perror("monitor socket bind");
11639 close(s);
11640 return -1;
11641 }
11642
11643 return s;
11644}
11645
11646
11647static int hex2num(char c)
11648{
11649 if (c >= '0' && c <= '9')
11650 return c - '0';
11651 if (c >= 'a' && c <= 'f')
11652 return c - 'a' + 10;
11653 if (c >= 'A' && c <= 'F')
11654 return c - 'A' + 10;
11655 return -1;
11656}
11657
11658
11659int hwaddr_aton(const char *txt, unsigned char *addr)
11660{
11661 int i;
11662
11663 for (i = 0; i < 6; i++) {
11664 int a, b;
11665
11666 a = hex2num(*txt++);
11667 if (a < 0)
11668 return -1;
11669 b = hex2num(*txt++);
11670 if (b < 0)
11671 return -1;
11672 *addr++ = (a << 4) | b;
11673 if (i < 5 && *txt++ != ':')
11674 return -1;
11675 }
11676
11677 return 0;
11678}
11679
11680#endif /* defined(__linux__) || defined(__QNXNTO__) */
11681
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011682
11683#ifdef NL80211_SUPPORT
11684static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
11685 const u8 *data, size_t data_len, int freq)
11686{
11687 struct nl_msg *msg;
11688 int ret = 0;
11689 int ifindex;
11690
11691 ifindex = if_nametoindex(intf);
11692 if (ifindex == 0) {
11693 sigma_dut_print(dut, DUT_MSG_ERROR,
11694 "%s: Index for interface %s failed",
11695 __func__, intf);
11696 return -1;
11697 }
11698
11699 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11700 NL80211_CMD_FRAME)) ||
11701 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11702 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
11703 sigma_dut_print(dut, DUT_MSG_ERROR,
11704 "%s: Error in adding NL80211_CMD_FRAME",
11705 __func__);
11706 nlmsg_free(msg);
11707 return -1;
11708 }
11709
11710 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11711 if (ret) {
11712 sigma_dut_print(dut, DUT_MSG_ERROR,
11713 "nl80211: Frame command failed: ret=%d (%s) req=%u",
11714 ret, strerror(-ret), freq);
11715 return -1;
11716 }
11717
11718 return 0;
11719}
11720#endif /* NL80211_SUPPORT */
11721
11722
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011723enum send_frame_type {
11724 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
11725};
11726enum send_frame_protection {
11727 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
11728};
11729
11730
11731static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011732 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011733 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011734 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011735{
11736#ifdef __linux__
11737 unsigned char buf[1000], *pos;
11738 int s, res;
11739 char bssid[20], addr[20];
11740 char result[32], ssid[100];
11741 size_t ssid_len;
11742
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011743 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011744 sizeof(result)) < 0 ||
11745 strncmp(result, "COMPLETED", 9) != 0) {
11746 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
11747 return 0;
11748 }
11749
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011750 if (get_wpa_status(get_station_ifname(dut), "bssid",
11751 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011752 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11753 "current BSSID");
11754 return 0;
11755 }
11756
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011757 if (get_wpa_status(get_station_ifname(dut), "address",
11758 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011759 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11760 "own MAC address");
11761 return 0;
11762 }
11763
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011764 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011765 < 0) {
11766 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11767 "current SSID");
11768 return 0;
11769 }
11770 ssid_len = strlen(ssid);
11771
11772 pos = buf;
11773
11774 /* Frame Control */
11775 switch (frame) {
11776 case DISASSOC:
11777 *pos++ = 0xa0;
11778 break;
11779 case DEAUTH:
11780 *pos++ = 0xc0;
11781 break;
11782 case SAQUERY:
11783 *pos++ = 0xd0;
11784 break;
11785 case AUTH:
11786 *pos++ = 0xb0;
11787 break;
11788 case ASSOCREQ:
11789 *pos++ = 0x00;
11790 break;
11791 case REASSOCREQ:
11792 *pos++ = 0x20;
11793 break;
11794 case DLS_REQ:
11795 *pos++ = 0xd0;
11796 break;
11797 }
11798
11799 if (protected == INCORRECT_KEY)
11800 *pos++ = 0x40; /* Set Protected field to 1 */
11801 else
11802 *pos++ = 0x00;
11803
11804 /* Duration */
11805 *pos++ = 0x00;
11806 *pos++ = 0x00;
11807
11808 /* addr1 = DA (current AP) */
11809 hwaddr_aton(bssid, pos);
11810 pos += 6;
11811 /* addr2 = SA (own address) */
11812 hwaddr_aton(addr, pos);
11813 pos += 6;
11814 /* addr3 = BSSID (current AP) */
11815 hwaddr_aton(bssid, pos);
11816 pos += 6;
11817
11818 /* Seq# (to be filled by driver/mac80211) */
11819 *pos++ = 0x00;
11820 *pos++ = 0x00;
11821
11822 if (protected == INCORRECT_KEY) {
11823 /* CCMP parameters */
11824 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
11825 pos += 8;
11826 }
11827
11828 if (protected == INCORRECT_KEY) {
11829 switch (frame) {
11830 case DEAUTH:
11831 /* Reason code (encrypted) */
11832 memcpy(pos, "\xa7\x39", 2);
11833 pos += 2;
11834 break;
11835 case DISASSOC:
11836 /* Reason code (encrypted) */
11837 memcpy(pos, "\xa7\x39", 2);
11838 pos += 2;
11839 break;
11840 case SAQUERY:
11841 /* Category|Action|TransID (encrypted) */
11842 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
11843 pos += 4;
11844 break;
11845 default:
11846 return -1;
11847 }
11848
11849 /* CCMP MIC */
11850 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
11851 pos += 8;
11852 } else {
11853 switch (frame) {
11854 case DEAUTH:
11855 /* reason code = 8 */
11856 *pos++ = 0x08;
11857 *pos++ = 0x00;
11858 break;
11859 case DISASSOC:
11860 /* reason code = 8 */
11861 *pos++ = 0x08;
11862 *pos++ = 0x00;
11863 break;
11864 case SAQUERY:
11865 /* Category - SA Query */
11866 *pos++ = 0x08;
11867 /* SA query Action - Request */
11868 *pos++ = 0x00;
11869 /* Transaction ID */
11870 *pos++ = 0x12;
11871 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011872 if (dut->saquery_oci_freq) {
11873 /* OCI IE - Extended ID */
11874 *pos++ = 0xFF;
11875 *pos++ = 0x04;
11876 *pos++ = 0x36;
11877 /* Operating Class */
11878 *pos++ = 0x74;
11879 /* Primary Channel */
11880 *pos++ = freq_to_channel(dut->saquery_oci_freq);
11881 /* Frequency Segment 1 Channel Number */
11882 *pos++ = 0x00;
11883 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011884 break;
11885 case AUTH:
11886 /* Auth Alg (Open) */
11887 *pos++ = 0x00;
11888 *pos++ = 0x00;
11889 /* Seq# */
11890 *pos++ = 0x01;
11891 *pos++ = 0x00;
11892 /* Status code */
11893 *pos++ = 0x00;
11894 *pos++ = 0x00;
11895 break;
11896 case ASSOCREQ:
11897 /* Capability Information */
11898 *pos++ = 0x31;
11899 *pos++ = 0x04;
11900 /* Listen Interval */
11901 *pos++ = 0x0a;
11902 *pos++ = 0x00;
11903 /* SSID */
11904 *pos++ = 0x00;
11905 *pos++ = ssid_len;
11906 memcpy(pos, ssid, ssid_len);
11907 pos += ssid_len;
11908 /* Supported Rates */
11909 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11910 10);
11911 pos += 10;
11912 /* Extended Supported Rates */
11913 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11914 pos += 6;
11915 /* RSN */
11916 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
11917 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
11918 "\x00\x00\x00\x00\x0f\xac\x06", 28);
11919 pos += 28;
11920 break;
11921 case REASSOCREQ:
11922 /* Capability Information */
11923 *pos++ = 0x31;
11924 *pos++ = 0x04;
11925 /* Listen Interval */
11926 *pos++ = 0x0a;
11927 *pos++ = 0x00;
11928 /* Current AP */
11929 hwaddr_aton(bssid, pos);
11930 pos += 6;
11931 /* SSID */
11932 *pos++ = 0x00;
11933 *pos++ = ssid_len;
11934 memcpy(pos, ssid, ssid_len);
11935 pos += ssid_len;
11936 /* Supported Rates */
11937 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11938 10);
11939 pos += 10;
11940 /* Extended Supported Rates */
11941 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11942 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011943 /* RSNE - Group and Pairwise ciphers */
11944 memcpy(pos,
11945 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
11946 14);
11947 pos += 14;
11948 /* RSNE - AKM Suite count */
11949 *pos++ = 0x01;
11950 *pos++ = 0x00;
11951 /* RSNE - AKM Suites */
11952 if (dut->program == PROGRAM_WPA3)
11953 memcpy(pos, "\x00\x0f\xac\x08", 4);
11954 else
11955 memcpy(pos, "\x00\x0f\xac\x02", 4);
11956 pos += 4;
11957 /* RSNE - Capabilities */
11958 *pos++ = 0xc0;
11959 if (dut->ocvc)
11960 *pos++ = 0x40;
11961 else
11962 *pos++ = 0x00;
11963 /* RSNE - PMKID list and Group Management Ciphers */
11964 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
11965 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011966 break;
11967 case DLS_REQ:
11968 /* Category - DLS */
11969 *pos++ = 0x02;
11970 /* DLS Action - Request */
11971 *pos++ = 0x00;
11972 /* Destination MACAddress */
11973 if (dest)
11974 hwaddr_aton(dest, pos);
11975 else
11976 memset(pos, 0, 6);
11977 pos += 6;
11978 /* Source MACAddress */
11979 hwaddr_aton(addr, pos);
11980 pos += 6;
11981 /* Capability Information */
11982 *pos++ = 0x10; /* Privacy */
11983 *pos++ = 0x06; /* QoS */
11984 /* DLS Timeout Value */
11985 *pos++ = 0x00;
11986 *pos++ = 0x01;
11987 /* Supported rates */
11988 *pos++ = 0x01;
11989 *pos++ = 0x08;
11990 *pos++ = 0x0c; /* 6 Mbps */
11991 *pos++ = 0x12; /* 9 Mbps */
11992 *pos++ = 0x18; /* 12 Mbps */
11993 *pos++ = 0x24; /* 18 Mbps */
11994 *pos++ = 0x30; /* 24 Mbps */
11995 *pos++ = 0x48; /* 36 Mbps */
11996 *pos++ = 0x60; /* 48 Mbps */
11997 *pos++ = 0x6c; /* 54 Mbps */
11998 /* TODO: Extended Supported Rates */
11999 /* TODO: HT Capabilities */
12000 break;
12001 }
12002 }
12003
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012004 if (use_monitor) {
12005 s = open_monitor("sigmadut");
12006 if (s < 0) {
12007 send_resp(dut, conn, SIGMA_ERROR,
12008 "errorCode,Failed to open monitor socket");
12009 return 0;
12010 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012011
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012012 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
12013 if (res < 0) {
12014 send_resp(dut, conn, SIGMA_ERROR,
12015 "errorCode,Failed to inject frame");
12016 close(s);
12017 return 0;
12018 }
12019 if (res < pos - buf) {
12020 send_resp(dut, conn, SIGMA_ERROR,
12021 "errorCode,Only partial frame sent");
12022 close(s);
12023 return 0;
12024 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012025
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012026 close(s);
12027 } else {
12028#ifdef NL80211_SUPPORT
12029 int freq;
12030 char freq_str[10];
12031
12032 if (get_wpa_status(get_station_ifname(dut), "freq",
12033 freq_str, sizeof(freq_str)) < 0) {
12034 send_resp(dut, conn, SIGMA_ERROR,
12035 "errorCode,Could not get current operating frequency");
12036 return 0;
12037 }
12038 freq = atoi(freq_str);
12039
12040 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
12041 send_resp(dut, conn, SIGMA_ERROR,
12042 "errorCode,Failed to inject frame");
12043 return 0;
12044 }
12045#else /* NL80211_SUPPORT */
12046 send_resp(dut, conn, SIGMA_ERROR,
12047 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
12048 return 0;
12049#endif /* NL80211_SUPPORT */
12050 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012051
12052 return 1;
12053#else /* __linux__ */
12054 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
12055 "yet supported");
12056 return 0;
12057#endif /* __linux__ */
12058}
12059
12060
12061static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
12062 struct sigma_conn *conn,
12063 struct sigma_cmd *cmd)
12064{
12065 const char *intf = get_param(cmd, "Interface");
12066 const char *sta, *val;
12067 unsigned char addr[ETH_ALEN];
12068 char buf[100];
12069
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012070 if (!intf)
12071 return -1;
12072
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012073 sta = get_param(cmd, "peer");
12074 if (sta == NULL)
12075 sta = get_param(cmd, "station");
12076 if (sta == NULL) {
12077 send_resp(dut, conn, SIGMA_ERROR,
12078 "ErrorCode,Missing peer address");
12079 return 0;
12080 }
12081 if (hwaddr_aton(sta, addr) < 0) {
12082 send_resp(dut, conn, SIGMA_ERROR,
12083 "ErrorCode,Invalid peer address");
12084 return 0;
12085 }
12086
12087 val = get_param(cmd, "type");
12088 if (val == NULL)
12089 return -1;
12090
12091 if (strcasecmp(val, "DISCOVERY") == 0) {
12092 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
12093 if (wpa_command(intf, buf) < 0) {
12094 send_resp(dut, conn, SIGMA_ERROR,
12095 "ErrorCode,Failed to send TDLS discovery");
12096 return 0;
12097 }
12098 return 1;
12099 }
12100
12101 if (strcasecmp(val, "SETUP") == 0) {
12102 int status = 0, timeout = 0;
12103
12104 val = get_param(cmd, "Status");
12105 if (val)
12106 status = atoi(val);
12107
12108 val = get_param(cmd, "Timeout");
12109 if (val)
12110 timeout = atoi(val);
12111
12112 if (status != 0 && status != 37) {
12113 send_resp(dut, conn, SIGMA_ERROR,
12114 "ErrorCode,Unsupported status value");
12115 return 0;
12116 }
12117
12118 if (timeout != 0 && timeout != 301) {
12119 send_resp(dut, conn, SIGMA_ERROR,
12120 "ErrorCode,Unsupported timeout value");
12121 return 0;
12122 }
12123
12124 if (status && timeout) {
12125 send_resp(dut, conn, SIGMA_ERROR,
12126 "ErrorCode,Unsupported timeout+status "
12127 "combination");
12128 return 0;
12129 }
12130
12131 if (status == 37 &&
12132 wpa_command(intf, "SET tdls_testing 0x200")) {
12133 send_resp(dut, conn, SIGMA_ERROR,
12134 "ErrorCode,Failed to enable "
12135 "decline setup response test mode");
12136 return 0;
12137 }
12138
12139 if (timeout == 301) {
12140 int res;
12141 if (dut->no_tpk_expiration)
12142 res = wpa_command(intf,
12143 "SET tdls_testing 0x108");
12144 else
12145 res = wpa_command(intf,
12146 "SET tdls_testing 0x8");
12147 if (res) {
12148 send_resp(dut, conn, SIGMA_ERROR,
12149 "ErrorCode,Failed to set short TPK "
12150 "lifetime");
12151 return 0;
12152 }
12153 }
12154
12155 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
12156 if (wpa_command(intf, buf) < 0) {
12157 send_resp(dut, conn, SIGMA_ERROR,
12158 "ErrorCode,Failed to send TDLS setup");
12159 return 0;
12160 }
12161 return 1;
12162 }
12163
12164 if (strcasecmp(val, "TEARDOWN") == 0) {
12165 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
12166 if (wpa_command(intf, buf) < 0) {
12167 send_resp(dut, conn, SIGMA_ERROR,
12168 "ErrorCode,Failed to send TDLS teardown");
12169 return 0;
12170 }
12171 return 1;
12172 }
12173
12174 send_resp(dut, conn, SIGMA_ERROR,
12175 "ErrorCode,Unsupported TDLS frame");
12176 return 0;
12177}
12178
12179
12180static int sta_ap_known(const char *ifname, const char *bssid)
12181{
12182 char buf[4096];
12183
Jouni Malinendd32f192018-09-15 02:55:19 +030012184 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012185 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
12186 return 0;
12187 if (strncmp(buf, "id=", 3) != 0)
12188 return 0;
12189 return 1;
12190}
12191
12192
12193static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
12194 const char *bssid)
12195{
12196 int res;
12197 struct wpa_ctrl *ctrl;
12198 char buf[256];
12199
12200 if (sta_ap_known(ifname, bssid))
12201 return 0;
12202 sigma_dut_print(dut, DUT_MSG_DEBUG,
12203 "AP not in BSS table - start scan");
12204
12205 ctrl = open_wpa_mon(ifname);
12206 if (ctrl == NULL) {
12207 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12208 "wpa_supplicant monitor connection");
12209 return -1;
12210 }
12211
12212 if (wpa_command(ifname, "SCAN") < 0) {
12213 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
12214 wpa_ctrl_detach(ctrl);
12215 wpa_ctrl_close(ctrl);
12216 return -1;
12217 }
12218
12219 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12220 buf, sizeof(buf));
12221
12222 wpa_ctrl_detach(ctrl);
12223 wpa_ctrl_close(ctrl);
12224
12225 if (res < 0) {
12226 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
12227 return -1;
12228 }
12229
12230 if (sta_ap_known(ifname, bssid))
12231 return 0;
12232 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
12233 return -1;
12234}
12235
12236
12237static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
12238 struct sigma_conn *conn,
12239 struct sigma_cmd *cmd,
12240 const char *intf)
12241{
12242 char buf[200];
12243
12244 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
12245 if (system(buf) != 0) {
12246 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
12247 "ndsend");
12248 return 0;
12249 }
12250
12251 return 1;
12252}
12253
12254
12255static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
12256 struct sigma_conn *conn,
12257 struct sigma_cmd *cmd,
12258 const char *intf)
12259{
12260 char buf[200];
12261 const char *ip = get_param(cmd, "SenderIP");
12262
Peng Xu26b356d2017-10-04 17:58:16 -070012263 if (!ip)
12264 return 0;
12265
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012266 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
12267 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12268 if (system(buf) == 0) {
12269 sigma_dut_print(dut, DUT_MSG_INFO,
12270 "Neighbor Solicitation got a response "
12271 "for %s@%s", ip, intf);
12272 }
12273
12274 return 1;
12275}
12276
12277
12278static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
12279 struct sigma_conn *conn,
12280 struct sigma_cmd *cmd,
12281 const char *ifname)
12282{
12283 char buf[200];
12284 const char *ip = get_param(cmd, "SenderIP");
12285
12286 if (ip == NULL) {
12287 send_resp(dut, conn, SIGMA_ERROR,
12288 "ErrorCode,Missing SenderIP parameter");
12289 return 0;
12290 }
12291 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
12292 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12293 if (system(buf) != 0) {
12294 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
12295 "for %s@%s", ip, ifname);
12296 }
12297
12298 return 1;
12299}
12300
12301
12302static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
12303 struct sigma_conn *conn,
12304 struct sigma_cmd *cmd,
12305 const char *ifname)
12306{
12307 char buf[200];
12308 char ip[16];
12309 int s;
Peng Xub3756882017-10-04 14:39:09 -070012310 struct ifreq ifr;
12311 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012312
12313 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070012314 if (s < 0) {
12315 perror("socket");
12316 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012317 }
12318
Peng Xub3756882017-10-04 14:39:09 -070012319 memset(&ifr, 0, sizeof(ifr));
12320 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
12321 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
12322 sigma_dut_print(dut, DUT_MSG_INFO,
12323 "Failed to get %s IP address: %s",
12324 ifname, strerror(errno));
12325 close(s);
12326 return -1;
12327 }
12328 close(s);
12329
12330 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
12331 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
12332
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012333 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
12334 ip);
12335 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12336 if (system(buf) != 0) {
12337 }
12338
12339 return 1;
12340}
12341
12342
12343static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
12344 struct sigma_conn *conn,
12345 struct sigma_cmd *cmd,
12346 const char *ifname)
12347{
12348 char buf[200], addr[20];
12349 char dst[ETH_ALEN], src[ETH_ALEN];
12350 short ethtype = htons(ETH_P_ARP);
12351 char *pos;
12352 int s, res;
12353 const char *val;
12354 struct sockaddr_in taddr;
12355
12356 val = get_param(cmd, "dest");
12357 if (val)
12358 hwaddr_aton(val, (unsigned char *) dst);
12359
12360 val = get_param(cmd, "DestIP");
12361 if (val)
12362 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070012363 else
12364 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012365
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012366 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012367 sizeof(addr)) < 0)
12368 return -2;
12369 hwaddr_aton(addr, (unsigned char *) src);
12370
12371 pos = buf;
12372 *pos++ = 0x00;
12373 *pos++ = 0x01;
12374 *pos++ = 0x08;
12375 *pos++ = 0x00;
12376 *pos++ = 0x06;
12377 *pos++ = 0x04;
12378 *pos++ = 0x00;
12379 *pos++ = 0x02;
12380 memcpy(pos, src, ETH_ALEN);
12381 pos += ETH_ALEN;
12382 memcpy(pos, &taddr.sin_addr, 4);
12383 pos += 4;
12384 memcpy(pos, dst, ETH_ALEN);
12385 pos += ETH_ALEN;
12386 memcpy(pos, &taddr.sin_addr, 4);
12387 pos += 4;
12388
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012389 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012390 if (s < 0) {
12391 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
12392 "monitor socket");
12393 return 0;
12394 }
12395
12396 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
12397 if (res < 0) {
12398 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
12399 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053012400 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012401 return 0;
12402 }
12403
12404 close(s);
12405
12406 return 1;
12407}
12408
12409
12410static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
12411 struct sigma_conn *conn,
12412 struct sigma_cmd *cmd,
12413 const char *intf, const char *dest)
12414{
12415 char buf[100];
12416
12417 if (if_nametoindex("sigmadut") == 0) {
12418 snprintf(buf, sizeof(buf),
12419 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012420 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012421 if (system(buf) != 0 ||
12422 if_nametoindex("sigmadut") == 0) {
12423 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12424 "monitor interface with '%s'", buf);
12425 return -2;
12426 }
12427 }
12428
12429 if (system("ifconfig sigmadut up") != 0) {
12430 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12431 "monitor interface up");
12432 return -2;
12433 }
12434
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012435 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012436}
12437
12438
12439static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
12440 struct sigma_conn *conn,
12441 struct sigma_cmd *cmd)
12442{
12443 const char *intf = get_param(cmd, "Interface");
12444 const char *dest = get_param(cmd, "Dest");
12445 const char *type = get_param(cmd, "FrameName");
12446 const char *val;
12447 char buf[200], *pos, *end;
12448 int count, count2;
12449
12450 if (type == NULL)
12451 type = get_param(cmd, "Type");
12452
12453 if (intf == NULL || dest == NULL || type == NULL)
12454 return -1;
12455
12456 if (strcasecmp(type, "NeighAdv") == 0)
12457 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
12458
12459 if (strcasecmp(type, "NeighSolicitReq") == 0)
12460 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
12461
12462 if (strcasecmp(type, "ARPProbe") == 0)
12463 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
12464
12465 if (strcasecmp(type, "ARPAnnounce") == 0)
12466 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
12467
12468 if (strcasecmp(type, "ARPReply") == 0)
12469 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
12470
12471 if (strcasecmp(type, "DLS-request") == 0 ||
12472 strcasecmp(type, "DLSrequest") == 0)
12473 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
12474 dest);
12475
12476 if (strcasecmp(type, "ANQPQuery") != 0 &&
12477 strcasecmp(type, "Query") != 0) {
12478 send_resp(dut, conn, SIGMA_ERROR,
12479 "ErrorCode,Unsupported HS 2.0 send frame type");
12480 return 0;
12481 }
12482
12483 if (sta_scan_ap(dut, intf, dest) < 0) {
12484 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
12485 "the requested AP");
12486 return 0;
12487 }
12488
12489 pos = buf;
12490 end = buf + sizeof(buf);
12491 count = 0;
12492 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
12493
12494 val = get_param(cmd, "ANQP_CAP_LIST");
12495 if (val && atoi(val)) {
12496 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
12497 count++;
12498 }
12499
12500 val = get_param(cmd, "VENUE_NAME");
12501 if (val && atoi(val)) {
12502 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
12503 count++;
12504 }
12505
12506 val = get_param(cmd, "NETWORK_AUTH_TYPE");
12507 if (val && atoi(val)) {
12508 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
12509 count++;
12510 }
12511
12512 val = get_param(cmd, "ROAMING_CONS");
12513 if (val && atoi(val)) {
12514 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
12515 count++;
12516 }
12517
12518 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
12519 if (val && atoi(val)) {
12520 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
12521 count++;
12522 }
12523
12524 val = get_param(cmd, "NAI_REALM_LIST");
12525 if (val && atoi(val)) {
12526 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
12527 count++;
12528 }
12529
12530 val = get_param(cmd, "3GPP_INFO");
12531 if (val && atoi(val)) {
12532 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
12533 count++;
12534 }
12535
12536 val = get_param(cmd, "DOMAIN_LIST");
12537 if (val && atoi(val)) {
12538 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
12539 count++;
12540 }
12541
Jouni Malinen34cf9532018-04-29 19:26:33 +030012542 val = get_param(cmd, "Venue_URL");
12543 if (val && atoi(val)) {
12544 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
12545 count++;
12546 }
12547
Jouni Malinend3bca5d2018-04-29 17:25:23 +030012548 val = get_param(cmd, "Advice_Of_Charge");
12549 if (val && atoi(val)) {
12550 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
12551 count++;
12552 }
12553
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012554 if (count && wpa_command(intf, buf)) {
12555 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
12556 return 0;
12557 }
12558
12559 pos = buf;
12560 end = buf + sizeof(buf);
12561 count2 = 0;
12562 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
12563
12564 val = get_param(cmd, "HS_CAP_LIST");
12565 if (val && atoi(val)) {
12566 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
12567 count2++;
12568 }
12569
12570 val = get_param(cmd, "OPER_NAME");
12571 if (val && atoi(val)) {
12572 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
12573 count2++;
12574 }
12575
12576 val = get_param(cmd, "WAN_METRICS");
12577 if (!val)
12578 val = get_param(cmd, "WAN_MAT");
12579 if (!val)
12580 val = get_param(cmd, "WAN_MET");
12581 if (val && atoi(val)) {
12582 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
12583 count2++;
12584 }
12585
12586 val = get_param(cmd, "CONNECTION_CAPABILITY");
12587 if (val && atoi(val)) {
12588 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
12589 count2++;
12590 }
12591
12592 val = get_param(cmd, "OP_CLASS");
12593 if (val && atoi(val)) {
12594 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
12595 count2++;
12596 }
12597
12598 val = get_param(cmd, "OSU_PROVIDER_LIST");
12599 if (val && atoi(val)) {
12600 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
12601 count2++;
12602 }
12603
Jouni Malinenf67afec2018-04-29 19:24:58 +030012604 val = get_param(cmd, "OPER_ICON_METADATA");
12605 if (!val)
12606 val = get_param(cmd, "OPERATOR_ICON_METADATA");
12607 if (val && atoi(val)) {
12608 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
12609 count2++;
12610 }
12611
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012612 if (count && count2) {
12613 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
12614 "second query");
12615 sleep(1);
12616 }
12617
12618 if (count2 && wpa_command(intf, buf)) {
12619 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
12620 "failed");
12621 return 0;
12622 }
12623
12624 val = get_param(cmd, "NAI_HOME_REALM_LIST");
12625 if (val) {
12626 if (count || count2) {
12627 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12628 "sending out second query");
12629 sleep(1);
12630 }
12631
12632 if (strcmp(val, "1") == 0)
12633 val = "mail.example.com";
12634 snprintf(buf, end - pos,
12635 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
12636 dest, val);
12637 if (wpa_command(intf, buf)) {
12638 send_resp(dut, conn, SIGMA_ERROR,
12639 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
12640 "failed");
12641 return 0;
12642 }
12643 }
12644
12645 val = get_param(cmd, "ICON_REQUEST");
12646 if (val) {
12647 if (count || count2) {
12648 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12649 "sending out second query");
12650 sleep(1);
12651 }
12652
12653 snprintf(buf, end - pos,
12654 "HS20_ICON_REQUEST %s %s", dest, val);
12655 if (wpa_command(intf, buf)) {
12656 send_resp(dut, conn, SIGMA_ERROR,
12657 "ErrorCode,HS20_ICON_REQUEST failed");
12658 return 0;
12659 }
12660 }
12661
12662 return 1;
12663}
12664
12665
12666static int ath_sta_send_frame_vht(struct sigma_dut *dut,
12667 struct sigma_conn *conn,
12668 struct sigma_cmd *cmd)
12669{
12670 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012671 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012672 int chwidth, nss;
12673
12674 val = get_param(cmd, "framename");
12675 if (!val)
12676 return -1;
12677 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12678
12679 /* Command sequence to generate Op mode notification */
12680 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012681 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012682
12683 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012684 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012685
12686 /* Extract Channel width */
12687 val = get_param(cmd, "Channel_width");
12688 if (val) {
12689 switch (atoi(val)) {
12690 case 20:
12691 chwidth = 0;
12692 break;
12693 case 40:
12694 chwidth = 1;
12695 break;
12696 case 80:
12697 chwidth = 2;
12698 break;
12699 case 160:
12700 chwidth = 3;
12701 break;
12702 default:
12703 chwidth = 2;
12704 break;
12705 }
12706
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012707 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012708 }
12709
12710 /* Extract NSS */
12711 val = get_param(cmd, "NSS");
12712 if (val) {
12713 switch (atoi(val)) {
12714 case 1:
12715 nss = 1;
12716 break;
12717 case 2:
12718 nss = 3;
12719 break;
12720 case 3:
12721 nss = 7;
12722 break;
12723 default:
12724 /* We do not support NSS > 3 */
12725 nss = 3;
12726 break;
12727 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012728 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012729 }
12730
12731 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012732 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012733 }
12734
12735 return 1;
12736}
12737
12738
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012739static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
12740 enum send_frame_protection protected)
12741{
12742#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012743 return wcn_wifi_test_config_set_u8(
12744 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
12745 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012746#else /* NL80211_SUPPORT */
12747 sigma_dut_print(dut, DUT_MSG_ERROR,
12748 "PMF config cannot be set without NL80211_SUPPORT defined");
12749 return -1;
12750#endif /* NL80211_SUPPORT */
12751}
12752
12753
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012754static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
12755 struct sigma_conn *conn,
12756 struct sigma_cmd *cmd)
12757{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012758 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012759 case DRIVER_ATHEROS:
12760 return ath_sta_send_frame_vht(dut, conn, cmd);
12761 default:
12762 send_resp(dut, conn, SIGMA_ERROR,
12763 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
12764 return 0;
12765 }
12766}
12767
12768
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012769static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
12770{
12771#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012772 return wcn_wifi_test_config_set_flag(
12773 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012774#else /* NL80211_SUPPORT */
12775 sigma_dut_print(dut, DUT_MSG_ERROR,
12776 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
12777 return -1;
12778#endif /* NL80211_SUPPORT */
12779}
12780
12781
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012782static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
12783 struct sigma_cmd *cmd)
12784{
12785 const char *val;
12786 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012787 enum send_frame_protection protected;
12788 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012789
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012790 if (!intf)
12791 return -1;
12792
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012793 val = get_param(cmd, "framename");
12794 if (!val)
12795 return -1;
12796 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12797
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012798 pmf = get_param(cmd, "PMFProtected");
12799 if (!pmf)
12800 pmf = get_param(cmd, "Protected");
12801 if (pmf) {
12802 if (strcasecmp(pmf, "Correct-key") == 0 ||
12803 strcasecmp(pmf, "CorrectKey") == 0) {
12804 protected = CORRECT_KEY;
12805 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
12806 protected = INCORRECT_KEY;
12807 } else if (strcasecmp(pmf, "Unprotected") == 0) {
12808 protected = UNPROTECTED;
12809 } else {
12810 send_resp(dut, conn, SIGMA_ERROR,
12811 "errorCode,Unsupported PMFProtected");
12812 return STATUS_SENT_ERROR;
12813 }
12814 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
12815 protected);
12816 wcn_sta_set_pmf_config(dut, intf, protected);
12817 }
12818
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012819 /* Command sequence to generate Op mode notification */
12820 if (val && strcasecmp(val, "action") == 0) {
12821 val = get_param(cmd, "PPDUTxType");
12822 if (val && strcasecmp(val, "TB") == 0) {
12823 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
12824 sigma_dut_print(dut, DUT_MSG_ERROR,
12825 "failed to send TB PPDU Tx cfg");
12826 send_resp(dut, conn, SIGMA_ERROR,
12827 "ErrorCode,set TB PPDU Tx cfg failed");
12828 return 0;
12829 }
12830 return 1;
12831 }
12832
12833 sigma_dut_print(dut, DUT_MSG_ERROR,
12834 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012835
12836 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012837 }
12838
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012839 if (strcasecmp(val, "disassoc") == 0)
12840 wcn_sta_send_disassoc(dut, intf);
12841
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012842 return 1;
12843}
12844
12845
12846static int cmd_sta_send_frame_he(struct sigma_dut *dut,
12847 struct sigma_conn *conn,
12848 struct sigma_cmd *cmd)
12849{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012850 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012851 case DRIVER_WCN:
12852 return wcn_sta_send_frame_he(dut, conn, cmd);
12853 default:
12854 send_resp(dut, conn, SIGMA_ERROR,
12855 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
12856 return 0;
12857 }
12858}
12859
12860
Lior David0fe101e2017-03-09 16:09:50 +020012861#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012862
12863static int
12864wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
12865 const char *frame_name, const char *dest_mac)
12866{
12867 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
12868 const char *ssid = get_param(cmd, "ssid");
12869 const char *countstr = get_param(cmd, "count");
12870 const char *channelstr = get_param(cmd, "channel");
12871 const char *group_id = get_param(cmd, "groupid");
12872 const char *client_id = get_param(cmd, "clientmac");
12873 int count, channel, freq, i;
12874 const char *fname;
12875 char frame[1024], src_mac[20], group_id_attr[25],
12876 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
12877 const char *group_ssid;
12878 const int group_ssid_prefix_len = 9;
12879 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
12880 size_t framelen = sizeof(frame);
12881 struct template_frame_tag tags[2];
12882 size_t tags_total = ARRAY_SIZE(tags);
12883 int tag_index, len, dst_len;
12884
12885 if (!countstr || !channelstr) {
12886 sigma_dut_print(dut, DUT_MSG_ERROR,
12887 "Missing argument: count, channel");
12888 return -1;
12889 }
12890 if (isprobereq && !ssid) {
12891 sigma_dut_print(dut, DUT_MSG_ERROR,
12892 "Missing argument: ssid");
12893 return -1;
12894 }
12895 if (!isprobereq && (!group_id || !client_id)) {
12896 sigma_dut_print(dut, DUT_MSG_ERROR,
12897 "Missing argument: group_id, client_id");
12898 return -1;
12899 }
12900
12901 count = atoi(countstr);
12902 channel = atoi(channelstr);
12903 freq = channel_to_freq(dut, channel);
12904
12905 if (!freq) {
12906 sigma_dut_print(dut, DUT_MSG_ERROR,
12907 "invalid channel: %s", channelstr);
12908 return -1;
12909 }
12910
12911 if (isprobereq) {
12912 if (strcasecmp(ssid, "wildcard") == 0) {
12913 fname = "probe_req_wildcard.txt";
12914 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
12915 fname = "probe_req_P2P_Wildcard.txt";
12916 } else {
12917 sigma_dut_print(dut, DUT_MSG_ERROR,
12918 "invalid probe request type");
12919 return -1;
12920 }
12921 } else {
12922 fname = "P2P_device_discovery_req.txt";
12923 }
12924
12925 if (parse_template_frame_file(dut, fname, frame, &framelen,
12926 tags, &tags_total)) {
12927 sigma_dut_print(dut, DUT_MSG_ERROR,
12928 "invalid frame template: %s", fname);
12929 return -1;
12930 }
12931
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012932 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012933 src_mac, sizeof(src_mac)) < 0 ||
12934 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
12935 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
12936 return -1;
12937 /* Use wildcard BSSID, since we are in PBSS */
12938 memset(&hdr->addr3, 0xFF, ETH_ALEN);
12939
12940 if (!isprobereq) {
12941 tag_index = find_template_frame_tag(tags, tags_total, 1);
12942 if (tag_index < 0) {
12943 sigma_dut_print(dut, DUT_MSG_ERROR,
12944 "can't find device id attribute");
12945 return -1;
12946 }
12947 if (parse_mac_address(dut, client_id,
12948 (unsigned char *) client_mac)) {
12949 sigma_dut_print(dut, DUT_MSG_ERROR,
12950 "invalid client_id: %s", client_id);
12951 return -1;
12952 }
12953 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
12954 framelen - tags[tag_index].offset,
12955 IEEE80211_P2P_ATTR_DEVICE_ID,
12956 client_mac, ETH_ALEN)) {
12957 sigma_dut_print(dut, DUT_MSG_ERROR,
12958 "fail to replace device id attribute");
12959 return -1;
12960 }
12961
12962 /*
12963 * group_id arg contains device MAC address followed by
12964 * space and SSID (DIRECT-somessid).
12965 * group id attribute contains device address (6 bytes)
12966 * followed by SSID prefix DIRECT-XX (9 bytes)
12967 */
12968 if (strlen(group_id) < sizeof(device_macstr)) {
12969 sigma_dut_print(dut, DUT_MSG_ERROR,
12970 "group_id arg too short");
12971 return -1;
12972 }
12973 memcpy(device_macstr, group_id, sizeof(device_macstr));
12974 device_macstr[sizeof(device_macstr) - 1] = '\0';
12975 if (parse_mac_address(dut, device_macstr,
12976 (unsigned char *) group_id_attr)) {
12977 sigma_dut_print(dut, DUT_MSG_ERROR,
12978 "fail to parse device address from group_id");
12979 return -1;
12980 }
12981 group_ssid = strchr(group_id, ' ');
12982 if (!group_ssid) {
12983 sigma_dut_print(dut, DUT_MSG_ERROR,
12984 "invalid group_id arg, no ssid");
12985 return -1;
12986 }
12987 group_ssid++;
12988 len = strlen(group_ssid);
12989 if (len < group_ssid_prefix_len) {
12990 sigma_dut_print(dut, DUT_MSG_ERROR,
12991 "group_id SSID too short");
12992 return -1;
12993 }
12994 dst_len = sizeof(group_id_attr) - ETH_ALEN;
12995 if (len > dst_len) {
12996 sigma_dut_print(dut, DUT_MSG_ERROR,
12997 "group_id SSID (%s) too long",
12998 group_ssid);
12999 return -1;
13000 }
13001
13002 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
13003 tag_index = find_template_frame_tag(tags, tags_total, 2);
13004 if (tag_index < 0) {
13005 sigma_dut_print(dut, DUT_MSG_ERROR,
13006 "can't find group id attribute");
13007 return -1;
13008 }
13009 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13010 framelen - tags[tag_index].offset,
13011 IEEE80211_P2P_ATTR_GROUP_ID,
13012 group_id_attr,
13013 sizeof(group_id_attr))) {
13014 sigma_dut_print(dut, DUT_MSG_ERROR,
13015 "fail to replace group id attribute");
13016 return -1;
13017 }
13018 }
13019
13020 for (i = 0; i < count; i++) {
13021 if (wil6210_transmit_frame(dut, freq,
13022 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
13023 frame, framelen)) {
13024 sigma_dut_print(dut, DUT_MSG_ERROR,
13025 "fail to transmit probe request frame");
13026 return -1;
13027 }
13028 }
13029
13030 return 0;
13031}
13032
13033
Lior David0fe101e2017-03-09 16:09:50 +020013034int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
13035 struct sigma_cmd *cmd)
13036{
13037 const char *frame_name = get_param(cmd, "framename");
13038 const char *mac = get_param(cmd, "dest_mac");
13039
13040 if (!frame_name || !mac) {
13041 sigma_dut_print(dut, DUT_MSG_ERROR,
13042 "framename and dest_mac must be provided");
13043 return -1;
13044 }
13045
13046 if (strcasecmp(frame_name, "brp") == 0) {
13047 const char *l_rx = get_param(cmd, "L-RX");
13048 int l_rx_i;
13049
13050 if (!l_rx) {
13051 sigma_dut_print(dut, DUT_MSG_ERROR,
13052 "L-RX must be provided");
13053 return -1;
13054 }
13055 l_rx_i = atoi(l_rx);
13056
13057 sigma_dut_print(dut, DUT_MSG_INFO,
13058 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
13059 mac, l_rx);
13060 if (l_rx_i != 16) {
13061 sigma_dut_print(dut, DUT_MSG_ERROR,
13062 "unsupported L-RX: %s", l_rx);
13063 return -1;
13064 }
13065
13066 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
13067 return -1;
13068 } else if (strcasecmp(frame_name, "ssw") == 0) {
13069 sigma_dut_print(dut, DUT_MSG_INFO,
13070 "dev_send_frame: SLS, dest_mac %s", mac);
13071 if (wil6210_send_sls(dut, mac))
13072 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013073 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
13074 (strcasecmp(frame_name, "devdiscreq") == 0)) {
13075 sigma_dut_print(dut, DUT_MSG_INFO,
13076 "dev_send_frame: %s, dest_mac %s", frame_name,
13077 mac);
13078 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
13079 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020013080 } else {
13081 sigma_dut_print(dut, DUT_MSG_ERROR,
13082 "unsupported frame type: %s", frame_name);
13083 return -1;
13084 }
13085
13086 return 1;
13087}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013088
Lior David0fe101e2017-03-09 16:09:50 +020013089#endif /* __linux__ */
13090
13091
13092static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
13093 struct sigma_conn *conn,
13094 struct sigma_cmd *cmd)
13095{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013096 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020013097#ifdef __linux__
13098 case DRIVER_WIL6210:
13099 return wil6210_send_frame_60g(dut, conn, cmd);
13100#endif /* __linux__ */
13101 default:
13102 send_resp(dut, conn, SIGMA_ERROR,
13103 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
13104 return 0;
13105 }
13106}
13107
13108
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013109static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13110 const char *intf, struct sigma_cmd *cmd)
13111{
13112 const char *val, *addr;
13113 char buf[100];
13114
13115 addr = get_param(cmd, "DestMac");
13116 if (!addr) {
13117 send_resp(dut, conn, SIGMA_INVALID,
13118 "ErrorCode,AP MAC address is missing");
13119 return 0;
13120 }
13121
13122 val = get_param(cmd, "ANQPQuery_ID");
13123 if (!val) {
13124 send_resp(dut, conn, SIGMA_INVALID,
13125 "ErrorCode,Missing ANQPQuery_ID");
13126 return 0;
13127 }
13128
13129 if (strcasecmp(val, "NeighborReportReq") == 0) {
13130 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
13131 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
13132 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
13133 } else {
13134 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
13135 val);
13136 send_resp(dut, conn, SIGMA_INVALID,
13137 "ErrorCode,Invalid ANQPQuery_ID");
13138 return 0;
13139 }
13140
Ashwini Patild174f2c2017-04-13 16:49:46 +053013141 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
13142 * (Address3 = Wildcard BSSID when sent to not-associated AP;
13143 * if associated, AP BSSID).
13144 */
13145 if (wpa_command(intf, "SET gas_address3 1") < 0) {
13146 send_resp(dut, conn, SIGMA_ERROR,
13147 "ErrorCode,Failed to set gas_address3");
13148 return 0;
13149 }
13150
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013151 if (wpa_command(intf, buf) < 0) {
13152 send_resp(dut, conn, SIGMA_ERROR,
13153 "ErrorCode,Failed to send ANQP query");
13154 return 0;
13155 }
13156
13157 return 1;
13158}
13159
13160
13161static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
13162 struct sigma_conn *conn,
13163 const char *intf,
13164 struct sigma_cmd *cmd)
13165{
13166 const char *val = get_param(cmd, "FrameName");
13167
13168 if (val && strcasecmp(val, "ANQPQuery") == 0)
13169 return mbo_send_anqp_query(dut, conn, intf, cmd);
13170
13171 return 2;
13172}
13173
13174
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013175static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
13176 struct sigma_conn *conn,
13177 const char *intf,
13178 struct sigma_cmd *cmd)
13179{
13180 const char *val = get_param(cmd, "framename");
13181
13182 if (!val)
13183 return INVALID_SEND_STATUS;
13184
13185 if (strcasecmp(val, "SAQueryReq") == 0) {
13186 val = get_param(cmd, "OCIChannel");
13187
13188 if (!val) {
13189 send_resp(dut, conn, SIGMA_ERROR,
13190 "errorCode,OCIChannel not present");
13191 return STATUS_SENT_ERROR;
13192 }
13193
13194 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
13195 if (!dut->saquery_oci_freq) {
13196 send_resp(dut, conn, SIGMA_ERROR,
13197 "errorCode,Invalid OCIChannel number");
13198 return STATUS_SENT_ERROR;
13199 }
13200
13201 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
13202 NULL, 0);
13203 }
13204
13205 if (strcasecmp(val, "reassocreq") == 0)
13206 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
13207 CORRECT_KEY, NULL, 0);
13208
Veerendranath9f81dfb2020-08-10 01:21:29 -070013209 if (strcasecmp(val, "ANQPQuery") == 0) {
13210 char buf[50];
13211 const char *dest = get_param(cmd, "DestMac");
13212 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013213 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070013214 int len, freq;
13215
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013216 if (freq_str)
13217 freq = atoi(freq_str);
13218 else
13219 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
13220
Veerendranath9f81dfb2020-08-10 01:21:29 -070013221 if (!dest || !freq)
13222 return INVALID_SEND_STATUS;
13223
13224 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
13225 dest, freq);
13226 if (len < 0 || len >= sizeof(buf)) {
13227 sigma_dut_print(dut, DUT_MSG_ERROR,
13228 "Failed to allocate buf");
13229 return ERROR_SEND_STATUS;
13230 }
13231
13232 if (wpa_command(intf, buf) != 0) {
13233 send_resp(dut, conn, SIGMA_ERROR,
13234 "ErrorCode,Failed to send ANQP Query frame");
13235 return STATUS_SENT_ERROR;
13236 }
13237
13238 sigma_dut_print(dut, DUT_MSG_DEBUG,
13239 "ANQP Query sent: %s", buf);
13240
13241 return SUCCESS_SEND_STATUS;
13242 }
13243
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013244 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
13245 return STATUS_SENT_ERROR;
13246}
13247
13248
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013249static int
13250get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13251 char *pos, int rem_len, int num_of_scs_desc,
13252 int num_of_tclas_elem)
13253{
13254 const char *val;
13255 int ipv6;
13256 int len, total_len = 0;
13257
13258 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
13259 num_of_tclas_elem);
13260 if (!val) {
13261 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
13262 __func__);
13263 return -1;
13264 }
13265
13266 if (strcmp(val, "6") == 0) {
13267 ipv6 = 1;
13268 } else if (strcmp(val, "4") == 0) {
13269 ipv6 = 0;
13270 } else {
13271 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
13272 __func__);
13273 return -1;
13274 }
13275
13276 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
13277 if (len < 0 || len >= rem_len)
13278 return -1;
13279
13280 pos += len;
13281 rem_len -= len;
13282 total_len += len;
13283
13284 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
13285 num_of_scs_desc, num_of_tclas_elem);
13286 if (val) {
13287 len = snprintf(pos, rem_len, " src_ip=%s", val);
13288 if (len < 0 || len >= rem_len)
13289 return -1;
13290
13291 pos += len;
13292 rem_len -= len;
13293 total_len += len;
13294 }
13295
13296 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
13297 num_of_scs_desc, num_of_tclas_elem);
13298 if (val) {
13299 len = snprintf(pos, rem_len, " dst_ip=%s", val);
13300 if (len < 0 || len >= rem_len)
13301 return -1;
13302
13303 pos += len;
13304 rem_len -= len;
13305 total_len += len;
13306 }
13307
13308 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
13309 num_of_tclas_elem);
13310 if (val) {
13311 len = snprintf(pos, rem_len, " src_port=%s", val);
13312 if (len < 0 || len >= rem_len)
13313 return -1;
13314
13315 pos += len;
13316 rem_len -= len;
13317 total_len += len;
13318 }
13319
13320 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
13321 num_of_scs_desc, num_of_tclas_elem);
13322 if (val) {
13323 len = snprintf(pos, rem_len, " dst_port=%s", val);
13324 if (len < 0 || len >= rem_len)
13325 return -1;
13326
13327 pos += len;
13328 rem_len -= len;
13329 total_len += len;
13330 }
13331
13332 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
13333 num_of_tclas_elem);
13334 if (val) {
13335 len = snprintf(pos, rem_len, " dscp=%s", val);
13336 if (len < 0 || len >= rem_len)
13337 return -1;
13338
13339 pos += len;
13340 rem_len -= len;
13341 total_len += len;
13342 }
13343
13344 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
13345 num_of_scs_desc, num_of_tclas_elem);
13346 if (val) {
13347 char *prot;
13348
13349 switch (atoi(val)) {
13350 case 17:
13351 prot = "udp";
13352 break;
13353 case 6:
13354 prot = "tcp";
13355 break;
13356 case 50:
13357 prot = "esp";
13358 break;
13359 default:
13360 sigma_dut_print(dut, DUT_MSG_ERROR,
13361 "Invalid protocol %d", atoi(val));
13362 return -1;
13363 }
13364
13365 if (ipv6)
13366 len = snprintf(pos, rem_len, " next_header=%s", prot);
13367 else
13368 len = snprintf(pos, rem_len, " protocol=%s", prot);
13369 if (len < 0 || len >= rem_len)
13370 return -1;
13371
13372 pos += len;
13373 rem_len -= len;
13374 total_len += len;
13375 }
13376
13377 return total_len;
13378}
13379
13380
13381static int
13382get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13383 char *pos, int rem_len, int num_of_scs_desc,
13384 int num_of_tclas_elem)
13385{
13386 const char *val;
13387 int len, total_len = 0;
13388
13389 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
13390 num_of_scs_desc, num_of_tclas_elem);
13391 if (val) {
13392 len = snprintf(pos, rem_len, " prot_instance=%s",
13393 val);
13394 if (len < 0 || len >= rem_len)
13395 return -1;
13396
13397 pos += len;
13398 rem_len -= len;
13399 total_len += len;
13400 }
13401
13402 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
13403 num_of_scs_desc, num_of_tclas_elem);
13404 if (val) {
13405 char *prot;
13406
13407 switch (atoi(val)) {
13408 case 17:
13409 prot = "udp";
13410 break;
13411 case 6:
13412 prot = "tcp";
13413 break;
13414 case 50:
13415 prot = "esp";
13416 break;
13417 default:
13418 sigma_dut_print(dut, DUT_MSG_ERROR,
13419 "Invalid protocol %d",
13420 atoi(val));
13421 return -1;
13422 }
13423
13424 len = snprintf(pos, rem_len, " prot_number=%s", prot);
13425 if (len < 0 || len >= rem_len)
13426 return -1;
13427
13428 pos += len;
13429 rem_len -= len;
13430 total_len += len;
13431 }
13432
13433 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
13434 num_of_scs_desc, num_of_tclas_elem);
13435 if (val) {
13436 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
13437 if (len < 0 || len >= rem_len)
13438 return -1;
13439
13440 pos += len;
13441 rem_len -= len;
13442 total_len += len;
13443 }
13444
13445 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
13446 num_of_tclas_elem);
13447 if (val && strlen(val) >= 2) {
13448 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
13449 if (len < 0 || len >= rem_len)
13450 return -1;
13451
13452 pos += len;
13453 rem_len -= len;
13454 total_len += len;
13455 }
13456
13457 return total_len;
13458}
13459
13460
13461static enum sigma_cmd_result
13462cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
13463 const char *intf, struct sigma_cmd *cmd)
13464{
13465 char buf[4096], *pos;
13466 const char *val, *scs_id, *classifier_type;
13467 int len, rem_len, total_bytes;
13468 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
13469
13470 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
13471 if (!scs_id) {
13472 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
13473 return INVALID_SEND_STATUS;
13474 }
13475
13476 rem_len = sizeof(buf);
13477 pos = buf;
13478
13479 len = snprintf(buf, sizeof(buf), "SCS");
13480 if (len < 0 || len > rem_len)
13481 goto fail;
13482
13483 pos += len;
13484 rem_len -= len;
13485
13486 while (scs_id) {
13487 num_of_scs_desc++;
13488
13489 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
13490 num_of_scs_desc);
13491 if (!val)
13492 return INVALID_SEND_STATUS;
13493
13494 if (strcasecmp(val, "Add") == 0) {
13495 len = snprintf(pos, rem_len, " scs_id=%s add",
13496 scs_id);
13497 } else if (strcasecmp(val, "Change") == 0) {
13498 len = snprintf(pos, rem_len, " scs_id=%s change",
13499 scs_id);
13500 } else if (strcasecmp(val, "Remove") == 0) {
13501 len = snprintf(pos, rem_len, " scs_id=%s remove",
13502 scs_id);
13503 if (len < 0 || len >= rem_len)
13504 goto fail;
13505
13506 pos += len;
13507 rem_len -= len;
13508 goto scs_desc_end;
13509 } else {
13510 sigma_dut_print(dut, DUT_MSG_ERROR,
13511 "%s: request type - %s is invalid",
13512 __func__, val);
13513 return INVALID_SEND_STATUS;
13514 }
13515
13516 if (len < 0 || len >= rem_len)
13517 goto fail;
13518
13519 pos += len;
13520 rem_len -= len;
13521
13522 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
13523 num_of_scs_desc);
13524 if (!val) {
13525 sigma_dut_print(dut, DUT_MSG_ERROR,
13526 "IntraAccess Priority empty");
13527 return INVALID_SEND_STATUS;
13528 }
13529
13530 len = snprintf(pos, rem_len, " scs_up=%s", val);
13531 if (len < 0 || len >= rem_len)
13532 goto fail;
13533
13534 pos += len;
13535 rem_len -= len;
13536
13537 classifier_type = get_param_fmt(cmd,
13538 "TCLASElem_ClassifierType_%d_1",
13539 num_of_scs_desc);
13540 if (!classifier_type) {
13541 sigma_dut_print(dut, DUT_MSG_ERROR,
13542 "classifier type missing");
13543 return INVALID_SEND_STATUS;
13544 }
13545
13546 while (classifier_type) {
13547 num_of_tclas_elem++;
13548
13549 len = snprintf(pos, rem_len, " classifier_type=%s",
13550 classifier_type);
13551 if (len < 0 || len >= rem_len)
13552 goto fail;
13553
13554 pos += len;
13555 rem_len -= len;
13556
13557 if (strcmp(classifier_type, "10") == 0) {
13558 total_bytes = get_type10_frame_classifier(
13559 dut, cmd, pos, rem_len,
13560 num_of_scs_desc,
13561 num_of_tclas_elem);
13562 } else if (strcmp(classifier_type, "4") == 0) {
13563 total_bytes = get_type4_frame_classifier(
13564 dut, cmd, pos, rem_len,
13565 num_of_scs_desc,
13566 num_of_tclas_elem);
13567 } else {
13568 sigma_dut_print(dut, DUT_MSG_ERROR,
13569 "classifier_type invalid");
13570 goto fail;
13571 }
13572
13573 if (total_bytes < 0)
13574 goto fail;
13575
13576 pos += total_bytes;
13577 rem_len -= total_bytes;
13578
13579 classifier_type = get_param_fmt(
13580 cmd, "TCLASElem_ClassifierType_%d_%d",
13581 num_of_scs_desc, num_of_tclas_elem + 1);
13582 }
13583
13584 if (num_of_tclas_elem > 1) {
13585 val = get_param_fmt(cmd,
13586 "TCLASProcessingElem_Processing_%d",
13587 num_of_scs_desc);
13588 if (!val) {
13589 sigma_dut_print(dut, DUT_MSG_ERROR,
13590 "Tclas_processing element %d empty",
13591 num_of_scs_desc);
13592 goto fail;
13593 }
13594
13595 len = snprintf(pos, rem_len,
13596 " tclas_processing=%s", val);
13597 if (len < 0 || len >= rem_len)
13598 goto fail;
13599
13600 pos += len;
13601 rem_len -= len;
13602 }
13603scs_desc_end:
13604 num_of_tclas_elem = 0;
13605 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
13606 num_of_scs_desc + 1);
13607 }
13608
13609 if (wpa_command(intf, buf) != 0) {
13610 send_resp(dut, conn, SIGMA_ERROR,
13611 "ErrorCode,Failed to send SCS frame request");
13612 return STATUS_SENT_ERROR;
13613 }
13614
13615 sigma_dut_print(dut, DUT_MSG_DEBUG,
13616 "SCS frame request sent: %s", buf);
13617
13618 return SUCCESS_SEND_STATUS;
13619fail:
13620 sigma_dut_print(dut, DUT_MSG_ERROR,
13621 "Failed to create SCS frame request");
13622 return ERROR_SEND_STATUS;
13623}
13624
13625
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013626static enum sigma_cmd_result
13627cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
13628 const char *intf, struct sigma_cmd *cmd)
13629{
13630 char buf[128], *pos;
13631 const char *val, *classifier_type = "04", *type;
13632 int len, rem_len;
13633 u8 up_bitmap;
13634
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013635 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013636 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013637 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013638 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013639 return INVALID_SEND_STATUS;
13640 }
13641
13642 rem_len = sizeof(buf);
13643 pos = buf;
13644 if (strcasecmp(type, "add") == 0) {
13645 len = snprintf(pos, rem_len, "MSCS add");
13646 } else if (strcasecmp(type, "update") == 0) {
13647 len = snprintf(pos, rem_len, "MSCS change");
13648 } else if (strcasecmp(type, "remove") == 0) {
13649 if (wpa_command(intf, "MSCS remove") != 0) {
13650 send_resp(dut, conn, SIGMA_ERROR,
13651 "ErrorCode,Failed to send MSCS frame req");
13652 return STATUS_SENT_ERROR;
13653 }
13654 return SUCCESS_SEND_STATUS;
13655 } else {
13656 sigma_dut_print(dut, DUT_MSG_ERROR,
13657 "%s: request type invalid", __func__);
13658 return INVALID_SEND_STATUS;
13659 }
13660
13661 if (len < 0 || len >= rem_len)
13662 goto fail;
13663
13664 pos += len;
13665 rem_len -= len;
13666
13667 val = get_param(cmd, "User_Priority_Bitmap");
13668 if (!val) {
13669 sigma_dut_print(dut, DUT_MSG_ERROR,
13670 "%s: user priority bitmap empty", __func__);
13671 return INVALID_SEND_STATUS;
13672 }
13673
13674 switch (atoi(val)) {
13675 case 0:
13676 up_bitmap = 0x00;
13677 break;
13678 case 1:
13679 up_bitmap = 0xF0;
13680 break;
13681 case 2:
13682 up_bitmap = 0xF6;
13683 break;
13684 default:
13685 sigma_dut_print(dut, DUT_MSG_ERROR,
13686 "%s: Unknown User_Priority_Bitmap value %d",
13687 __func__, atoi(val));
13688 return INVALID_SEND_STATUS;
13689 }
13690
13691 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
13692 if (len < 0 || len >= rem_len)
13693 goto fail;
13694
13695 pos += len;
13696 rem_len -= len;
13697
13698 val = get_param(cmd, "User_Priority_Limit");
13699 if (!val) {
13700 sigma_dut_print(dut, DUT_MSG_ERROR,
13701 "%s: invalid user priority limit", __func__);
13702 return INVALID_SEND_STATUS;
13703 }
13704
13705 len = snprintf(pos, rem_len, " up_limit=%s", val);
13706 if (len < 0 || len >= rem_len)
13707 goto fail;
13708
13709 pos += len;
13710 rem_len -= len;
13711
13712 val = get_param(cmd, "Stream_Timeout");
13713 if (!val)
13714 val = get_param(cmd, "Stream_Timtout");
13715 if (!val) {
13716 sigma_dut_print(dut, DUT_MSG_ERROR,
13717 "%s: invalid stream timeout", __func__);
13718 return INVALID_SEND_STATUS;
13719 }
13720
13721 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
13722 if (len < 0 || len >= rem_len)
13723 goto fail;
13724
13725 pos += len;
13726 rem_len -= len;
13727
13728 val = get_param(cmd, "TCLAS_Mask");
13729 if (!val) {
13730 sigma_dut_print(dut, DUT_MSG_ERROR,
13731 "%s: invalid tclas mask", __func__);
13732 return INVALID_SEND_STATUS;
13733 }
13734
13735 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
13736 classifier_type, strtol(val, NULL, 2), 0);
13737 if (len < 0 || len >= rem_len)
13738 goto fail;
13739
13740 if (wpa_command(intf, buf) != 0) {
13741 send_resp(dut, conn, SIGMA_ERROR,
13742 "ErrorCode,Failed to send MSCS frame req");
13743 return STATUS_SENT_ERROR;
13744 }
13745
13746 sigma_dut_print(dut, DUT_MSG_DEBUG,
13747 "MSCS frame request sent: %s", buf);
13748
13749 return SUCCESS_SEND_STATUS;
13750fail:
13751 sigma_dut_print(dut, DUT_MSG_ERROR,
13752 "Failed to create MSCS frame req");
13753 return ERROR_SEND_STATUS;
13754}
13755
13756
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013757static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013758cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13759 const char *intf, struct sigma_cmd *cmd)
13760{
13761 char buf[150], *pos;
13762 const char *val;
13763 int len, rem_len;
13764
13765 rem_len = sizeof(buf);
13766 pos = buf;
13767
13768 len = snprintf(pos, rem_len, "DSCP_QUERY");
13769 if (len < 0 || len >= rem_len)
13770 goto fail;
13771
13772 pos += len;
13773 rem_len -= len;
13774
13775 val = get_param(cmd, "Wildcard");
13776 if (val && strcasecmp(val, "Yes") == 0) {
13777 len = snprintf(pos, rem_len, " wildcard");
13778 if (len < 0 || len >= rem_len)
13779 goto fail;
13780 } else if (strlen(dut->qm_domain_name)) {
13781 len = snprintf(pos, rem_len, " domain_name=%s",
13782 dut->qm_domain_name);
13783 if (len < 0 || len >= rem_len)
13784 goto fail;
13785 } else {
13786 sigma_dut_print(dut, DUT_MSG_ERROR,
13787 "Invalid DSCP Query configuration");
13788 return INVALID_SEND_STATUS;
13789 }
13790
13791 if (wpa_command(intf, buf) != 0) {
13792 send_resp(dut, conn, SIGMA_ERROR,
13793 "ErrorCode,Failed to send DSCP policy query frame");
13794 return STATUS_SENT_ERROR;
13795 }
13796
13797 sigma_dut_print(dut, DUT_MSG_DEBUG,
13798 "DSCP policy query frame sent: %s", buf);
13799 return SUCCESS_SEND_STATUS;
13800fail:
13801 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
13802 return ERROR_SEND_STATUS;
13803}
13804
13805
13806static enum sigma_cmd_result
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013807cmd_sta_send_frame_dscp_response(struct sigma_dut *dut, struct sigma_conn *conn,
13808 const char *intf, struct sigma_cmd *cmd)
13809{
13810 char buf[256], *pos, *item, *list, *saveptr;
13811 const char *val;
13812 int len, rem_len;
13813
13814 pos = buf;
13815 rem_len = sizeof(buf);
13816
13817 len = snprintf(pos, rem_len, "DSCP_RESP");
13818 if (snprintf_error(rem_len, len)) {
13819 sigma_dut_print(dut, DUT_MSG_ERROR,
13820 "Failed to create DSCP Policy Response command");
13821 return ERROR_SEND_STATUS;
13822 }
13823
13824 pos += len;
13825 rem_len -= len;
13826
13827 val = get_param(cmd, "PolicyID_List");
13828 if (!val) {
13829 sigma_dut_print(dut, DUT_MSG_ERROR,
13830 "DSCP policy ID list missing");
13831 return INVALID_SEND_STATUS;
13832 }
13833
13834 list = strdup(val);
13835 if (!list)
13836 return ERROR_SEND_STATUS;
13837
13838 item = strtok_r(list, "_", &saveptr);
13839 while (item) {
13840 unsigned int i;
13841 int policy_id = atoi(item);
13842
13843 for (i = 0; i < dut->num_dscp_status; i++)
13844 if (dut->dscp_status[i].id == policy_id)
13845 break;
13846
13847 if (i == dut->num_dscp_status) {
13848 free(list);
13849 send_resp(dut, conn, SIGMA_ERROR,
13850 "ErrorCode,DSCP policy id not found in status list");
13851 return STATUS_SENT_ERROR;
13852 }
13853
13854 len = snprintf(pos, rem_len, " policy_id=%d status=%d",
13855 policy_id, dut->dscp_status[i].status);
13856 if (snprintf_error(rem_len, len)) {
13857 free(list);
13858 sigma_dut_print(dut, DUT_MSG_ERROR,
13859 "Failed to write DSCP policy list");
13860 return ERROR_SEND_STATUS;
13861 }
13862
13863 pos += len;
13864 rem_len -= len;
13865
13866 if (dut->dscp_status[i].status)
13867 remove_dscp_policy(dut, policy_id);
13868
13869 item = strtok_r(NULL, "_", &saveptr);
13870 }
13871
13872 free(list);
13873
13874 if (wpa_command(intf, buf) != 0) {
13875 send_resp(dut, conn, SIGMA_ERROR,
13876 "ErrorCode,Failed to send DSCP Policy Response frame");
13877 return STATUS_SENT_ERROR;
13878 }
13879
13880 sigma_dut_print(dut, DUT_MSG_DEBUG,
13881 "DSCP Policy Response frame sent: %s", buf);
13882 return SUCCESS_SEND_STATUS;
13883}
13884
13885
13886static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013887cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
13888 const char *intf, struct sigma_cmd *cmd)
13889{
13890 const char *val;
13891
13892 val = get_param(cmd, "FrameName");
13893 if (val) {
13894 if (strcasecmp(val, "MSCSReq") == 0)
13895 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
13896 if (strcasecmp(val, "SCSReq") == 0)
13897 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013898 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
13899 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
13900 cmd);
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013901 if (strcasecmp(val, "DSCPPolicyResponse") == 0)
13902 return cmd_sta_send_frame_dscp_response(dut, conn, intf,
13903 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013904
13905 sigma_dut_print(dut, DUT_MSG_ERROR,
13906 "%s: frame name - %s is invalid",
13907 __func__, val);
13908 }
13909
13910 return INVALID_SEND_STATUS;
13911}
13912
13913
Jouni Malinenf7222712019-06-13 01:50:21 +030013914enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
13915 struct sigma_conn *conn,
13916 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013917{
13918 const char *intf = get_param(cmd, "Interface");
13919 const char *val;
13920 enum send_frame_type frame;
13921 enum send_frame_protection protected;
13922 char buf[100];
13923 unsigned char addr[ETH_ALEN];
13924 int res;
13925
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030013926 if (!intf)
13927 return -1;
13928
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013929 val = get_param(cmd, "program");
13930 if (val == NULL)
13931 val = get_param(cmd, "frame");
13932 if (val && strcasecmp(val, "TDLS") == 0)
13933 return cmd_sta_send_frame_tdls(dut, conn, cmd);
13934 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030013935 strcasecmp(val, "HS2-R2") == 0 ||
13936 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013937 return cmd_sta_send_frame_hs2(dut, conn, cmd);
13938 if (val && strcasecmp(val, "VHT") == 0)
13939 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070013940 if (val && strcasecmp(val, "HE") == 0)
13941 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070013942 if (val && strcasecmp(val, "LOC") == 0)
13943 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020013944 if (val && strcasecmp(val, "60GHz") == 0)
13945 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013946 if (val && strcasecmp(val, "MBO") == 0) {
13947 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
13948 if (res != 2)
13949 return res;
13950 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013951 if (val && strcasecmp(val, "WPA3") == 0)
13952 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013953 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013954 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013955
13956 val = get_param(cmd, "TD_DISC");
13957 if (val) {
13958 if (hwaddr_aton(val, addr) < 0)
13959 return -1;
13960 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
13961 if (wpa_command(intf, buf) < 0) {
13962 send_resp(dut, conn, SIGMA_ERROR,
13963 "ErrorCode,Failed to send TDLS discovery");
13964 return 0;
13965 }
13966 return 1;
13967 }
13968
13969 val = get_param(cmd, "TD_Setup");
13970 if (val) {
13971 if (hwaddr_aton(val, addr) < 0)
13972 return -1;
13973 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
13974 if (wpa_command(intf, buf) < 0) {
13975 send_resp(dut, conn, SIGMA_ERROR,
13976 "ErrorCode,Failed to start TDLS setup");
13977 return 0;
13978 }
13979 return 1;
13980 }
13981
13982 val = get_param(cmd, "TD_TearDown");
13983 if (val) {
13984 if (hwaddr_aton(val, addr) < 0)
13985 return -1;
13986 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
13987 if (wpa_command(intf, buf) < 0) {
13988 send_resp(dut, conn, SIGMA_ERROR,
13989 "ErrorCode,Failed to tear down TDLS link");
13990 return 0;
13991 }
13992 return 1;
13993 }
13994
13995 val = get_param(cmd, "TD_ChannelSwitch");
13996 if (val) {
13997 /* TODO */
13998 send_resp(dut, conn, SIGMA_ERROR,
13999 "ErrorCode,TD_ChannelSwitch not yet supported");
14000 return 0;
14001 }
14002
14003 val = get_param(cmd, "TD_NF");
14004 if (val) {
14005 /* TODO */
14006 send_resp(dut, conn, SIGMA_ERROR,
14007 "ErrorCode,TD_NF not yet supported");
14008 return 0;
14009 }
14010
14011 val = get_param(cmd, "PMFFrameType");
14012 if (val == NULL)
14013 val = get_param(cmd, "FrameName");
14014 if (val == NULL)
14015 val = get_param(cmd, "Type");
14016 if (val == NULL)
14017 return -1;
14018 if (strcasecmp(val, "disassoc") == 0)
14019 frame = DISASSOC;
14020 else if (strcasecmp(val, "deauth") == 0)
14021 frame = DEAUTH;
14022 else if (strcasecmp(val, "saquery") == 0)
14023 frame = SAQUERY;
14024 else if (strcasecmp(val, "auth") == 0)
14025 frame = AUTH;
14026 else if (strcasecmp(val, "assocreq") == 0)
14027 frame = ASSOCREQ;
14028 else if (strcasecmp(val, "reassocreq") == 0)
14029 frame = REASSOCREQ;
14030 else if (strcasecmp(val, "neigreq") == 0) {
14031 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
14032
14033 val = get_param(cmd, "ssid");
14034 if (val == NULL)
14035 return -1;
14036
14037 res = send_neighbor_request(dut, intf, val);
14038 if (res) {
14039 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14040 "Failed to send neighbor report request");
14041 return 0;
14042 }
14043
14044 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053014045 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
14046 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014047 sigma_dut_print(dut, DUT_MSG_DEBUG,
14048 "Got Transition Management Query");
14049
Ashwini Patil5acd7382017-04-13 15:55:04 +053014050 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014051 if (res) {
14052 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14053 "Failed to send Transition Management Query");
14054 return 0;
14055 }
14056
14057 return 1;
14058 } else {
14059 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14060 "PMFFrameType");
14061 return 0;
14062 }
14063
14064 val = get_param(cmd, "PMFProtected");
14065 if (val == NULL)
14066 val = get_param(cmd, "Protected");
14067 if (val == NULL)
14068 return -1;
14069 if (strcasecmp(val, "Correct-key") == 0 ||
14070 strcasecmp(val, "CorrectKey") == 0)
14071 protected = CORRECT_KEY;
14072 else if (strcasecmp(val, "IncorrectKey") == 0)
14073 protected = INCORRECT_KEY;
14074 else if (strcasecmp(val, "Unprotected") == 0)
14075 protected = UNPROTECTED;
14076 else {
14077 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14078 "PMFProtected");
14079 return 0;
14080 }
14081
14082 if (protected != UNPROTECTED &&
14083 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
14084 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
14085 "PMFProtected for auth/assocreq/reassocreq");
14086 return 0;
14087 }
14088
14089 if (if_nametoindex("sigmadut") == 0) {
14090 snprintf(buf, sizeof(buf),
14091 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014092 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014093 if (system(buf) != 0 ||
14094 if_nametoindex("sigmadut") == 0) {
14095 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
14096 "monitor interface with '%s'", buf);
14097 return -2;
14098 }
14099 }
14100
14101 if (system("ifconfig sigmadut up") != 0) {
14102 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
14103 "monitor interface up");
14104 return -2;
14105 }
14106
Veerendranath Jakkam49774122020-07-05 09:52:18 +053014107 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014108}
14109
14110
14111static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
14112 struct sigma_conn *conn,
14113 struct sigma_cmd *cmd,
14114 const char *ifname)
14115{
14116 char buf[200];
14117 const char *val;
14118
14119 val = get_param(cmd, "ClearARP");
14120 if (val && atoi(val) == 1) {
14121 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
14122 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14123 if (system(buf) != 0) {
14124 send_resp(dut, conn, SIGMA_ERROR,
14125 "errorCode,Failed to clear ARP cache");
14126 return 0;
14127 }
14128 }
14129
14130 return 1;
14131}
14132
14133
14134int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
14135 struct sigma_cmd *cmd)
14136{
14137 const char *intf = get_param(cmd, "Interface");
14138 const char *val;
14139
14140 if (intf == NULL)
14141 return -1;
14142
14143 val = get_param(cmd, "program");
14144 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014145 strcasecmp(val, "HS2-R2") == 0 ||
14146 strcasecmp(val, "HS2-R3") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014147 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
14148
14149 return -1;
14150}
14151
14152
Jouni Malinenf7222712019-06-13 01:50:21 +030014153static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
14154 struct sigma_conn *conn,
14155 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014156{
14157 const char *intf = get_param(cmd, "Interface");
14158 const char *mac = get_param(cmd, "MAC");
14159
14160 if (intf == NULL || mac == NULL)
14161 return -1;
14162
14163 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
14164 "interface %s to %s", intf, mac);
14165
14166 if (dut->set_macaddr) {
14167 char buf[128];
14168 int res;
14169 if (strcasecmp(mac, "default") == 0) {
14170 res = snprintf(buf, sizeof(buf), "%s",
14171 dut->set_macaddr);
14172 dut->tmp_mac_addr = 0;
14173 } else {
14174 res = snprintf(buf, sizeof(buf), "%s %s",
14175 dut->set_macaddr, mac);
14176 dut->tmp_mac_addr = 1;
14177 }
14178 if (res < 0 || res >= (int) sizeof(buf))
14179 return -1;
14180 if (system(buf) != 0) {
14181 send_resp(dut, conn, SIGMA_ERROR,
14182 "errorCode,Failed to set MAC "
14183 "address");
14184 return 0;
14185 }
14186 return 1;
14187 }
14188
14189 if (strcasecmp(mac, "default") == 0)
14190 return 1;
14191
14192 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14193 "command");
14194 return 0;
14195}
14196
14197
14198static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
14199 struct sigma_conn *conn, const char *intf,
14200 int val)
14201{
14202 char buf[200];
14203 int res;
14204
14205 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
14206 intf, val);
14207 if (res < 0 || res >= (int) sizeof(buf))
14208 return -1;
14209 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14210 if (system(buf) != 0) {
14211 send_resp(dut, conn, SIGMA_ERROR,
14212 "errorCode,Failed to configure offchannel mode");
14213 return 0;
14214 }
14215
14216 return 1;
14217}
14218
14219
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014220static int off_chan_val(enum sec_ch_offset off)
14221{
14222 switch (off) {
14223 case SEC_CH_NO:
14224 return 0;
14225 case SEC_CH_40ABOVE:
14226 return 40;
14227 case SEC_CH_40BELOW:
14228 return -40;
14229 }
14230
14231 return 0;
14232}
14233
14234
14235static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
14236 const char *intf, int off_ch_num,
14237 enum sec_ch_offset sec)
14238{
14239 char buf[200];
14240 int res;
14241
14242 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
14243 intf, off_ch_num);
14244 if (res < 0 || res >= (int) sizeof(buf))
14245 return -1;
14246 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14247 if (system(buf) != 0) {
14248 send_resp(dut, conn, SIGMA_ERROR,
14249 "errorCode,Failed to set offchan");
14250 return 0;
14251 }
14252
14253 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
14254 intf, off_chan_val(sec));
14255 if (res < 0 || res >= (int) sizeof(buf))
14256 return -1;
14257 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14258 if (system(buf) != 0) {
14259 send_resp(dut, conn, SIGMA_ERROR,
14260 "errorCode,Failed to set sec chan offset");
14261 return 0;
14262 }
14263
14264 return 1;
14265}
14266
14267
14268static int tdls_set_offchannel_offset(struct sigma_dut *dut,
14269 struct sigma_conn *conn,
14270 const char *intf, int off_ch_num,
14271 enum sec_ch_offset sec)
14272{
14273 char buf[200];
14274 int res;
14275
14276 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
14277 off_ch_num);
14278 if (res < 0 || res >= (int) sizeof(buf))
14279 return -1;
14280 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14281
14282 if (wpa_command(intf, buf) < 0) {
14283 send_resp(dut, conn, SIGMA_ERROR,
14284 "ErrorCode,Failed to set offchan");
14285 return 0;
14286 }
14287 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
14288 off_chan_val(sec));
14289 if (res < 0 || res >= (int) sizeof(buf))
14290 return -1;
14291
14292 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14293
14294 if (wpa_command(intf, buf) < 0) {
14295 send_resp(dut, conn, SIGMA_ERROR,
14296 "ErrorCode,Failed to set sec chan offset");
14297 return 0;
14298 }
14299
14300 return 1;
14301}
14302
14303
14304static int tdls_set_offchannel_mode(struct sigma_dut *dut,
14305 struct sigma_conn *conn,
14306 const char *intf, int val)
14307{
14308 char buf[200];
14309 int res;
14310
14311 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
14312 val);
14313 if (res < 0 || res >= (int) sizeof(buf))
14314 return -1;
14315 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14316
14317 if (wpa_command(intf, buf) < 0) {
14318 send_resp(dut, conn, SIGMA_ERROR,
14319 "ErrorCode,Failed to configure offchannel mode");
14320 return 0;
14321 }
14322
14323 return 1;
14324}
14325
14326
14327static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
14328 struct sigma_conn *conn,
14329 struct sigma_cmd *cmd)
14330{
14331 const char *val;
14332 enum {
14333 CHSM_NOT_SET,
14334 CHSM_ENABLE,
14335 CHSM_DISABLE,
14336 CHSM_REJREQ,
14337 CHSM_UNSOLRESP
14338 } chsm = CHSM_NOT_SET;
14339 int off_ch_num = -1;
14340 enum sec_ch_offset sec_ch = SEC_CH_NO;
14341 int res;
14342
14343 val = get_param(cmd, "Uapsd");
14344 if (val) {
14345 char buf[100];
14346 if (strcasecmp(val, "Enable") == 0)
14347 snprintf(buf, sizeof(buf), "SET ps 99");
14348 else if (strcasecmp(val, "Disable") == 0)
14349 snprintf(buf, sizeof(buf), "SET ps 98");
14350 else {
14351 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14352 "Unsupported uapsd parameter value");
14353 return 0;
14354 }
14355 if (wpa_command(intf, buf)) {
14356 send_resp(dut, conn, SIGMA_ERROR,
14357 "ErrorCode,Failed to change U-APSD "
14358 "powersave mode");
14359 return 0;
14360 }
14361 }
14362
14363 val = get_param(cmd, "TPKTIMER");
14364 if (val && strcasecmp(val, "DISABLE") == 0) {
14365 if (wpa_command(intf, "SET tdls_testing 0x100")) {
14366 send_resp(dut, conn, SIGMA_ERROR,
14367 "ErrorCode,Failed to enable no TPK "
14368 "expiration test mode");
14369 return 0;
14370 }
14371 dut->no_tpk_expiration = 1;
14372 }
14373
14374 val = get_param(cmd, "ChSwitchMode");
14375 if (val) {
14376 if (strcasecmp(val, "Enable") == 0 ||
14377 strcasecmp(val, "Initiate") == 0)
14378 chsm = CHSM_ENABLE;
14379 else if (strcasecmp(val, "Disable") == 0 ||
14380 strcasecmp(val, "passive") == 0)
14381 chsm = CHSM_DISABLE;
14382 else if (strcasecmp(val, "RejReq") == 0)
14383 chsm = CHSM_REJREQ;
14384 else if (strcasecmp(val, "UnSolResp") == 0)
14385 chsm = CHSM_UNSOLRESP;
14386 else {
14387 send_resp(dut, conn, SIGMA_ERROR,
14388 "ErrorCode,Unknown ChSwitchMode value");
14389 return 0;
14390 }
14391 }
14392
14393 val = get_param(cmd, "OffChNum");
14394 if (val) {
14395 off_ch_num = atoi(val);
14396 if (off_ch_num == 0) {
14397 send_resp(dut, conn, SIGMA_ERROR,
14398 "ErrorCode,Invalid OffChNum");
14399 return 0;
14400 }
14401 }
14402
14403 val = get_param(cmd, "SecChOffset");
14404 if (val) {
14405 if (strcmp(val, "20") == 0)
14406 sec_ch = SEC_CH_NO;
14407 else if (strcasecmp(val, "40above") == 0)
14408 sec_ch = SEC_CH_40ABOVE;
14409 else if (strcasecmp(val, "40below") == 0)
14410 sec_ch = SEC_CH_40BELOW;
14411 else {
14412 send_resp(dut, conn, SIGMA_ERROR,
14413 "ErrorCode,Unknown SecChOffset value");
14414 return 0;
14415 }
14416 }
14417
14418 if (chsm == CHSM_NOT_SET) {
14419 /* no offchannel changes requested */
14420 return 1;
14421 }
14422
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014423 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
14424 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014425 send_resp(dut, conn, SIGMA_ERROR,
14426 "ErrorCode,Unknown interface");
14427 return 0;
14428 }
14429
14430 switch (chsm) {
14431 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030014432 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014433 break;
14434 case CHSM_ENABLE:
14435 if (off_ch_num < 0) {
14436 send_resp(dut, conn, SIGMA_ERROR,
14437 "ErrorCode,Missing OffChNum argument");
14438 return 0;
14439 }
14440 if (wifi_chip_type == DRIVER_WCN) {
14441 res = tdls_set_offchannel_offset(dut, conn, intf,
14442 off_ch_num, sec_ch);
14443 } else {
14444 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14445 sec_ch);
14446 }
14447 if (res != 1)
14448 return res;
14449 if (wifi_chip_type == DRIVER_WCN)
14450 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
14451 else
14452 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
14453 break;
14454 case CHSM_DISABLE:
14455 if (wifi_chip_type == DRIVER_WCN)
14456 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
14457 else
14458 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
14459 break;
14460 case CHSM_REJREQ:
14461 if (wifi_chip_type == DRIVER_WCN)
14462 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
14463 else
14464 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
14465 break;
14466 case CHSM_UNSOLRESP:
14467 if (off_ch_num < 0) {
14468 send_resp(dut, conn, SIGMA_ERROR,
14469 "ErrorCode,Missing OffChNum argument");
14470 return 0;
14471 }
14472 if (wifi_chip_type == DRIVER_WCN) {
14473 res = tdls_set_offchannel_offset(dut, conn, intf,
14474 off_ch_num, sec_ch);
14475 } else {
14476 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14477 sec_ch);
14478 }
14479 if (res != 1)
14480 return res;
14481 if (wifi_chip_type == DRIVER_WCN)
14482 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
14483 else
14484 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
14485 break;
14486 }
14487
14488 return res;
14489}
14490
14491
14492static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14493 struct sigma_conn *conn,
14494 struct sigma_cmd *cmd)
14495{
14496 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014497 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014498
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070014499 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080014500
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014501 val = get_param(cmd, "nss_mcs_opt");
14502 if (val) {
14503 /* String (nss_operating_mode; mcs_operating_mode) */
14504 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014505 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014506
14507 token = strdup(val);
14508 if (!token)
14509 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014510 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014511 if (!result) {
14512 sigma_dut_print(dut, DUT_MSG_ERROR,
14513 "VHT NSS not specified");
14514 goto failed;
14515 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014516 if (strcasecmp(result, "def") != 0) {
14517 nss = atoi(result);
14518 if (nss == 4)
14519 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014520 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014521 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014522
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014523 }
14524
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014525 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014526 if (!result) {
14527 sigma_dut_print(dut, DUT_MSG_ERROR,
14528 "VHT MCS not specified");
14529 goto failed;
14530 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014531 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014532 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014533 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014534 } else {
14535 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014536 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014537 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014538 }
14539 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014540 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014541 }
14542
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014543 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014544 return 1;
14545failed:
14546 free(token);
14547 return 0;
14548}
14549
14550
14551static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14552 struct sigma_conn *conn,
14553 struct sigma_cmd *cmd)
14554{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014555 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014556 case DRIVER_ATHEROS:
14557 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
14558 default:
14559 send_resp(dut, conn, SIGMA_ERROR,
14560 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
14561 return 0;
14562 }
14563}
14564
14565
Jouni Malinen1702fe32021-06-08 19:08:01 +030014566static enum sigma_cmd_result
14567wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14568 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014569{
14570 const char *val;
14571 char *token = NULL, *result;
14572 char buf[60];
14573
14574 val = get_param(cmd, "nss_mcs_opt");
14575 if (val) {
14576 /* String (nss_operating_mode; mcs_operating_mode) */
14577 int nss, mcs, ratecode;
14578 char *saveptr;
14579
14580 token = strdup(val);
14581 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014582 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014583
14584 result = strtok_r(token, ";", &saveptr);
14585 if (!result) {
14586 sigma_dut_print(dut, DUT_MSG_ERROR,
14587 "HE NSS not specified");
14588 goto failed;
14589 }
14590 nss = 1;
14591 if (strcasecmp(result, "def") != 0)
14592 nss = atoi(result);
14593
14594 result = strtok_r(NULL, ";", &saveptr);
14595 if (!result) {
14596 sigma_dut_print(dut, DUT_MSG_ERROR,
14597 "HE MCS not specified");
14598 goto failed;
14599 }
14600 mcs = 7;
14601 if (strcasecmp(result, "def") != 0)
14602 mcs = atoi(result);
14603
Arif Hussain557bf412018-05-25 17:29:36 -070014604 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014605 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070014606 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014607 } else if (nss > 2) {
14608 sigma_dut_print(dut, DUT_MSG_ERROR,
14609 "HE NSS %d not supported", nss);
14610 goto failed;
14611 }
14612
Arif Hussain557bf412018-05-25 17:29:36 -070014613 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
14614 if (system(buf) != 0) {
14615 sigma_dut_print(dut, DUT_MSG_ERROR,
14616 "nss_mcs_opt: iwpriv %s nss %d failed",
14617 intf, nss);
14618 goto failed;
14619 }
Arif Hussainac6c5112018-05-25 17:34:00 -070014620 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070014621
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014622 /* Add the MCS to the ratecode */
14623 if (mcs >= 0 && mcs <= 11) {
14624 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070014625#ifdef NL80211_SUPPORT
14626 if (dut->device_type == STA_testbed) {
14627 enum he_mcs_config mcs_config;
14628 int ret;
14629
14630 if (mcs <= 7)
14631 mcs_config = HE_80_MCS0_7;
14632 else if (mcs <= 9)
14633 mcs_config = HE_80_MCS0_9;
14634 else
14635 mcs_config = HE_80_MCS0_11;
14636 ret = sta_set_he_mcs(dut, intf, mcs_config);
14637 if (ret) {
14638 sigma_dut_print(dut, DUT_MSG_ERROR,
14639 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
14640 mcs, mcs_config, ret);
14641 goto failed;
14642 }
14643 }
14644#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014645 } else {
14646 sigma_dut_print(dut, DUT_MSG_ERROR,
14647 "HE MCS %d not supported", mcs);
14648 goto failed;
14649 }
14650 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
14651 intf, ratecode);
14652 if (system(buf) != 0) {
14653 sigma_dut_print(dut, DUT_MSG_ERROR,
14654 "iwpriv setting of 11ax rates failed");
14655 goto failed;
14656 }
14657 free(token);
14658 }
14659
14660 val = get_param(cmd, "GI");
14661 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014662 int fix_rate_sgi;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014663 u8 he_gi_val = 0;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014664
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014665 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014666 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014667 fix_rate_sgi = 1;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014668 he_gi_val = NL80211_RATE_INFO_HE_GI_0_8;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014669 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014670 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
14671 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014672 fix_rate_sgi = 2;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014673 he_gi_val = NL80211_RATE_INFO_HE_GI_1_6;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014674 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014675 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
14676 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014677 fix_rate_sgi = 3;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014678 he_gi_val = NL80211_RATE_INFO_HE_GI_3_2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014679 } else {
14680 send_resp(dut, conn, SIGMA_ERROR,
14681 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014682 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014683 }
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014684 if (wcn_set_he_gi(dut, intf, he_gi_val)) {
14685 sigma_dut_print(dut, DUT_MSG_INFO,
14686 "wcn_set_he_gi failed, using iwpriv");
14687 if (system(buf) != 0) {
14688 send_resp(dut, conn, SIGMA_ERROR,
14689 "errorCode,Failed to set shortgi");
14690 return STATUS_SENT_ERROR;
14691 }
14692 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
14693 intf, fix_rate_sgi);
14694 if (system(buf) != 0) {
14695 send_resp(dut, conn, SIGMA_ERROR,
14696 "errorCode,Failed to set fix rate shortgi");
14697 return STATUS_SENT_ERROR;
14698 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014699 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014700 }
14701
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014702 val = get_param(cmd, "LTF");
14703 if (val) {
14704#ifdef NL80211_SUPPORT
14705 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014706 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014707 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014708 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014709 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014710 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014711 } else {
14712 send_resp(dut, conn, SIGMA_ERROR,
14713 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014714 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014715 }
14716#else /* NL80211_SUPPORT */
14717 sigma_dut_print(dut, DUT_MSG_ERROR,
14718 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014719 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014720#endif /* NL80211_SUPPORT */
14721 }
14722
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070014723 val = get_param(cmd, "KeepAlive");
14724 if (val) {
14725 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
14726
14727 if (strcasecmp(val, "Data") == 0)
14728 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
14729 else if (strcasecmp(val, "Mgmt") == 0)
14730 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
14731
14732 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
14733 send_resp(dut, conn, SIGMA_ERROR,
14734 "ErrorCode,Failed to set keep alive type config");
14735 return STATUS_SENT_ERROR;
14736 }
14737 }
14738
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014739 val = get_param(cmd, "TxSUPPDU");
14740 if (val) {
14741 int set_val = 1;
14742
14743 if (strcasecmp(val, "Enable") == 0)
14744 set_val = 1;
14745 else if (strcasecmp(val, "Disable") == 0)
14746 set_val = 0;
14747
14748 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
14749 send_resp(dut, conn, SIGMA_ERROR,
14750 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014751 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014752 }
14753 }
14754
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070014755 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
14756 if (val) {
14757 int set_val = 0;
14758
14759 if (strcasecmp(val, "Enable") == 0)
14760 set_val = 0;
14761 else if (strcasecmp(val, "Disable") == 0)
14762 set_val = 1;
14763
14764 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
14765 send_resp(dut, conn, SIGMA_ERROR,
14766 "ErrorCode,Failed to set mgmt/data Tx disable config");
14767 return STATUS_SENT_ERROR;
14768 }
14769 }
14770
Arif Hussain480d5f42019-03-12 14:40:42 -070014771 val = get_param(cmd, "TWT_Setup");
14772 if (val) {
14773 if (strcasecmp(val, "Request") == 0) {
Kiran Kumar Lokereafac46a2021-11-29 14:03:20 -080014774 if (set_power_save_wcn(dut, intf, 1) < 0)
14775 sigma_dut_print(dut, DUT_MSG_ERROR,
14776 "Failed to enable power save");
Arif Hussain480d5f42019-03-12 14:40:42 -070014777 if (sta_twt_request(dut, conn, cmd)) {
14778 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014779 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014780 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014781 }
14782 } else if (strcasecmp(val, "Teardown") == 0) {
14783 if (sta_twt_teardown(dut, conn, cmd)) {
14784 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014785 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014786 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014787 }
14788 }
14789 }
14790
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014791 val = get_param(cmd, "TWT_Operation");
14792 if (val) {
14793 if (strcasecmp(val, "Suspend") == 0) {
14794 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
14795 send_resp(dut, conn, SIGMA_ERROR,
14796 "ErrorCode,TWT suspend failed");
14797 return STATUS_SENT_ERROR;
14798 }
14799 } else if (strcasecmp(val, "Resume") == 0) {
14800 if (sta_twt_resume(dut, conn, cmd)) {
14801 send_resp(dut, conn, SIGMA_ERROR,
14802 "ErrorCode,TWT resume failed");
14803 return STATUS_SENT_ERROR;
14804 }
14805 }
14806 }
14807
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080014808 val = get_param(cmd, "transmitOMI");
14809 if (val && sta_transmit_omi(dut, conn, cmd)) {
14810 send_resp(dut, conn, SIGMA_ERROR,
14811 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014812 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070014813 }
14814
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014815 val = get_param(cmd, "Powersave");
14816 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014817 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014818
14819 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014820 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014821 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014822 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014823 } else {
14824 sigma_dut_print(dut, DUT_MSG_ERROR,
14825 "Unsupported Powersave value '%s'",
14826 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014827 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014828 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014829 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014830 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014831 }
14832
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080014833 val = get_param(cmd, "MU_EDCA");
14834 if (val) {
14835 if (strcasecmp(val, "Override") == 0) {
14836 if (sta_set_mu_edca_override(dut, intf, 1)) {
14837 send_resp(dut, conn, SIGMA_ERROR,
14838 "errorCode,MU EDCA override set failed");
14839 return STATUS_SENT;
14840 }
14841 } else if (strcasecmp(val, "Disable") == 0) {
14842 if (sta_set_mu_edca_override(dut, intf, 0)) {
14843 send_resp(dut, conn, SIGMA_ERROR,
14844 "errorCode,MU EDCA override disable failed");
14845 return STATUS_SENT;
14846 }
14847 }
14848 }
14849
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070014850 val = get_param(cmd, "RUAllocTone");
14851 if (val && strcasecmp(val, "242") == 0) {
14852 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
14853 send_resp(dut, conn, SIGMA_ERROR,
14854 "ErrorCode,Failed to set RU 242 tone Tx");
14855 return STATUS_SENT_ERROR;
14856 }
14857 }
14858
14859 val = get_param(cmd, "PPDUTxType");
14860 if (val && strcasecmp(val, "ER-SU") == 0) {
14861 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
14862 send_resp(dut, conn, SIGMA_ERROR,
14863 "ErrorCode,Failed to set ER-SU PPDU type Tx");
14864 return STATUS_SENT_ERROR;
14865 }
14866 }
14867
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070014868 val = get_param(cmd, "Ch_Pref");
14869 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14870 return STATUS_SENT;
14871
14872 val = get_param(cmd, "Cellular_Data_Cap");
14873 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14874 return STATUS_SENT;
14875
Jouni Malinen1702fe32021-06-08 19:08:01 +030014876 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014877
14878failed:
14879 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014880 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014881}
14882
14883
Jouni Malinen1702fe32021-06-08 19:08:01 +030014884static enum sigma_cmd_result
14885cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14886 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014887{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014888 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014889 case DRIVER_WCN:
14890 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
14891 default:
14892 send_resp(dut, conn, SIGMA_ERROR,
14893 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014894 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014895 }
14896}
14897
14898
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014899static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
14900 struct sigma_conn *conn,
14901 struct sigma_cmd *cmd)
14902{
14903 const char *val;
14904
14905 val = get_param(cmd, "powersave");
14906 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014907 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014908
14909 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014910 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014911 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014912 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014913 } else {
14914 sigma_dut_print(dut, DUT_MSG_ERROR,
14915 "Unsupported power save config");
14916 return -1;
14917 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014918 if (set_power_save_wcn(dut, intf, ps) < 0)
14919 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014920 return 1;
14921 }
14922
14923 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
14924
14925 return 0;
14926}
14927
14928
Ashwini Patil5acd7382017-04-13 15:55:04 +053014929static int btm_query_candidate_list(struct sigma_dut *dut,
14930 struct sigma_conn *conn,
14931 struct sigma_cmd *cmd)
14932{
14933 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
14934 int len, ret;
14935 char buf[10];
14936
14937 /*
14938 * Neighbor Report elements format:
14939 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
14940 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
14941 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
14942 */
14943
14944 bssid = get_param(cmd, "Nebor_BSSID");
14945 if (!bssid) {
14946 send_resp(dut, conn, SIGMA_INVALID,
14947 "errorCode,Nebor_BSSID is missing");
14948 return 0;
14949 }
14950
14951 info = get_param(cmd, "Nebor_Bssid_Info");
14952 if (!info) {
14953 sigma_dut_print(dut, DUT_MSG_INFO,
14954 "Using default value for Nebor_Bssid_Info: %s",
14955 DEFAULT_NEIGHBOR_BSSID_INFO);
14956 info = DEFAULT_NEIGHBOR_BSSID_INFO;
14957 }
14958
14959 op_class = get_param(cmd, "Nebor_Op_Class");
14960 if (!op_class) {
14961 send_resp(dut, conn, SIGMA_INVALID,
14962 "errorCode,Nebor_Op_Class is missing");
14963 return 0;
14964 }
14965
14966 ch = get_param(cmd, "Nebor_Op_Ch");
14967 if (!ch) {
14968 send_resp(dut, conn, SIGMA_INVALID,
14969 "errorCode,Nebor_Op_Ch is missing");
14970 return 0;
14971 }
14972
14973 phy_type = get_param(cmd, "Nebor_Phy_Type");
14974 if (!phy_type) {
14975 sigma_dut_print(dut, DUT_MSG_INFO,
14976 "Using default value for Nebor_Phy_Type: %s",
14977 DEFAULT_NEIGHBOR_PHY_TYPE);
14978 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
14979 }
14980
14981 /* Parse optional subelements */
14982 buf[0] = '\0';
14983 pref = get_param(cmd, "Nebor_Pref");
14984 if (pref) {
14985 /* hexdump for preferrence subelement */
14986 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
14987 if (ret < 0 || ret >= (int) sizeof(buf)) {
14988 sigma_dut_print(dut, DUT_MSG_ERROR,
14989 "snprintf failed for optional subelement ret: %d",
14990 ret);
14991 send_resp(dut, conn, SIGMA_ERROR,
14992 "errorCode,snprintf failed for subelement");
14993 return 0;
14994 }
14995 }
14996
14997 if (!dut->btm_query_cand_list) {
14998 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
14999 if (!dut->btm_query_cand_list) {
15000 send_resp(dut, conn, SIGMA_ERROR,
15001 "errorCode,Failed to allocate memory for btm_query_cand_list");
15002 return 0;
15003 }
15004 }
15005
15006 len = strlen(dut->btm_query_cand_list);
15007 ret = snprintf(dut->btm_query_cand_list + len,
15008 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
15009 bssid, info, op_class, ch, phy_type, buf);
15010 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
15011 sigma_dut_print(dut, DUT_MSG_ERROR,
15012 "snprintf failed for neighbor report list ret: %d",
15013 ret);
15014 send_resp(dut, conn, SIGMA_ERROR,
15015 "errorCode,snprintf failed for neighbor report");
15016 free(dut->btm_query_cand_list);
15017 dut->btm_query_cand_list = NULL;
15018 return 0;
15019 }
15020
15021 return 1;
15022}
15023
15024
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015025int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
15026 struct sigma_ese_alloc *allocs, int *allocs_size)
15027{
15028 int max_count = *allocs_size;
15029 int count = 0, i;
15030 const char *val;
15031
15032 do {
15033 val = get_param_indexed(cmd, "AllocID", count);
15034 if (val)
15035 count++;
15036 } while (val);
15037
15038 if (count == 0 || count > max_count) {
15039 sigma_dut_print(dut, DUT_MSG_ERROR,
15040 "Invalid number of allocations(%d)", count);
15041 return -1;
15042 }
15043
15044 for (i = 0; i < count; i++) {
15045 val = get_param_indexed(cmd, "PercentBI", i);
15046 if (!val) {
15047 sigma_dut_print(dut, DUT_MSG_ERROR,
15048 "Missing PercentBI parameter at index %d",
15049 i);
15050 return -1;
15051 }
15052 allocs[i].percent_bi = atoi(val);
15053
15054 val = get_param_indexed(cmd, "SrcAID", i);
15055 if (val)
15056 allocs[i].src_aid = strtol(val, NULL, 0);
15057 else
15058 allocs[i].src_aid = ESE_BCAST_AID;
15059
15060 val = get_param_indexed(cmd, "DestAID", i);
15061 if (val)
15062 allocs[i].dst_aid = strtol(val, NULL, 0);
15063 else
15064 allocs[i].dst_aid = ESE_BCAST_AID;
15065
15066 allocs[i].type = ESE_CBAP;
15067 sigma_dut_print(dut, DUT_MSG_INFO,
15068 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
15069 i, allocs[i].percent_bi, allocs[i].src_aid,
15070 allocs[i].dst_aid);
15071 }
15072
15073 *allocs_size = count;
15074 return 0;
15075}
15076
15077
15078static int sta_set_60g_ese(struct sigma_dut *dut, int count,
15079 struct sigma_ese_alloc *allocs)
15080{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015081 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015082#ifdef __linux__
15083 case DRIVER_WIL6210:
15084 if (wil6210_set_ese(dut, count, allocs))
15085 return -1;
15086 return 1;
15087#endif /* __linux__ */
15088 default:
15089 sigma_dut_print(dut, DUT_MSG_ERROR,
15090 "Unsupported sta_set_60g_ese with the current driver");
15091 return -1;
15092 }
15093}
15094
15095
15096static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
15097 struct sigma_conn *conn,
15098 struct sigma_cmd *cmd)
15099{
15100 const char *val;
15101
15102 val = get_param(cmd, "ExtSchIE");
15103 if (val && !strcasecmp(val, "Enable")) {
15104 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
15105 int count = MAX_ESE_ALLOCS;
15106
15107 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
15108 return -1;
15109 return sta_set_60g_ese(dut, count, allocs);
15110 }
15111
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015112 val = get_param(cmd, "MCS_FixedRate");
15113 if (val) {
15114 int sta_mcs = atoi(val);
15115
15116 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
15117 sta_mcs);
15118 wil6210_set_force_mcs(dut, 1, sta_mcs);
15119
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015120 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015121 }
15122
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015123 send_resp(dut, conn, SIGMA_ERROR,
15124 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015125 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015126}
15127
15128
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015129static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
15130 const char *oci_frametype, uint32_t oci_freq)
15131{
15132#ifdef NL80211_SUPPORT
15133 struct nl_msg *msg;
15134 int ret = 0;
15135 struct nlattr *params;
15136 struct nlattr *attr;
15137 int ifindex;
15138 u8 frame_type;
15139
15140 ifindex = if_nametoindex(intf);
15141 if (ifindex == 0) {
15142 sigma_dut_print(dut, DUT_MSG_ERROR,
15143 "%s: Index for interface %s failed",
15144 __func__, intf);
15145 return -1;
15146 }
15147
15148 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15149 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
15150 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15151 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
15152 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15153 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
15154 } else {
15155 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
15156 __func__, oci_frametype);
15157 return -1;
15158 }
15159
15160
15161 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
15162 NL80211_CMD_VENDOR)) ||
15163 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
15164 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
15165 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
15166 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
15167 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
15168 !(params = nla_nest_start(
15169 msg,
15170 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
15171 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
15172 frame_type) ||
15173 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
15174 oci_freq)) {
15175 sigma_dut_print(dut, DUT_MSG_ERROR,
15176 "%s: err in adding vendor_cmd and vendor_data",
15177 __func__);
15178 nlmsg_free(msg);
15179 return -1;
15180 }
15181 nla_nest_end(msg, params);
15182 nla_nest_end(msg, attr);
15183
15184 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
15185 if (ret) {
15186 sigma_dut_print(dut, DUT_MSG_ERROR,
15187 "%s: err in send_and_recv_msgs, ret=%d",
15188 __func__, ret);
15189 }
15190 return ret;
15191#else /* NL80211_SUPPORT */
15192 sigma_dut_print(dut, DUT_MSG_ERROR,
15193 "OCI override not possible without NL80211_SUPPORT defined");
15194 return -1;
15195#endif /* NL80211_SUPPORT */
15196}
15197
15198
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015199static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
15200 uint8_t ignore_csa)
15201{
15202#ifdef NL80211_SUPPORT
15203 return wcn_wifi_test_config_set_u8(
15204 dut, intf,
15205 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
15206#else /* NL80211_SUPPORT */
15207 sigma_dut_print(dut, DUT_MSG_ERROR,
15208 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
15209 return -1;
15210#endif /* NL80211_SUPPORT */
15211}
15212
15213
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015214static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
15215 uint8_t rsnxe_used)
15216{
15217#ifdef NL80211_SUPPORT
15218 return wcn_wifi_test_config_set_u8(
15219 dut, intf,
15220 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
15221 rsnxe_used);
15222#else /* NL80211_SUPPORT */
15223 sigma_dut_print(dut, DUT_MSG_ERROR,
15224 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
15225 return -1;
15226#endif /* NL80211_SUPPORT */
15227}
15228
15229
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015230static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
15231 const char *intf,
15232 uint8_t ignore_sa_query_timeout)
15233{
15234#ifdef NL80211_SUPPORT
15235 return wcn_wifi_test_config_set_u8(
15236 dut, intf,
15237 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
15238 ignore_sa_query_timeout);
15239#else /* NL80211_SUPPORT */
15240 sigma_dut_print(dut, DUT_MSG_ERROR,
15241 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
15242 return -1;
15243#endif /* NL80211_SUPPORT */
15244}
15245
15246
Jouni Malinen6250cb02020-04-15 13:54:45 +030015247static enum sigma_cmd_result
15248cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
15249 struct sigma_conn *conn,
15250 struct sigma_cmd *cmd)
15251{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015252 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030015253
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053015254 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030015255 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015256 if (wifi_chip_type == DRIVER_WCN) {
15257 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
15258 send_resp(dut, conn, SIGMA_ERROR,
15259 "errorCode,Failed to set ft_rsnxe_used");
15260 return STATUS_SENT_ERROR;
15261 }
15262 return SUCCESS_SEND_STATUS;
15263 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030015264 send_resp(dut, conn, SIGMA_ERROR,
15265 "errorCode,Failed to set ft_rsnxe_used");
15266 return STATUS_SENT_ERROR;
15267 }
15268 return SUCCESS_SEND_STATUS;
15269 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015270
15271 oci_chan = get_param(cmd, "OCIChannel");
15272 oci_frametype = get_param(cmd, "OCIFrameType");
15273 if (oci_chan && oci_frametype) {
15274 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
15275 char buf[100];
15276
15277 if (!oci_freq) {
15278 send_resp(dut, conn, SIGMA_ERROR,
15279 "errorCode,Invalid OCIChannel number");
15280 return STATUS_SENT_ERROR;
15281 }
15282
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015283 if (wifi_chip_type == DRIVER_WCN &&
15284 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
15285 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
15286 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
15287 if (wcn_sta_override_oci(dut, intf, oci_frametype,
15288 oci_freq)) {
15289 send_resp(dut, conn, SIGMA_ERROR,
15290 "errorCode,Failed to override OCI");
15291 return STATUS_SENT_ERROR;
15292 }
15293 return SUCCESS_SEND_STATUS;
15294 }
15295
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015296 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
15297 snprintf(buf, sizeof(buf),
15298 "SET oci_freq_override_eapol %d", oci_freq);
15299 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15300 snprintf(buf, sizeof(buf),
15301 "SET oci_freq_override_saquery_req %d",
15302 oci_freq);
15303 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15304 snprintf(buf, sizeof(buf),
15305 "SET oci_freq_override_saquery_resp %d",
15306 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015307 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
15308 snprintf(buf, sizeof(buf),
15309 "SET oci_freq_override_eapol_g2 %d",
15310 oci_freq);
15311 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15312 snprintf(buf, sizeof(buf),
15313 "SET oci_freq_override_ft_assoc %d",
15314 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015315 } else {
15316 send_resp(dut, conn, SIGMA_ERROR,
15317 "errorCode,Unsupported OCIFrameType");
15318 return STATUS_SENT_ERROR;
15319 }
15320 if (wpa_command(intf, buf) < 0) {
15321 send_resp(dut, conn, SIGMA_ERROR,
15322 "errorCode,Failed to set oci_freq_override");
15323 return STATUS_SENT_ERROR;
15324 }
15325 return SUCCESS_SEND_STATUS;
15326 }
15327
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015328 val = get_param(cmd, "IgnoreCSA");
15329 if (val && atoi(val) == 1) {
15330 if (wifi_chip_type == DRIVER_WCN) {
15331 if (wcn_sta_ignore_csa(dut, intf, 1)) {
15332 send_resp(dut, conn, SIGMA_ERROR,
15333 "errorCode,Failed to set ignore CSA");
15334 return STATUS_SENT_ERROR;
15335 }
15336 return SUCCESS_SEND_STATUS;
15337 }
15338 }
15339
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015340 val = get_param(cmd, "Deauth_Per_SAQueryResp");
15341 if (val && atoi(val) == 0) {
15342 if (wifi_chip_type == DRIVER_WCN) {
15343 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
15344 send_resp(dut, conn, SIGMA_ERROR,
15345 "errorCode,Failed to set ignore SA Query timeout");
15346 return STATUS_SENT_ERROR;
15347 }
15348 return SUCCESS_SEND_STATUS;
15349 }
15350 }
15351
Jouni Malinen6250cb02020-04-15 13:54:45 +030015352 send_resp(dut, conn, SIGMA_ERROR,
15353 "errorCode,Unsupported WPA3 rfeature");
15354 return STATUS_SENT_ERROR;
15355}
15356
15357
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015358static enum sigma_cmd_result
15359cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
15360 struct sigma_conn *conn, struct sigma_cmd *cmd)
15361{
15362 const char *val;
15363
15364 val = get_param(cmd, "DomainName_Domain");
15365 if (val) {
15366 if (strlen(val) >= sizeof(dut->qm_domain_name))
15367 return ERROR_SEND_STATUS;
15368
15369 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
15370 return SUCCESS_SEND_STATUS;
15371 }
15372
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053015373 val = get_param(cmd, "DSCPPolicy_PolicyID");
15374 if (val) {
15375 unsigned int i;
15376 int policy_id = atoi(val);
15377
15378 val = get_param(cmd, "DSCPPolicy_RequestType");
15379
15380 if (!policy_id || !val)
15381 return INVALID_SEND_STATUS;
15382
15383 if (dut->num_dscp_status >= ARRAY_SIZE(dut->dscp_status)) {
15384 send_resp(dut, conn, SIGMA_ERROR,
15385 "errorCode,DSCP status list full");
15386 return STATUS_SENT_ERROR;
15387 }
15388
15389 for (i = 0; i < dut->num_dscp_status; i++)
15390 if (dut->dscp_status[i].id == policy_id)
15391 break;
15392
15393 /* New policy configured */
15394 if (i == dut->num_dscp_status) {
15395 dut->dscp_status[i].id = policy_id;
15396 dut->num_dscp_status++;
15397 }
15398
15399 dut->dscp_status[i].status = strcasecmp(val, "Remove") ?
15400 DSCP_POLICY_SUCCESS : DSCP_POLICY_REJECT;
15401
15402 return SUCCESS_SEND_STATUS;
15403 }
15404
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015405 send_resp(dut, conn, SIGMA_ERROR,
15406 "errorCode,Unsupported QM rfeature");
15407 return STATUS_SENT_ERROR;
15408}
15409
15410
Jouni Malinenf7222712019-06-13 01:50:21 +030015411static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
15412 struct sigma_conn *conn,
15413 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015414{
15415 const char *intf = get_param(cmd, "Interface");
15416 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015417 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015418
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015419 if (!prog)
15420 prog = get_param(cmd, "Program");
15421
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015422 if (intf == NULL || prog == NULL)
15423 return -1;
15424
Ashwini Patil5acd7382017-04-13 15:55:04 +053015425 /* BSS Transition candidate list for BTM query */
15426 val = get_param(cmd, "Nebor_BSSID");
15427 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
15428 return 0;
15429
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015430 if (strcasecmp(prog, "TDLS") == 0)
15431 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
15432
15433 if (strcasecmp(prog, "VHT") == 0)
15434 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
15435
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015436 if (strcasecmp(prog, "HE") == 0)
15437 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
15438
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015439 if (strcasecmp(prog, "MBO") == 0) {
15440 val = get_param(cmd, "Cellular_Data_Cap");
15441 if (val &&
15442 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
15443 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053015444
15445 val = get_param(cmd, "Ch_Pref");
15446 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
15447 return 0;
15448
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015449 return 1;
15450 }
15451
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015452 if (strcasecmp(prog, "60GHz") == 0)
15453 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
15454
Jouni Malinen6250cb02020-04-15 13:54:45 +030015455 if (strcasecmp(prog, "WPA3") == 0)
15456 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015457 if (strcasecmp(prog, "QM") == 0)
15458 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030015459
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015460 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
15461 return 0;
15462}
15463
15464
Jouni Malinenf7222712019-06-13 01:50:21 +030015465static enum sigma_cmd_result cmd_sta_set_radio(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 *mode = get_param(cmd, "Mode");
15471 int res;
15472
15473 if (intf == NULL || mode == NULL)
15474 return -1;
15475
15476 if (strcasecmp(mode, "On") == 0)
15477 res = wpa_command(intf, "SET radio_disabled 0");
15478 else if (strcasecmp(mode, "Off") == 0)
15479 res = wpa_command(intf, "SET radio_disabled 1");
15480 else
15481 return -1;
15482
15483 if (res) {
15484 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15485 "radio mode");
15486 return 0;
15487 }
15488
15489 return 1;
15490}
15491
15492
Jouni Malinenf7222712019-06-13 01:50:21 +030015493static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
15494 struct sigma_conn *conn,
15495 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015496{
15497 const char *intf = get_param(cmd, "Interface");
15498 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015499 const char *prog = get_param(cmd, "program");
15500 const char *powersave = get_param(cmd, "powersave");
15501 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015502
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015503 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015504 return -1;
15505
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015506 if (prog && strcasecmp(prog, "60GHz") == 0) {
15507 /*
15508 * The CAPI mode parameter does not exist in 60G
15509 * unscheduled PS.
15510 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080015511 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015512 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015513 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020015514 strcasecmp(prog, "HE") == 0) {
15515 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015516 } else {
15517 if (mode == NULL)
15518 return -1;
15519
15520 if (strcasecmp(mode, "On") == 0)
15521 res = set_ps(intf, dut, 1);
15522 else if (strcasecmp(mode, "Off") == 0)
15523 res = set_ps(intf, dut, 0);
15524 else
15525 return -1;
15526 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015527
15528 if (res) {
15529 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15530 "power save mode");
15531 return 0;
15532 }
15533
15534 return 1;
15535}
15536
15537
Jouni Malinenf7222712019-06-13 01:50:21 +030015538static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
15539 struct sigma_conn *conn,
15540 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015541{
15542 const char *intf = get_param(cmd, "Interface");
15543 const char *val, *bssid;
15544 int res;
15545 char *buf;
15546 size_t buf_len;
15547
15548 val = get_param(cmd, "BSSID_FILTER");
15549 if (val == NULL)
15550 return -1;
15551
15552 bssid = get_param(cmd, "BSSID_List");
15553 if (atoi(val) == 0 || bssid == NULL) {
15554 /* Disable BSSID filter */
15555 if (wpa_command(intf, "SET bssid_filter ")) {
15556 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
15557 "to disable BSSID filter");
15558 return 0;
15559 }
15560
15561 return 1;
15562 }
15563
15564 buf_len = 100 + strlen(bssid);
15565 buf = malloc(buf_len);
15566 if (buf == NULL)
15567 return -1;
15568
15569 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
15570 res = wpa_command(intf, buf);
15571 free(buf);
15572 if (res) {
15573 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
15574 "BSSID filter");
15575 return 0;
15576 }
15577
15578 return 1;
15579}
15580
15581
Jouni Malinenf7222712019-06-13 01:50:21 +030015582static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
15583 struct sigma_conn *conn,
15584 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015585{
15586 const char *intf = get_param(cmd, "Interface");
15587 const char *val;
15588
15589 /* TODO: ARP */
15590
15591 val = get_param(cmd, "HS2_CACHE_PROFILE");
15592 if (val && strcasecmp(val, "All") == 0)
15593 hs2_clear_credentials(intf);
15594
15595 return 1;
15596}
15597
15598
Jouni Malinenf7222712019-06-13 01:50:21 +030015599static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
15600 struct sigma_conn *conn,
15601 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015602{
15603 const char *intf = get_param(cmd, "Interface");
15604 const char *key_type = get_param(cmd, "KeyType");
15605 char buf[100], resp[200];
15606
15607 if (key_type == NULL)
15608 return -1;
15609
15610 if (strcasecmp(key_type, "GTK") == 0) {
15611 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
15612 strncmp(buf, "FAIL", 4) == 0) {
15613 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15614 "not fetch current GTK");
15615 return 0;
15616 }
15617 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
15618 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15619 return 0;
15620 } else {
15621 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
15622 "KeyType");
15623 return 0;
15624 }
15625
15626 return 1;
15627}
15628
15629
15630static int hs2_set_policy(struct sigma_dut *dut)
15631{
15632#ifdef ANDROID
15633 system("ip rule del prio 23000");
15634 if (system("ip rule add from all lookup main prio 23000") != 0) {
15635 sigma_dut_print(dut, DUT_MSG_ERROR,
15636 "Failed to run:ip rule add from all lookup main prio");
15637 return -1;
15638 }
15639 if (system("ip route flush cache") != 0) {
15640 sigma_dut_print(dut, DUT_MSG_ERROR,
15641 "Failed to run ip route flush cache");
15642 return -1;
15643 }
15644 return 1;
15645#else /* ANDROID */
15646 return 0;
15647#endif /* ANDROID */
15648}
15649
15650
Jouni Malinenf7222712019-06-13 01:50:21 +030015651static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
15652 struct sigma_conn *conn,
15653 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015654{
15655 const char *intf = get_param(cmd, "Interface");
15656 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030015657 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015658 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030015659 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015660 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
15661 int tries = 0;
15662 int ignore_blacklist = 0;
15663 const char *events[] = {
15664 "CTRL-EVENT-CONNECTED",
15665 "INTERWORKING-BLACKLISTED",
15666 "INTERWORKING-NO-MATCH",
15667 NULL
15668 };
15669
15670 start_sta_mode(dut);
15671
Jouni Malinen439352d2018-09-13 03:42:23 +030015672 if (band) {
15673 if (strcmp(band, "2.4") == 0) {
15674 wpa_command(intf, "SET setband 2G");
15675 } else if (strcmp(band, "5") == 0) {
15676 wpa_command(intf, "SET setband 5G");
15677 } else {
15678 send_resp(dut, conn, SIGMA_ERROR,
15679 "errorCode,Unsupported band");
15680 return 0;
15681 }
15682 }
15683
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015684 blacklisted[0] = '\0';
15685 if (val && atoi(val))
15686 ignore_blacklist = 1;
15687
15688try_again:
15689 ctrl = open_wpa_mon(intf);
15690 if (ctrl == NULL) {
15691 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15692 "wpa_supplicant monitor connection");
15693 return -2;
15694 }
15695
15696 tries++;
15697 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
15698 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
15699 "Interworking connection");
15700 wpa_ctrl_detach(ctrl);
15701 wpa_ctrl_close(ctrl);
15702 return 0;
15703 }
15704
15705 buf[0] = '\0';
15706 while (1) {
15707 char *pos;
15708 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15709 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
15710 if (!pos)
15711 break;
15712 pos += 25;
15713 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
15714 pos);
15715 if (!blacklisted[0])
15716 memcpy(blacklisted, pos, strlen(pos) + 1);
15717 }
15718
15719 if (ignore_blacklist && blacklisted[0]) {
15720 char *end;
15721 end = strchr(blacklisted, ' ');
15722 if (end)
15723 *end = '\0';
15724 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
15725 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030015726 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
15727 blacklisted);
15728 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015729 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
15730 wpa_ctrl_detach(ctrl);
15731 wpa_ctrl_close(ctrl);
15732 return 0;
15733 }
15734 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15735 buf, sizeof(buf));
15736 }
15737
15738 wpa_ctrl_detach(ctrl);
15739 wpa_ctrl_close(ctrl);
15740
15741 if (res < 0) {
15742 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15743 "connect");
15744 return 0;
15745 }
15746
15747 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
15748 strstr(buf, "INTERWORKING-BLACKLISTED")) {
15749 if (tries < 2) {
15750 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
15751 goto try_again;
15752 }
15753 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
15754 "matching credentials found");
15755 return 0;
15756 }
15757
15758 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15759 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15760 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15761 "get current BSSID/SSID");
15762 return 0;
15763 }
15764
15765 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
15766 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15767 hs2_set_policy(dut);
15768 return 0;
15769}
15770
15771
Jouni Malinenf7222712019-06-13 01:50:21 +030015772static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
15773 struct sigma_conn *conn,
15774 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015775{
15776 const char *intf = get_param(cmd, "Interface");
15777 const char *display = get_param(cmd, "Display");
15778 struct wpa_ctrl *ctrl;
15779 char buf[300], params[400], *pos;
15780 char bssid[20];
15781 int info_avail = 0;
15782 unsigned int old_timeout;
15783 int res;
15784
15785 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
15786 send_resp(dut, conn, SIGMA_ERROR,
15787 "ErrorCode,Could not get current BSSID");
15788 return 0;
15789 }
15790 ctrl = open_wpa_mon(intf);
15791 if (!ctrl) {
15792 sigma_dut_print(dut, DUT_MSG_ERROR,
15793 "Failed to open wpa_supplicant monitor connection");
15794 return -2;
15795 }
15796
15797 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
15798 wpa_command(intf, buf);
15799
15800 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
15801 if (res < 0) {
15802 send_resp(dut, conn, SIGMA_ERROR,
15803 "ErrorCode,Could not complete GAS query");
15804 goto fail;
15805 }
15806
15807 old_timeout = dut->default_timeout;
15808 dut->default_timeout = 2;
15809 res = get_wpa_cli_event(dut, ctrl, "RX-VENUE-URL", buf, sizeof(buf));
15810 dut->default_timeout = old_timeout;
15811 if (res < 0)
15812 goto done;
15813 pos = strchr(buf, ' ');
15814 if (!pos)
15815 goto done;
15816 pos++;
15817 pos = strchr(pos, ' ');
15818 if (!pos)
15819 goto done;
15820 pos++;
15821 info_avail = 1;
15822 snprintf(params, sizeof(params), "browser %s", pos);
15823
15824 if (display && strcasecmp(display, "Yes") == 0) {
15825 pid_t pid;
15826
15827 pid = fork();
15828 if (pid < 0) {
15829 perror("fork");
15830 return -1;
15831 }
15832
15833 if (pid == 0) {
15834 run_hs20_osu(dut, params);
15835 exit(0);
15836 }
15837 }
15838
15839done:
15840 snprintf(buf, sizeof(buf), "Info_available,%s",
15841 info_avail ? "Yes" : "No");
15842 send_resp(dut, conn, SIGMA_COMPLETE, buf);
15843fail:
15844 wpa_ctrl_detach(ctrl);
15845 wpa_ctrl_close(ctrl);
15846 return 0;
15847}
15848
15849
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015850static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
15851 struct sigma_conn *conn,
15852 const char *ifname,
15853 struct sigma_cmd *cmd)
15854{
15855 const char *val;
15856 int id;
15857
15858 id = add_cred(ifname);
15859 if (id < 0)
15860 return -2;
15861 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15862
15863 val = get_param(cmd, "prefer");
15864 if (val && atoi(val) > 0)
15865 set_cred(ifname, id, "priority", "1");
15866
15867 val = get_param(cmd, "REALM");
15868 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
15869 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15870 "realm");
15871 return 0;
15872 }
15873
15874 val = get_param(cmd, "HOME_FQDN");
15875 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
15876 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15877 "home_fqdn");
15878 return 0;
15879 }
15880
15881 val = get_param(cmd, "Username");
15882 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
15883 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15884 "username");
15885 return 0;
15886 }
15887
15888 val = get_param(cmd, "Password");
15889 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
15890 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15891 "password");
15892 return 0;
15893 }
15894
15895 val = get_param(cmd, "ROOT_CA");
15896 if (val) {
15897 char fname[200];
15898 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
15899#ifdef __linux__
15900 if (!file_exists(fname)) {
15901 char msg[300];
15902 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
15903 "file (%s) not found", fname);
15904 send_resp(dut, conn, SIGMA_ERROR, msg);
15905 return 0;
15906 }
15907#endif /* __linux__ */
15908 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
15909 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15910 "not set root CA");
15911 return 0;
15912 }
15913 }
15914
15915 return 1;
15916}
15917
15918
15919static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
15920{
15921 FILE *in, *out;
15922 char buf[500];
15923 int found = 0;
15924
15925 in = fopen("devdetail.xml", "r");
15926 if (in == NULL)
15927 return -1;
15928 out = fopen("devdetail.xml.tmp", "w");
15929 if (out == NULL) {
15930 fclose(in);
15931 return -1;
15932 }
15933
15934 while (fgets(buf, sizeof(buf), in)) {
15935 char *pos = strstr(buf, "<IMSI>");
15936 if (pos) {
15937 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
15938 imsi);
15939 pos += 6;
15940 *pos = '\0';
15941 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
15942 found++;
15943 } else {
15944 fprintf(out, "%s", buf);
15945 }
15946 }
15947
15948 fclose(out);
15949 fclose(in);
15950 if (found)
15951 rename("devdetail.xml.tmp", "devdetail.xml");
15952 else
15953 unlink("devdetail.xml.tmp");
15954
15955 return 0;
15956}
15957
15958
15959static int sta_add_credential_sim(struct sigma_dut *dut,
15960 struct sigma_conn *conn,
15961 const char *ifname, struct sigma_cmd *cmd)
15962{
15963 const char *val, *imsi = NULL;
15964 int id;
15965 char buf[200];
15966 int res;
15967 const char *pos;
15968 size_t mnc_len;
15969 char plmn_mcc[4];
15970 char plmn_mnc[4];
15971
15972 id = add_cred(ifname);
15973 if (id < 0)
15974 return -2;
15975 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15976
15977 val = get_param(cmd, "prefer");
15978 if (val && atoi(val) > 0)
15979 set_cred(ifname, id, "priority", "1");
15980
15981 val = get_param(cmd, "PLMN_MCC");
15982 if (val == NULL) {
15983 send_resp(dut, conn, SIGMA_ERROR,
15984 "errorCode,Missing PLMN_MCC");
15985 return 0;
15986 }
15987 if (strlen(val) != 3) {
15988 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
15989 return 0;
15990 }
15991 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
15992
15993 val = get_param(cmd, "PLMN_MNC");
15994 if (val == NULL) {
15995 send_resp(dut, conn, SIGMA_ERROR,
15996 "errorCode,Missing PLMN_MNC");
15997 return 0;
15998 }
15999 if (strlen(val) != 2 && strlen(val) != 3) {
16000 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
16001 return 0;
16002 }
16003 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
16004
16005 val = get_param(cmd, "IMSI");
16006 if (val == NULL) {
16007 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
16008 "IMSI");
16009 return 0;
16010 }
16011
16012 imsi = pos = val;
16013
16014 if (strncmp(plmn_mcc, pos, 3) != 0) {
16015 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
16016 return 0;
16017 }
16018 pos += 3;
16019
16020 mnc_len = strlen(plmn_mnc);
16021 if (mnc_len < 2) {
16022 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
16023 return 0;
16024 }
16025
16026 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
16027 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
16028 return 0;
16029 }
16030 pos += mnc_len;
16031
16032 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
16033 if (res < 0 || res >= (int) sizeof(buf))
16034 return -1;
16035 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
16036 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16037 "not set IMSI");
16038 return 0;
16039 }
16040
16041 val = get_param(cmd, "Password");
16042 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
16043 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16044 "not set password");
16045 return 0;
16046 }
16047
Jouni Malinenba630452018-06-22 11:49:59 +030016048 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016049 /*
16050 * Set provisioning_sp for the test cases where SIM/USIM
16051 * provisioning is used.
16052 */
16053 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
16054 "wi-fi.org") < 0) {
16055 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16056 "not set provisioning_sp");
16057 return 0;
16058 }
16059
16060 update_devdetail_imsi(dut, imsi);
16061 }
16062
16063 return 1;
16064}
16065
16066
16067static int sta_add_credential_cert(struct sigma_dut *dut,
16068 struct sigma_conn *conn,
16069 const char *ifname,
16070 struct sigma_cmd *cmd)
16071{
16072 const char *val;
16073 int id;
16074
16075 id = add_cred(ifname);
16076 if (id < 0)
16077 return -2;
16078 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16079
16080 val = get_param(cmd, "prefer");
16081 if (val && atoi(val) > 0)
16082 set_cred(ifname, id, "priority", "1");
16083
16084 val = get_param(cmd, "REALM");
16085 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
16086 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16087 "realm");
16088 return 0;
16089 }
16090
16091 val = get_param(cmd, "HOME_FQDN");
16092 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
16093 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16094 "home_fqdn");
16095 return 0;
16096 }
16097
16098 val = get_param(cmd, "Username");
16099 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
16100 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16101 "username");
16102 return 0;
16103 }
16104
16105 val = get_param(cmd, "clientCertificate");
16106 if (val) {
16107 char fname[200];
16108 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16109#ifdef __linux__
16110 if (!file_exists(fname)) {
16111 char msg[300];
16112 snprintf(msg, sizeof(msg),
16113 "ErrorCode,clientCertificate "
16114 "file (%s) not found", fname);
16115 send_resp(dut, conn, SIGMA_ERROR, msg);
16116 return 0;
16117 }
16118#endif /* __linux__ */
16119 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
16120 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16121 "not set client_cert");
16122 return 0;
16123 }
16124 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
16125 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16126 "not set private_key");
16127 return 0;
16128 }
16129 }
16130
16131 val = get_param(cmd, "ROOT_CA");
16132 if (val) {
16133 char fname[200];
16134 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16135#ifdef __linux__
16136 if (!file_exists(fname)) {
16137 char msg[300];
16138 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16139 "file (%s) not found", fname);
16140 send_resp(dut, conn, SIGMA_ERROR, msg);
16141 return 0;
16142 }
16143#endif /* __linux__ */
16144 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16145 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16146 "not set root CA");
16147 return 0;
16148 }
16149 }
16150
16151 return 1;
16152}
16153
16154
Jouni Malinenf7222712019-06-13 01:50:21 +030016155static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
16156 struct sigma_conn *conn,
16157 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016158{
16159 const char *intf = get_param(cmd, "Interface");
16160 const char *type;
16161
16162 start_sta_mode(dut);
16163
16164 type = get_param(cmd, "Type");
16165 if (!type)
16166 return -1;
16167
16168 if (strcasecmp(type, "uname_pwd") == 0)
16169 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
16170
16171 if (strcasecmp(type, "sim") == 0)
16172 return sta_add_credential_sim(dut, conn, intf, cmd);
16173
16174 if (strcasecmp(type, "cert") == 0)
16175 return sta_add_credential_cert(dut, conn, intf, cmd);
16176
16177 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
16178 "type");
16179 return 0;
16180}
16181
16182
Jouni Malinenf7222712019-06-13 01:50:21 +030016183static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
16184 struct sigma_conn *conn,
16185 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016186{
16187 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016188 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070016189 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053016190 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016191 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016192 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016193 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016194 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016195
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020016196 start_sta_mode(dut);
16197
Arif Hussain66a4af02019-02-07 15:04:51 -080016198 val = get_param(cmd, "GetParameter");
16199 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016200 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080016201 buf, sizeof(buf)) < 0) {
16202 sigma_dut_print(dut, DUT_MSG_ERROR,
16203 "Could not get ssid bssid");
16204 return ERROR_SEND_STATUS;
16205 }
16206
16207 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
16208 send_resp(dut, conn, SIGMA_COMPLETE, buf);
16209 return STATUS_SENT;
16210 }
16211
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016212 val = get_param(cmd, "HESSID");
16213 if (val) {
16214 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
16215 if (res < 0 || res >= (int) sizeof(buf))
16216 return -1;
16217 wpa_command(intf, buf);
16218 }
16219
16220 val = get_param(cmd, "ACCS_NET_TYPE");
16221 if (val) {
16222 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
16223 val);
16224 if (res < 0 || res >= (int) sizeof(buf))
16225 return -1;
16226 wpa_command(intf, buf);
16227 }
16228
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016229 if (get_param(cmd, "RxMac"))
16230 sta_set_scan_unicast_probe(dut, intf, 1);
16231
vamsi krishna89ad8c62017-09-19 12:51:18 +053016232 bssid = get_param(cmd, "Bssid");
16233 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016234 if (!bssid)
16235 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053016236
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016237 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
16238 dut->device_type == STA_testbed) {
16239 ssid = NULL;
16240 wildcard_ssid = 1;
16241 }
16242
vamsi krishna89ad8c62017-09-19 12:51:18 +053016243 if (ssid) {
16244 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
16245 send_resp(dut, conn, SIGMA_ERROR,
16246 "ErrorCode,Too long SSID");
16247 return 0;
16248 }
16249 ascii2hexstr(ssid, ssid_hex);
16250 }
16251
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016252 short_ssid = get_param(cmd, "ShortSSID");
16253 if (short_ssid) {
16254 uint32_t short_ssid_hex;
16255
16256 short_ssid_hex = strtoul(short_ssid, NULL, 16);
16257 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
16258 (((short_ssid_hex >> 8) & 0xFF) << 16) |
16259 (((short_ssid_hex >> 16) & 0xFF) << 8) |
16260 ((short_ssid_hex >> 24) & 0xFF);
16261
16262 res = snprintf(buf, sizeof(buf),
16263 "VENDOR_ELEM_ADD 14 ff053a%08x",
16264 short_ssid_hex);
16265 if (res < 0 || res >= (int) sizeof(buf) ||
16266 wpa_command(intf, buf)) {
16267 send_resp(dut, conn, SIGMA_ERROR,
16268 "errorCode,Failed to add short SSID");
16269 return STATUS_SENT_ERROR;
16270 }
16271 }
16272
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016273 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053016274 if (scan_freq) {
16275 if (strcasecmp(scan_freq, "2G") == 0)
16276 scan_freq = "2412-2462";
16277 else if (strcasecmp(scan_freq, "5G") == 0)
16278 scan_freq = "5180-5925";
16279 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016280
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016281 val = get_param(cmd, "WaitCompletion");
16282 if (val && atoi(val) == 1) {
16283 ctrl = open_wpa_mon(intf);
16284 if (!ctrl) {
16285 send_resp(dut, conn, SIGMA_ERROR,
16286 "errorCode,Failed to open monitor socket");
16287 return STATUS_SENT_ERROR;
16288 }
16289 }
16290
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016291 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053016292 bssid ? " bssid=": "",
16293 bssid ? bssid : "",
16294 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016295 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016296 wildcard_ssid ? " wildcard_ssid=1" : "",
16297 scan_freq ? " freq=" : "",
16298 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016299 if (res < 0 || res >= (int) sizeof(buf)) {
16300 send_resp(dut, conn, SIGMA_ERROR,
16301 "errorCode,Could not build scan command");
16302 status = STATUS_SENT_ERROR;
16303 goto remove_s_ssid;
16304 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053016305
Veerendranathdc581b52020-08-10 03:29:08 -070016306 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
16307 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
16308 sigma_dut_print(dut, DUT_MSG_DEBUG,
16309 "Scan request rejected with busy status, abort ongoing scan and try again");
16310 wpa_command(intf, "ABORT_SCAN");
16311 res = wpa_command(intf, buf);
16312 }
16313
16314 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016315 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
16316 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016317 status = STATUS_SENT_ERROR;
16318 } else {
16319 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016320 }
16321
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016322remove_s_ssid:
16323 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
16324 sigma_dut_print(dut, DUT_MSG_ERROR,
16325 "Failed to delete vendor element");
16326
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016327 if (ctrl) {
16328 if (status == SUCCESS_SEND_STATUS) {
16329 res = get_wpa_cli_event(dut, ctrl,
16330 "CTRL-EVENT-SCAN-RESULTS",
16331 buf, sizeof(buf));
16332 if (res < 0) {
16333 send_resp(dut, conn, SIGMA_ERROR,
16334 "ErrorCode,scan did not complete");
16335 status = STATUS_SENT_ERROR;
16336 }
16337 }
16338
16339 wpa_ctrl_detach(ctrl);
16340 wpa_ctrl_close(ctrl);
16341 }
16342
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016343 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016344}
16345
16346
Jouni Malinenf7222712019-06-13 01:50:21 +030016347static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
16348 struct sigma_conn *conn,
16349 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016350{
16351 const char *intf = get_param(cmd, "Interface");
16352 const char *bssid;
16353 char buf[4096], *pos;
16354 int freq, chan;
16355 char *ssid;
16356 char resp[100];
16357 int res;
16358 struct wpa_ctrl *ctrl;
16359
16360 bssid = get_param(cmd, "BSSID");
16361 if (!bssid) {
16362 send_resp(dut, conn, SIGMA_INVALID,
16363 "errorCode,BSSID argument is missing");
16364 return 0;
16365 }
16366
16367 ctrl = open_wpa_mon(intf);
16368 if (!ctrl) {
16369 sigma_dut_print(dut, DUT_MSG_ERROR,
16370 "Failed to open wpa_supplicant monitor connection");
16371 return -1;
16372 }
16373
16374 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
16375 send_resp(dut, conn, SIGMA_ERROR,
16376 "errorCode,Could not start scan");
16377 wpa_ctrl_detach(ctrl);
16378 wpa_ctrl_close(ctrl);
16379 return 0;
16380 }
16381
16382 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
16383 buf, sizeof(buf));
16384
16385 wpa_ctrl_detach(ctrl);
16386 wpa_ctrl_close(ctrl);
16387
16388 if (res < 0) {
16389 send_resp(dut, conn, SIGMA_ERROR,
16390 "errorCode,Scan did not complete");
16391 return 0;
16392 }
16393
16394 snprintf(buf, sizeof(buf), "BSS %s", bssid);
16395 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
16396 strncmp(buf, "id=", 3) != 0) {
16397 send_resp(dut, conn, SIGMA_ERROR,
16398 "errorCode,Specified BSSID not found");
16399 return 0;
16400 }
16401
16402 pos = strstr(buf, "\nfreq=");
16403 if (!pos) {
16404 send_resp(dut, conn, SIGMA_ERROR,
16405 "errorCode,Channel not found");
16406 return 0;
16407 }
16408 freq = atoi(pos + 6);
16409 chan = freq_to_channel(freq);
16410
16411 pos = strstr(buf, "\nssid=");
16412 if (!pos) {
16413 send_resp(dut, conn, SIGMA_ERROR,
16414 "errorCode,SSID not found");
16415 return 0;
16416 }
16417 ssid = pos + 6;
16418 pos = strchr(ssid, '\n');
16419 if (pos)
16420 *pos = '\0';
16421 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
16422 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16423 return 0;
16424}
16425
16426
Jouni Malinenf7222712019-06-13 01:50:21 +030016427static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
16428 struct sigma_conn *conn,
16429 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016430{
16431#ifdef __linux__
16432 struct timeval tv;
16433 struct tm tm;
16434 time_t t;
16435 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016436 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016437
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016438 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016439
16440 memset(&tm, 0, sizeof(tm));
16441 val = get_param(cmd, "seconds");
16442 if (val)
16443 tm.tm_sec = atoi(val);
16444 val = get_param(cmd, "minutes");
16445 if (val)
16446 tm.tm_min = atoi(val);
16447 val = get_param(cmd, "hours");
16448 if (val)
16449 tm.tm_hour = atoi(val);
16450 val = get_param(cmd, "date");
16451 if (val)
16452 tm.tm_mday = atoi(val);
16453 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016454 if (val) {
16455 v = atoi(val);
16456 if (v < 1 || v > 12) {
16457 send_resp(dut, conn, SIGMA_INVALID,
16458 "errorCode,Invalid month");
16459 return 0;
16460 }
16461 tm.tm_mon = v - 1;
16462 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016463 val = get_param(cmd, "year");
16464 if (val) {
16465 int year = atoi(val);
16466#ifdef ANDROID
16467 if (year > 2035)
16468 year = 2035; /* years beyond 2035 not supported */
16469#endif /* ANDROID */
16470 tm.tm_year = year - 1900;
16471 }
16472 t = mktime(&tm);
16473 if (t == (time_t) -1) {
16474 send_resp(dut, conn, SIGMA_ERROR,
16475 "errorCode,Invalid date or time");
16476 return 0;
16477 }
16478
16479 memset(&tv, 0, sizeof(tv));
16480 tv.tv_sec = t;
16481
16482 if (settimeofday(&tv, NULL) < 0) {
16483 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
16484 strerror(errno));
16485 send_resp(dut, conn, SIGMA_ERROR,
16486 "errorCode,Failed to set time");
16487 return 0;
16488 }
16489
16490 return 1;
16491#endif /* __linux__ */
16492
16493 return -1;
16494}
16495
16496
Jouni Malinenf7222712019-06-13 01:50:21 +030016497static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
16498 struct sigma_conn *conn,
16499 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016500{
16501 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016502 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016503 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016504 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016505 int res;
16506 struct wpa_ctrl *ctrl;
16507
16508 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016509 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016510
16511 val = get_param(cmd, "ProdESSAssoc");
16512 if (val)
16513 prod_ess_assoc = atoi(val);
16514
16515 kill_dhcp_client(dut, intf);
16516 if (start_dhcp_client(dut, intf) < 0)
16517 return -2;
16518
16519 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
16520 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16521 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016522 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016523 prod_ess_assoc ? "" : "-N",
16524 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016525 name ? "'" : "",
16526 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
16527 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016528
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053016529 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016530 if (run_hs20_osu(dut, buf) < 0) {
16531 FILE *f;
16532
16533 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
16534
16535 f = fopen("hs20-osu-client.res", "r");
16536 if (f) {
16537 char resp[400], res[300], *pos;
16538 if (!fgets(res, sizeof(res), f))
16539 res[0] = '\0';
16540 pos = strchr(res, '\n');
16541 if (pos)
16542 *pos = '\0';
16543 fclose(f);
16544 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
16545 res);
16546 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
16547 if (system(resp) != 0) {
16548 }
16549 snprintf(resp, sizeof(resp),
16550 "SSID,,BSSID,,failureReason,%s", res);
16551 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16552 return 0;
16553 }
16554
16555 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16556 return 0;
16557 }
16558
16559 if (!prod_ess_assoc)
16560 goto report;
16561
16562 ctrl = open_wpa_mon(intf);
16563 if (ctrl == NULL) {
16564 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16565 "wpa_supplicant monitor connection");
16566 return -1;
16567 }
16568
16569 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
16570 buf, sizeof(buf));
16571
16572 wpa_ctrl_detach(ctrl);
16573 wpa_ctrl_close(ctrl);
16574
16575 if (res < 0) {
16576 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
16577 "network after OSU");
16578 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16579 return 0;
16580 }
16581
16582report:
16583 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
16584 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
16585 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
16586 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16587 return 0;
16588 }
16589
16590 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
16591 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016592 return 0;
16593}
16594
16595
Jouni Malinenf7222712019-06-13 01:50:21 +030016596static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
16597 struct sigma_conn *conn,
16598 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016599{
16600 const char *val;
16601 int timeout = 120;
16602
16603 val = get_param(cmd, "PolicyUpdate");
16604 if (val == NULL || atoi(val) == 0)
16605 return 1; /* No operation requested */
16606
16607 val = get_param(cmd, "Timeout");
16608 if (val)
16609 timeout = atoi(val);
16610
16611 if (timeout) {
16612 /* TODO: time out the command and return
16613 * PolicyUpdateStatus,TIMEOUT if needed. */
16614 }
16615
16616 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
16617 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16618 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
16619 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
16620 return 0;
16621 }
16622
16623 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
16624 return 0;
16625}
16626
16627
Jouni Malinenf7222712019-06-13 01:50:21 +030016628static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
16629 struct sigma_conn *conn,
16630 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016631{
16632 struct wpa_ctrl *ctrl;
16633 const char *intf = get_param(cmd, "Interface");
16634 const char *bssid = get_param(cmd, "Bssid");
16635 const char *ssid = get_param(cmd, "SSID");
16636 const char *security = get_param(cmd, "Security");
16637 const char *passphrase = get_param(cmd, "Passphrase");
16638 const char *pin = get_param(cmd, "PIN");
16639 char buf[1000];
16640 char ssid_hex[200], passphrase_hex[200];
16641 const char *keymgmt, *cipher;
16642
16643 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016644 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016645
16646 if (!bssid) {
16647 send_resp(dut, conn, SIGMA_ERROR,
16648 "ErrorCode,Missing Bssid argument");
16649 return 0;
16650 }
16651
16652 if (!ssid) {
16653 send_resp(dut, conn, SIGMA_ERROR,
16654 "ErrorCode,Missing SSID argument");
16655 return 0;
16656 }
16657
16658 if (!security) {
16659 send_resp(dut, conn, SIGMA_ERROR,
16660 "ErrorCode,Missing Security argument");
16661 return 0;
16662 }
16663
16664 if (!passphrase) {
16665 send_resp(dut, conn, SIGMA_ERROR,
16666 "ErrorCode,Missing Passphrase argument");
16667 return 0;
16668 }
16669
16670 if (!pin) {
16671 send_resp(dut, conn, SIGMA_ERROR,
16672 "ErrorCode,Missing PIN argument");
16673 return 0;
16674 }
16675
vamsi krishna8c9c1562017-05-12 15:51:46 +053016676 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
16677 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016678 send_resp(dut, conn, SIGMA_ERROR,
16679 "ErrorCode,Too long SSID/passphrase");
16680 return 0;
16681 }
16682
16683 ctrl = open_wpa_mon(intf);
16684 if (ctrl == NULL) {
16685 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16686 "wpa_supplicant monitor connection");
16687 return -2;
16688 }
16689
16690 if (strcasecmp(security, "wpa2-psk") == 0) {
16691 keymgmt = "WPA2PSK";
16692 cipher = "CCMP";
16693 } else {
16694 wpa_ctrl_detach(ctrl);
16695 wpa_ctrl_close(ctrl);
16696 send_resp(dut, conn, SIGMA_ERROR,
16697 "ErrorCode,Unsupported Security value");
16698 return 0;
16699 }
16700
16701 ascii2hexstr(ssid, ssid_hex);
16702 ascii2hexstr(passphrase, passphrase_hex);
16703 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
16704 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
16705
16706 if (wpa_command(intf, buf) < 0) {
16707 wpa_ctrl_detach(ctrl);
16708 wpa_ctrl_close(ctrl);
16709 send_resp(dut, conn, SIGMA_ERROR,
16710 "ErrorCode,Failed to start registrar");
16711 return 0;
16712 }
16713
16714 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
16715 dut->er_oper_performed = 1;
16716
16717 return wps_connection_event(dut, conn, ctrl, intf, 0);
16718}
16719
16720
Jouni Malinenf7222712019-06-13 01:50:21 +030016721static enum sigma_cmd_result
16722cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
16723 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016724{
16725 struct wpa_ctrl *ctrl;
16726 const char *intf = get_param(cmd, "Interface");
16727 const char *bssid = get_param(cmd, "Bssid");
16728 char buf[100];
16729
16730 if (!bssid) {
16731 send_resp(dut, conn, SIGMA_ERROR,
16732 "ErrorCode,Missing Bssid argument");
16733 return 0;
16734 }
16735
16736 ctrl = open_wpa_mon(intf);
16737 if (ctrl == NULL) {
16738 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16739 "wpa_supplicant monitor connection");
16740 return -2;
16741 }
16742
16743 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
16744
16745 if (wpa_command(intf, buf) < 0) {
16746 wpa_ctrl_detach(ctrl);
16747 wpa_ctrl_close(ctrl);
16748 send_resp(dut, conn, SIGMA_ERROR,
16749 "ErrorCode,Failed to start registrar");
16750 return 0;
16751 }
16752
16753 return wps_connection_event(dut, conn, ctrl, intf, 0);
16754}
16755
16756
Jouni Malinenf7222712019-06-13 01:50:21 +030016757static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
16758 struct sigma_conn *conn,
16759 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053016760{
16761 struct wpa_ctrl *ctrl;
16762 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016763 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016764 const char *config_method = get_param(cmd, "WPSConfigMethod");
16765 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053016766 int res;
16767 char buf[256];
16768 const char *events[] = {
16769 "CTRL-EVENT-CONNECTED",
16770 "WPS-OVERLAP-DETECTED",
16771 "WPS-TIMEOUT",
16772 "WPS-FAIL",
16773 NULL
16774 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016775 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053016776
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016777 /* 60G WPS tests do not pass Interface parameter */
16778 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016779 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016780
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016781 if (dut->mode == SIGMA_MODE_AP)
16782 return ap_wps_registration(dut, conn, cmd);
16783
16784 if (config_method) {
16785 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
16786 * sta_wps_enter_pin before calling start_wps_registration. */
16787 if (strcasecmp(config_method, "PBC") == 0)
16788 dut->wps_method = WFA_CS_WPS_PBC;
16789 }
16790 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
16791 send_resp(dut, conn, SIGMA_ERROR,
16792 "ErrorCode,WPS parameters not yet set");
16793 return STATUS_SENT;
16794 }
16795
16796 /* Make sure WPS is enabled (also for STA mode) */
16797 dut->wps_disable = 0;
16798
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016799 if (dut->band == WPS_BAND_60G && network_mode &&
16800 strcasecmp(network_mode, "PBSS") == 0) {
16801 sigma_dut_print(dut, DUT_MSG_DEBUG,
16802 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016803 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016804 return -2;
16805 }
16806
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016807 if (dut->force_rsn_ie) {
16808 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
16809 dut->force_rsn_ie);
16810 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
16811 sigma_dut_print(dut, DUT_MSG_INFO,
16812 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020016813 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016814 }
16815 }
16816
vamsi krishna9b144002017-09-20 13:28:13 +053016817 ctrl = open_wpa_mon(intf);
16818 if (!ctrl) {
16819 sigma_dut_print(dut, DUT_MSG_ERROR,
16820 "Failed to open wpa_supplicant monitor connection");
16821 return -2;
16822 }
16823
16824 role = get_param(cmd, "WpsRole");
16825 if (!role) {
16826 send_resp(dut, conn, SIGMA_INVALID,
16827 "ErrorCode,WpsRole not provided");
16828 goto fail;
16829 }
16830
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016831 if (strcasecmp(role, "Enrollee") != 0) {
16832 /* Registrar role for STA not supported */
16833 send_resp(dut, conn, SIGMA_ERROR,
16834 "ErrorCode,Unsupported WpsRole value");
16835 goto fail;
16836 }
16837
16838 if (is_60g_sigma_dut(dut)) {
16839 if (dut->wps_method == WFA_CS_WPS_PBC)
16840 snprintf(buf, sizeof(buf), "WPS_PBC");
16841 else /* WFA_CS_WPS_PIN_KEYPAD */
16842 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
16843 dut->wps_pin);
16844 if (wpa_command(intf, buf) < 0) {
16845 send_resp(dut, conn, SIGMA_ERROR,
16846 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053016847 goto fail;
16848 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016849 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16850 if (res < 0) {
16851 send_resp(dut, conn, SIGMA_ERROR,
16852 "ErrorCode,WPS connection did not complete");
16853 goto fail;
16854 }
16855 if (strstr(buf, "WPS-TIMEOUT")) {
16856 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
16857 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16858 send_resp(dut, conn, SIGMA_COMPLETE,
16859 "WpsState,OverlapSession");
16860 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16861 send_resp(dut, conn, SIGMA_COMPLETE,
16862 "WpsState,Successful");
16863 } else {
16864 send_resp(dut, conn, SIGMA_COMPLETE,
16865 "WpsState,Failure");
16866 }
16867 } else {
16868 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053016869 if (wpa_command(intf, "WPS_PBC") < 0) {
16870 send_resp(dut, conn, SIGMA_ERROR,
16871 "ErrorCode,Failed to enable PBC");
16872 goto fail;
16873 }
16874 } else {
16875 /* TODO: PIN method */
16876 send_resp(dut, conn, SIGMA_ERROR,
16877 "ErrorCode,Unsupported WpsConfigMethod value");
16878 goto fail;
16879 }
16880 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16881 if (res < 0) {
16882 send_resp(dut, conn, SIGMA_ERROR,
16883 "ErrorCode,WPS connection did not complete");
16884 goto fail;
16885 }
16886 if (strstr(buf, "WPS-TIMEOUT")) {
16887 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
16888 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16889 send_resp(dut, conn, SIGMA_ERROR,
16890 "ErrorCode,OverlapSession");
16891 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16892 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
16893 } else {
16894 send_resp(dut, conn, SIGMA_ERROR,
16895 "ErrorCode,WPS operation failed");
16896 }
vamsi krishna9b144002017-09-20 13:28:13 +053016897 }
16898
16899fail:
16900 wpa_ctrl_detach(ctrl);
16901 wpa_ctrl_close(ctrl);
16902 return 0;
16903}
16904
16905
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016906static int req_intf(struct sigma_cmd *cmd)
16907{
16908 return get_param(cmd, "interface") == NULL ? -1 : 0;
16909}
16910
16911
16912void sta_register_cmds(void)
16913{
16914 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
16915 cmd_sta_get_ip_config);
16916 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
16917 cmd_sta_set_ip_config);
16918 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
16919 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
16920 cmd_sta_get_mac_address);
16921 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
16922 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
16923 cmd_sta_verify_ip_connection);
16924 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
16925 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
16926 cmd_sta_set_encryption);
16927 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
16928 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
16929 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
16930 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
16931 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
16932 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
16933 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
16934 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
16935 cmd_sta_set_eapakaprime);
16936 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
16937 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
16938 /* TODO: sta_set_ibss */
16939 /* TODO: sta_set_mode */
16940 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
16941 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
16942 /* TODO: sta_up_load */
16943 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
16944 cmd_sta_preset_testparameters);
16945 /* TODO: sta_set_system */
16946 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
16947 /* TODO: sta_set_rifs_test */
16948 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
16949 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
16950 /* TODO: sta_send_coexist_mgmt */
16951 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
16952 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
16953 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
16954 sigma_dut_reg_cmd("sta_reset_default", req_intf,
16955 cmd_sta_reset_default);
16956 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
16957 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
16958 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
16959 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
16960 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020016961 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016962 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
16963 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
16964 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
16965 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
16966 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030016967 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
16968 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016969 sigma_dut_reg_cmd("sta_add_credential", req_intf,
16970 cmd_sta_add_credential);
16971 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016972 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016973 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
16974 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
16975 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
16976 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
16977 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
16978 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030016979 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016980 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
16981 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016982 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053016983 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016984}