blob: 07f18e60124493c57caf7d121f9e1762b6247d4b [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (station/AP)
3 * Copyright (c) 2010-2011, Atheros Communications, Inc.
Jouni Malinen9d7e31d2017-12-22 18:55:04 +02004 * Copyright (c) 2011-2017, Qualcomm Atheros, Inc.
Jouni Malinen2feb9132021-11-16 00:53:06 +02005 * Copyright (c) 2018-2021, The Linux Foundation
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006 * All Rights Reserved.
7 * Licensed under the Clear BSD license. See README for more details.
8 */
9
10#include "sigma_dut.h"
11#include <sys/ioctl.h>
12#include <sys/stat.h>
Jouni Malinen82905202018-04-29 17:20:10 +030013#include <sys/wait.h>
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030014#include <ctype.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015#ifdef __linux__
Lior Davidcc88b562017-01-03 18:52:09 +020016#include <regex.h>
17#include <dirent.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020018#include <sys/time.h>
19#include <netpacket/packet.h>
20#include <linux/if_ether.h>
21#ifdef ANDROID
22#include <cutils/properties.h>
23#include <android/log.h>
24#include "keystore_get.h"
25#else /* ANDROID */
26#include <ifaddrs.h>
27#endif /* ANDROID */
28#include <netdb.h>
29#endif /* __linux__ */
30#ifdef __QNXNTO__
31#include <net/if_dl.h>
32#endif /* __QNXNTO__ */
33#include "wpa_ctrl.h"
34#include "wpa_helpers.h"
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070035#include "miracast.h"
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070036#include "qca-vendor_copy.h"
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080037#include "nl80211_copy.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020038
39/* Temporary files for sta_send_addba */
40#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
41#define VI_QOS_FILE "/tmp/vi-qos.txt"
42#define VI_QOS_REFFILE "/etc/vi-qos.txt"
43
44/*
45 * MTU for Ethernet need to take into account 8-byte SNAP header
46 * to be added when encapsulating Ethernet frame into 802.11
47 */
48#ifndef IEEE80211_MAX_DATA_LEN_DMG
49#define IEEE80211_MAX_DATA_LEN_DMG 7920
50#endif
51#ifndef IEEE80211_SNAP_LEN_DMG
52#define IEEE80211_SNAP_LEN_DMG 8
53#endif
54
Ashwini Patil00402582017-04-13 12:29:39 +053055#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053056#define NEIGHBOR_REPORT_SIZE 1000
57#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
58#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053059
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030060#define WIL_DEFAULT_BI 100
61
62/* default remain on channel time for transmitting frames (milliseconds) */
63#define WIL_TRANSMIT_FRAME_DEFAULT_ROC 500
64#define IEEE80211_P2P_ATTR_DEVICE_ID 3
65#define IEEE80211_P2P_ATTR_GROUP_ID 15
66
67/* describes tagged bytes in template frame file */
68struct template_frame_tag {
69 int num;
70 int offset;
71 size_t len;
72};
73
Jouni Malinencd4e3c32015-10-29 12:39:56 +020074extern char *sigma_wpas_ctrl;
75extern char *sigma_cert_path;
76extern enum driver_type wifi_chip_type;
77extern char *sigma_radio_ifname[];
78
Lior David0fe101e2017-03-09 16:09:50 +020079#ifdef __linux__
80#define WIL_WMI_MAX_PAYLOAD 248
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020081#define WIL_WMI_ESE_CFG_CMDID 0xa01
Lior David0fe101e2017-03-09 16:09:50 +020082#define WIL_WMI_BF_TRIG_CMDID 0x83a
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020083#define WIL_WMI_UNIT_TEST_CMDID 0x900
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030084#define WIL_WMI_P2P_CFG_CMDID 0x910
85#define WIL_WMI_START_LISTEN_CMDID 0x914
86#define WIL_WMI_DISCOVERY_STOP_CMDID 0x917
Lior David0fe101e2017-03-09 16:09:50 +020087
88struct wil_wmi_header {
89 uint8_t mid;
90 uint8_t reserved;
91 uint16_t cmd;
92 uint32_t ts;
93} __attribute__((packed));
94
95enum wil_wmi_bf_trig_type {
96 WIL_WMI_SLS,
97 WIL_WMI_BRP_RX,
98 WIL_WMI_BRP_TX,
99};
100
101struct wil_wmi_bf_trig_cmd {
102 /* enum wil_wmi_bf_trig_type */
103 uint32_t bf_type;
104 /* cid when type == WMI_BRP_RX */
105 uint32_t sta_id;
106 uint32_t reserved;
107 /* mac address when type = WIL_WMI_SLS */
108 uint8_t dest_mac[6];
109} __attribute__((packed));
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200110
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200111enum wil_wmi_sched_scheme_advertisment {
112 WIL_WMI_ADVERTISE_ESE_DISABLED,
113 WIL_WMI_ADVERTISE_ESE_IN_BEACON,
114 WIL_WMI_ADVERTISE_ESE_IN_ANNOUNCE_FRAME,
115};
116
117enum wil_wmi_ese_slot_type {
118 WIL_WMI_ESE_SP,
119 WIL_WMI_ESE_CBAP,
120 WIL_WMI_ESE_ANNOUNCE_NO_ACK,
121};
122
123struct wil_wmi_ese_slot {
124 /* offset from start of BI in microseconds */
125 uint32_t tbtt_offset;
126 uint8_t flags;
127 /* enum wil_wmi_ese_slot_type */
128 uint8_t slot_type;
129 /* duration in microseconds */
130 uint16_t duration;
131 /* frame exchange sequence duration, microseconds */
132 uint16_t tx_op;
133 /* time between 2 blocks for periodic allocation(microseconds) */
134 uint16_t period;
135 /* number of blocks in periodic allocation */
136 uint8_t num_blocks;
137 /* for semi-active allocations */
138 uint8_t idle_period;
139 uint8_t src_aid;
140 uint8_t dst_aid;
141 uint32_t reserved;
142} __attribute__((packed));
143
144#define WIL_WMI_MAX_ESE_SLOTS 4
145struct wil_wmi_ese_cfg {
146 uint8_t serial_num;
147 /* wil_wmi_sched_scheme_advertisment */
148 uint8_t ese_advertisment;
149 uint16_t flags;
150 uint8_t num_allocs;
151 uint8_t reserved[3];
152 uint64_t start_tbtt;
153 /* allocations list */
154 struct wil_wmi_ese_slot slots[WIL_WMI_MAX_ESE_SLOTS];
155} __attribute__((packed));
156
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200157#define WIL_WMI_UT_FORCE_MCS 6
158struct wil_wmi_force_mcs {
159 /* WIL_WMI_UT_HW_SYSAPI */
160 uint16_t module_id;
161 /* WIL_WMI_UT_FORCE_MCS */
162 uint16_t subtype_id;
163 /* cid (ignored in oob_mode, affects all stations) */
164 uint32_t cid;
165 /* 1 to force MCS, 0 to restore default behavior */
166 uint32_t force_enable;
167 /* MCS index, 0-12 */
168 uint32_t mcs;
169} __attribute__((packed));
170
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200171#define WIL_WMI_UT_HW_SYSAPI 10
172#define WIL_WMI_UT_FORCE_RSN_IE 0x29
173struct wil_wmi_force_rsn_ie {
174 /* WIL_WMI_UT_HW_SYSAPI */
175 uint16_t module_id;
176 /* WIL_WMI_UT_FORCE_RSN_IE */
177 uint16_t subtype_id;
178 /* 0 = no change, 1 = remove if exists, 2 = add if does not exist */
179 uint32_t state;
180} __attribute__((packed));
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300181
182enum wil_wmi_discovery_mode {
183 WMI_DISCOVERY_MODE_NON_OFFLOAD,
184 WMI_DISCOVERY_MODE_OFFLOAD,
185 WMI_DISCOVERY_MODE_PEER2PEER,
186};
187
188struct wil_wmi_p2p_cfg_cmd {
189 /* enum wil_wmi_discovery_mode */
190 uint8_t discovery_mode;
191 /* 0-based (wireless channel - 1) */
192 uint8_t channel;
193 /* set to WIL_DEFAULT_BI */
194 uint16_t bcon_interval;
195} __attribute__((packed));
Lior David0fe101e2017-03-09 16:09:50 +0200196#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200197
198#ifdef ANDROID
199
200static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
201
202#define ANDROID_KEYSTORE_GET 'g'
203#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
204
205static int android_keystore_get(char cmd, const char *key, unsigned char *val)
206{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200207 /* Android 4.3 changed keystore design, so need to use keystore_get() */
208#ifndef KEYSTORE_MESSAGE_SIZE
209#define KEYSTORE_MESSAGE_SIZE 65535
210#endif /* KEYSTORE_MESSAGE_SIZE */
211
212 ssize_t len;
213 uint8_t *value = NULL;
214
215 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
216 "keystore command '%c' key '%s' --> keystore_get",
217 cmd, key);
218
219 len = keystore_get(key, strlen(key), &value);
220 if (len < 0) {
221 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
222 "keystore_get() failed");
223 return -1;
224 }
225
226 if (len > KEYSTORE_MESSAGE_SIZE)
227 len = KEYSTORE_MESSAGE_SIZE;
228 memcpy(val, value, len);
229 free(value);
230 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200231}
232#endif /* ANDROID */
233
234
Vinita S. Maloo0fcb57d2020-04-24 14:03:56 +0530235#ifdef NL80211_SUPPORT
236static int nl80211_sta_set_power_save(struct sigma_dut *dut,
237 const char *intf,
238 enum nl80211_ps_state ps_state)
239{
240 struct nl_msg *msg;
241 int ifindex, ret;
242
243 ifindex = if_nametoindex(intf);
244 if (ifindex == 0) {
245 sigma_dut_print(dut, DUT_MSG_ERROR,
246 "%s: Index for interface %s not found",
247 __func__, intf);
248 return -1;
249 }
250
251 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
252 NL80211_CMD_SET_POWER_SAVE);
253 if (!msg) {
254 sigma_dut_print(dut, DUT_MSG_ERROR,
255 "%s: err in creating nl80211 msg", __func__);
256 return -1;
257 }
258
259 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state)) {
260 sigma_dut_print(dut, DUT_MSG_ERROR,
261 "%s: err in populating nl80211 msg", __func__);
262 nlmsg_free(msg);
263 return -1;
264 }
265
266 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
267 if (ret) {
268 sigma_dut_print(dut, DUT_MSG_ERROR,
269 "%s: err in send_and_recv_msgs, ret=%d (%s)",
270 __func__, ret, strerror(-ret));
271 return -1;
272 }
273
274 return 0;
275}
276#endif /* NL80211_SUPPORT */
277
278
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530279static int set_power_save_wcn(struct sigma_dut *dut, const char *intf, int ps)
280{
281 char buf[100];
Vinita S. Maloo0fcb57d2020-04-24 14:03:56 +0530282#ifdef NL80211_SUPPORT
283 enum nl80211_ps_state ps_state;
284
285 ps_state = ps == 1 ? NL80211_PS_ENABLED : NL80211_PS_DISABLED;
286 if (nl80211_sta_set_power_save(dut, intf, ps_state) == 0)
287 return 0;
288#endif /* NL80211_SUPPORT */
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530289
290 snprintf(buf, sizeof(buf), "iwpriv %s setPower %d", intf, ps);
291 if (system(buf) != 0) {
292 sigma_dut_print(dut, DUT_MSG_ERROR,
293 "iwpriv setPower %d failed", ps);
294 return -1;
295 }
296 return 0;
297}
298
299
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200300int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
301{
302#ifdef __linux__
303 char buf[100];
304
305 if (wifi_chip_type == DRIVER_WCN) {
306 if (enabled) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530307 if (set_power_save_wcn(dut, intf, 1) < 0) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530308 snprintf(buf, sizeof(buf),
309 "iwpriv wlan0 dump 906");
310 if (system(buf) != 0)
311 goto set_power_save;
312 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200313 } else {
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530314 if (set_power_save_wcn(dut, intf, 2) < 0) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530315 snprintf(buf, sizeof(buf),
316 "iwpriv wlan0 dump 905");
317 if (system(buf) != 0)
318 goto set_power_save;
319 snprintf(buf, sizeof(buf),
320 "iwpriv wlan0 dump 912");
321 if (system(buf) != 0)
322 goto set_power_save;
323 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200324 }
325
326 return 0;
327 }
328
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530329set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200330 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
331 intf, enabled ? "on" : "off");
332 if (system(buf) != 0) {
333 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
334 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530335 if (system(buf) != 0) {
336 sigma_dut_print(dut, DUT_MSG_ERROR,
337 "Failed to set power save %s",
338 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200339 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530340 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200341 }
342
343 return 0;
344#else /* __linux__ */
345 return -1;
346#endif /* __linux__ */
347}
348
349
Lior Davidcc88b562017-01-03 18:52:09 +0200350#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200351
Lior Davidcc88b562017-01-03 18:52:09 +0200352static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
353 size_t len)
354{
355 DIR *dir, *wil_dir;
356 struct dirent *entry;
357 int ret = -1;
358 const char *root_path = "/sys/kernel/debug/ieee80211";
359
360 dir = opendir(root_path);
361 if (!dir)
362 return -2;
363
364 while ((entry = readdir(dir))) {
365 if (strcmp(entry->d_name, ".") == 0 ||
366 strcmp(entry->d_name, "..") == 0)
367 continue;
368
369 if (snprintf(path, len, "%s/%s/wil6210",
370 root_path, entry->d_name) >= (int) len) {
371 ret = -3;
372 break;
373 }
374
375 wil_dir = opendir(path);
376 if (wil_dir) {
377 closedir(wil_dir);
378 ret = 0;
379 break;
380 }
381 }
382
383 closedir(dir);
384 return ret;
385}
Lior David0fe101e2017-03-09 16:09:50 +0200386
387
388static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
389 void *payload, uint16_t length)
390{
391 struct {
392 struct wil_wmi_header hdr;
393 char payload[WIL_WMI_MAX_PAYLOAD];
394 } __attribute__((packed)) cmd;
395 char buf[128], fname[128];
396 size_t towrite, written;
397 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300398 int res;
Lior David0fe101e2017-03-09 16:09:50 +0200399
400 if (length > WIL_WMI_MAX_PAYLOAD) {
401 sigma_dut_print(dut, DUT_MSG_ERROR,
402 "payload too large(%u, max %u)",
403 length, WIL_WMI_MAX_PAYLOAD);
404 return -1;
405 }
406
407 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
408 cmd.hdr.cmd = command;
409 memcpy(cmd.payload, payload, length);
410
411 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
412 sigma_dut_print(dut, DUT_MSG_ERROR,
413 "failed to get wil6210 debugfs dir");
414 return -1;
415 }
416
Jouni Malinen3aa72862019-05-29 23:14:51 +0300417 res = snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
418 if (res < 0 || res >= sizeof(fname))
419 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200420 f = fopen(fname, "wb");
421 if (!f) {
422 sigma_dut_print(dut, DUT_MSG_ERROR,
423 "failed to open: %s", fname);
424 return -1;
425 }
426
427 towrite = sizeof(cmd.hdr) + length;
428 written = fwrite(&cmd, 1, towrite, f);
429 fclose(f);
430 if (written != towrite) {
431 sigma_dut_print(dut, DUT_MSG_ERROR,
432 "failed to send wmi %u", command);
433 return -1;
434 }
435
436 return 0;
437}
438
439
440static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
441 const char *pattern, unsigned int *field)
442{
443 char buf[128], fname[128];
444 FILE *f;
445 regex_t re;
446 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +0300447 int rc, ret = -1, res;
Lior David0fe101e2017-03-09 16:09:50 +0200448
449 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
450 sigma_dut_print(dut, DUT_MSG_ERROR,
451 "failed to get wil6210 debugfs dir");
452 return -1;
453 }
454
Jouni Malinen3aa72862019-05-29 23:14:51 +0300455 res = snprintf(fname, sizeof(fname), "%s/stations", buf);
456 if (res < 0 || res >= sizeof(fname))
457 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200458 f = fopen(fname, "r");
459 if (!f) {
460 sigma_dut_print(dut, DUT_MSG_ERROR,
461 "failed to open: %s", fname);
462 return -1;
463 }
464
465 if (regcomp(&re, pattern, REG_EXTENDED)) {
466 sigma_dut_print(dut, DUT_MSG_ERROR,
467 "regcomp failed: %s", pattern);
468 goto out;
469 }
470
471 /*
472 * find the entry for the mac address
473 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
474 */
475 while (fgets(buf, sizeof(buf), f)) {
476 if (strcasestr(buf, bssid)) {
477 /* extract the field (CID/AID/state) */
478 rc = regexec(&re, buf, 2, m, 0);
479 if (!rc && (m[1].rm_so >= 0)) {
480 buf[m[1].rm_eo] = 0;
481 *field = atoi(&buf[m[1].rm_so]);
482 ret = 0;
483 break;
484 }
485 }
486 }
487
488 regfree(&re);
489 if (ret)
490 sigma_dut_print(dut, DUT_MSG_ERROR,
491 "could not extract field");
492
493out:
494 fclose(f);
495
496 return ret;
497}
498
499
500static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
501 unsigned int *cid)
502{
503 const char *pattern = "\\[([0-9]+)\\]";
504
505 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
506}
507
508
509static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
510 int l_rx)
511{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700512 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200513 unsigned int cid;
514
Rakesh Sunki556237d2017-03-30 14:49:31 -0700515 memset(&cmd, 0, sizeof(cmd));
516
Lior David0fe101e2017-03-09 16:09:50 +0200517 if (wil6210_get_cid(dut, mac, &cid))
518 return -1;
519
520 cmd.bf_type = WIL_WMI_BRP_RX;
521 cmd.sta_id = cid;
522 /* training length (l_rx) is ignored, FW always uses length 16 */
523 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
524 &cmd, sizeof(cmd));
525}
526
527
528static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
529{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700530 struct wil_wmi_bf_trig_cmd cmd;
531
532 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200533
534 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
535 return -1;
536
537 cmd.bf_type = WIL_WMI_SLS;
538 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
539 &cmd, sizeof(cmd));
540}
541
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200542
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200543int wil6210_set_ese(struct sigma_dut *dut, int count,
544 struct sigma_ese_alloc *allocs)
545{
546 struct wil_wmi_ese_cfg cmd = { };
547 int i;
548
549 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
550 return -1;
551
552 if (dut->ap_bcnint <= 0) {
553 sigma_dut_print(dut, DUT_MSG_ERROR,
554 "invalid beacon interval(%d), check test",
555 dut->ap_bcnint);
556 return -1;
557 }
558
559 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
560 cmd.flags = 0x1d;
561 cmd.num_allocs = count;
562 for (i = 0; i < count; i++) {
563 /*
564 * Convert percent from BI (BI specified in milliseconds)
565 * to absolute duration in microseconds.
566 */
567 cmd.slots[i].duration =
568 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
569 switch (allocs[i].type) {
570 case ESE_CBAP:
571 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
572 break;
573 case ESE_SP:
574 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
575 break;
576 default:
577 sigma_dut_print(dut, DUT_MSG_ERROR,
578 "invalid slot type(%d) at index %d",
579 allocs[i].type, i);
580 return -1;
581 }
582 cmd.slots[i].src_aid = allocs[i].src_aid;
583 cmd.slots[i].dst_aid = allocs[i].dst_aid;
584 sigma_dut_print(dut, DUT_MSG_INFO,
585 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
586 i, cmd.slots[i].duration,
587 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
588 cmd.slots[i].dst_aid);
589 }
590
591 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
592}
593
594
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200595int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
596{
597 struct wil_wmi_force_mcs cmd = { };
598
599 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
600 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
601 cmd.force_enable = (uint32_t) force;
602 cmd.mcs = (uint32_t) mcs;
603
604 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
605 &cmd, sizeof(cmd));
606}
607
608
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200609static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
610{
611 struct wil_wmi_force_rsn_ie cmd = { };
612
613 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
614 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
615 cmd.state = (uint32_t) state;
616
617 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
618 &cmd, sizeof(cmd));
619}
620
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300621
622/*
623 * this function is also used to configure generic remain-on-channel
624 */
625static int wil6210_p2p_cfg(struct sigma_dut *dut, int freq)
626{
627 struct wil_wmi_p2p_cfg_cmd cmd = { };
628 int channel = freq_to_channel(freq);
629
630 if (channel < 0)
631 return -1;
632 cmd.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD;
633 cmd.channel = channel - 1;
634 cmd.bcon_interval = WIL_DEFAULT_BI;
635 cmd.discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER;
636
637 return wil6210_wmi_send(dut, WIL_WMI_P2P_CFG_CMDID,
638 &cmd, sizeof(cmd));
639}
640
641
642static int wil6210_remain_on_channel(struct sigma_dut *dut, int freq)
643{
644 int ret = wil6210_p2p_cfg(dut, freq);
645
646 if (ret)
647 return ret;
648
649 ret = wil6210_wmi_send(dut, WIL_WMI_START_LISTEN_CMDID, NULL, 0);
650 if (!ret) {
651 /*
652 * wait a bit to allow FW to setup the radio
653 * especially important if we switch channels
654 */
655 usleep(500000);
656 }
657
658 return ret;
659}
660
661
662static int wil6210_stop_discovery(struct sigma_dut *dut)
663{
664 return wil6210_wmi_send(dut, WIL_WMI_DISCOVERY_STOP_CMDID, NULL, 0);
665}
666
667
668static int wil6210_transmit_frame(struct sigma_dut *dut, int freq,
669 int wait_duration,
670 const char *frame, size_t frame_len)
671{
672 char buf[128], fname[128];
673 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300674 int res = 0, r;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300675 size_t written;
676
677 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
678 sigma_dut_print(dut, DUT_MSG_ERROR,
679 "failed to get wil6210 debugfs dir");
680 return -1;
681 }
Jouni Malinen3aa72862019-05-29 23:14:51 +0300682 r = snprintf(fname, sizeof(fname), "%s/tx_mgmt", buf);
683 if (r < 0 || r >= sizeof(fname))
684 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300685
686 if (wil6210_remain_on_channel(dut, freq)) {
687 sigma_dut_print(dut, DUT_MSG_ERROR,
688 "failed to listen on channel");
689 return -1;
690 }
691
692 f = fopen(fname, "wb");
693 if (!f) {
694 sigma_dut_print(dut, DUT_MSG_ERROR,
695 "failed to open: %s", fname);
696 res = -1;
697 goto out_stop;
698 }
699 written = fwrite(frame, 1, frame_len, f);
700 fclose(f);
701
702 if (written != frame_len) {
703 sigma_dut_print(dut, DUT_MSG_ERROR,
704 "failed to transmit frame (got %zd, expected %zd)",
705 written, frame_len);
706 res = -1;
707 goto out_stop;
708 }
709
710 usleep(wait_duration * 1000);
711
712out_stop:
713 wil6210_stop_discovery(dut);
714 return res;
715}
716
717
718static int find_template_frame_tag(struct template_frame_tag *tags,
719 int total_tags, int tag_num)
720{
721 int i;
722
723 for (i = 0; i < total_tags; i++) {
724 if (tag_num == tags[i].num)
725 return i;
726 }
727
728 return -1;
729}
730
731
732static int replace_p2p_attribute(struct sigma_dut *dut, char *buf, size_t len,
733 int id, const char *value, size_t val_len)
734{
735 struct wfa_p2p_attribute *attr = (struct wfa_p2p_attribute *) buf;
736
737 if (len < 3 + val_len) {
738 sigma_dut_print(dut, DUT_MSG_ERROR,
739 "not enough space to replace P2P attribute");
740 return -1;
741 }
742
743 if (attr->len != val_len) {
744 sigma_dut_print(dut, DUT_MSG_ERROR,
745 "attribute length mismatch (need %zu have %hu)",
746 val_len, attr->len);
747 return -1;
748 }
749
750 if (attr->id != id) {
751 sigma_dut_print(dut, DUT_MSG_ERROR,
752 "incorrect attribute id (expected %d actual %d)",
753 id, attr->id);
754 return -1;
755 }
756
757 memcpy(attr->variable, value, val_len);
758
759 return 0;
760}
761
762
763static int parse_template_frame_file(struct sigma_dut *dut, const char *fname,
764 char *buf, size_t *length,
765 struct template_frame_tag *tags,
766 size_t *num_tags)
767{
768 char line[512];
769 FILE *f;
770 size_t offset = 0, tag_index = 0;
771 int num, index;
772 int in_tag = 0, tag_num = 0, tag_offset = 0;
773
774 if (*length < sizeof(struct ieee80211_hdr_3addr)) {
775 sigma_dut_print(dut, DUT_MSG_ERROR,
776 "supplied buffer is too small");
777 return -1;
778 }
779
780 f = fopen(fname, "r");
781 if (!f) {
782 sigma_dut_print(dut, DUT_MSG_ERROR,
783 "failed to open template file %s", fname);
784 return -1;
785 }
786
787 /*
788 * template file format: lines beginning with # are comments and
789 * ignored.
790 * It is possible to tag bytes in the frame to make it easy
791 * to replace fields in the template, espcially if they appear
792 * in variable-sized sections (such as IEs)
793 * This is done by a line beginning with $NUM where NUM is an integer
794 * tag number. It can be followed by space(s) and comment.
795 * The next line is considered the tagged bytes. The parser will fill
796 * the tag number, offset and length of the tagged bytes.
797 * rest of the lines contain frame bytes as sequence of hex digits,
798 * 2 digits for each byte. Spaces are allowed between bytes.
799 * On bytes lines only hex digits and spaces are allowed
800 */
801 while (!feof(f)) {
802 if (!fgets(line, sizeof(line), f))
803 break;
804 index = 0;
805 while (isspace((unsigned char) line[index]))
806 index++;
807 if (!line[index] || line[index] == '#')
808 continue;
809 if (line[index] == '$') {
810 if (tags) {
811 index++;
812 tag_num = strtol(&line[index], NULL, 0);
813 tag_offset = offset;
814 in_tag = 1;
815 }
816 continue;
817 }
818 while (line[index]) {
819 if (isspace((unsigned char) line[index])) {
820 index++;
821 continue;
822 }
823 num = hex_byte(&line[index]);
824 if (num < 0)
825 break;
826 buf[offset++] = num;
827 if (offset == *length)
828 goto out;
829 index += 2;
830 }
831
832 if (in_tag) {
833 if (tag_index < *num_tags) {
834 tags[tag_index].num = tag_num;
835 tags[tag_index].offset = tag_offset;
836 tags[tag_index].len = offset - tag_offset;
837 tag_index++;
838 } else {
839 sigma_dut_print(dut, DUT_MSG_INFO,
840 "too many tags, tag ignored");
841 }
842 in_tag = 0;
843 }
844 }
845
846 if (num_tags)
847 *num_tags = tag_index;
848out:
849 fclose(f);
850 if (offset < sizeof(struct ieee80211_hdr_3addr)) {
851 sigma_dut_print(dut, DUT_MSG_ERROR,
852 "template frame is too small");
853 return -1;
854 }
855
856 *length = offset;
857 return 0;
858}
859
Lior Davidcc88b562017-01-03 18:52:09 +0200860#endif /* __linux__ */
861
862
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200863static void static_ip_file(int proto, const char *addr, const char *mask,
864 const char *gw)
865{
866 if (proto) {
867 FILE *f = fopen("static-ip", "w");
868 if (f) {
869 fprintf(f, "%d %s %s %s\n", proto, addr,
870 mask ? mask : "N/A",
871 gw ? gw : "N/A");
872 fclose(f);
873 }
874 } else {
875 unlink("static-ip");
876 }
877}
878
879
880static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
881 const char *ssid)
882{
883#ifdef __linux__
884 char buf[100];
885
886 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
887 intf, ssid);
888 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
889
890 if (system(buf) != 0) {
891 sigma_dut_print(dut, DUT_MSG_ERROR,
892 "iwpriv neighbor request failed");
893 return -1;
894 }
895
896 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
897
898 return 0;
899#else /* __linux__ */
900 return -1;
901#endif /* __linux__ */
902}
903
904
905static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530906 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200907{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530908 const char *val;
909 int reason_code = 0;
910 char buf[1024];
911
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200912 /*
913 * In the earlier builds we used WNM_QUERY and in later
914 * builds used WNM_BSS_QUERY.
915 */
916
Ashwini Patil5acd7382017-04-13 15:55:04 +0530917 val = get_param(cmd, "BTMQuery_Reason_Code");
918 if (val)
919 reason_code = atoi(val);
920
921 val = get_param(cmd, "Cand_List");
922 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
923 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
924 dut->btm_query_cand_list);
925 free(dut->btm_query_cand_list);
926 dut->btm_query_cand_list = NULL;
927 } else {
928 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
929 }
930
931 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200932 sigma_dut_print(dut, DUT_MSG_ERROR,
933 "transition management query failed");
934 return -1;
935 }
936
937 sigma_dut_print(dut, DUT_MSG_DEBUG,
938 "transition management query sent");
939
940 return 0;
941}
942
943
944int is_ip_addr(const char *str)
945{
946 const char *pos = str;
947 struct in_addr addr;
948
949 while (*pos) {
950 if (*pos != '.' && (*pos < '0' || *pos > '9'))
951 return 0;
952 pos++;
953 }
954
955 return inet_aton(str, &addr);
956}
957
958
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200959int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
960 size_t buf_len)
961{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530962 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200963 char ip[16], mask[15], dns[16], sec_dns[16];
964 int is_dhcp = 0;
965 int s;
966#ifdef ANDROID
967 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530968#else /* ANDROID */
969 FILE *f;
970#ifdef __linux__
971 const char *str_ps;
972#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200973#endif /* ANDROID */
974
975 ip[0] = '\0';
976 mask[0] = '\0';
977 dns[0] = '\0';
978 sec_dns[0] = '\0';
979
980 s = socket(PF_INET, SOCK_DGRAM, 0);
981 if (s >= 0) {
982 struct ifreq ifr;
983 struct sockaddr_in saddr;
984
985 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700986 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200987 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
988 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
989 "%s IP address: %s",
990 ifname, strerror(errno));
991 } else {
992 memcpy(&saddr, &ifr.ifr_addr,
993 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700994 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200995 }
996
997 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
998 memcpy(&saddr, &ifr.ifr_addr,
999 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -07001000 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001001 }
1002 close(s);
1003 }
1004
1005#ifdef ANDROID
1006 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
1007 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
1008 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
1009 if (property_get(tmp, prop, NULL) != 0 &&
1010 strcmp(prop, "ok") == 0) {
1011 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
1012 ifname);
1013 if (property_get(tmp, prop, NULL) != 0 &&
1014 strcmp(ip, prop) == 0)
1015 is_dhcp = 1;
1016 }
1017 }
1018
1019 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -07001020 if (property_get(tmp, prop, NULL) != 0)
1021 strlcpy(dns, prop, sizeof(dns));
1022 else if (property_get("net.dns1", prop, NULL) != 0)
1023 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001024
1025 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -07001026 if (property_get(tmp, prop, NULL) != 0)
1027 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001028#else /* ANDROID */
1029#ifdef __linux__
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001030 if (get_driver_type(dut) == DRIVER_OPENWRT)
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301031 str_ps = "ps -w";
1032 else
1033 str_ps = "ps ax";
1034 snprintf(tmp, sizeof(tmp),
1035 "%s | grep dhclient | grep -v grep | grep -q %s",
1036 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001037 if (system(tmp) == 0)
1038 is_dhcp = 1;
1039 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301040 snprintf(tmp, sizeof(tmp),
1041 "%s | grep udhcpc | grep -v grep | grep -q %s",
1042 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001043 if (system(tmp) == 0)
1044 is_dhcp = 1;
1045 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301046 snprintf(tmp, sizeof(tmp),
1047 "%s | grep dhcpcd | grep -v grep | grep -q %s",
1048 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001049 if (system(tmp) == 0)
1050 is_dhcp = 1;
1051 }
1052 }
1053#endif /* __linux__ */
1054
1055 f = fopen("/etc/resolv.conf", "r");
1056 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +05301057 char *pos, *pos2;
1058
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001059 while (fgets(tmp, sizeof(tmp), f)) {
1060 if (strncmp(tmp, "nameserver", 10) != 0)
1061 continue;
1062 pos = tmp + 10;
1063 while (*pos == ' ' || *pos == '\t')
1064 pos++;
1065 pos2 = pos;
1066 while (*pos2) {
1067 if (*pos2 == '\n' || *pos2 == '\r') {
1068 *pos2 = '\0';
1069 break;
1070 }
1071 pos2++;
1072 }
Peng Xub8fc5cc2017-05-10 17:27:28 -07001073 if (!dns[0])
1074 strlcpy(dns, pos, sizeof(dns));
1075 else if (!sec_dns[0])
1076 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001077 }
1078 fclose(f);
1079 }
1080#endif /* ANDROID */
1081
1082 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
1083 is_dhcp, ip, mask, dns);
1084 buf[buf_len - 1] = '\0';
1085
1086 return 0;
1087}
1088
1089
1090
1091
1092int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
1093 size_t buf_len)
1094{
1095#ifdef __linux__
1096#ifdef ANDROID
1097 char cmd[200], result[1000], *pos, *end;
1098 FILE *f;
1099 size_t len;
1100
1101 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
1102 f = popen(cmd, "r");
1103 if (f == NULL)
1104 return -1;
1105 len = fread(result, 1, sizeof(result) - 1, f);
1106 pclose(f);
1107 if (len == 0)
1108 return -1;
1109 result[len] = '\0';
1110 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
1111
1112 pos = strstr(result, "inet6 ");
1113 if (pos == NULL)
1114 return -1;
1115 pos += 6;
1116 end = strchr(pos, ' ');
1117 if (end)
1118 *end = '\0';
1119 end = strchr(pos, '/');
1120 if (end)
1121 *end = '\0';
1122 snprintf(buf, buf_len, "ip,%s", pos);
1123 buf[buf_len - 1] = '\0';
1124 return 0;
1125#else /* ANDROID */
1126 struct ifaddrs *ifaddr, *ifa;
1127 int res, found = 0;
1128 char host[NI_MAXHOST];
1129
1130 if (getifaddrs(&ifaddr) < 0) {
1131 perror("getifaddrs");
1132 return -1;
1133 }
1134
1135 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1136 if (strcasecmp(ifname, ifa->ifa_name) != 0)
1137 continue;
1138 if (ifa->ifa_addr == NULL ||
1139 ifa->ifa_addr->sa_family != AF_INET6)
1140 continue;
1141
1142 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
1143 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1144 if (res != 0) {
1145 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
1146 gai_strerror(res));
1147 continue;
1148 }
1149 if (strncmp(host, "fe80::", 6) == 0)
1150 continue; /* skip link-local */
1151
1152 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
1153 found = 1;
1154 break;
1155 }
1156
1157 freeifaddrs(ifaddr);
1158
1159 if (found) {
1160 char *pos;
1161 pos = strchr(host, '%');
1162 if (pos)
1163 *pos = '\0';
1164 snprintf(buf, buf_len, "ip,%s", host);
1165 buf[buf_len - 1] = '\0';
1166 return 0;
1167 }
1168
1169#endif /* ANDROID */
1170#endif /* __linux__ */
1171 return -1;
1172}
1173
1174
Jouni Malinenf7222712019-06-13 01:50:21 +03001175static enum sigma_cmd_result cmd_sta_get_ip_config(struct sigma_dut *dut,
1176 struct sigma_conn *conn,
1177 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001178{
1179 const char *intf = get_param(cmd, "Interface");
1180 const char *ifname;
1181 char buf[200];
1182 const char *val;
1183 int type = 1;
1184
1185 if (intf == NULL)
1186 return -1;
1187
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001188 if (strcmp(intf, get_main_ifname(dut)) == 0)
1189 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001190 else
1191 ifname = intf;
1192
1193 /*
1194 * UCC may assume the IP address to be available immediately after
1195 * association without trying to run sta_get_ip_config multiple times.
1196 * Sigma CAPI does not specify this command as a block command that
1197 * would wait for the address to become available, but to pass tests
1198 * more reliably, it looks like such a wait may be needed here.
1199 */
1200 if (wait_ip_addr(dut, ifname, 15) < 0) {
1201 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
1202 "for sta_get_ip_config");
1203 /*
1204 * Try to continue anyway since many UCC tests do not really
1205 * care about the return value from here..
1206 */
1207 }
1208
1209 val = get_param(cmd, "Type");
1210 if (val)
1211 type = atoi(val);
1212 if (type == 2 || dut->last_set_ip_config_ipv6) {
1213 int i;
1214
1215 /*
1216 * Since we do not have proper wait for IPv6 addresses, use a
1217 * fixed two second delay here as a workaround for UCC script
1218 * assuming IPv6 address is available when this command returns.
1219 * Some scripts did not use Type,2 properly for IPv6, so include
1220 * also the cases where the previous sta_set_ip_config indicated
1221 * use of IPv6.
1222 */
1223 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
1224 for (i = 0; i < 10; i++) {
1225 sleep(1);
1226 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
1227 {
1228 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
1229 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1230#ifdef ANDROID
1231 sigma_dut_print(dut, DUT_MSG_INFO,
1232 "Adding IPv6 rule on Android");
1233 add_ipv6_rule(dut, intf);
1234#endif /* ANDROID */
1235
1236 return 0;
1237 }
1238 }
1239 }
1240 if (type == 1) {
1241 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
1242 return -2;
1243 } else if (type == 2) {
1244 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
1245 return -2;
1246 } else {
1247 send_resp(dut, conn, SIGMA_ERROR,
1248 "errorCode,Unsupported address type");
1249 return 0;
1250 }
1251
1252 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1253 return 0;
1254}
1255
1256
1257static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
1258{
1259#ifdef __linux__
1260 char buf[200];
1261 char path[128];
1262 struct stat s;
1263
1264#ifdef ANDROID
1265 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
1266#else /* ANDROID */
1267 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
1268#endif /* ANDROID */
1269 if (stat(path, &s) == 0) {
1270 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1271 sigma_dut_print(dut, DUT_MSG_INFO,
1272 "Kill previous DHCP client: %s", buf);
1273 if (system(buf) != 0)
1274 sigma_dut_print(dut, DUT_MSG_INFO,
1275 "Failed to kill DHCP client");
1276 unlink(path);
1277 sleep(1);
1278 } else {
1279 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
1280
1281 if (stat(path, &s) == 0) {
1282 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1283 sigma_dut_print(dut, DUT_MSG_INFO,
1284 "Kill previous DHCP client: %s", buf);
1285 if (system(buf) != 0)
1286 sigma_dut_print(dut, DUT_MSG_INFO,
1287 "Failed to kill DHCP client");
1288 unlink(path);
1289 sleep(1);
1290 }
1291 }
1292#endif /* __linux__ */
1293}
1294
1295
1296static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1297{
1298#ifdef __linux__
1299 char buf[200];
1300
1301#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301302 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1303 snprintf(buf, sizeof(buf),
1304 "/system/bin/dhcpcd -b %s", ifname);
1305 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1306 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301307 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1308 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1309 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1310 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301311 } else {
1312 sigma_dut_print(dut, DUT_MSG_ERROR,
1313 "DHCP client program missing");
1314 return 0;
1315 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001316#else /* ANDROID */
1317 snprintf(buf, sizeof(buf),
1318 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1319 ifname, ifname);
1320#endif /* ANDROID */
1321 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1322 if (system(buf) != 0) {
1323 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1324 if (system(buf) != 0) {
1325 sigma_dut_print(dut, DUT_MSG_INFO,
1326 "Failed to start DHCP client");
1327#ifndef ANDROID
1328 return -1;
1329#endif /* ANDROID */
1330 }
1331 }
1332#endif /* __linux__ */
1333
1334 return 0;
1335}
1336
1337
1338static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1339{
1340#ifdef __linux__
1341 char buf[200];
1342
1343 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1344 if (system(buf) != 0) {
1345 sigma_dut_print(dut, DUT_MSG_INFO,
1346 "Failed to clear IP addresses");
1347 return -1;
1348 }
1349#endif /* __linux__ */
1350
1351 return 0;
1352}
1353
1354
1355#ifdef ANDROID
1356static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1357{
1358 char cmd[200], *result, *pos;
1359 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301360 int tableid;
1361 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001362
1363 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1364 ifname);
1365 fp = popen(cmd, "r");
1366 if (fp == NULL)
1367 return -1;
1368
1369 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301370 if (result == NULL) {
1371 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001372 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301373 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001374
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301375 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001376 fclose(fp);
1377
1378 if (len == 0) {
1379 free(result);
1380 return -1;
1381 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301382 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001383
1384 pos = strstr(result, "table ");
1385 if (pos == NULL) {
1386 free(result);
1387 return -1;
1388 }
1389
1390 pos += strlen("table ");
1391 tableid = atoi(pos);
1392 if (tableid != 0) {
1393 if (system("ip -6 rule del prio 22000") != 0) {
1394 /* ignore any error */
1395 }
1396 snprintf(cmd, sizeof(cmd),
1397 "ip -6 rule add from all lookup %d prio 22000",
1398 tableid);
1399 if (system(cmd) != 0) {
1400 sigma_dut_print(dut, DUT_MSG_INFO,
1401 "Failed to run %s", cmd);
1402 free(result);
1403 return -1;
1404 }
1405 } else {
1406 sigma_dut_print(dut, DUT_MSG_INFO,
1407 "No Valid Table Id found %s", pos);
1408 free(result);
1409 return -1;
1410 }
1411 free(result);
1412
1413 return 0;
1414}
1415#endif /* ANDROID */
1416
1417
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301418int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1419 const char *ip, const char *mask)
1420{
1421 char buf[200];
1422
1423 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1424 ifname, ip, mask);
1425 return system(buf) == 0;
1426}
1427
1428
1429int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1430{
1431 char buf[200];
1432
1433 if (!is_ip_addr(gw)) {
1434 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1435 return -1;
1436 }
1437
1438 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1439 if (!dut->no_ip_addr_set && system(buf) != 0) {
1440 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1441 gw);
1442 if (system(buf) != 0)
1443 return 0;
1444 }
1445
1446 return 1;
1447}
1448
1449
Jouni Malinenf7222712019-06-13 01:50:21 +03001450static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1451 struct sigma_conn *conn,
1452 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001453{
1454 const char *intf = get_param(cmd, "Interface");
1455 const char *ifname;
1456 char buf[200];
1457 const char *val, *ip, *mask, *gw;
1458 int type = 1;
1459
1460 if (intf == NULL)
1461 return -1;
1462
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001463 if (strcmp(intf, get_main_ifname(dut)) == 0)
1464 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001465 else
1466 ifname = intf;
1467
1468 if (if_nametoindex(ifname) == 0) {
1469 send_resp(dut, conn, SIGMA_ERROR,
1470 "ErrorCode,Unknown interface");
1471 return 0;
1472 }
1473
1474 val = get_param(cmd, "Type");
1475 if (val) {
1476 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301477 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001478 send_resp(dut, conn, SIGMA_ERROR,
1479 "ErrorCode,Unsupported address type");
1480 return 0;
1481 }
1482 }
1483
1484 dut->last_set_ip_config_ipv6 = 0;
1485
1486 val = get_param(cmd, "dhcp");
1487 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1488 static_ip_file(0, NULL, NULL, NULL);
1489#ifdef __linux__
1490 if (type == 2) {
1491 dut->last_set_ip_config_ipv6 = 1;
1492 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1493 "stateless address autoconfiguration");
1494#ifdef ANDROID
Hu Wang8fd144d2021-12-29 17:07:45 +08001495 snprintf(buf, sizeof(buf),
1496 "sysctl net.ipv6.conf.%s.disable_ipv6=0",
1497 ifname);
1498 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1499 if (system(buf) != 0) {
1500 sigma_dut_print(dut, DUT_MSG_DEBUG,
1501 "Failed to enable IPv6 address");
1502 }
1503
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001504 /*
1505 * This sleep is required as the assignment in case of
1506 * Android is taking time and is done by the kernel.
1507 * The subsequent ping for IPv6 is impacting HS20 test
1508 * case.
1509 */
1510 sleep(2);
1511 add_ipv6_rule(dut, intf);
1512#endif /* ANDROID */
1513 /* Assume this happens by default */
1514 return 1;
1515 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301516 if (type != 3) {
1517 kill_dhcp_client(dut, ifname);
1518 if (start_dhcp_client(dut, ifname) < 0)
1519 return -2;
1520 } else {
1521 sigma_dut_print(dut, DUT_MSG_DEBUG,
1522 "Using FILS HLP DHCPv4 Rapid Commit");
1523 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001524
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001525 return 1;
1526#endif /* __linux__ */
1527 return -2;
1528 }
1529
1530 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301531 if (!ip) {
1532 send_resp(dut, conn, SIGMA_INVALID,
1533 "ErrorCode,Missing IP address");
1534 return 0;
1535 }
1536
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001537 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301538 if (!mask) {
1539 send_resp(dut, conn, SIGMA_INVALID,
1540 "ErrorCode,Missing subnet mask");
1541 return 0;
1542 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001543
1544 if (type == 2) {
1545 int net = atoi(mask);
1546
1547 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1548 return -1;
1549
1550 if (dut->no_ip_addr_set) {
1551 snprintf(buf, sizeof(buf),
1552 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1553 ifname);
1554 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1555 if (system(buf) != 0) {
1556 sigma_dut_print(dut, DUT_MSG_DEBUG,
1557 "Failed to disable IPv6 address before association");
1558 }
1559 } else {
Veerendranath Jakkam176181c2020-05-16 00:19:21 +05301560 if (set_ipv6_addr(dut, ip, mask, ifname) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001561 send_resp(dut, conn, SIGMA_ERROR,
1562 "ErrorCode,Failed to set IPv6 address");
1563 return 0;
1564 }
1565 }
1566
1567 dut->last_set_ip_config_ipv6 = 1;
1568 static_ip_file(6, ip, mask, NULL);
1569 return 1;
1570 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301571 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001572 return -1;
1573 }
1574
1575 kill_dhcp_client(dut, ifname);
1576
1577 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301578 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001579 send_resp(dut, conn, SIGMA_ERROR,
1580 "ErrorCode,Failed to set IP address");
1581 return 0;
1582 }
1583 }
1584
1585 gw = get_param(cmd, "defaultGateway");
1586 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301587 if (set_ipv4_gw(dut, gw) < 1) {
1588 send_resp(dut, conn, SIGMA_ERROR,
1589 "ErrorCode,Failed to set default gateway");
1590 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001591 }
1592 }
1593
1594 val = get_param(cmd, "primary-dns");
1595 if (val) {
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301596#ifdef ANDROID
Shivani Baranwal31182012021-12-07 21:11:13 +05301597 char dns_cmd[200];
1598 int len;
1599 char dnsmasq[100];
1600
1601 kill_pid(dut, concat_sigma_tmpdir(dut, "/sigma_dut-dnsmasq.pid",
1602 dnsmasq, sizeof(dnsmasq)));
1603
1604 len = snprintf(dns_cmd, sizeof(dns_cmd),
1605 "/system/bin/dnsmasq -uroot --no-resolv -S%s -x/%s", val,
1606 dnsmasq);
1607 if (len < 0 || len >= sizeof(dns_cmd))
1608 return ERROR_SEND_STATUS;
1609 sigma_dut_print(dut, DUT_MSG_DEBUG, "Running %s", dns_cmd);
1610 if (system(dns_cmd) != 0) {
1611 send_resp(dut, conn, SIGMA_ERROR,
1612 "ErrorCode,Failed to set primary-dns");
1613 return STATUS_SENT_ERROR;
1614 }
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301615#else /* ANDROID */
1616 char dns_cmd[200];
1617 int len;
1618
1619 if (system("sed -i '/nameserver/d' /etc/resolv.conf") != 0) {
1620 sigma_dut_print(dut, DUT_MSG_ERROR,
1621 "Failed to clear nameserver entries in /etc/resolv.conf");
1622 return ERROR_SEND_STATUS;
1623 }
1624
1625 len = snprintf(dns_cmd, sizeof(dns_cmd),
1626 "sed -i '1 i nameserver %s' /etc/resolv.conf", val);
1627 if (len < 0 || len >= sizeof(dns_cmd))
1628 return ERROR_SEND_STATUS;
1629
1630 sigma_dut_print(dut, DUT_MSG_DEBUG, "Running %s", dns_cmd);
1631 if (system(dns_cmd) != 0) {
1632 send_resp(dut, conn, SIGMA_ERROR,
1633 "ErrorCode,Failed to set primary-dns");
1634 return STATUS_SENT_ERROR;
1635 }
1636#endif /* ANDROID */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001637 }
1638
1639 val = get_param(cmd, "secondary-dns");
1640 if (val) {
1641 /* TODO */
1642 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1643 "setting", val);
1644 }
1645
1646 static_ip_file(4, ip, mask, gw);
1647
1648 return 1;
1649}
1650
1651
Jouni Malinenf7222712019-06-13 01:50:21 +03001652static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1653 struct sigma_conn *conn,
1654 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001655{
1656 /* const char *intf = get_param(cmd, "Interface"); */
1657 /* TODO: could report more details here */
1658 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1659 return 0;
1660}
1661
1662
Jouni Malinenf7222712019-06-13 01:50:21 +03001663static enum sigma_cmd_result cmd_sta_get_mac_address(struct sigma_dut *dut,
1664 struct sigma_conn *conn,
1665 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001666{
1667 /* const char *intf = get_param(cmd, "Interface"); */
1668 char addr[20], resp[50];
1669
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301670 if (dut->dev_role == DEVROLE_STA_CFON)
1671 return sta_cfon_get_mac_address(dut, conn, cmd);
1672
Jouni Malinen9540e012019-11-05 17:08:42 +02001673 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001674 if (get_wpa_status(get_station_ifname(dut), "address",
1675 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001676 return -2;
1677
1678 snprintf(resp, sizeof(resp), "mac,%s", addr);
1679 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1680 return 0;
1681}
1682
1683
Jouni Malinenf7222712019-06-13 01:50:21 +03001684static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1685 struct sigma_conn *conn,
1686 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001687{
1688 /* const char *intf = get_param(cmd, "Interface"); */
1689 int connected = 0;
1690 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001691 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001692 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001693 sigma_dut_print(dut, DUT_MSG_INFO,
1694 "Could not get interface %s status",
1695 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001696 return -2;
1697 }
1698
1699 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1700 if (strncmp(result, "COMPLETED", 9) == 0)
1701 connected = 1;
1702
1703 if (connected)
1704 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1705 else
1706 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1707
1708 return 0;
1709}
1710
1711
Jouni Malinenf7222712019-06-13 01:50:21 +03001712static enum sigma_cmd_result
1713cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1714 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001715{
1716 /* const char *intf = get_param(cmd, "Interface"); */
1717 const char *dst, *timeout;
1718 int wait_time = 90;
1719 char buf[100];
1720 int res;
1721
1722 dst = get_param(cmd, "destination");
1723 if (dst == NULL || !is_ip_addr(dst))
1724 return -1;
1725
1726 timeout = get_param(cmd, "timeout");
1727 if (timeout) {
1728 wait_time = atoi(timeout);
1729 if (wait_time < 1)
1730 wait_time = 1;
1731 }
1732
1733 /* TODO: force renewal of IP lease if DHCP is enabled */
1734
1735 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1736 res = system(buf);
1737 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1738 if (res == 0)
1739 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1740 else if (res == 256)
1741 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1742 else
1743 return -2;
1744
1745 return 0;
1746}
1747
1748
Jouni Malinenf7222712019-06-13 01:50:21 +03001749static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1750 struct sigma_conn *conn,
1751 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001752{
1753 /* const char *intf = get_param(cmd, "Interface"); */
1754 char bssid[20], resp[50];
1755
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001756 if (get_wpa_status(get_station_ifname(dut), "bssid",
1757 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001758 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001759
1760 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1761 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1762 return 0;
1763}
1764
1765
1766#ifdef __SAMSUNG__
1767static int add_use_network(const char *ifname)
1768{
1769 char buf[100];
1770
1771 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1772 wpa_command(ifname, buf);
1773 return 0;
1774}
1775#endif /* __SAMSUNG__ */
1776
1777
1778static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1779 const char *ifname, struct sigma_cmd *cmd)
1780{
1781 const char *ssid = get_param(cmd, "ssid");
1782 int id;
1783 const char *val;
1784
1785 if (ssid == NULL)
1786 return -1;
1787
1788 start_sta_mode(dut);
1789
1790#ifdef __SAMSUNG__
1791 add_use_network(ifname);
1792#endif /* __SAMSUNG__ */
1793
1794 id = add_network(ifname);
1795 if (id < 0)
1796 return -2;
1797 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1798
1799 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1800 return -2;
1801
1802 dut->infra_network_id = id;
1803 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1804
1805 val = get_param(cmd, "program");
1806 if (!val)
1807 val = get_param(cmd, "prog");
1808 if (val && strcasecmp(val, "hs2") == 0) {
1809 char buf[100];
1810 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1811 wpa_command(ifname, buf);
1812
1813 val = get_param(cmd, "prefer");
1814 if (val && atoi(val) > 0)
1815 set_network(ifname, id, "priority", "1");
1816 }
1817
1818 return id;
1819}
1820
1821
Jouni Malinenf7222712019-06-13 01:50:21 +03001822static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1823 struct sigma_conn *conn,
1824 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001825{
1826 const char *intf = get_param(cmd, "Interface");
1827 const char *ssid = get_param(cmd, "ssid");
1828 const char *type = get_param(cmd, "encpType");
1829 const char *ifname;
1830 char buf[200];
1831 int id;
1832
1833 if (intf == NULL || ssid == NULL)
1834 return -1;
1835
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001836 if (strcmp(intf, get_main_ifname(dut)) == 0)
1837 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001838 else
1839 ifname = intf;
1840
1841 id = add_network_common(dut, conn, ifname, cmd);
1842 if (id < 0)
1843 return id;
1844
1845 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1846 return -2;
1847
1848 if (type && strcasecmp(type, "wep") == 0) {
1849 const char *val;
1850 int i;
1851
1852 val = get_param(cmd, "activeKey");
1853 if (val) {
1854 int keyid;
1855 keyid = atoi(val);
1856 if (keyid < 1 || keyid > 4)
1857 return -1;
1858 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1859 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1860 return -2;
1861 }
1862
1863 for (i = 0; i < 4; i++) {
1864 snprintf(buf, sizeof(buf), "key%d", i + 1);
1865 val = get_param(cmd, buf);
1866 if (val == NULL)
1867 continue;
1868 snprintf(buf, sizeof(buf), "wep_key%d", i);
1869 if (set_network(ifname, id, buf, val) < 0)
1870 return -2;
1871 }
1872 }
1873
1874 return 1;
1875}
1876
1877
Jouni Malinene4fde732019-03-25 22:29:37 +02001878static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1879 int id, const char *val)
1880{
1881 char key_mgmt[200], *end, *pos;
1882 const char *in_pos = val;
1883
Jouni Malinen8179fee2019-03-28 03:19:47 +02001884 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001885 pos = key_mgmt;
1886 end = pos + sizeof(key_mgmt);
1887 while (*in_pos) {
1888 int res, akm = atoi(in_pos);
1889 const char *str;
1890
Jouni Malinen8179fee2019-03-28 03:19:47 +02001891 if (akm >= 0 && akm < 32)
1892 dut->akm_values |= 1 << akm;
1893
Jouni Malinene4fde732019-03-25 22:29:37 +02001894 switch (akm) {
1895 case AKM_WPA_EAP:
1896 str = "WPA-EAP";
1897 break;
1898 case AKM_WPA_PSK:
1899 str = "WPA-PSK";
1900 break;
1901 case AKM_FT_EAP:
1902 str = "FT-EAP";
1903 break;
1904 case AKM_FT_PSK:
1905 str = "FT-PSK";
1906 break;
1907 case AKM_EAP_SHA256:
1908 str = "WPA-EAP-SHA256";
1909 break;
1910 case AKM_PSK_SHA256:
1911 str = "WPA-PSK-SHA256";
1912 break;
1913 case AKM_SAE:
1914 str = "SAE";
1915 break;
1916 case AKM_FT_SAE:
1917 str = "FT-SAE";
1918 break;
1919 case AKM_SUITE_B:
1920 str = "WPA-EAP-SUITE-B-192";
1921 break;
1922 case AKM_FT_SUITE_B:
1923 str = "FT-EAP-SHA384";
1924 break;
1925 case AKM_FILS_SHA256:
1926 str = "FILS-SHA256";
1927 break;
1928 case AKM_FILS_SHA384:
1929 str = "FILS-SHA384";
1930 break;
1931 case AKM_FT_FILS_SHA256:
1932 str = "FT-FILS-SHA256";
1933 break;
1934 case AKM_FT_FILS_SHA384:
1935 str = "FT-FILS-SHA384";
1936 break;
1937 default:
1938 sigma_dut_print(dut, DUT_MSG_ERROR,
1939 "Unsupported AKMSuitetype %d", akm);
1940 return -1;
1941 }
1942
1943 res = snprintf(pos, end - pos, "%s%s",
1944 pos == key_mgmt ? "" : " ", str);
1945 if (res < 0 || res >= end - pos)
1946 return -1;
1947 pos += res;
1948
1949 in_pos = strchr(in_pos, ';');
1950 if (!in_pos)
1951 break;
1952 while (*in_pos == ';')
1953 in_pos++;
1954 }
1955 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1956 val, key_mgmt);
1957 return set_network(ifname, id, "key_mgmt", key_mgmt);
1958}
1959
1960
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001961static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1962 const char *ifname, struct sigma_cmd *cmd)
1963{
1964 const char *val;
1965 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001966 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001967 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301968 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001969
1970 id = add_network_common(dut, conn, ifname, cmd);
1971 if (id < 0)
1972 return id;
1973
Jouni Malinen47dcc952017-10-09 16:43:24 +03001974 val = get_param(cmd, "Type");
1975 owe = val && strcasecmp(val, "OWE") == 0;
1976
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001977 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001978 if (!val && owe)
1979 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001980 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001981 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1982 * this missing parameter and assume proto=WPA2. */
1983 if (set_network(ifname, id, "proto", "WPA2") < 0)
1984 return ERROR_SEND_STATUS;
1985 } else if (strcasecmp(val, "wpa") == 0 ||
1986 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001987 if (set_network(ifname, id, "proto", "WPA") < 0)
1988 return -2;
1989 } else if (strcasecmp(val, "wpa2") == 0 ||
1990 strcasecmp(val, "wpa2-psk") == 0 ||
1991 strcasecmp(val, "wpa2-ft") == 0 ||
1992 strcasecmp(val, "wpa2-sha256") == 0) {
1993 if (set_network(ifname, id, "proto", "WPA2") < 0)
1994 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301995 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1996 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001997 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1998 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001999 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05302000 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03002001 if (set_network(ifname, id, "proto", "WPA2") < 0)
2002 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03002003 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002004 } else {
2005 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
2006 return 0;
2007 }
2008
2009 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03002010 if (val) {
2011 cipher_set = 1;
2012 if (strcasecmp(val, "tkip") == 0) {
2013 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
2014 return -2;
2015 } else if (strcasecmp(val, "aes-ccmp") == 0) {
2016 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2017 return -2;
2018 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
2019 if (set_network(ifname, id, "pairwise",
2020 "CCMP TKIP") < 0)
2021 return -2;
2022 } else if (strcasecmp(val, "aes-gcmp") == 0) {
2023 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2024 return -2;
2025 if (set_network(ifname, id, "group", "GCMP") < 0)
2026 return -2;
2027 } else {
2028 send_resp(dut, conn, SIGMA_ERROR,
2029 "errorCode,Unrecognized encpType value");
2030 return 0;
2031 }
2032 }
2033
2034 val = get_param(cmd, "PairwiseCipher");
2035 if (val) {
2036 cipher_set = 1;
2037 /* TODO: Support space separated list */
2038 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2039 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
2040 return -2;
2041 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2042 if (set_network(ifname, id, "pairwise",
2043 "CCMP-256") < 0)
2044 return -2;
2045 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2046 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2047 return -2;
2048 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2049 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2050 return -2;
2051 } else {
2052 send_resp(dut, conn, SIGMA_ERROR,
2053 "errorCode,Unrecognized PairwiseCipher value");
2054 return 0;
2055 }
2056 }
2057
Jouni Malinen47dcc952017-10-09 16:43:24 +03002058 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03002059 send_resp(dut, conn, SIGMA_ERROR,
2060 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002061 return 0;
2062 }
Jouni Malinenad395a22017-09-01 21:13:46 +03002063
2064 val = get_param(cmd, "GroupCipher");
2065 if (val) {
2066 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2067 if (set_network(ifname, id, "group", "GCMP-256") < 0)
2068 return -2;
2069 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2070 if (set_network(ifname, id, "group", "CCMP-256") < 0)
2071 return -2;
2072 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2073 if (set_network(ifname, id, "group", "GCMP") < 0)
2074 return -2;
2075 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2076 if (set_network(ifname, id, "group", "CCMP") < 0)
2077 return -2;
2078 } else {
2079 send_resp(dut, conn, SIGMA_ERROR,
2080 "errorCode,Unrecognized GroupCipher value");
2081 return 0;
2082 }
2083 }
2084
Jouni Malinen7b239522017-09-14 21:37:18 +03002085 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03002086 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03002087 const char *cipher;
2088
2089 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2090 cipher = "BIP-GMAC-256";
2091 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2092 cipher = "BIP-CMAC-256";
2093 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2094 cipher = "BIP-GMAC-128";
2095 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2096 cipher = "AES-128-CMAC";
2097 } else {
2098 send_resp(dut, conn, SIGMA_INVALID,
2099 "errorCode,Unsupported GroupMgntCipher");
2100 return 0;
2101 }
2102 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
2103 send_resp(dut, conn, SIGMA_INVALID,
2104 "errorCode,Failed to set GroupMgntCipher");
2105 return 0;
2106 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002107 }
2108
Jouni Malinene4fde732019-03-25 22:29:37 +02002109 val = get_param(cmd, "AKMSuiteType");
2110 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2111 return ERROR_SEND_STATUS;
2112
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002113 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302114
2115 if (dut->program == PROGRAM_OCE) {
2116 dut->sta_pmf = STA_PMF_OPTIONAL;
2117 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2118 return -2;
2119 }
2120
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002121 val = get_param(cmd, "PMF");
2122 if (val) {
2123 if (strcasecmp(val, "Required") == 0 ||
2124 strcasecmp(val, "Forced_Required") == 0) {
2125 dut->sta_pmf = STA_PMF_REQUIRED;
2126 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2127 return -2;
2128 } else if (strcasecmp(val, "Optional") == 0) {
2129 dut->sta_pmf = STA_PMF_OPTIONAL;
2130 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2131 return -2;
2132 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002133 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002134 strcasecmp(val, "Forced_Disabled") == 0) {
2135 dut->sta_pmf = STA_PMF_DISABLED;
2136 } else {
2137 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2138 return 0;
2139 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302140 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002141 dut->sta_pmf = STA_PMF_REQUIRED;
2142 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2143 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002144 }
2145
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002146 val = get_param(cmd, "BeaconProtection");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05302147 if (val)
2148 dut->beacon_prot = atoi(val);
2149 if (dut->beacon_prot && set_network(ifname, id, "beacon_prot", "1") < 0)
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002150 return ERROR_SEND_STATUS;
2151
Veerendranath Jakkam54fd51c2020-12-21 01:36:04 +05302152 if (dut->ocvc && set_network(ifname, id, "ocv", "1") < 0)
2153 return ERROR_SEND_STATUS;
2154
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002155 return id;
2156}
2157
2158
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302159static int wcn_set_ignore_h2e_rsnxe(struct sigma_dut *dut, const char *intf,
2160 uint8_t cfg)
2161{
2162#ifdef NL80211_SUPPORT
2163 return wcn_wifi_test_config_set_u8(
2164 dut, intf,
2165 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE, cfg);
2166#else /* NL80211_SUPPORT */
2167 sigma_dut_print(dut, DUT_MSG_ERROR,
2168 "Ignore SAE H2E requirement mismatch can't be set without NL80211_SUPPORT defined");
2169 return -1;
2170#endif /* NL80211_SUPPORT */
2171}
2172
2173
Jouni Malinenf7222712019-06-13 01:50:21 +03002174static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2175 struct sigma_conn *conn,
2176 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002177{
2178 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002179 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002180 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002181 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002182 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002183 const char *ifname, *val, *alg;
2184 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002185 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002186 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002187
2188 if (intf == NULL)
2189 return -1;
2190
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002191 if (strcmp(intf, get_main_ifname(dut)) == 0)
2192 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002193 else
2194 ifname = intf;
2195
2196 id = set_wpa_common(dut, conn, ifname, cmd);
2197 if (id < 0)
2198 return id;
2199
2200 val = get_param(cmd, "keyMgmtType");
2201 alg = get_param(cmd, "micAlg");
2202
Jouni Malinen992a81e2017-08-22 13:57:47 +03002203 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002204 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002205 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2206 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002207 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002208 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2209 return -2;
2210 }
2211 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2212 sigma_dut_print(dut, DUT_MSG_ERROR,
2213 "Failed to clear sae_groups to default");
2214 return -2;
2215 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002216 if (!pmf) {
2217 dut->sta_pmf = STA_PMF_REQUIRED;
2218 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2219 return -2;
2220 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002221 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2222 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2223 if (set_network(ifname, id, "key_mgmt",
2224 "FT-SAE FT-PSK") < 0)
2225 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002226 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002227 if (set_network(ifname, id, "key_mgmt",
2228 "SAE WPA-PSK") < 0)
2229 return -2;
2230 }
2231 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2232 sigma_dut_print(dut, DUT_MSG_ERROR,
2233 "Failed to clear sae_groups to default");
2234 return -2;
2235 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002236 if (!pmf) {
2237 dut->sta_pmf = STA_PMF_OPTIONAL;
2238 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2239 return -2;
2240 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002241 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002242 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2243 return -2;
2244 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2245 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2246 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302247 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2248 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2249 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002250 } else if (!akm &&
2251 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2252 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002253 if (set_network(ifname, id, "key_mgmt",
2254 "WPA-PSK WPA-PSK-SHA256") < 0)
2255 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002256 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002257 if (set_network(ifname, id, "key_mgmt",
2258 "WPA-PSK WPA-PSK-SHA256") < 0)
2259 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002260 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002261 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2262 return -2;
2263 }
2264
2265 val = get_param(cmd, "passPhrase");
2266 if (val == NULL)
2267 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002268 if (type && strcasecmp(type, "SAE") == 0) {
2269 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2270 return -2;
2271 } else {
2272 if (set_network_quoted(ifname, id, "psk", val) < 0)
2273 return -2;
2274 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002275
Jouni Malinen78d10c42019-03-25 22:34:32 +02002276 val = get_param(cmd, "PasswordId");
2277 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2278 return ERROR_SEND_STATUS;
2279
Jouni Malinen992a81e2017-08-22 13:57:47 +03002280 val = get_param(cmd, "ECGroupID");
2281 if (val) {
Jouni Malinenb54f0df2019-12-12 01:57:29 +02002282 snprintf(buf, sizeof(buf), "SET sae_groups %s", val);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002283 if (wpa_command(ifname, buf) != 0) {
2284 sigma_dut_print(dut, DUT_MSG_ERROR,
2285 "Failed to clear sae_groups");
2286 return -2;
2287 }
2288 }
2289
Jouni Malinen68143132017-09-02 02:34:08 +03002290 val = get_param(cmd, "InvalidSAEElement");
2291 if (val) {
2292 free(dut->sae_commit_override);
2293 dut->sae_commit_override = strdup(val);
2294 }
2295
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002296 val = get_param(cmd, "PMKID_Include");
2297 if (val) {
2298 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2299 get_enable_disable(val));
2300 wpa_command(intf, buf);
2301 }
2302
Jouni Malineneeb43d32019-12-06 17:40:07 +02002303 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2304 if (val) {
2305 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2306 get_enable_disable(val));
2307 wpa_command(intf, buf);
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302308 if (get_driver_type(dut) == DRIVER_WCN)
2309 wcn_set_ignore_h2e_rsnxe(dut, intf,
2310 get_enable_disable(val));
Jouni Malineneeb43d32019-12-06 17:40:07 +02002311 }
2312
Jouni Malinenf2348d22019-12-07 11:52:55 +02002313 val = get_param(cmd, "ECGroupID_RGE");
2314 if (val) {
2315 snprintf(buf, sizeof(buf), "SET extra_sae_rejected_groups %s",
2316 val);
2317 wpa_command(intf, buf);
2318 }
2319
Jouni Malinen99e55022019-12-07 13:59:41 +02002320 val = get_param(cmd, "RSNXE_Content");
2321 if (val) {
2322 const char *param;
2323
2324 if (strncasecmp(val, "AssocReq:", 9) == 0) {
2325 val += 9;
2326 param = "rsnxe_override_assoc";
2327 } else if (strncasecmp(val, "EapolM2:", 8) == 0) {
2328 val += 8;
2329 param = "rsnxe_override_eapol";
2330 } else {
2331 send_resp(dut, conn, SIGMA_ERROR,
2332 "errorCode,Unsupported RSNXE_Content value");
2333 return STATUS_SENT_ERROR;
2334 }
2335 snprintf(buf, sizeof(buf), "SET %s %s", param, val);
2336 wpa_command(intf, buf);
2337 }
2338
Jouni Malinen11e55212019-11-22 21:46:59 +02002339 val = get_param(cmd, "sae_pwe");
2340 if (val) {
2341 if (strcasecmp(val, "h2e") == 0) {
2342 dut->sae_pwe = SAE_PWE_H2E;
Jouni Malinen7244a412019-12-07 11:54:10 +02002343 } else if (strcasecmp(val, "loop") == 0 ||
2344 strcasecmp(val, "looping") == 0) {
Jouni Malinen11e55212019-11-22 21:46:59 +02002345 dut->sae_pwe = SAE_PWE_LOOP;
2346 } else {
2347 send_resp(dut, conn, SIGMA_ERROR,
2348 "errorCode,Unsupported sae_pwe value");
2349 return STATUS_SENT_ERROR;
2350 }
2351 }
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302352
2353 val = get_param(cmd, "Clear_RSNXE");
2354 if (val && strcmp(val, "1") == 0 &&
2355 (wpa_command(intf, "SET rsnxe_override_assoc ") ||
2356 wpa_command(intf, "SET rsnxe_override_eapol "))) {
2357 send_resp(dut, conn, SIGMA_ERROR,
2358 "errorCode,Failed to clear RSNXE");
Jouni Malinenb11498c2020-08-03 11:05:53 +03002359 return STATUS_SENT_ERROR;
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302360 }
2361
Jouni Malinenc0078772020-03-04 21:23:16 +02002362 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2363 sae_pwe = 3;
2364 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002365 sae_pwe = 0;
2366 else if (dut->sae_pwe == SAE_PWE_H2E)
2367 sae_pwe = 1;
2368 else if (dut->sae_h2e_default)
2369 sae_pwe = 2;
2370 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2371 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2372 return ERROR_SEND_STATUS;
2373
Veerendranath Jakkam0316be12020-06-23 20:11:41 +05302374 val = get_param(cmd, "sae_pk");
2375 if (val && strcmp(val, "0") == 0 &&
2376 set_network(ifname, id, "sae_pk", "2") < 0)
2377 return ERROR_SEND_STATUS;
2378
Veerendranath Jakkama9177042020-08-10 00:14:03 +05302379 val = get_param(cmd, "sae_pk_only");
2380 if (val && strcmp(val, "1") == 0 &&
2381 set_network(ifname, id, "sae_pk", "1") < 0)
2382 return ERROR_SEND_STATUS;
2383
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002384 if (dut->program == PROGRAM_60GHZ && network_mode &&
2385 strcasecmp(network_mode, "PBSS") == 0 &&
2386 set_network(ifname, id, "pbss", "1") < 0)
2387 return -2;
2388
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002389 return 1;
2390}
2391
2392
Jouni Malinen8ac93452019-08-14 15:19:13 +03002393static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2394 struct sigma_conn *conn,
2395 const char *ifname, int id)
2396{
2397 char buf[200];
2398
2399 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2400 if (!file_exists(buf))
2401 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2402 if (!file_exists(buf))
2403 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2404 if (!file_exists(buf)) {
2405 char msg[300];
2406
2407 snprintf(msg, sizeof(msg),
2408 "ErrorCode,trustedRootCA system store (%s) not found",
2409 buf);
2410 send_resp(dut, conn, SIGMA_ERROR, msg);
2411 return STATUS_SENT_ERROR;
2412 }
2413
2414 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2415 return ERROR_SEND_STATUS;
2416
2417 return SUCCESS_SEND_STATUS;
2418}
2419
2420
2421static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2422 struct sigma_conn *conn,
2423 const char *ifname, int id,
2424 const char *val)
2425{
2426 char buf[200];
2427#ifdef ANDROID
2428 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2429 int length;
2430#endif /* ANDROID */
2431
2432 if (strcmp(val, "DEFAULT") == 0)
2433 return set_trust_root_system(dut, conn, ifname, id);
2434
2435#ifdef ANDROID
2436 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2437 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2438 if (length > 0) {
2439 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2440 buf);
2441 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2442 goto ca_cert_selected;
2443 }
2444#endif /* ANDROID */
2445
2446 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2447#ifdef __linux__
2448 if (!file_exists(buf)) {
2449 char msg[300];
2450
2451 snprintf(msg, sizeof(msg),
2452 "ErrorCode,trustedRootCA file (%s) not found", buf);
2453 send_resp(dut, conn, SIGMA_ERROR, msg);
2454 return STATUS_SENT_ERROR;
2455 }
2456#endif /* __linux__ */
2457#ifdef ANDROID
2458ca_cert_selected:
2459#endif /* ANDROID */
2460 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2461 return ERROR_SEND_STATUS;
2462
2463 return SUCCESS_SEND_STATUS;
2464}
2465
2466
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002467static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302468 const char *ifname, int username_identity,
2469 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002470{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002471 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002472 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002473 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002474 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002475 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002476
2477 id = set_wpa_common(dut, conn, ifname, cmd);
2478 if (id < 0)
2479 return id;
2480
2481 val = get_param(cmd, "keyMgmtType");
2482 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302483 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002484 trust_root = get_param(cmd, "trustedRootCA");
2485 domain = get_param(cmd, "Domain");
2486 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002487
Jouni Malinenad395a22017-09-01 21:13:46 +03002488 if (val && strcasecmp(val, "SuiteB") == 0) {
2489 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2490 0)
2491 return -2;
2492 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002493 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2494 return -2;
2495 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2496 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2497 return -2;
2498 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2499 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2500 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002501 } else if (!akm &&
2502 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2503 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002504 if (set_network(ifname, id, "key_mgmt",
2505 "WPA-EAP WPA-EAP-SHA256") < 0)
2506 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302507 } else if (akm && atoi(akm) == 14) {
2508 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2509 dut->sta_pmf == STA_PMF_REQUIRED) {
2510 if (set_network(ifname, id, "key_mgmt",
2511 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2512 return -2;
2513 } else {
2514 if (set_network(ifname, id, "key_mgmt",
2515 "WPA-EAP FILS-SHA256") < 0)
2516 return -2;
2517 }
2518
Jouni Malinen8179fee2019-03-28 03:19:47 +02002519 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302520 } else if (akm && atoi(akm) == 15) {
2521 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2522 dut->sta_pmf == STA_PMF_REQUIRED) {
2523 if (set_network(ifname, id, "key_mgmt",
2524 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2525 return -2;
2526 } else {
2527 if (set_network(ifname, id, "key_mgmt",
2528 "WPA-EAP FILS-SHA384") < 0)
2529 return -2;
2530 }
2531
Jouni Malinen8179fee2019-03-28 03:19:47 +02002532 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002533 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002534 if (set_network(ifname, id, "key_mgmt",
2535 "WPA-EAP WPA-EAP-SHA256") < 0)
2536 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002537 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002538 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2539 return -2;
2540 }
2541
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002542 if (trust_root) {
2543 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2544 !domain_suffix) {
2545 send_resp(dut, conn, SIGMA_ERROR,
2546 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2547 return STATUS_SENT_ERROR;
2548 }
2549 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002550 if (res != SUCCESS_SEND_STATUS)
2551 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002552 }
2553
Jouni Malinen53264f62019-05-03 13:04:40 +03002554 val = get_param(cmd, "ServerCert");
2555 if (val) {
2556 FILE *f;
2557 char *result = NULL, *pos;
2558
2559 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2560 val);
2561 f = fopen(buf, "r");
2562 if (f) {
2563 result = fgets(buf, sizeof(buf), f);
2564 fclose(f);
2565 }
2566 if (!result) {
2567 snprintf(buf2, sizeof(buf2),
2568 "ErrorCode,ServerCert hash could not be read from %s",
2569 buf);
2570 send_resp(dut, conn, SIGMA_ERROR, buf2);
2571 return STATUS_SENT_ERROR;
2572 }
2573 pos = strchr(buf, '\n');
2574 if (pos)
2575 *pos = '\0';
Jouni Malinen0572a742020-10-08 13:53:25 +03002576 pos = strchr(buf, '\r');
2577 if (pos)
2578 *pos = '\0';
Jouni Malinen53264f62019-05-03 13:04:40 +03002579 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2580 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2581 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002582
2583 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2584 if (file_exists(buf)) {
2585 sigma_dut_print(dut, DUT_MSG_DEBUG,
2586 "TOD policy enabled for the configured ServerCert hash");
2587 dut->sta_tod_policy = 1;
2588 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002589 }
2590
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002591 if (domain &&
2592 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002593 return ERROR_SEND_STATUS;
2594
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002595 if (domain_suffix &&
2596 set_network_quoted(ifname, id, "domain_suffix_match",
2597 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002598 return ERROR_SEND_STATUS;
2599
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302600 if (username_identity) {
2601 val = get_param(cmd, "username");
2602 if (val) {
2603 if (set_network_quoted(ifname, id, "identity", val) < 0)
2604 return -2;
2605 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002606
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302607 val = get_param(cmd, "password");
2608 if (val) {
2609 if (set_network_quoted(ifname, id, "password", val) < 0)
2610 return -2;
2611 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002612 }
2613
Jouni Malinen8179fee2019-03-28 03:19:47 +02002614 if (dut->akm_values &
2615 ((1 << AKM_FILS_SHA256) |
2616 (1 << AKM_FILS_SHA384) |
2617 (1 << AKM_FT_FILS_SHA256) |
2618 (1 << AKM_FT_FILS_SHA384)))
2619 erp = 1;
2620 if (erp && set_network(ifname, id, "erp", "1") < 0)
2621 return ERROR_SEND_STATUS;
2622
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002623 dut->sta_associate_wait_connect = 1;
2624
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002625 return id;
2626}
2627
2628
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002629static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2630{
2631 const char *val;
2632
2633 if (!cipher)
2634 return 0;
2635
2636 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2637 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2638 else if (strcasecmp(cipher,
2639 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2640 val = "ECDHE-RSA-AES256-GCM-SHA384";
2641 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2642 val = "DHE-RSA-AES256-GCM-SHA384";
2643 else if (strcasecmp(cipher,
2644 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2645 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2646 else
2647 return -1;
2648
2649 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2650 set_network_quoted(ifname, id, "phase1", "");
2651
2652 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2653}
2654
2655
Jouni Malinenf7222712019-06-13 01:50:21 +03002656static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2657 struct sigma_conn *conn,
2658 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002659{
2660 const char *intf = get_param(cmd, "Interface");
2661 const char *ifname, *val;
2662 int id;
2663 char buf[200];
2664#ifdef ANDROID
2665 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2666 int length;
2667 int jb_or_newer = 0;
2668 char prop[PROPERTY_VALUE_MAX];
2669#endif /* ANDROID */
2670
2671 if (intf == NULL)
2672 return -1;
2673
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002674 if (strcmp(intf, get_main_ifname(dut)) == 0)
2675 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002676 else
2677 ifname = intf;
2678
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302679 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002680 if (id < 0)
2681 return id;
2682
2683 if (set_network(ifname, id, "eap", "TLS") < 0)
2684 return -2;
2685
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302686 if (!get_param(cmd, "username") &&
2687 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002688 "wifi-user@wifilabs.local") < 0)
2689 return -2;
2690
2691 val = get_param(cmd, "clientCertificate");
2692 if (val == NULL)
2693 return -1;
2694#ifdef ANDROID
2695 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2696 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2697 if (length < 0) {
2698 /*
2699 * JB started reporting keystore type mismatches, so retry with
2700 * the GET_PUBKEY command if the generic GET fails.
2701 */
2702 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2703 buf, kvalue);
2704 }
2705
2706 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2707 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2708 if (strncmp(prop, "4.0", 3) != 0)
2709 jb_or_newer = 1;
2710 } else
2711 jb_or_newer = 1; /* assume newer */
2712
2713 if (jb_or_newer && length > 0) {
2714 sigma_dut_print(dut, DUT_MSG_INFO,
2715 "Use Android keystore [%s]", buf);
2716 if (set_network(ifname, id, "engine", "1") < 0)
2717 return -2;
2718 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2719 return -2;
2720 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2721 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2722 return -2;
2723 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2724 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2725 return -2;
2726 return 1;
2727 } else if (length > 0) {
2728 sigma_dut_print(dut, DUT_MSG_INFO,
2729 "Use Android keystore [%s]", buf);
2730 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2731 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2732 return -2;
2733 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2734 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2735 return -2;
2736 return 1;
2737 }
2738#endif /* ANDROID */
2739
2740 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2741#ifdef __linux__
2742 if (!file_exists(buf)) {
2743 char msg[300];
2744 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2745 "(%s) not found", buf);
2746 send_resp(dut, conn, SIGMA_ERROR, msg);
2747 return -3;
2748 }
2749#endif /* __linux__ */
2750 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2751 return -2;
2752 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2753 return -2;
2754
2755 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2756 return -2;
2757
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002758 val = get_param(cmd, "keyMgmtType");
2759 if (val && strcasecmp(val, "SuiteB") == 0) {
2760 val = get_param(cmd, "CertType");
2761 if (val && strcasecmp(val, "RSA") == 0) {
2762 if (set_network_quoted(ifname, id, "phase1",
2763 "tls_suiteb=1") < 0)
2764 return -2;
2765 } else {
2766 if (set_network_quoted(ifname, id, "openssl_ciphers",
2767 "SUITEB192") < 0)
2768 return -2;
2769 }
2770
2771 val = get_param(cmd, "TLSCipher");
2772 if (set_tls_cipher(ifname, id, val) < 0) {
2773 send_resp(dut, conn, SIGMA_ERROR,
2774 "ErrorCode,Unsupported TLSCipher value");
2775 return -3;
2776 }
2777 }
2778
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002779 return 1;
2780}
2781
2782
Jouni Malinenf7222712019-06-13 01:50:21 +03002783static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2784 struct sigma_conn *conn,
2785 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002786{
2787 const char *intf = get_param(cmd, "Interface");
2788 const char *ifname;
2789 int id;
2790
2791 if (intf == NULL)
2792 return -1;
2793
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002794 if (strcmp(intf, get_main_ifname(dut)) == 0)
2795 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002796 else
2797 ifname = intf;
2798
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302799 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002800 if (id < 0)
2801 return id;
2802
2803 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2804 send_resp(dut, conn, SIGMA_ERROR,
2805 "errorCode,Failed to set TTLS method");
2806 return 0;
2807 }
2808
2809 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2810 send_resp(dut, conn, SIGMA_ERROR,
2811 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2812 return 0;
2813 }
2814
2815 return 1;
2816}
2817
2818
Jouni Malinenf7222712019-06-13 01:50:21 +03002819static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2820 struct sigma_conn *conn,
2821 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002822{
2823 const char *intf = get_param(cmd, "Interface");
2824 const char *ifname;
2825 int id;
2826
2827 if (intf == NULL)
2828 return -1;
2829
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002830 if (strcmp(intf, get_main_ifname(dut)) == 0)
2831 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002832 else
2833 ifname = intf;
2834
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302835 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002836 if (id < 0)
2837 return id;
2838
2839 if (set_network(ifname, id, "eap", "SIM") < 0)
2840 return -2;
2841
2842 return 1;
2843}
2844
2845
Jouni Malinenf7222712019-06-13 01:50:21 +03002846static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2847 struct sigma_conn *conn,
2848 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002849{
2850 const char *intf = get_param(cmd, "Interface");
2851 const char *ifname, *val;
2852 int id;
2853 char buf[100];
2854
2855 if (intf == NULL)
2856 return -1;
2857
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002858 if (strcmp(intf, get_main_ifname(dut)) == 0)
2859 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002860 else
2861 ifname = intf;
2862
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302863 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002864 if (id < 0)
2865 return id;
2866
2867 if (set_network(ifname, id, "eap", "PEAP") < 0)
2868 return -2;
2869
2870 val = get_param(cmd, "innerEAP");
2871 if (val) {
2872 if (strcasecmp(val, "MSCHAPv2") == 0) {
2873 if (set_network_quoted(ifname, id, "phase2",
2874 "auth=MSCHAPV2") < 0)
2875 return -2;
2876 } else if (strcasecmp(val, "GTC") == 0) {
2877 if (set_network_quoted(ifname, id, "phase2",
2878 "auth=GTC") < 0)
2879 return -2;
2880 } else
2881 return -1;
2882 }
2883
2884 val = get_param(cmd, "peapVersion");
2885 if (val) {
2886 int ver = atoi(val);
2887 if (ver < 0 || ver > 1)
2888 return -1;
2889 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2890 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2891 return -2;
2892 }
2893
2894 return 1;
2895}
2896
2897
Jouni Malinenf7222712019-06-13 01:50:21 +03002898static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2899 struct sigma_conn *conn,
2900 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002901{
2902 const char *intf = get_param(cmd, "Interface");
2903 const char *ifname, *val;
2904 int id;
2905 char buf[100];
2906
2907 if (intf == NULL)
2908 return -1;
2909
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002910 if (strcmp(intf, get_main_ifname(dut)) == 0)
2911 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002912 else
2913 ifname = intf;
2914
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302915 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002916 if (id < 0)
2917 return id;
2918
2919 if (set_network(ifname, id, "eap", "FAST") < 0)
2920 return -2;
2921
2922 val = get_param(cmd, "innerEAP");
2923 if (val) {
2924 if (strcasecmp(val, "MSCHAPV2") == 0) {
2925 if (set_network_quoted(ifname, id, "phase2",
2926 "auth=MSCHAPV2") < 0)
2927 return -2;
2928 } else if (strcasecmp(val, "GTC") == 0) {
2929 if (set_network_quoted(ifname, id, "phase2",
2930 "auth=GTC") < 0)
2931 return -2;
2932 } else
2933 return -1;
2934 }
2935
2936 val = get_param(cmd, "validateServer");
2937 if (val) {
2938 /* TODO */
2939 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2940 "validateServer=%s", val);
2941 }
2942
2943 val = get_param(cmd, "pacFile");
2944 if (val) {
2945 snprintf(buf, sizeof(buf), "blob://%s", val);
2946 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2947 return -2;
2948 }
2949
2950 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2951 0)
2952 return -2;
2953
2954 return 1;
2955}
2956
2957
Jouni Malinenf7222712019-06-13 01:50:21 +03002958static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2959 struct sigma_conn *conn,
2960 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002961{
2962 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302963 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002964 const char *ifname;
2965 int id;
2966
2967 if (intf == NULL)
2968 return -1;
2969
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002970 if (strcmp(intf, get_main_ifname(dut)) == 0)
2971 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002972 else
2973 ifname = intf;
2974
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302975 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002976 if (id < 0)
2977 return id;
2978
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302979 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2980 * hexadecimal).
2981 */
2982 if (username && username[0] == '6') {
2983 if (set_network(ifname, id, "eap", "AKA'") < 0)
2984 return -2;
2985 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002986 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302987 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002988
2989 return 1;
2990}
2991
2992
Jouni Malinenf7222712019-06-13 01:50:21 +03002993static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2994 struct sigma_conn *conn,
2995 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002996{
2997 const char *intf = get_param(cmd, "Interface");
2998 const char *ifname;
2999 int id;
3000
3001 if (intf == NULL)
3002 return -1;
3003
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003004 if (strcmp(intf, get_main_ifname(dut)) == 0)
3005 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003006 else
3007 ifname = intf;
3008
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05303009 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003010 if (id < 0)
3011 return id;
3012
3013 if (set_network(ifname, id, "eap", "AKA'") < 0)
3014 return -2;
3015
3016 return 1;
3017}
3018
3019
3020static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
3021 struct sigma_cmd *cmd)
3022{
3023 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003024 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003025 const char *ifname;
3026 int id;
3027
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003028 if (strcmp(intf, get_main_ifname(dut)) == 0)
3029 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003030 else
3031 ifname = intf;
3032
3033 id = add_network_common(dut, conn, ifname, cmd);
3034 if (id < 0)
3035 return id;
3036
3037 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
3038 return -2;
3039
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003040 if (dut->program == PROGRAM_60GHZ && network_mode &&
3041 strcasecmp(network_mode, "PBSS") == 0 &&
3042 set_network(ifname, id, "pbss", "1") < 0)
3043 return -2;
3044
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003045 return 1;
3046}
3047
3048
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003049static enum sigma_cmd_result sta_set_owe(struct sigma_dut *dut,
3050 struct sigma_conn *conn,
3051 struct sigma_cmd *cmd)
Jouni Malinen47dcc952017-10-09 16:43:24 +03003052{
3053 const char *intf = get_param(cmd, "Interface");
3054 const char *ifname, *val;
3055 int id;
3056
3057 if (intf == NULL)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003058 return INVALID_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003059
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003060 if (strcmp(intf, get_main_ifname(dut)) == 0)
3061 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003062 else
3063 ifname = intf;
3064
3065 id = set_wpa_common(dut, conn, ifname, cmd);
3066 if (id < 0)
3067 return id;
3068
3069 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003070 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003071
Hu Wangdd5eed22020-07-16 12:18:03 +08003072 if (dut->owe_ptk_workaround &&
3073 set_network(ifname, id, "owe_ptk_workaround", "1") < 0) {
3074 sigma_dut_print(dut, DUT_MSG_ERROR,
3075 "Failed to set owe_ptk_workaround to 1");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003076 return ERROR_SEND_STATUS;
Hu Wangdd5eed22020-07-16 12:18:03 +08003077 }
3078
Jouni Malinen47dcc952017-10-09 16:43:24 +03003079 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003080 if (val && strcmp(val, "0") == 0) {
3081 if (wpa_command(ifname,
3082 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
3083 sigma_dut_print(dut, DUT_MSG_ERROR,
3084 "Failed to set OWE DH Param element override");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003085 return ERROR_SEND_STATUS;
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003086 }
Hu Wangdd5eed22020-07-16 12:18:03 +08003087 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03003088 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08003089 "Failed to set owe_group");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003090 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003091 }
3092
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003093 return SUCCESS_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003094}
3095
3096
Jouni Malinenf7222712019-06-13 01:50:21 +03003097static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
3098 struct sigma_conn *conn,
3099 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003100{
3101 const char *type = get_param(cmd, "Type");
3102
3103 if (type == NULL) {
3104 send_resp(dut, conn, SIGMA_ERROR,
3105 "ErrorCode,Missing Type argument");
3106 return 0;
3107 }
3108
3109 if (strcasecmp(type, "OPEN") == 0)
3110 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003111 if (strcasecmp(type, "OWE") == 0)
3112 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03003113 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03003114 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03003115 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003116 return cmd_sta_set_psk(dut, conn, cmd);
3117 if (strcasecmp(type, "EAPTLS") == 0)
3118 return cmd_sta_set_eaptls(dut, conn, cmd);
3119 if (strcasecmp(type, "EAPTTLS") == 0)
3120 return cmd_sta_set_eapttls(dut, conn, cmd);
3121 if (strcasecmp(type, "EAPPEAP") == 0)
3122 return cmd_sta_set_peap(dut, conn, cmd);
3123 if (strcasecmp(type, "EAPSIM") == 0)
3124 return cmd_sta_set_eapsim(dut, conn, cmd);
3125 if (strcasecmp(type, "EAPFAST") == 0)
3126 return cmd_sta_set_eapfast(dut, conn, cmd);
3127 if (strcasecmp(type, "EAPAKA") == 0)
3128 return cmd_sta_set_eapaka(dut, conn, cmd);
3129 if (strcasecmp(type, "EAPAKAPRIME") == 0)
3130 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08003131 if (strcasecmp(type, "wep") == 0)
3132 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003133
3134 send_resp(dut, conn, SIGMA_ERROR,
3135 "ErrorCode,Unsupported Type value");
3136 return 0;
3137}
3138
3139
3140int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
3141{
3142#ifdef __linux__
3143 /* special handling for ath6kl */
3144 char path[128], fname[128], *pos;
3145 ssize_t res;
3146 FILE *f;
3147
Jouni Malinene39cd562019-05-29 23:39:56 +03003148 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3149 intf);
3150 if (res < 0 || res >= sizeof(fname))
3151 return 0;
3152 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003153 if (res < 0)
3154 return 0; /* not ath6kl */
3155
3156 if (res >= (int) sizeof(path))
3157 res = sizeof(path) - 1;
3158 path[res] = '\0';
3159 pos = strrchr(path, '/');
3160 if (pos == NULL)
3161 pos = path;
3162 else
3163 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003164 res = snprintf(fname, sizeof(fname),
3165 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3166 "create_qos", pos);
3167 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003168 return 0; /* not ath6kl */
3169
3170 if (uapsd) {
3171 f = fopen(fname, "w");
3172 if (f == NULL)
3173 return -1;
3174
3175 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3176 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3177 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3178 "20000 0\n");
3179 fclose(f);
3180 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003181 res = snprintf(fname, sizeof(fname),
3182 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3183 "delete_qos", pos);
3184 if (res < 0 || res >= sizeof(fname))
3185 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003186
3187 f = fopen(fname, "w");
3188 if (f == NULL)
3189 return -1;
3190
3191 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3192 fprintf(f, "2 4\n");
3193 fclose(f);
3194 }
3195#endif /* __linux__ */
3196
3197 return 0;
3198}
3199
3200
Jouni Malinenf7222712019-06-13 01:50:21 +03003201static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3202 struct sigma_conn *conn,
3203 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003204{
3205 const char *intf = get_param(cmd, "Interface");
3206 /* const char *ssid = get_param(cmd, "ssid"); */
3207 const char *val;
3208 int max_sp_len = 4;
3209 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3210 char buf[100];
3211 int ret1, ret2;
3212
3213 val = get_param(cmd, "maxSPLength");
3214 if (val) {
3215 max_sp_len = atoi(val);
3216 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3217 max_sp_len != 4)
3218 return -1;
3219 }
3220
3221 val = get_param(cmd, "acBE");
3222 if (val)
3223 ac_be = atoi(val);
3224
3225 val = get_param(cmd, "acBK");
3226 if (val)
3227 ac_bk = atoi(val);
3228
3229 val = get_param(cmd, "acVI");
3230 if (val)
3231 ac_vi = atoi(val);
3232
3233 val = get_param(cmd, "acVO");
3234 if (val)
3235 ac_vo = atoi(val);
3236
3237 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3238
3239 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3240 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3241 ret1 = wpa_command(intf, buf);
3242
3243 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3244 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3245 ret2 = wpa_command(intf, buf);
3246
3247 if (ret1 && ret2) {
3248 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3249 "UAPSD parameters.");
3250 return -2;
3251 }
3252
3253 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3254 send_resp(dut, conn, SIGMA_ERROR,
3255 "ErrorCode,Failed to set ath6kl QoS parameters");
3256 return 0;
3257 }
3258
3259 return 1;
3260}
3261
3262
Jouni Malinenf7222712019-06-13 01:50:21 +03003263static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3264 struct sigma_conn *conn,
3265 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003266{
3267 char buf[1000];
3268 const char *intf = get_param(cmd, "Interface");
3269 const char *grp = get_param(cmd, "Group");
3270 const char *act = get_param(cmd, "Action");
3271 const char *tid = get_param(cmd, "Tid");
3272 const char *dir = get_param(cmd, "Direction");
3273 const char *psb = get_param(cmd, "Psb");
3274 const char *up = get_param(cmd, "Up");
3275 const char *fixed = get_param(cmd, "Fixed");
3276 const char *size = get_param(cmd, "Size");
3277 const char *msize = get_param(cmd, "Maxsize");
3278 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3279 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3280 const char *inact = get_param(cmd, "Inactivity");
3281 const char *sus = get_param(cmd, "Suspension");
3282 const char *mindr = get_param(cmd, "Mindatarate");
3283 const char *meandr = get_param(cmd, "Meandatarate");
3284 const char *peakdr = get_param(cmd, "Peakdatarate");
3285 const char *phyrate = get_param(cmd, "Phyrate");
3286 const char *burstsize = get_param(cmd, "Burstsize");
3287 const char *sba = get_param(cmd, "Sba");
3288 int direction;
3289 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003290 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003291 int fixed_int;
3292 int psb_ts;
3293
3294 if (intf == NULL || grp == NULL || act == NULL )
3295 return -1;
3296
3297 if (strcasecmp(act, "addts") == 0) {
3298 if (tid == NULL || dir == NULL || psb == NULL ||
3299 up == NULL || fixed == NULL || size == NULL)
3300 return -1;
3301
3302 /*
3303 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3304 * possible values, but WMM-AC and V-E test scripts use "UP,
3305 * "DOWN", and "BIDI".
3306 */
3307 if (strcasecmp(dir, "uplink") == 0 ||
3308 strcasecmp(dir, "up") == 0) {
3309 direction = 0;
3310 } else if (strcasecmp(dir, "downlink") == 0 ||
3311 strcasecmp(dir, "down") == 0) {
3312 direction = 1;
3313 } else if (strcasecmp(dir, "bidi") == 0) {
3314 direction = 2;
3315 } else {
3316 sigma_dut_print(dut, DUT_MSG_ERROR,
3317 "Direction %s not supported", dir);
3318 return -1;
3319 }
3320
3321 if (strcasecmp(psb, "legacy") == 0) {
3322 psb_ts = 0;
3323 } else if (strcasecmp(psb, "uapsd") == 0) {
3324 psb_ts = 1;
3325 } else {
3326 sigma_dut_print(dut, DUT_MSG_ERROR,
3327 "PSB %s not supported", psb);
3328 return -1;
3329 }
3330
3331 if (atoi(tid) < 0 || atoi(tid) > 7) {
3332 sigma_dut_print(dut, DUT_MSG_ERROR,
3333 "TID %s not supported", tid);
3334 return -1;
3335 }
3336
3337 if (strcasecmp(fixed, "true") == 0) {
3338 fixed_int = 1;
3339 } else {
3340 fixed_int = 0;
3341 }
3342
Peng Xu93319622017-10-04 17:58:16 -07003343 if (sba)
3344 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003345
3346 dut->dialog_token++;
3347 handle = 7000 + dut->dialog_token;
3348
3349 /*
3350 * size: convert to hex
3351 * maxsi: convert to hex
3352 * mindr: convert to hex
3353 * meandr: convert to hex
3354 * peakdr: convert to hex
3355 * burstsize: convert to hex
3356 * phyrate: convert to hex
3357 * sba: convert to hex with modification
3358 * minsi: convert to integer
3359 * sus: convert to integer
3360 * inact: convert to integer
3361 * maxsi: convert to integer
3362 */
3363
3364 /*
3365 * The Nominal MSDU Size field is 2 octets long and contains an
3366 * unsigned integer that specifies the nominal size, in octets,
3367 * of MSDUs belonging to the traffic under this traffic
3368 * specification and is defined in Figure 16. If the Fixed
3369 * subfield is set to 1, then the size of the MSDU is fixed and
3370 * is indicated by the Size Subfield. If the Fixed subfield is
3371 * set to 0, then the size of the MSDU might not be fixed and
3372 * the Size indicates the nominal MSDU size.
3373 *
3374 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3375 * and specifies the excess allocation of time (and bandwidth)
3376 * over and above the stated rates required to transport an MSDU
3377 * belonging to the traffic in this TSPEC. This field is
3378 * represented as an unsigned binary number with an implicit
3379 * binary point after the leftmost 3 bits. For example, an SBA
3380 * of 1.75 is represented as 0x3800. This field is included to
3381 * account for retransmissions. As such, the value of this field
3382 * must be greater than unity.
3383 */
3384
3385 snprintf(buf, sizeof(buf),
3386 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3387 " 0x%X 0x%X 0x%X"
3388 " 0x%X 0x%X 0x%X"
3389 " 0x%X %d %d %d %d"
3390 " %d %d",
3391 intf, handle, tid, direction, psb_ts, up,
3392 (unsigned int) ((fixed_int << 15) | atoi(size)),
3393 msize ? atoi(msize) : 0,
3394 mindr ? atoi(mindr) : 0,
3395 meandr ? atoi(meandr) : 0,
3396 peakdr ? atoi(peakdr) : 0,
3397 burstsize ? atoi(burstsize) : 0,
3398 phyrate ? atoi(phyrate) : 0,
3399 sba ? ((unsigned int) (((int) sba_fv << 13) |
3400 (int)((sba_fv - (int) sba_fv) *
3401 8192))) : 0,
3402 minsi ? atoi(minsi) : 0,
3403 sus ? atoi(sus) : 0,
3404 0, 0,
3405 inact ? atoi(inact) : 0,
3406 maxsi ? atoi(maxsi) : 0);
3407
3408 if (system(buf) != 0) {
3409 sigma_dut_print(dut, DUT_MSG_ERROR,
3410 "iwpriv addtspec request failed");
3411 send_resp(dut, conn, SIGMA_ERROR,
3412 "errorCode,Failed to execute addTspec command");
3413 return 0;
3414 }
3415
3416 sigma_dut_print(dut, DUT_MSG_INFO,
3417 "iwpriv addtspec request send");
3418
3419 /* Mapping handle to a TID */
3420 dut->tid_to_handle[atoi(tid)] = handle;
3421 } else if (strcasecmp(act, "delts") == 0) {
3422 if (tid == NULL)
3423 return -1;
3424
3425 if (atoi(tid) < 0 || atoi(tid) > 7) {
3426 sigma_dut_print(dut, DUT_MSG_ERROR,
3427 "TID %s not supported", tid);
3428 send_resp(dut, conn, SIGMA_ERROR,
3429 "errorCode,Unsupported TID");
3430 return 0;
3431 }
3432
3433 handle = dut->tid_to_handle[atoi(tid)];
3434
3435 if (handle < 7000 || handle > 7255) {
3436 /* Invalid handle ie no mapping for that TID */
3437 sigma_dut_print(dut, DUT_MSG_ERROR,
3438 "handle-> %d not found", handle);
3439 }
3440
3441 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3442 intf, handle);
3443
3444 if (system(buf) != 0) {
3445 sigma_dut_print(dut, DUT_MSG_ERROR,
3446 "iwpriv deltspec request failed");
3447 send_resp(dut, conn, SIGMA_ERROR,
3448 "errorCode,Failed to execute delTspec command");
3449 return 0;
3450 }
3451
3452 sigma_dut_print(dut, DUT_MSG_INFO,
3453 "iwpriv deltspec request send");
3454
3455 dut->tid_to_handle[atoi(tid)] = 0;
3456 } else {
3457 sigma_dut_print(dut, DUT_MSG_ERROR,
3458 "Action type %s not supported", act);
3459 send_resp(dut, conn, SIGMA_ERROR,
3460 "errorCode,Unsupported Action");
3461 return 0;
3462 }
3463
3464 return 1;
3465}
3466
3467
vamsi krishna52e16f92017-08-29 12:37:34 +05303468static int find_network(struct sigma_dut *dut, const char *ssid)
3469{
3470 char list[4096];
3471 char *pos;
3472
3473 sigma_dut_print(dut, DUT_MSG_DEBUG,
3474 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003475 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303476 list, sizeof(list)) < 0)
3477 return -1;
3478 pos = strstr(list, ssid);
3479 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3480 return -1;
3481
3482 while (pos > list && pos[-1] != '\n')
3483 pos--;
3484 dut->infra_network_id = atoi(pos);
3485 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3486 return 0;
3487}
3488
3489
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303490/**
3491 * enum qca_sta_helper_config_params - This helper enum defines the config
3492 * parameters which can be delivered to sta.
3493 */
3494enum qca_sta_helper_config_params {
3495 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE */
3496 STA_SET_RSNIE,
3497
3498 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC */
3499 STA_SET_LDPC,
3500
3501 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC */
3502 STA_SET_TX_STBC,
3503
3504 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC */
3505 STA_SET_RX_STBC,
3506
3507 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION */
3508 STA_SET_TX_MSDU,
3509
3510 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION */
3511 STA_SET_RX_MSDU,
Shivani Baranwal2a572842021-09-16 12:27:15 +05303512
3513 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH */
3514 STA_SET_CHAN_WIDTH,
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303515
3516 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS */
3517 STA_SET_FT_DS,
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303518};
3519
3520
3521static int sta_config_params(struct sigma_dut *dut, const char *intf,
3522 enum qca_sta_helper_config_params config_cmd,
3523 int value)
Sunil Dutt44595082018-02-12 19:41:45 +05303524{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303525#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05303526 struct nl_msg *msg;
3527 int ret;
3528 struct nlattr *params;
3529 int ifindex;
3530
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303531 ifindex = if_nametoindex(intf);
3532 if (ifindex == 0) {
3533 sigma_dut_print(dut, DUT_MSG_ERROR,
3534 "%s: Interface %s does not exist",
3535 __func__, intf);
3536 return -1;
3537 }
3538
Sunil Dutt44595082018-02-12 19:41:45 +05303539 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3540 NL80211_CMD_VENDOR)) ||
3541 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3542 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3543 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3544 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303545 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)))
3546 goto fail;
3547
3548 switch (config_cmd) {
3549 case STA_SET_RSNIE:
3550 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, value))
3551 goto fail;
3552 break;
3553 case STA_SET_LDPC:
3554 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC, value))
3555 goto fail;
3556 break;
3557 case STA_SET_TX_STBC:
3558 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC, value))
3559 goto fail;
3560 break;
3561 case STA_SET_RX_STBC:
3562 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC, value))
3563 goto fail;
3564 break;
3565 case STA_SET_TX_MSDU:
3566 if (nla_put_u8(msg,
3567 QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION,
3568 value))
3569 goto fail;
3570 break;
3571 case STA_SET_RX_MSDU:
3572 if (nla_put_u8(msg,
3573 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION,
3574 value))
3575 goto fail;
3576 break;
Shivani Baranwal2a572842021-09-16 12:27:15 +05303577 case STA_SET_CHAN_WIDTH:
3578 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
3579 value))
3580 goto fail;
3581 break;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303582 case STA_SET_FT_DS:
3583 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS,
3584 value))
3585 goto fail;
3586 break;
Sunil Dutt44595082018-02-12 19:41:45 +05303587 }
3588 nla_nest_end(msg, params);
3589
3590 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3591 if (ret) {
3592 sigma_dut_print(dut, DUT_MSG_ERROR,
3593 "%s: err in send_and_recv_msgs, ret=%d",
3594 __func__, ret);
3595 return ret;
3596 }
3597
3598 return 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303599
3600fail:
3601 sigma_dut_print(dut, DUT_MSG_ERROR,
3602 "%s: err in adding vendor_cmd and vendor_data",
3603 __func__);
3604 nlmsg_free(msg);
Sunil Dutt44595082018-02-12 19:41:45 +05303605#endif /* NL80211_SUPPORT */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303606 return -1;
3607}
Sunil Dutt44595082018-02-12 19:41:45 +05303608
3609
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303610void free_dscp_policy_table(struct sigma_dut *dut)
3611{
3612 struct dscp_policy_data *dscp_policy;
3613
3614 while (dut->dscp_policy_table) {
3615 dscp_policy = dut->dscp_policy_table;
3616 dut->dscp_policy_table = dscp_policy->next;
3617 free(dscp_policy);
3618 }
3619}
3620
3621
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303622static char * protocol_to_str(int proto)
3623{
3624 switch (proto) {
3625 case 6:
3626 return "tcp";
3627 case 17:
3628 return "udp";
3629 case 50:
3630 return "esp";
3631 default:
3632 return "unknown";
3633 }
3634}
3635
3636
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303637static int delete_nft_table(struct sigma_dut *dut, const char *table,
3638 const char *ip_type)
3639{
3640 int res;
3641 char cmd[200];
3642
3643 res = snprintf(cmd, sizeof(cmd), "nft delete table %s %s_%s", ip_type,
3644 table, ip_type);
3645 if (snprintf_error(sizeof(cmd), res)) {
3646 sigma_dut_print(dut, DUT_MSG_ERROR,
3647 "Failed to create delete table command");
3648 return -1;
3649 }
3650
3651 if (system(cmd) != 0) {
3652 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3653 return -1;
3654 }
3655
3656 return 0;
3657}
3658
3659
3660static int remove_nft_rule(struct sigma_dut *dut, int policy_id,
3661 enum ip_version ip_ver)
3662{
3663 int res;
3664 char table[50];
3665
3666 res = snprintf(table, sizeof(table), "wifi_%s_dscp_policy_%d",
3667 dut->station_ifname, policy_id);
3668 if (snprintf_error(sizeof(table), res)) {
3669 sigma_dut_print(dut, DUT_MSG_INFO,
3670 "Failed to create table name for policy %d",
3671 policy_id);
3672 return -1;
3673 }
3674
3675
3676 if (ip_ver == IPV6)
3677 return delete_nft_table(dut, table, "ip6");
3678 else
3679 return delete_nft_table(dut, table, "ip");
3680}
3681
3682
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303683static int remove_iptable_rule(struct sigma_dut *dut,
3684 struct dscp_policy_data *dscp_policy)
3685{
3686 char ip_cmd[1000];
3687 char *pos;
3688 int ret, len;
3689 enum ip_version ip_ver = dscp_policy->ip_version;
3690
3691 pos = ip_cmd;
3692 len = sizeof(ip_cmd);
3693
3694 ret = snprintf(pos, len,
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05303695 "%s -t mangle -D OUTPUT -o %s",
3696#ifdef ANDROID
3697 ip_ver == IPV6 ? "/system/bin/ip6tables" : "/system/bin/iptables",
3698#else /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303699 ip_ver == IPV6 ? "ip6tables" : "iptables",
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05303700#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303701 dut->station_ifname);
3702 if (snprintf_error(len, ret)) {
3703 sigma_dut_print(dut, DUT_MSG_INFO,
3704 "Failed to create delete iptables command %s",
3705 ip_cmd);
3706 return -1;
3707 }
3708
3709 pos += ret;
3710 len -= ret;
3711
3712 if (strlen(dscp_policy->src_ip)) {
3713 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
3714 if (snprintf_error(len, ret)) {
3715 sigma_dut_print(dut, DUT_MSG_INFO,
3716 "Error in adding src_ip %s in delete command",
3717 dscp_policy->src_ip);
3718 return -1;
3719 }
3720 pos += ret;
3721 len -= ret;
3722 }
3723
3724 if (strlen(dscp_policy->dst_ip)) {
3725 ret = snprintf(pos, len, " -d %s",
3726 dscp_policy->dst_ip);
3727 if (snprintf_error(len, ret)) {
3728 sigma_dut_print(dut, DUT_MSG_INFO,
3729 "Error in adding dst_ip %s in delete cmd",
3730 dscp_policy->dst_ip);
3731 return -1;
3732 }
3733 pos += ret;
3734 len -= ret;
3735 }
3736
3737 if (dscp_policy->src_port || dscp_policy->dst_port ||
3738 (dscp_policy->start_port && dscp_policy->end_port)) {
3739 ret = snprintf(pos, len, " -p %s",
3740 protocol_to_str(dscp_policy->protocol));
3741 if (snprintf_error(len, ret)) {
3742 sigma_dut_print(dut, DUT_MSG_INFO,
3743 "Error in adding protocol %d in delete command",
3744 dscp_policy->protocol);
3745 return -1;
3746 }
3747 pos += ret;
3748 len -= ret;
3749 }
3750
3751 if (dscp_policy->src_port) {
3752 ret = snprintf(pos, len, " --sport %d",
3753 dscp_policy->src_port);
3754 if (snprintf_error(len, ret)) {
3755 sigma_dut_print(dut, DUT_MSG_INFO,
3756 "Error in adding src_port %d in delete command",
3757 dscp_policy->src_port);
3758 return -1;
3759 }
3760 pos += ret;
3761 len -= ret;
3762 }
3763
3764 if (dscp_policy->dst_port) {
3765 ret = snprintf(pos, len, " --dport %d",
3766 dscp_policy->dst_port);
3767 if (snprintf_error(len, ret)) {
3768 sigma_dut_print(dut, DUT_MSG_INFO,
3769 "Error in adding dst_port %d in delete command",
3770 dscp_policy->dst_port);
3771 return -1;
3772 }
3773 pos += ret;
3774 len -= ret;
3775 }
3776
3777 if (dscp_policy->start_port && dscp_policy->end_port) {
3778 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
3779 dscp_policy->start_port,
3780 dscp_policy->end_port);
3781 if (snprintf_error(len, ret)) {
3782 sigma_dut_print(dut, DUT_MSG_INFO,
3783 "Error in adding start:end port %d:%d in delete command",
3784 dscp_policy->start_port,
3785 dscp_policy->end_port);
3786 return -1;
3787 }
3788 pos += ret;
3789 len -= ret;
3790 }
3791
3792 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
3793 dscp_policy->dscp);
3794 if (snprintf_error(len, ret)) {
3795 sigma_dut_print(dut, DUT_MSG_INFO,
3796 "Error in adding dscp %0x in delete command",
3797 dscp_policy->dscp);
3798 return -1;
3799 }
3800 ret = system(ip_cmd);
3801 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
3802 ip_cmd, ret);
3803
3804 return ret;
3805}
3806
3807
3808static int remove_dscp_policy_rule(struct sigma_dut *dut,
3809 struct dscp_policy_data *dscp_policy)
3810{
3811 return dut->dscp_use_iptables ? remove_iptable_rule(dut, dscp_policy) :
3812 remove_nft_rule(dut, dscp_policy->policy_id,
3813 dscp_policy->ip_version);
3814}
3815
3816
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303817static int create_nft_table(struct sigma_dut *dut, int policy_id,
3818 const char *table_name, enum ip_version ip_ver)
3819{
3820 char cmd[200];
3821 int res;
3822
3823 res = snprintf(cmd, sizeof(cmd), "nft add table %s %s",
3824 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3825 if (snprintf_error(sizeof(cmd), res)) {
3826 sigma_dut_print(dut, DUT_MSG_INFO,
3827 "Failed to add rule to create table for policy id %d",
3828 policy_id);
3829 return -1;
3830 }
3831
3832 if (system(cmd) != 0) {
3833 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3834 return -1;
3835 }
3836
3837 res = snprintf(cmd, sizeof(cmd),
3838 "nft add chain %s %s OUTPUT { type filter hook output priority 0 \\; }",
3839 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3840 if (snprintf_error(sizeof(cmd), res)) {
3841 sigma_dut_print(dut, DUT_MSG_INFO,
3842 "Failed to add rule to create chain for table = %s",
3843 table_name);
3844 return -1;
3845 }
3846
3847 if (system(cmd) != 0) {
3848 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3849 return -1;
3850 }
3851
3852 return 0;
3853}
3854
3855
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303856static int remove_dscp_policy(struct sigma_dut *dut, u8 policy_id)
3857{
3858 struct dscp_policy_data *dscp_policy = dut->dscp_policy_table;
3859 struct dscp_policy_data *prev = NULL;
3860
3861 while (dscp_policy) {
3862 if (dscp_policy->policy_id == policy_id)
3863 break;
3864
3865 prev = dscp_policy;
3866 dscp_policy = dscp_policy->next;
3867 }
3868
3869 /*
3870 * Consider remove request for a policy id which does not exist as
3871 * success.
3872 */
3873 if (!dscp_policy)
3874 return 0;
3875
3876 if (strlen(dscp_policy->domain_name) == 0 &&
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303877 remove_dscp_policy_rule(dut, dscp_policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303878 return -1;
3879
3880 if (prev)
3881 prev->next = dscp_policy->next;
3882 else
3883 dut->dscp_policy_table = dscp_policy->next;
3884
3885 free(dscp_policy);
3886 return 0;
3887}
3888
3889
3890static int add_nft_rule(struct sigma_dut *dut,
3891 struct dscp_policy_data *dscp_policy)
3892{
3893 char nft_cmd[1000], ip[4], table_name[100];
3894 char *pos;
3895 int ret, len, policy_id = dscp_policy->policy_id;
3896 enum ip_version ip_ver = dscp_policy->ip_version;
3897
3898 if (ip_ver == IPV6)
3899 strlcpy(ip, "ip6", sizeof(ip));
3900 else
3901 strlcpy(ip, "ip", sizeof(ip));
3902
3903 ret = snprintf(table_name, sizeof(table_name),
3904 "wifi_%s_dscp_policy_%d_%s",
3905 dut->station_ifname, policy_id, ip);
3906 if (snprintf_error(sizeof(table_name), ret))
3907 return -1;
3908
3909 if (create_nft_table(dut, policy_id, table_name, ip_ver)) {
3910 sigma_dut_print(dut, DUT_MSG_INFO,
3911 "Failed to create nft table");
3912 return -1;
3913 }
3914
3915 pos = nft_cmd;
3916 len = sizeof(nft_cmd);
3917
3918 ret = snprintf(pos, len,
3919 "nft add rule %s %s OUTPUT oifname \"%s\"",
3920 ip, table_name, dut->station_ifname);
3921 if (snprintf_error(len, ret)) {
3922 sigma_dut_print(dut, DUT_MSG_INFO,
3923 "Failed to create nft cmd %s", nft_cmd);
3924 return -1;
3925 }
3926
3927 pos += ret;
3928 len -= ret;
3929
3930 if (strlen(dscp_policy->src_ip)) {
3931 ret = snprintf(pos, len, " %s saddr %s", ip,
3932 dscp_policy->src_ip);
3933 if (snprintf_error(len, ret))
3934 return -1;
3935
3936 pos += ret;
3937 len -= ret;
3938 }
3939
3940 if (strlen(dscp_policy->dst_ip)) {
3941 ret = snprintf(pos, len, " %s daddr %s", ip,
3942 dscp_policy->dst_ip);
3943 if (snprintf_error(len, ret))
3944 return -1;
3945
3946 pos += ret;
3947 len -= ret;
3948 }
3949
3950 if (dscp_policy->src_port) {
3951 ret = snprintf(pos, len, " %s sport %d",
3952 protocol_to_str(dscp_policy->protocol),
3953 dscp_policy->src_port);
3954 if (snprintf_error(len, ret))
3955 return -1;
3956
3957 pos += ret;
3958 len -= ret;
3959 }
3960
3961 if (dscp_policy->dst_port) {
3962 ret = snprintf(pos, len, " %s dport %d",
3963 protocol_to_str(dscp_policy->protocol),
3964 dscp_policy->dst_port);
3965 if (snprintf_error(len, ret))
3966 return -1;
3967
3968 pos += ret;
3969 len -= ret;
3970 }
3971
3972 if (dscp_policy->start_port && dscp_policy->end_port) {
3973 ret = snprintf(pos, len, " %s dport %d-%d",
3974 protocol_to_str(dscp_policy->protocol),
3975 dscp_policy->start_port,
3976 dscp_policy->end_port);
3977 if (snprintf_error(len, ret))
3978 return -1;
3979
3980 pos += ret;
3981 len -= ret;
3982 }
3983
3984 ret = snprintf(pos, len, " counter %s dscp set 0x%0x", ip,
3985 dscp_policy->dscp);
3986 if (snprintf_error(len, ret))
3987 return -1;
3988
3989 ret = system(nft_cmd);
3990 sigma_dut_print(dut, DUT_MSG_INFO, "nft rule: %s err: %d",
3991 nft_cmd, ret);
3992
3993 return ret;
3994}
3995
3996
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303997static int add_iptable_rule(struct sigma_dut *dut,
3998 struct dscp_policy_data *dscp_policy)
3999{
4000 char ip_cmd[1000];
4001 char *pos;
4002 int ret, len;
4003 enum ip_version ip_ver = dscp_policy->ip_version;
4004 struct dscp_policy_data *active_policy = dut->dscp_policy_table;
4005 int ipv4_rule_num = 1, ipv6_rule_num = 1;
4006
4007 pos = ip_cmd;
4008 len = sizeof(ip_cmd);
4009
4010 /*
4011 * DSCP target in the mangle table doesn't stop processing of rules
4012 * so to make sure the most granular rule is applied last, add the new
4013 * rules in granularity increasing order.
4014 */
4015 while (active_policy) {
4016 /*
4017 * Domain name rules are managed in sigma_dut thus don't count
4018 * them while counting the number of active rules.
4019 */
4020 if (strlen(active_policy->domain_name)) {
4021 active_policy = active_policy->next;
4022 continue;
4023 }
4024
4025 if (active_policy->granularity_score >
4026 dscp_policy->granularity_score)
4027 break;
4028
4029 if (active_policy->ip_version == IPV6)
4030 ipv6_rule_num++;
4031 else
4032 ipv4_rule_num++;
4033
4034 active_policy = active_policy->next;
4035 }
4036
4037 ret = snprintf(pos, len,
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304038 "%s -t mangle -I OUTPUT %d -o %s",
4039#ifdef ANDROID
4040 ip_ver == IPV6 ? "/system/bin/ip6tables" : "/system/bin/iptables",
4041#else /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304042 ip_ver == IPV6 ? "ip6tables" : "iptables",
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304043#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304044 ip_ver == IPV6 ? ipv6_rule_num : ipv4_rule_num,
4045 dut->station_ifname);
4046 if (snprintf_error(len, ret)) {
4047 sigma_dut_print(dut, DUT_MSG_INFO,
4048 "Failed to create iptables command %s", ip_cmd);
4049 return -1;
4050 }
4051
4052 pos += ret;
4053 len -= ret;
4054
4055 if (strlen(dscp_policy->src_ip)) {
4056 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
4057 if (snprintf_error(len, ret)) {
4058 sigma_dut_print(dut, DUT_MSG_INFO,
4059 "Error in adding src_ip %s",
4060 dscp_policy->src_ip);
4061 return -1;
4062 }
4063 pos += ret;
4064 len -= ret;
4065 }
4066
4067 if (strlen(dscp_policy->dst_ip)) {
4068 ret = snprintf(pos, len, " -d %s", dscp_policy->dst_ip);
4069 if (snprintf_error(len, ret)) {
4070 sigma_dut_print(dut, DUT_MSG_INFO,
4071 "Error in adding dst_ip %s",
4072 dscp_policy->dst_ip);
4073 return -1;
4074 }
4075 pos += ret;
4076 len -= ret;
4077 }
4078
4079 if (dscp_policy->src_port || dscp_policy->dst_port ||
4080 (dscp_policy->start_port && dscp_policy->end_port)) {
4081 ret = snprintf(pos, len, " -p %s",
4082 protocol_to_str(dscp_policy->protocol));
4083 if (snprintf_error(len, ret)) {
4084 sigma_dut_print(dut, DUT_MSG_INFO,
4085 "Error in adding protocol %d in add command",
4086 dscp_policy->protocol);
4087 return -1;
4088 }
4089 pos += ret;
4090 len -= ret;
4091 }
4092
4093 if (dscp_policy->src_port) {
4094 ret = snprintf(pos, len, " --sport %d", dscp_policy->src_port);
4095 if (snprintf_error(len, ret)) {
4096 sigma_dut_print(dut, DUT_MSG_INFO,
4097 "Error in adding src_port %d",
4098 dscp_policy->src_port);
4099 return -1;
4100 }
4101 pos += ret;
4102 len -= ret;
4103 }
4104
4105 if (dscp_policy->dst_port) {
4106 ret = snprintf(pos, len, " --dport %d", dscp_policy->dst_port);
4107 if (snprintf_error(len, ret)) {
4108 sigma_dut_print(dut, DUT_MSG_INFO,
4109 "Error in adding dst_port %d",
4110 dscp_policy->dst_port);
4111 return -1;
4112 }
4113 pos += ret;
4114 len -= ret;
4115 }
4116
4117 if (dscp_policy->start_port && dscp_policy->end_port) {
4118 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
4119 dscp_policy->start_port, dscp_policy->end_port);
4120 if (snprintf_error(len, ret)) {
4121 sigma_dut_print(dut, DUT_MSG_INFO,
4122 "Error in adding start:end port %d:%d",
4123 dscp_policy->start_port,
4124 dscp_policy->end_port);
4125 return -1;
4126 }
4127 pos += ret;
4128 len -= ret;
4129 }
4130
4131 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
4132 dscp_policy->dscp);
4133 if (snprintf_error(len, ret)) {
4134 sigma_dut_print(dut, DUT_MSG_INFO,
4135 "Error in adding dscp %0x", dscp_policy->dscp);
4136 return -1;
4137 }
4138 ret = system(ip_cmd);
4139 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
4140 ip_cmd, ret);
4141
4142 return ret;
4143}
4144
4145
4146static int add_dscp_policy_rule(struct sigma_dut *dut,
4147 struct dscp_policy_data *dscp_policy)
4148{
4149 return dut->dscp_use_iptables ? add_iptable_rule(dut, dscp_policy) :
4150 add_nft_rule(dut, dscp_policy);
4151}
4152
4153
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304154static void clear_all_dscp_policies(struct sigma_dut *dut)
4155{
4156 free_dscp_policy_table(dut);
4157
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304158 if (dut->dscp_use_iptables) {
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304159#ifdef ANDROID
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304160 if (system("/system/bin/iptables -t mangle -F && /system/bin/iptables -t mangle -X") != 0 ||
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304161 system("/system/bin/ip6tables -t mangle -F && /system/bin/ip6tables -t mangle -X") != 0)
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304162 sigma_dut_print(dut, DUT_MSG_ERROR,
4163 "iptables: Failed to flush DSCP policy");
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304164#else /* ANDROID */
4165 if (system("iptables -t mangle -F && iptables -t mangle -X") != 0 ||
4166 system("ip6tables -t mangle -F && ip6tables -t mangle -X") != 0)
4167 sigma_dut_print(dut, DUT_MSG_ERROR,
4168 "iptables: Failed to flush DSCP policy");
4169#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304170 } else {
4171 if (system("nft flush ruleset") != 0)
4172 sigma_dut_print(dut, DUT_MSG_ERROR,
4173 "nftables: Failed to flush DSCP policy");
4174 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304175}
4176
4177
4178static int send_dscp_response(struct sigma_dut *dut,
4179 struct dscp_policy_status *status_list,
4180 int num_status)
4181{
4182 int rem_len, ret;
4183 char buf[200] = "", *pos, cmd[256];
4184
4185 pos = buf;
4186 rem_len = sizeof(buf);
4187
4188 ret = snprintf(pos, rem_len, " solicited");
4189 if (snprintf_error(rem_len, ret)) {
4190 sigma_dut_print(dut, DUT_MSG_ERROR,
4191 "Failed to write DSCP policy response command");
4192 return -1;
4193 }
4194 pos += ret;
4195 rem_len -= ret;
4196
4197 for (int i = 0; i < num_status; i++) {
4198 ret = snprintf(pos, rem_len, " policy_id=%d status=%d",
4199 status_list[i].id, status_list[i].status);
4200 if (snprintf_error(rem_len, ret)) {
4201 sigma_dut_print(dut, DUT_MSG_ERROR,
4202 "Failed to wite DSCP policy response");
4203 return -1;
4204 }
4205
4206 pos += ret;
4207 rem_len -= ret;
4208 }
4209
4210 ret = snprintf(cmd, sizeof(cmd), "DSCP_RESP%s", buf);
4211 if (snprintf_error(sizeof(cmd), ret)) {
4212 sigma_dut_print(dut, DUT_MSG_ERROR,
4213 "Failed to create DSCP Policy Response frame");
4214 return -1;
4215 }
4216
4217 if (wpa_command(dut->station_ifname, cmd) != 0) {
4218 sigma_dut_print(dut, DUT_MSG_ERROR,
4219 "Failed to send DSCP Policy Response frame");
4220 return -1;
4221 }
4222
4223 sigma_dut_print(dut, DUT_MSG_DEBUG,
4224 "DSCP Policy Response frame sent: %s", cmd);
4225 return 0;
4226}
4227
4228
4229#ifdef ANDROID
4230static void thread_cancel_handler(int sig)
4231{
4232 if (sig == SIGUSR1)
4233 pthread_exit(0);
4234}
4235#endif /* ANDROID */
4236
4237
4238static void * mon_dscp_policies(void *ptr)
4239{
4240 struct sigma_dut *dut = ptr;
4241 int ret, policy_id;
4242 struct wpa_ctrl *ctrl;
4243 char buf[4096], *pos, *end;
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304244 struct dscp_policy_data *policy = NULL, *current_policy, *prev_policy;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304245 struct dscp_policy_status status_list[10];
4246 int num_status = 0;
4247 const char *events[] = {
4248 "CTRL-EVENT-DISCONNECTED",
4249 "CTRL-EVENT-DSCP-POLICY",
4250 NULL
4251 };
4252#ifdef ANDROID
4253 struct sigaction actions;
4254#endif /* ANDROID */
4255
4256 ctrl = open_wpa_mon(get_station_ifname(dut));
4257 if (!ctrl) {
4258 sigma_dut_print(dut, DUT_MSG_ERROR,
4259 "Failed to open wpa_supplicant monitor connection");
4260 return NULL;
4261 }
4262
4263#ifdef ANDROID
4264 memset(&actions, 0, sizeof(actions));
4265 sigemptyset(&actions.sa_mask);
4266 actions.sa_flags = 0;
4267 actions.sa_handler = thread_cancel_handler;
4268 if (sigaction(SIGUSR1, &actions, NULL) == -1) {
4269 sigma_dut_print(dut, DUT_MSG_ERROR,
4270 "Failed to register exit handler for %s",
4271 __func__);
4272 wpa_ctrl_detach(ctrl);
4273 wpa_ctrl_close(ctrl);
4274 return NULL;
4275 }
4276#endif /* ANDROID */
4277
4278 while (1) {
4279 ret = get_wpa_cli_events_timeout(dut, ctrl, events,
4280 buf, sizeof(buf), 0);
4281
4282 if (ret || strlen(buf) == 0) {
4283 sigma_dut_print(dut, DUT_MSG_INFO,
4284 "Did not receive any event");
4285 continue;
4286 }
4287
4288 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4289 clear_all_dscp_policies(dut);
4290 break;
4291 }
4292
4293 if (strstr(buf, "request_start")) {
4294 num_status = 0;
4295 if (strstr(buf, "clear_all"))
4296 clear_all_dscp_policies(dut);
4297 continue;
4298 }
4299
4300 if (strstr(buf, "request_end")) {
4301 send_dscp_response(dut, status_list, num_status);
4302 continue;
4303 }
4304
4305 if (!strstr(buf, "add") && !strstr(buf, "remove") &&
4306 !strstr(buf, "reject")) {
4307 sigma_dut_print(dut, DUT_MSG_DEBUG, "Ignore event: %s",
4308 buf);
4309 continue;
4310 }
4311
4312 pos = strstr(buf, "policy_id=");
4313 if (!pos) {
4314 sigma_dut_print(dut, DUT_MSG_INFO,
4315 "Policy id not present");
4316 continue;
4317 }
4318 policy_id = atoi(pos + 10);
4319
4320 if (num_status >= ARRAY_SIZE(status_list)) {
4321 sigma_dut_print(dut, DUT_MSG_INFO,
4322 "Max policies allowed per DSCP request reached. Drop policy id %d request",
4323 policy_id);
4324 continue;
4325 }
4326 status_list[num_status].id = policy_id;
4327
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05304328 if (dut->reject_dscp_policies) {
4329 status_list[num_status].status =
4330 dut->dscp_reject_resp_code;
4331 num_status++;
4332 continue;
4333 }
4334
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304335 if (strstr(buf, "reject"))
4336 goto reject;
4337
4338 /*
4339 * In case of "add" also if policy with same policy id exist it
4340 * shall be removed. So always call remove_dscp_policy().
4341 */
4342 if (remove_dscp_policy(dut, policy_id))
4343 goto reject;
4344
4345 if (strstr(buf, "remove"))
4346 goto success;
4347
4348 policy = malloc(sizeof(*policy));
4349 if (!policy)
4350 goto reject;
4351
4352 memset(policy, 0, sizeof(*policy));
4353
4354 policy->policy_id = policy_id;
4355
4356 pos = strstr(buf, "dscp=");
4357 if (!pos) {
4358 sigma_dut_print(dut, DUT_MSG_ERROR,
4359 "DSCP info not present");
4360 goto reject;
4361 }
4362 policy->dscp = atoi(pos + 5);
4363
4364 pos = strstr(buf, "ip_version=");
4365 if (!pos) {
4366 sigma_dut_print(dut, DUT_MSG_ERROR,
4367 "IP version info not present");
4368 goto reject;
4369 }
4370 policy->ip_version = atoi(pos + 11);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304371 if (policy->ip_version)
4372 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304373
4374 pos = strstr(buf, "domain_name=");
4375 if (pos) {
4376 pos += 12;
4377 end = strchr(pos, ' ');
4378 if (!end)
4379 end = pos + strlen(pos);
4380
4381 if (end - pos >= (int) sizeof(policy->domain_name))
4382 goto reject;
4383
4384 memcpy(policy->domain_name, pos, end - pos);
4385 policy->domain_name[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304386 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304387 }
4388
4389 pos = strstr(buf, "start_port=");
4390 if (pos) {
4391 pos += 11;
4392 policy->start_port = atoi(pos);
4393 }
4394
4395 pos = strstr(buf, "end_port=");
4396 if (pos) {
4397 pos += 9;
4398 policy->end_port = atoi(pos);
4399 }
4400
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304401 if (policy->start_port && policy->end_port)
4402 policy->granularity_score++;
4403
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304404 pos = strstr(buf, "src_ip=");
4405 if (pos) {
4406 pos += 7;
4407 end = strchr(pos, ' ');
4408 if (!end)
4409 end = pos + strlen(pos);
4410
4411 if (end - pos >= (int) sizeof(policy->src_ip))
4412 goto reject;
4413
4414 memcpy(policy->src_ip, pos, end - pos);
4415 policy->src_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304416 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304417 }
4418
4419 pos = strstr(buf, "dst_ip=");
4420 if (pos) {
4421 pos += 7;
4422 end = strchr(pos, ' ');
4423 if (!end)
4424 end = pos + strlen(pos);
4425
4426 if (end - pos >= (int) sizeof(policy->dst_ip))
4427 goto reject;
4428
4429 memcpy(policy->dst_ip, pos, end - pos);
4430 policy->dst_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304431 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304432 }
4433
4434 pos = strstr(buf, "src_port=");
4435 if (pos) {
4436 pos += 9;
4437 policy->src_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304438 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304439 }
4440
4441 pos = strstr(buf, "dst_port=");
4442 if (pos) {
4443 pos += 9;
4444 policy->dst_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304445 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304446 }
4447
4448 pos = strstr(buf, "protocol=");
4449 if (pos) {
4450 pos += 9;
4451 policy->protocol = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304452 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304453 }
4454
4455 /*
4456 * Skip adding nft rules for doman name policies.
4457 * Domain name rules are applied in sigma_dut itself.
4458 */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304459 if (!strlen(policy->domain_name) &&
4460 add_dscp_policy_rule(dut, policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304461 goto reject;
4462
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304463 /*
4464 * Add the new policy in policy table in granularity increasing
4465 * order.
4466 */
4467 current_policy = dut->dscp_policy_table;
4468 prev_policy = NULL;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304469
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304470 while (current_policy) {
4471 if (current_policy->granularity_score >
4472 policy->granularity_score)
4473 break;
4474
4475 prev_policy = current_policy;
4476 current_policy = current_policy->next;
4477 }
4478
4479 if (prev_policy)
4480 prev_policy->next = policy;
4481 else
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304482 dut->dscp_policy_table = policy;
4483
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304484 policy->next = current_policy;
4485
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304486success:
4487 status_list[num_status].status = DSCP_POLICY_SUCCESS;
4488 num_status++;
4489 policy = NULL;
4490 continue;
4491reject:
4492 status_list[num_status].status = DSCP_POLICY_REJECT;
4493 num_status++;
4494 free(policy);
4495 policy = NULL;
4496 }
4497
4498 free_dscp_policy_table(dut);
4499 wpa_ctrl_detach(ctrl);
4500 wpa_ctrl_close(ctrl);
4501
4502 pthread_exit(0);
4503 return NULL;
4504}
4505
4506
4507static void start_dscp_policy_mon_thread(struct sigma_dut *dut)
4508{
4509 /* Create event thread */
4510 pthread_create(&dut->dscp_policy_mon_thread, NULL, &mon_dscp_policies,
4511 (void *) dut);
4512}
4513
4514
4515void stop_dscp_policy_mon_thread(struct sigma_dut *dut)
4516{
4517 if (dut->dscp_policy_mon_thread) {
4518#ifdef ANDROID
4519 /* pthread_cancel not supported in Android */
4520 pthread_kill(dut->dscp_policy_mon_thread, SIGUSR1);
4521#else /* ANDROID */
4522 pthread_cancel(dut->dscp_policy_mon_thread);
4523#endif /* ANDROID */
4524 dut->dscp_policy_mon_thread = 0;
4525 }
4526}
4527
4528
Jouni Malinenf7222712019-06-13 01:50:21 +03004529static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
4530 struct sigma_conn *conn,
4531 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004532{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304533#ifdef NL80211_SUPPORT
4534 const char *intf = get_param(cmd, "Interface");
4535#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004536 const char *ssid = get_param(cmd, "ssid");
4537 const char *wps_param = get_param(cmd, "WPS");
4538 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03004539 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004540 const char *network_mode = get_param(cmd, "network_mode");
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304541 const char *ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004542 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03004543 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004544 int e;
4545 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
4546 struct wpa_ctrl *ctrl = NULL;
4547 int num_network_not_found = 0;
4548 int num_disconnected = 0;
4549 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004550
4551 if (ssid == NULL)
4552 return -1;
4553
Jouni Malinen37d5c692019-08-19 16:56:55 +03004554 dut->server_cert_tod = 0;
4555
Jouni Malinen3c367e82017-06-23 17:01:47 +03004556 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05304557#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004558 if (get_driver_type(dut) == DRIVER_WCN) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304559 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Sunil Dutt44595082018-02-12 19:41:45 +05304560 dut->config_rsnie = 1;
4561 }
4562#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03004563 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
4564 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004565 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03004566 send_resp(dut, conn, SIGMA_ERROR,
4567 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
4568 return 0;
4569 }
4570 }
4571
Jouni Malinen68143132017-09-02 02:34:08 +03004572 if (dut->sae_commit_override) {
4573 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
4574 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004575 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03004576 send_resp(dut, conn, SIGMA_ERROR,
4577 "ErrorCode,Failed to set SAE commit override");
4578 return 0;
4579 }
4580 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304581#ifdef ANDROID
4582 if (dut->fils_hlp)
4583 process_fils_hlp(dut);
4584#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03004585
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004586 if (wps_param &&
4587 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
4588 wps = 1;
4589
4590 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004591 if (dut->program == PROGRAM_60GHZ && network_mode &&
4592 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004593 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004594 "pbss", "1") < 0)
4595 return -2;
4596
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004597 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
4598 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
4599 "parameters not yet set");
4600 return 0;
4601 }
4602 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004603 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004604 return -2;
4605 } else {
4606 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
4607 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004608 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004609 return -2;
4610 }
4611 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05304612 if (strcmp(ssid, dut->infra_ssid) == 0) {
4613 sigma_dut_print(dut, DUT_MSG_DEBUG,
4614 "sta_associate for the most recently added network");
4615 } else if (find_network(dut, ssid) < 0) {
4616 sigma_dut_print(dut, DUT_MSG_DEBUG,
4617 "sta_associate for a previously stored network profile");
4618 send_resp(dut, conn, SIGMA_ERROR,
4619 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004620 return 0;
4621 }
4622
4623 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004624 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004625 "bssid", bssid) < 0) {
4626 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4627 "Invalid bssid argument");
4628 return 0;
4629 }
4630
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304631 if ((dut->program == PROGRAM_WPA3 &&
4632 dut->sta_associate_wait_connect) ||
4633 dut->program == PROGRAM_QM) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004634 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004635 if (!ctrl)
4636 return ERROR_SEND_STATUS;
4637 }
4638
Jouni Malinen46a19b62017-06-23 14:31:27 +03004639 extra[0] = '\0';
4640 if (chan)
4641 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02004642 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03004643 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
4644 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004645 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004646 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
4647 "network id %d on %s",
4648 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004649 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004650 ret = ERROR_SEND_STATUS;
4651 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004652 }
4653 }
4654
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004655 if (!ctrl)
4656 return SUCCESS_SEND_STATUS;
4657
4658 /* Wait for connection result to be able to store server certificate
4659 * hash for trust root override testing
4660 * (dev_exec_action,ServerCertTrust). */
4661
4662 for (e = 0; e < 20; e++) {
4663 const char *events[] = {
4664 "CTRL-EVENT-EAP-PEER-CERT",
4665 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
4666 "CTRL-EVENT-DISCONNECTED",
4667 "CTRL-EVENT-CONNECTED",
4668 "CTRL-EVENT-NETWORK-NOT-FOUND",
4669 NULL
4670 };
4671 char buf[1024];
4672 int res;
4673
4674 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
4675 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02004676 send_resp(dut, conn, SIGMA_COMPLETE,
4677 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004678 ret = STATUS_SENT_ERROR;
4679 break;
4680 }
4681 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
4682 buf);
4683
4684 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
4685 strstr(buf, " depth=0")) {
4686 char *pos = strstr(buf, " hash=");
4687
4688 if (pos) {
4689 char *end;
4690
Jouni Malinen34b19cb2019-08-16 16:37:17 +03004691 if (strstr(buf, " tod=1"))
4692 tod = 1;
4693 else if (strstr(buf, " tod=2"))
4694 tod = 2;
4695 else
4696 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004697 sigma_dut_print(dut, DUT_MSG_DEBUG,
4698 "Server certificate TOD policy: %d",
4699 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03004700 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004701
4702 pos += 6;
4703 end = strchr(pos, ' ');
4704 if (end)
4705 *end = '\0';
4706 strlcpy(dut->server_cert_hash, pos,
4707 sizeof(dut->server_cert_hash));
4708 sigma_dut_print(dut, DUT_MSG_DEBUG,
4709 "Server certificate hash: %s",
4710 dut->server_cert_hash);
4711 }
4712 }
4713
4714 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
4715 send_resp(dut, conn, SIGMA_COMPLETE,
4716 "Result,TLS server certificate validation failed");
4717 ret = STATUS_SENT_ERROR;
4718 break;
4719 }
4720
4721 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
4722 num_network_not_found++;
4723
4724 if (num_network_not_found > 2) {
4725 send_resp(dut, conn, SIGMA_COMPLETE,
4726 "Result,Network not found");
4727 ret = STATUS_SENT_ERROR;
4728 break;
4729 }
4730 }
4731
4732 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4733 num_disconnected++;
4734
4735 if (num_disconnected > 2) {
4736 send_resp(dut, conn, SIGMA_COMPLETE,
4737 "Result,Connection failed");
4738 ret = STATUS_SENT_ERROR;
4739 break;
4740 }
4741 }
4742
4743 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
4744 if (tod >= 0) {
4745 sigma_dut_print(dut, DUT_MSG_DEBUG,
4746 "Network profile TOD policy update: %d -> %d",
4747 dut->sta_tod_policy, tod);
4748 dut->sta_tod_policy = tod;
4749 }
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304750 if (dut->program == PROGRAM_QM) {
4751 unsigned char iface_mac_addr[ETH_ALEN];
4752 char ipv6[100];
4753
4754 if (get_hwaddr(ifname, iface_mac_addr) < 0) {
4755 sigma_dut_print(dut, DUT_MSG_ERROR,
4756 "%s: get_hwaddr %s failed",
4757 __func__, ifname);
4758 ret = ERROR_SEND_STATUS;
4759 break;
4760 }
4761
4762 convert_mac_addr_to_ipv6_lladdr(iface_mac_addr,
4763 ipv6,
4764 sizeof(ipv6));
4765
4766 if (set_ipv6_addr(dut, ipv6, "64", ifname) !=
4767 0) {
4768 ret = ERROR_SEND_STATUS;
4769 break;
4770 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304771 start_dscp_policy_mon_thread(dut);
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304772 }
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004773 break;
4774 }
4775 }
4776done:
4777 if (ctrl) {
4778 wpa_ctrl_detach(ctrl);
4779 wpa_ctrl_close(ctrl);
4780 }
4781 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004782}
4783
4784
4785static int run_hs20_osu(struct sigma_dut *dut, const char *params)
4786{
4787 char buf[500], cmd[200];
4788 int res;
4789
4790 /* Use hs20-osu-client file at the current dir, if found; otherwise use
4791 * default path */
4792 res = snprintf(cmd, sizeof(cmd),
4793 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
4794 file_exists("./hs20-osu-client") ?
4795 "./hs20-osu-client" : "hs20-osu-client",
4796 sigma_wpas_ctrl,
4797 dut->summary_log ? "-s " : "",
4798 dut->summary_log ? dut->summary_log : "");
4799 if (res < 0 || res >= (int) sizeof(cmd))
4800 return -1;
4801
4802 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
4803 if (res < 0 || res >= (int) sizeof(buf))
4804 return -1;
4805 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
4806
4807 if (system(buf) != 0) {
4808 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
4809 return -1;
4810 }
4811 sigma_dut_print(dut, DUT_MSG_DEBUG,
4812 "Completed hs20-osu-client operation");
4813
4814 return 0;
4815}
4816
4817
4818static int download_ppsmo(struct sigma_dut *dut,
4819 struct sigma_conn *conn,
4820 const char *intf,
4821 struct sigma_cmd *cmd)
4822{
4823 const char *name, *path, *val;
4824 char url[500], buf[600], fbuf[100];
4825 char *fqdn = NULL;
4826
4827 name = get_param(cmd, "FileName");
4828 path = get_param(cmd, "FilePath");
4829 if (name == NULL || path == NULL)
4830 return -1;
4831
4832 if (strcasecmp(path, "VendorSpecific") == 0) {
4833 snprintf(url, sizeof(url), "PPS/%s", name);
4834 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
4835 "from the device (%s)", url);
4836 if (!file_exists(url)) {
4837 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
4838 "PPS MO file does not exist");
4839 return 0;
4840 }
4841 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
4842 if (system(buf) != 0) {
4843 send_resp(dut, conn, SIGMA_ERROR,
4844 "errorCode,Failed to copy PPS MO");
4845 return 0;
4846 }
4847 } else if (strncasecmp(path, "http:", 5) != 0 &&
4848 strncasecmp(path, "https:", 6) != 0) {
4849 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4850 "Unsupported FilePath value");
4851 return 0;
4852 } else {
4853 snprintf(url, sizeof(url), "%s/%s", path, name);
4854 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
4855 url);
4856 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
4857 remove("pps-tnds.xml");
4858 if (system(buf) != 0) {
4859 send_resp(dut, conn, SIGMA_ERROR,
4860 "errorCode,Failed to download PPS MO");
4861 return 0;
4862 }
4863 }
4864
4865 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
4866 send_resp(dut, conn, SIGMA_ERROR,
4867 "errorCode,Failed to parse downloaded PPSMO");
4868 return 0;
4869 }
4870 unlink("pps-tnds.xml");
4871
4872 val = get_param(cmd, "managementTreeURI");
4873 if (val) {
4874 const char *pos, *end;
4875 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
4876 val);
4877 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
4878 send_resp(dut, conn, SIGMA_ERROR,
4879 "errorCode,Invalid managementTreeURI prefix");
4880 return 0;
4881 }
4882 pos = val + 8;
4883 end = strchr(pos, '/');
4884 if (end == NULL ||
4885 strcmp(end, "/PerProviderSubscription") != 0) {
4886 send_resp(dut, conn, SIGMA_ERROR,
4887 "errorCode,Invalid managementTreeURI postfix");
4888 return 0;
4889 }
4890 if (end - pos >= (int) sizeof(fbuf)) {
4891 send_resp(dut, conn, SIGMA_ERROR,
4892 "errorCode,Too long FQDN in managementTreeURI");
4893 return 0;
4894 }
4895 memcpy(fbuf, pos, end - pos);
4896 fbuf[end - pos] = '\0';
4897 fqdn = fbuf;
4898 sigma_dut_print(dut, DUT_MSG_INFO,
4899 "FQDN from managementTreeURI: %s", fqdn);
4900 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
4901 FILE *f = fopen("pps-fqdn", "r");
4902 if (f) {
4903 if (fgets(fbuf, sizeof(fbuf), f)) {
4904 fbuf[sizeof(fbuf) - 1] = '\0';
4905 fqdn = fbuf;
4906 sigma_dut_print(dut, DUT_MSG_DEBUG,
4907 "Use FQDN %s", fqdn);
4908 }
4909 fclose(f);
4910 }
4911 }
4912
4913 if (fqdn == NULL) {
4914 send_resp(dut, conn, SIGMA_ERROR,
4915 "errorCode,No FQDN specified");
4916 return 0;
4917 }
4918
4919 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4920 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
4921 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4922
4923 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
4924 if (rename("pps.xml", buf) < 0) {
4925 send_resp(dut, conn, SIGMA_ERROR,
4926 "errorCode,Could not move PPS MO");
4927 return 0;
4928 }
4929
4930 if (strcasecmp(path, "VendorSpecific") == 0) {
4931 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
4932 fqdn);
4933 if (system(buf)) {
4934 send_resp(dut, conn, SIGMA_ERROR,
4935 "errorCode,Failed to copy OSU CA cert");
4936 return 0;
4937 }
4938
4939 snprintf(buf, sizeof(buf),
4940 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
4941 fqdn);
4942 if (system(buf)) {
4943 send_resp(dut, conn, SIGMA_ERROR,
4944 "errorCode,Failed to copy AAA CA cert");
4945 return 0;
4946 }
4947 } else {
4948 snprintf(buf, sizeof(buf),
4949 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
4950 fqdn, fqdn);
4951 if (run_hs20_osu(dut, buf) < 0) {
4952 send_resp(dut, conn, SIGMA_ERROR,
4953 "errorCode,Failed to download OSU CA cert");
4954 return 0;
4955 }
4956
4957 snprintf(buf, sizeof(buf),
4958 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
4959 fqdn, fqdn);
4960 if (run_hs20_osu(dut, buf) < 0) {
4961 sigma_dut_print(dut, DUT_MSG_INFO,
4962 "Failed to download AAA CA cert");
4963 }
4964 }
4965
4966 if (file_exists("next-client-cert.pem")) {
4967 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
4968 if (rename("next-client-cert.pem", buf) < 0) {
4969 send_resp(dut, conn, SIGMA_ERROR,
4970 "errorCode,Could not move client certificate");
4971 return 0;
4972 }
4973 }
4974
4975 if (file_exists("next-client-key.pem")) {
4976 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
4977 if (rename("next-client-key.pem", buf) < 0) {
4978 send_resp(dut, conn, SIGMA_ERROR,
4979 "errorCode,Could not move client key");
4980 return 0;
4981 }
4982 }
4983
4984 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
4985 if (run_hs20_osu(dut, buf) < 0) {
4986 send_resp(dut, conn, SIGMA_ERROR,
4987 "errorCode,Failed to configure credential from "
4988 "PPSMO");
4989 return 0;
4990 }
4991
4992 return 1;
4993}
4994
4995
4996static int download_cert(struct sigma_dut *dut,
4997 struct sigma_conn *conn,
4998 const char *intf,
4999 struct sigma_cmd *cmd)
5000{
5001 const char *name, *path;
5002 char url[500], buf[600];
5003
5004 name = get_param(cmd, "FileName");
5005 path = get_param(cmd, "FilePath");
5006 if (name == NULL || path == NULL)
5007 return -1;
5008
5009 if (strcasecmp(path, "VendorSpecific") == 0) {
5010 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
5011 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
5012 "certificate from the device (%s)", url);
5013 if (!file_exists(url)) {
5014 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
5015 "certificate file does not exist");
5016 return 0;
5017 }
5018 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
5019 if (system(buf) != 0) {
5020 send_resp(dut, conn, SIGMA_ERROR,
5021 "errorCode,Failed to copy client "
5022 "certificate");
5023 return 0;
5024 }
5025
5026 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
5027 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
5028 "private key from the device (%s)", url);
5029 if (!file_exists(url)) {
5030 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
5031 "private key file does not exist");
5032 return 0;
5033 }
5034 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
5035 if (system(buf) != 0) {
5036 send_resp(dut, conn, SIGMA_ERROR,
5037 "errorCode,Failed to copy client key");
5038 return 0;
5039 }
5040 } else if (strncasecmp(path, "http:", 5) != 0 &&
5041 strncasecmp(path, "https:", 6) != 0) {
5042 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
5043 "Unsupported FilePath value");
5044 return 0;
5045 } else {
5046 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
5047 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
5048 "certificate/key from %s", url);
5049 snprintf(buf, sizeof(buf),
5050 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
5051 if (system(buf) != 0) {
5052 send_resp(dut, conn, SIGMA_ERROR,
5053 "errorCode,Failed to download client "
5054 "certificate");
5055 return 0;
5056 }
5057
5058 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
5059 {
5060 send_resp(dut, conn, SIGMA_ERROR,
5061 "errorCode,Failed to copy client key");
5062 return 0;
5063 }
5064 }
5065
5066 return 1;
5067}
5068
5069
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005070static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
5071 struct sigma_conn *conn,
5072 struct sigma_cmd *cmd)
5073{
5074 const char *val;
5075 const char *intf = get_param(cmd, "interface");
5076
5077 if (!intf)
5078 return -1;
5079
5080 val = get_param(cmd, "WscIEFragment");
5081 if (val && strcasecmp(val, "enable") == 0) {
5082 sigma_dut_print(dut, DUT_MSG_DEBUG,
5083 "Enable WSC IE fragmentation");
5084
5085 dut->wsc_fragment = 1;
5086 /* set long attributes to force fragmentation */
5087 if (wpa_command(intf, "SET device_name "
5088 WPS_LONG_DEVICE_NAME) < 0)
5089 return -2;
5090 if (wpa_command(intf, "SET manufacturer "
5091 WPS_LONG_MANUFACTURER) < 0)
5092 return -2;
5093 if (wpa_command(intf, "SET model_name "
5094 WPS_LONG_MODEL_NAME) < 0)
5095 return -2;
5096 if (wpa_command(intf, "SET model_number "
5097 WPS_LONG_MODEL_NUMBER) < 0)
5098 return -2;
5099 if (wpa_command(intf, "SET serial_number "
5100 WPS_LONG_SERIAL_NUMBER) < 0)
5101 return -2;
5102 }
5103
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005104 val = get_param(cmd, "RSN_IE");
5105 if (val) {
5106 if (strcasecmp(val, "disable") == 0)
5107 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
5108 else if (strcasecmp(val, "enable") == 0)
5109 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
5110 }
5111
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02005112 val = get_param(cmd, "WpsVersion");
5113 if (val)
5114 dut->wps_forced_version = get_wps_forced_version(dut, val);
5115
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005116 val = get_param(cmd, "WscEAPFragment");
5117 if (val && strcasecmp(val, "enable") == 0)
5118 dut->eap_fragment = 1;
5119
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005120 return 1;
5121}
5122
5123
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005124static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
5125 struct sigma_conn *conn,
5126 const char *intf,
5127 struct sigma_cmd *cmd)
5128{
5129 const char *val;
5130
5131 val = get_param(cmd, "FileType");
5132 if (val && strcasecmp(val, "PPSMO") == 0)
5133 return download_ppsmo(dut, conn, intf, cmd);
5134 if (val && strcasecmp(val, "CERT") == 0)
5135 return download_cert(dut, conn, intf, cmd);
5136 if (val) {
5137 send_resp(dut, conn, SIGMA_ERROR,
5138 "ErrorCode,Unsupported FileType");
5139 return 0;
5140 }
5141
5142 return 1;
5143}
5144
5145
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305146static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
5147 struct sigma_conn *conn,
5148 const char *intf,
5149 struct sigma_cmd *cmd)
5150{
5151 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305152 char buf[1000];
5153 char text[20];
5154 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305155
5156 val = get_param(cmd, "OCESupport");
5157 if (val && strcasecmp(val, "Disable") == 0) {
5158 if (wpa_command(intf, "SET oce 0") < 0) {
5159 send_resp(dut, conn, SIGMA_ERROR,
5160 "ErrorCode,Failed to disable OCE");
5161 return 0;
5162 }
5163 } else if (val && strcasecmp(val, "Enable") == 0) {
5164 if (wpa_command(intf, "SET oce 1") < 0) {
5165 send_resp(dut, conn, SIGMA_ERROR,
5166 "ErrorCode,Failed to enable OCE");
5167 return 0;
5168 }
5169 }
5170
vamsi krishnaa2799492017-12-05 14:28:01 +05305171 val = get_param(cmd, "FILScap");
5172 if (val && (atoi(val) == 1)) {
5173 if (wpa_command(intf, "SET disable_fils 0") < 0) {
5174 send_resp(dut, conn, SIGMA_ERROR,
5175 "ErrorCode,Failed to enable FILS");
5176 return 0;
5177 }
5178 } else if (val && (atoi(val) == 0)) {
5179 if (wpa_command(intf, "SET disable_fils 1") < 0) {
5180 send_resp(dut, conn, SIGMA_ERROR,
5181 "ErrorCode,Failed to disable FILS");
5182 return 0;
5183 }
5184 }
5185
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305186 val = get_param(cmd, "FILSHLP");
5187 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005188 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305189 sizeof(text)) < 0)
5190 return -2;
5191 hwaddr_aton(text, addr);
5192 snprintf(buf, sizeof(buf),
5193 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
5194 "080045100140000040004011399e00000000ffffffff00440043"
5195 "012cb30001010600fd4f46410000000000000000000000000000"
5196 "000000000000"
5197 "%02x%02x%02x%02x%02x%02x"
5198 "0000000000000000000000000000000000000000000000000000"
5199 "0000000000000000000000000000000000000000000000000000"
5200 "0000000000000000000000000000000000000000000000000000"
5201 "0000000000000000000000000000000000000000000000000000"
5202 "0000000000000000000000000000000000000000000000000000"
5203 "0000000000000000000000000000000000000000000000000000"
5204 "0000000000000000000000000000000000000000000000000000"
5205 "0000000000000000000000000000000000000000638253633501"
5206 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
5207 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
5208 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
5209 if (wpa_command(intf, buf)) {
5210 send_resp(dut, conn, SIGMA_ERROR,
5211 "ErrorCode,Failed to add HLP");
5212 return 0;
5213 }
5214 dut->fils_hlp = 1;
5215 }
5216
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305217 return 1;
5218}
5219
5220
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005221static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
5222 const char *val)
5223{
5224 int counter = 0;
5225 char token[50];
5226 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305227 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005228
Peng Xub8fc5cc2017-05-10 17:27:28 -07005229 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005230 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305231 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005232 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005233 if (strcmp(result, "disable") == 0)
5234 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
5235 else
5236 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305237 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005238 counter++;
5239 }
5240}
5241
5242
5243static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
5244 const char *val)
5245{
5246 char buf[100];
5247
5248 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
5249 if (system(buf) != 0) {
5250 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
5251 }
5252}
5253
5254
5255static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5256 const char *val)
5257{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005258 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005259 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005260 }
5261}
5262
5263
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005264static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5265 const char *val)
5266{
5267#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005268 int wmmenable = 1;
5269
5270 if (val &&
5271 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
5272 wmmenable = 0;
5273
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305274 return wcn_wifi_test_config_set_u8(
5275 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
5276 wmmenable);
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005277#else /* NL80211_SUPPORT */
5278 sigma_dut_print(dut, DUT_MSG_ERROR,
5279 "WMM cannot be changed without NL80211_SUPPORT defined");
5280 return -1;
5281#endif /* NL80211_SUPPORT */
5282}
5283
5284
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005285static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
5286 const char *val)
5287{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005288 int sgi20;
5289
5290 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5291
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005292 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005293}
5294
5295
5296static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
5297 const char *val)
5298{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305299 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005300
5301 /* Disable Tx Beam forming when using a fixed rate */
5302 ath_disable_txbf(dut, intf);
5303
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305304 v = atoi(val);
5305 if (v < 0 || v > 32) {
5306 sigma_dut_print(dut, DUT_MSG_ERROR,
5307 "Invalid Fixed MCS rate: %d", v);
5308 return;
5309 }
5310 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005311
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005312 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005313
5314 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005315 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005316}
5317
5318
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005319static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
5320 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005321{
5322 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305323 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005324
5325 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
5326 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
5327 else
5328 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5329
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305330 ret = system(buf);
5331#ifdef NL80211_SUPPORT
5332 if (ret) {
5333 int value = (strcasecmp(val, "Enable") == 0) ? 2 : 1;
5334
5335 ret = sta_config_params(dut, intf, STA_SET_TX_MSDU, value);
5336 ret |= sta_config_params(dut, intf, STA_SET_RX_MSDU, value);
5337 }
5338#endif /* NL80211_SUPPORT */
5339 if (ret)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005340 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
5341}
5342
5343
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005344static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
5345 int ampdu)
5346{
5347 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005348 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005349
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005350 if (ampdu)
5351 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005352 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
5353 if (system(buf) != 0) {
5354 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
5355 return -1;
5356 }
5357
5358 return 0;
5359}
5360
5361
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005362static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5363 const char *val)
5364{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005365 run_iwpriv(dut, intf, "tx_stbc %s", val);
5366 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005367}
5368
5369
5370static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
5371 const char *val)
5372{
5373 char buf[60];
5374
Peng Xucc317ed2017-05-18 16:44:37 -07005375 if (strcmp(val, "160") == 0) {
5376 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
5377 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005378 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5379 } else if (strcmp(val, "40") == 0) {
5380 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
5381 } else if (strcmp(val, "20") == 0) {
5382 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
5383 } else if (strcasecmp(val, "Auto") == 0) {
5384 buf[0] = '\0';
5385 } else {
5386 sigma_dut_print(dut, DUT_MSG_ERROR,
5387 "WIDTH/CTS_WIDTH value not supported");
5388 return -1;
5389 }
5390
5391 if (buf[0] != '\0' && system(buf) != 0) {
5392 sigma_dut_print(dut, DUT_MSG_ERROR,
5393 "Failed to set WIDTH/CTS_WIDTH");
5394 return -1;
5395 }
5396
5397 return 0;
5398}
5399
5400
5401int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
5402 const char *intf, const char *val)
5403{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005404 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005405 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005406 dut->chwidth = 0;
5407 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005408 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005409 dut->chwidth = 0;
5410 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005411 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005412 dut->chwidth = 1;
5413 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005414 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005415 dut->chwidth = 2;
5416 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005417 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005418 dut->chwidth = 3;
5419 } else {
5420 send_resp(dut, conn, SIGMA_ERROR,
5421 "ErrorCode,WIDTH not supported");
5422 return -1;
5423 }
5424
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005425 return 0;
5426}
5427
5428
5429static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
5430 const char *val)
5431{
5432 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07005433 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005434
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005435 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005436 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005437 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005438 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005439 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005440 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005441 } else {
5442 sigma_dut_print(dut, DUT_MSG_ERROR,
5443 "SP_STREAM value not supported");
5444 return -1;
5445 }
5446
5447 if (system(buf) != 0) {
5448 sigma_dut_print(dut, DUT_MSG_ERROR,
5449 "Failed to set SP_STREAM");
5450 return -1;
5451 }
5452
Arif Hussainac6c5112018-05-25 17:34:00 -07005453 dut->sta_nss = sta_nss;
5454
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005455 return 0;
5456}
5457
5458
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305459static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5460 const char *val)
5461{
5462 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305463 int ret;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305464
5465 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305466 ret = system(buf);
5467#ifdef NL80211_SUPPORT
5468 if (ret)
5469 ret = sta_config_params(dut, intf, STA_SET_TX_STBC,
5470 strcmp(val, "0") == 0 ? 0 : 1);
5471#endif /* NL80211_SUPPORT */
5472 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305473 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
5474
5475 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305476 ret = system(buf);
5477#ifdef NL80211_SUPPORT
5478 if (ret)
5479 ret = sta_config_params(dut, intf, STA_SET_RX_STBC,
5480 strcmp(val, "0") == 0 ? 0 : 1);
5481#endif /* NL80211_SUPPORT */
5482 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305483 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
5484}
5485
5486
Ashwini Patil68d02cd2017-01-10 15:39:16 +05305487static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
5488 struct sigma_conn *conn,
5489 const char *intf, int capa)
5490{
5491 char buf[32];
5492
5493 if (capa > 0 && capa < 4) {
5494 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
5495 if (wpa_command(intf, buf) < 0) {
5496 send_resp(dut, conn, SIGMA_ERROR,
5497 "ErrorCode, Failed to set cellular data capability");
5498 return 0;
5499 }
5500 return 1;
5501 }
5502
5503 sigma_dut_print(dut, DUT_MSG_ERROR,
5504 "Invalid Cellular data capability: %d", capa);
5505 send_resp(dut, conn, SIGMA_INVALID,
5506 "ErrorCode,Invalid cellular data capability");
5507 return 0;
5508}
5509
5510
Ashwini Patil9183fdb2017-04-13 16:58:25 +05305511static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
5512 const char *intf, const char *val)
5513{
5514 if (strcasecmp(val, "Disable") == 0) {
5515 if (wpa_command(intf, "SET roaming 0") < 0) {
5516 send_resp(dut, conn, SIGMA_ERROR,
5517 "ErrorCode,Failed to disable roaming");
5518 return 0;
5519 }
5520 return 1;
5521 }
5522
5523 if (strcasecmp(val, "Enable") == 0) {
5524 if (wpa_command(intf, "SET roaming 1") < 0) {
5525 send_resp(dut, conn, SIGMA_ERROR,
5526 "ErrorCode,Failed to enable roaming");
5527 return 0;
5528 }
5529 return 1;
5530 }
5531
5532 sigma_dut_print(dut, DUT_MSG_ERROR,
5533 "Invalid value provided for roaming: %s", val);
5534 send_resp(dut, conn, SIGMA_INVALID,
5535 "ErrorCode,Unknown value provided for Roaming");
5536 return 0;
5537}
5538
5539
Ashwini Patila75de5a2017-04-13 16:35:05 +05305540static int mbo_set_assoc_disallow(struct sigma_dut *dut,
5541 struct sigma_conn *conn,
5542 const char *intf, const char *val)
5543{
5544 if (strcasecmp(val, "Disable") == 0) {
5545 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
5546 send_resp(dut, conn, SIGMA_ERROR,
5547 "ErrorCode,Failed to disable Assoc_disallow");
5548 return 0;
5549 }
5550 return 1;
5551 }
5552
5553 if (strcasecmp(val, "Enable") == 0) {
5554 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
5555 send_resp(dut, conn, SIGMA_ERROR,
5556 "ErrorCode,Failed to enable Assoc_disallow");
5557 return 0;
5558 }
5559 return 1;
5560 }
5561
5562 sigma_dut_print(dut, DUT_MSG_ERROR,
5563 "Invalid value provided for Assoc_disallow: %s", val);
5564 send_resp(dut, conn, SIGMA_INVALID,
5565 "ErrorCode,Unknown value provided for Assoc_disallow");
5566 return 0;
5567}
5568
5569
Ashwini Patilc63161e2017-04-13 16:30:23 +05305570static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
5571 const char *intf, const char *val)
5572{
5573 if (strcasecmp(val, "Reject") == 0) {
5574 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
5575 send_resp(dut, conn, SIGMA_ERROR,
5576 "ErrorCode,Failed to Reject BTM Request");
5577 return 0;
5578 }
5579 return 1;
5580 }
5581
5582 if (strcasecmp(val, "Accept") == 0) {
5583 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
5584 send_resp(dut, conn, SIGMA_ERROR,
5585 "ErrorCode,Failed to Accept BTM Request");
5586 return 0;
5587 }
5588 return 1;
5589 }
5590
5591 sigma_dut_print(dut, DUT_MSG_ERROR,
5592 "Invalid value provided for BSS_Transition: %s", val);
5593 send_resp(dut, conn, SIGMA_INVALID,
5594 "ErrorCode,Unknown value provided for BSS_Transition");
5595 return 0;
5596}
5597
5598
Ashwini Patil00402582017-04-13 12:29:39 +05305599static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
5600 struct sigma_conn *conn,
5601 const char *intf,
5602 struct sigma_cmd *cmd)
5603{
5604 const char *ch, *pref, *op_class, *reason;
5605 char buf[120];
5606 int len, ret;
5607
5608 pref = get_param(cmd, "Ch_Pref");
5609 if (!pref)
5610 return 1;
5611
5612 if (strcasecmp(pref, "clear") == 0) {
5613 free(dut->non_pref_ch_list);
5614 dut->non_pref_ch_list = NULL;
5615 } else {
5616 op_class = get_param(cmd, "Ch_Op_Class");
5617 if (!op_class) {
5618 send_resp(dut, conn, SIGMA_INVALID,
5619 "ErrorCode,Ch_Op_Class not provided");
5620 return 0;
5621 }
5622
5623 ch = get_param(cmd, "Ch_Pref_Num");
5624 if (!ch) {
5625 send_resp(dut, conn, SIGMA_INVALID,
5626 "ErrorCode,Ch_Pref_Num not provided");
5627 return 0;
5628 }
5629
5630 reason = get_param(cmd, "Ch_Reason_Code");
5631 if (!reason) {
5632 send_resp(dut, conn, SIGMA_INVALID,
5633 "ErrorCode,Ch_Reason_Code not provided");
5634 return 0;
5635 }
5636
5637 if (!dut->non_pref_ch_list) {
5638 dut->non_pref_ch_list =
5639 calloc(1, NON_PREF_CH_LIST_SIZE);
5640 if (!dut->non_pref_ch_list) {
5641 send_resp(dut, conn, SIGMA_ERROR,
5642 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
5643 return 0;
5644 }
5645 }
5646 len = strlen(dut->non_pref_ch_list);
5647 ret = snprintf(dut->non_pref_ch_list + len,
5648 NON_PREF_CH_LIST_SIZE - len,
5649 " %s:%s:%s:%s", op_class, ch, pref, reason);
5650 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
5651 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
5652 dut->non_pref_ch_list);
5653 } else {
5654 sigma_dut_print(dut, DUT_MSG_ERROR,
5655 "snprintf failed for non_pref_list, ret = %d",
5656 ret);
5657 send_resp(dut, conn, SIGMA_ERROR,
5658 "ErrorCode,snprintf failed");
5659 free(dut->non_pref_ch_list);
5660 dut->non_pref_ch_list = NULL;
5661 return 0;
5662 }
5663 }
5664
5665 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
5666 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
5667 if (ret < 0 || ret >= (int) sizeof(buf)) {
5668 sigma_dut_print(dut, DUT_MSG_DEBUG,
5669 "snprintf failed for set non_pref_chan, ret: %d",
5670 ret);
5671 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
5672 return 0;
5673 }
5674
5675 if (wpa_command(intf, buf) < 0) {
5676 send_resp(dut, conn, SIGMA_ERROR,
5677 "ErrorCode,Failed to set non-preferred channel list");
5678 return 0;
5679 }
5680
5681 return 1;
5682}
5683
5684
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005685#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005686
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005687static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
5688 uint8_t cfg)
5689{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305690 return wcn_wifi_test_config_set_u8(
5691 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
5692 cfg);
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005693}
5694
5695
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005696static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
5697 enum he_fragmentation_val frag)
5698{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305699 return wcn_wifi_test_config_set_u8(
5700 dut, intf,
5701 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION, frag);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005702}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005703
5704
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08005705int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
5706 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005707{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305708 return wcn_wifi_test_config_set_u8(
5709 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF, ltf);
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005710}
5711
5712
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005713static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
5714 int noack, enum qca_wlan_ac_type ac)
5715{
5716 struct nl_msg *msg;
5717 int ret = 0;
5718 struct nlattr *params;
5719 int ifindex;
5720
5721 ifindex = if_nametoindex(intf);
5722 if (ifindex == 0) {
5723 sigma_dut_print(dut, DUT_MSG_ERROR,
5724 "%s: Index for interface %s failed",
5725 __func__, intf);
5726 return -1;
5727 }
5728
5729 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5730 NL80211_CMD_VENDOR)) ||
5731 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5732 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5733 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5734 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5735 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5736 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
5737 noack) ||
5738 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
5739 ac)) {
5740 sigma_dut_print(dut, DUT_MSG_ERROR,
5741 "%s: err in adding vendor_cmd and vendor_data",
5742 __func__);
5743 nlmsg_free(msg);
5744 return -1;
5745 }
5746 nla_nest_end(msg, params);
5747
5748 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5749 if (ret) {
5750 sigma_dut_print(dut, DUT_MSG_ERROR,
5751 "%s: err in send_and_recv_msgs, ret=%d",
5752 __func__, ret);
5753 }
5754 return ret;
5755}
5756
5757
5758static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
5759 const char *val)
5760{
5761 int noack, ret;
5762 char token[100];
5763 char *result;
5764 char *saveptr;
5765 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
5766
5767 strlcpy(token, val, sizeof(token));
5768 token[sizeof(token) - 1] = '\0';
5769 result = strtok_r(token, ":", &saveptr);
5770 while (result) {
5771 noack = strcasecmp(result, "Disable") != 0;
5772 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
5773 if (ret) {
5774 sigma_dut_print(dut, DUT_MSG_ERROR,
5775 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
5776 ac, ret);
5777 }
5778 result = strtok_r(NULL, ":", &saveptr);
5779 ac++;
5780 }
5781}
5782
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305783
5784static int nlvendor_sta_set_phymode(struct sigma_dut *dut, const char *intf,
5785 enum qca_wlan_vendor_phy_mode val)
5786{
5787 struct nl_msg *msg;
5788 struct nlattr *params;
5789 int ifindex, ret;
5790
5791 ifindex = if_nametoindex(intf);
5792 if (ifindex == 0) {
5793 sigma_dut_print(dut, DUT_MSG_ERROR,
5794 "%s: Index for interface %s not found",
5795 __func__, intf);
5796 return -1;
5797 }
5798
5799 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5800 NL80211_CMD_VENDOR);
5801 if (!msg) {
5802 sigma_dut_print(dut, DUT_MSG_ERROR,
5803 "%s: err in adding vendor_cmd", __func__);
5804 return -1;
5805 }
5806
5807 if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5808 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5809 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION)) {
5810 sigma_dut_print(dut, DUT_MSG_ERROR,
5811 "%s: err in adding vendor_attr", __func__);
5812 nlmsg_free(msg);
5813 return -1;
5814 }
5815
5816 params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
5817 if (!params || nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE,
5818 val)) {
5819 sigma_dut_print(dut, DUT_MSG_ERROR,
5820 "%s: err in adding vendor_data", __func__);
5821 nlmsg_free(msg);
5822 return -1;
5823 }
5824
5825 nla_nest_end(msg, params);
5826 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5827 if (ret) {
5828 sigma_dut_print(dut, DUT_MSG_ERROR,
5829 "%s: err in send_and_recv_msgs, ret=%d (%s)",
5830 __func__, ret, strerror(-ret));
5831 return ret;
5832 }
5833
5834 return 0;
5835}
5836
5837
5838static enum qca_wlan_vendor_phy_mode get_qca_vendor_phymode(const char *val)
5839{
5840 if (strcmp(val, "11a") == 0) {
5841 /* IEEE80211_MODE_11A */
5842 return QCA_WLAN_VENDOR_PHY_MODE_11A;
5843 }
5844
5845 if (strcmp(val, "11g") == 0) {
5846 /* IEEE80211_MODE_11G */
5847 return QCA_WLAN_VENDOR_PHY_MODE_11G;
5848 }
5849
5850 if (strcmp(val, "11b") == 0) {
5851 /* IEEE80211_MODE_11B */
5852 return QCA_WLAN_VENDOR_PHY_MODE_11B;
5853 }
5854
5855 if (strcmp(val, "11n") == 0 ||
5856 strcmp(val, "11nl") == 0 ||
5857 strcmp(val, "11nl(nabg)") == 0) {
5858 /* IEEE80211_MODE_11AGN */
5859 return QCA_WLAN_VENDOR_PHY_MODE_11AGN;
5860 }
5861
5862 if (strcmp(val, "11ng") == 0) {
5863 /* IEEE80211_MODE_11NG_HT40 */
5864 return QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40;
5865 }
5866
5867 if (strcmp(val, "AC") == 0 ||
5868 strcasecmp(val, "11AC") == 0) {
5869 /* IEEE80211_MODE_11AC_VHT80 */
5870 return QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80;
5871 }
5872
5873 if (strcmp(val, "11na") == 0 ||
5874 strcasecmp(val, "11an") == 0) {
5875 /* IEEE80211_MODE_11NA_HT40 */
5876 return QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40;
5877 }
5878
5879 if (strcmp(val, "11ax") == 0 ||
5880 strcmp(val, "auto") == 0) {
5881 /* IEEE80211_MODE_AUTO */
5882 return QCA_WLAN_VENDOR_PHY_MODE_AUTO;
5883 }
5884
5885 return -1;
5886}
5887
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005888#endif /* NL80211_SUPPORT */
5889
5890
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305891static int get_phymode(const char *val)
5892{
5893 if (strcmp(val, "11a") == 0)
5894 return 1; /* IEEE80211_MODE_11A */
5895 if (strcmp(val, "11g") == 0)
5896 return 3; /* IEEE80211_MODE_11G */
5897 if (strcmp(val, "11b") == 0)
5898 return 2; /* IEEE80211_MODE_11B */
5899 if (strcmp(val, "11n") == 0 ||
5900 strcmp(val, "11nl") == 0 ||
5901 strcmp(val, "11nl(nabg)") == 0)
5902 return 22; /* IEEE80211_MODE_11AGN */
5903 if (strcmp(val, "11ng") == 0)
5904 return 13; /* IEEE80211_MODE_11NG_HT40 */
5905 if (strcmp(val, "AC") == 0 ||
5906 strcasecmp(val, "11AC") == 0)
5907 return 19; /* IEEE80211_MODE_11AC_VHT80 */
5908 if (strcmp(val, "11na") == 0 ||
5909 strcasecmp(val, "11an") == 0)
5910 return 14; /* IEEE80211_MODE_11NA_HT40 */
5911 if (strcmp(val, "11ax") == 0 ||
5912 strcmp(val, "auto") == 0)
5913 return 0; /* IEEE80211_MODE_AUTO */
5914 return -1;
5915}
5916
5917
5918static void sta_set_phymode(struct sigma_dut *dut, const char *intf,
5919 const char *val)
5920{
5921 char buf[100];
5922 int len, phymode;
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305923#ifdef NL80211_SUPPORT
5924 enum qca_wlan_vendor_phy_mode qca_phymode;
5925
5926 qca_phymode = get_qca_vendor_phymode(val);
5927 if (qca_phymode == -1) {
5928 sigma_dut_print(dut, DUT_MSG_DEBUG,
5929 "Ignoring mode change for mode: %s",
5930 val);
5931 return;
5932 }
5933
5934 if (nlvendor_sta_set_phymode(dut, intf, qca_phymode) == 0)
5935 return;
5936#endif /* NL80211_SUPPORT */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305937
5938 phymode = get_phymode(val);
5939 if (phymode == -1) {
5940 sigma_dut_print(dut, DUT_MSG_DEBUG,
5941 "Ignoring mode change for mode: %s",
5942 val);
5943 return;
5944 }
5945
5946 len = snprintf(buf, sizeof(buf), "iwpriv %s setphymode %d", intf,
5947 phymode);
5948 if (len < 0 || len >= sizeof(buf)) {
5949 sigma_dut_print(dut, DUT_MSG_ERROR,
5950 "Failed to set phymode");
5951 return;
5952 }
5953
5954 if (system(buf) != 0)
5955 sigma_dut_print(dut, DUT_MSG_ERROR,
5956 "iwpriv setting of phymode failed");
5957}
5958
5959
Jouni Malinenf7222712019-06-13 01:50:21 +03005960static enum sigma_cmd_result
5961cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
5962 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005963{
5964 const char *intf = get_param(cmd, "Interface");
5965 const char *val;
5966
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005967 val = get_param(cmd, "FT_DS");
5968 if (val) {
5969 if (strcasecmp(val, "Enable") == 0) {
5970 dut->sta_ft_ds = 1;
5971 } else if (strcasecmp(val, "Disable") == 0) {
5972 dut->sta_ft_ds = 0;
5973 } else {
5974 send_resp(dut, conn, SIGMA_ERROR,
5975 "errorCode,Unsupported value for FT_DS");
5976 return STATUS_SENT_ERROR;
5977 }
Shivani Baranwal7aa48602021-09-29 10:53:38 +05305978 if (get_driver_type(dut) == DRIVER_WCN &&
5979 sta_config_params(dut, intf, STA_SET_FT_DS,
5980 dut->sta_ft_ds) != 0) {
5981 send_resp(dut, conn, SIGMA_ERROR,
5982 "errorCode,Failed to enable/disable FT_DS");
5983 return STATUS_SENT_ERROR;
5984 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005985 }
5986
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005987 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03005988 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02005989 strcasecmp(val, "HS2-R3") == 0 ||
5990 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005991 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
5992 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005993
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005994 if (val && strcasecmp(val, "LOC") == 0)
5995 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02005996 if (val && strcasecmp(val, "60GHZ") == 0) {
5997 val = get_param(cmd, "WPS");
5998 if (val && strcasecmp(val, "disable") == 0) {
5999 dut->wps_disable = 1;
6000 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
6001 } else {
6002 /* wps_disable can have other value from the previous
6003 * test, so make sure it has the correct value.
6004 */
6005 dut->wps_disable = 0;
6006 }
6007
6008 val = get_param(cmd, "P2P");
6009 if (val && strcasecmp(val, "disable") == 0)
6010 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
6011 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07006012
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02006013 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
6014 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
6015
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006016#ifdef ANDROID_NAN
6017 if (val && strcasecmp(val, "NAN") == 0)
6018 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
6019#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006020#ifdef MIRACAST
6021 if (val && (strcasecmp(val, "WFD") == 0 ||
6022 strcasecmp(val, "DisplayR2") == 0))
6023 return miracast_preset_testparameters(dut, conn, cmd);
6024#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006025
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07006026 if (val &&
6027 (strcasecmp(val, "MBO") == 0 || strcasecmp(val, "HE") == 0)) {
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306028 val = get_param(cmd, "Cellular_Data_Cap");
6029 if (val &&
6030 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
6031 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05306032
6033 val = get_param(cmd, "Ch_Pref");
6034 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
6035 return 0;
6036
Ashwini Patilc63161e2017-04-13 16:30:23 +05306037 val = get_param(cmd, "BSS_Transition");
6038 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
6039 return 0;
6040
Ashwini Patila75de5a2017-04-13 16:35:05 +05306041 val = get_param(cmd, "Assoc_Disallow");
6042 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
6043 return 0;
6044
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306045 val = get_param(cmd, "Roaming");
6046 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
6047 return 0;
6048
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306049 return 1;
6050 }
6051
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306052 if (val && strcasecmp(val, "OCE") == 0)
6053 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
6054
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006055#if 0
6056 val = get_param(cmd, "Supplicant");
6057 if (val && strcasecmp(val, "Default") != 0) {
6058 send_resp(dut, conn, SIGMA_ERROR,
6059 "ErrorCode,Only default(Vendor) supplicant "
6060 "supported");
6061 return 0;
6062 }
6063#endif
6064
6065 val = get_param(cmd, "RTS");
6066 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006067 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006068 case DRIVER_ATHEROS:
6069 ath_sta_set_rts(dut, intf, val);
6070 break;
6071 default:
6072#if 0
6073 send_resp(dut, conn, SIGMA_ERROR,
6074 "ErrorCode,Setting RTS not supported");
6075 return 0;
6076#else
6077 sigma_dut_print(dut, DUT_MSG_DEBUG,
6078 "Setting RTS not supported");
6079 break;
6080#endif
6081 }
6082 }
6083
6084#if 0
6085 val = get_param(cmd, "FRGMNT");
6086 if (val) {
6087 /* TODO */
6088 send_resp(dut, conn, SIGMA_ERROR,
6089 "ErrorCode,Setting FRGMNT not supported");
6090 return 0;
6091 }
6092#endif
6093
6094#if 0
6095 val = get_param(cmd, "Preamble");
6096 if (val) {
6097 /* TODO: Long/Short */
6098 send_resp(dut, conn, SIGMA_ERROR,
6099 "ErrorCode,Setting Preamble not supported");
6100 return 0;
6101 }
6102#endif
6103
6104 val = get_param(cmd, "Mode");
6105 if (val) {
6106 if (strcmp(val, "11b") == 0 ||
6107 strcmp(val, "11g") == 0 ||
6108 strcmp(val, "11a") == 0 ||
6109 strcmp(val, "11n") == 0 ||
6110 strcmp(val, "11ng") == 0 ||
6111 strcmp(val, "11nl") == 0 ||
6112 strcmp(val, "11nl(nabg)") == 0 ||
6113 strcmp(val, "AC") == 0 ||
6114 strcmp(val, "11AC") == 0 ||
6115 strcmp(val, "11ac") == 0 ||
6116 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08006117 strcmp(val, "11an") == 0 ||
6118 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006119 /* STA supports all modes by default */
6120 } else {
6121 send_resp(dut, conn, SIGMA_ERROR,
6122 "ErrorCode,Setting Mode not supported");
6123 return 0;
6124 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006125
6126 /* Change the mode only in case of testbed for HE program
6127 * and for 11a and 11g modes only. */
6128 if (dut->program == PROGRAM_HE &&
6129 dut->device_type == STA_testbed) {
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05306130 sta_set_phymode(dut, intf, val);
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006131 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006132 }
6133
6134 val = get_param(cmd, "wmm");
6135 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006136 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006137 case DRIVER_ATHEROS:
6138 ath_sta_set_wmm(dut, intf, val);
6139 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08006140 case DRIVER_WCN:
6141 wcn_sta_set_wmm(dut, intf, val);
6142 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006143 default:
6144 sigma_dut_print(dut, DUT_MSG_DEBUG,
6145 "Setting wmm not supported");
6146 break;
6147 }
6148 }
6149
6150 val = get_param(cmd, "Powersave");
6151 if (val) {
6152 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006153 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306154 if (set_power_save_wcn(dut, intf, 2) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006155 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006156 }
6157
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006158 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006159 "P2P_SET ps 0") < 0)
6160 return -2;
6161 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006162 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6163 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006164 } else if (strcmp(val, "1") == 0 ||
6165 strcasecmp(val, "PSPoll") == 0 ||
6166 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006167 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306168 if (set_power_save_wcn(dut, intf, 1) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006169 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006170 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006171 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006172 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006173 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006174 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006175 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006176 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006177 "P2P_SET ps 99") < 0)
6178 return -2;
6179 } else if (strcmp(val, "2") == 0 ||
6180 strcasecmp(val, "Fast") == 0) {
6181 /* TODO */
6182 send_resp(dut, conn, SIGMA_ERROR,
6183 "ErrorCode,Powersave=Fast not supported");
6184 return 0;
6185 } else if (strcmp(val, "3") == 0 ||
6186 strcasecmp(val, "PSNonPoll") == 0) {
6187 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006188 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6189 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006190
6191 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006192 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006193 "P2P_SET ps 1") < 0)
6194 return -2;
6195 } else
6196 return -1;
6197 }
6198
6199 val = get_param(cmd, "NoAck");
6200 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006201 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006202 case DRIVER_ATHEROS:
6203 ath_sta_set_noack(dut, intf, val);
6204 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08006205#ifdef NL80211_SUPPORT
6206 case DRIVER_WCN:
6207 wcn_sta_set_noack(dut, intf, val);
6208 break;
6209#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006210 default:
6211 send_resp(dut, conn, SIGMA_ERROR,
6212 "ErrorCode,Setting NoAck not supported");
6213 return 0;
6214 }
6215 }
6216
6217 val = get_param(cmd, "IgnoreChswitchProhibit");
6218 if (val) {
6219 /* TODO: Enabled/disabled */
6220 if (strcasecmp(val, "Enabled") == 0) {
6221 send_resp(dut, conn, SIGMA_ERROR,
6222 "ErrorCode,Enabling IgnoreChswitchProhibit "
6223 "not supported");
6224 return 0;
6225 }
6226 }
6227
6228 val = get_param(cmd, "TDLS");
6229 if (val) {
6230 if (strcasecmp(val, "Disabled") == 0) {
6231 if (wpa_command(intf, "SET tdls_disabled 1")) {
6232 send_resp(dut, conn, SIGMA_ERROR,
6233 "ErrorCode,Failed to disable TDLS");
6234 return 0;
6235 }
6236 } else if (strcasecmp(val, "Enabled") == 0) {
6237 if (wpa_command(intf, "SET tdls_disabled 0")) {
6238 send_resp(dut, conn, SIGMA_ERROR,
6239 "ErrorCode,Failed to enable TDLS");
6240 return 0;
6241 }
6242 } else {
6243 send_resp(dut, conn, SIGMA_ERROR,
6244 "ErrorCode,Unsupported TDLS value");
6245 return 0;
6246 }
6247 }
6248
6249 val = get_param(cmd, "TDLSmode");
6250 if (val) {
6251 if (strcasecmp(val, "Default") == 0) {
6252 wpa_command(intf, "SET tdls_testing 0");
6253 } else if (strcasecmp(val, "APProhibit") == 0) {
6254 if (wpa_command(intf, "SET tdls_testing 0x400")) {
6255 send_resp(dut, conn, SIGMA_ERROR,
6256 "ErrorCode,Failed to enable ignore "
6257 "APProhibit TDLS mode");
6258 return 0;
6259 }
6260 } else if (strcasecmp(val, "HiLoMac") == 0) {
6261 /* STA should respond with TDLS setup req for a TDLS
6262 * setup req */
6263 if (wpa_command(intf, "SET tdls_testing 0x80")) {
6264 send_resp(dut, conn, SIGMA_ERROR,
6265 "ErrorCode,Failed to enable HiLoMac "
6266 "TDLS mode");
6267 return 0;
6268 }
6269 } else if (strcasecmp(val, "WeakSecurity") == 0) {
6270 /*
6271 * Since all security modes are enabled by default when
6272 * Sigma control is used, there is no need to do
6273 * anything here.
6274 */
6275 } else if (strcasecmp(val, "ExistLink") == 0) {
6276 /*
6277 * Since we allow new TDLS Setup Request even if there
6278 * is an existing link, nothing needs to be done for
6279 * this.
6280 */
6281 } else {
6282 /* TODO:
6283 * ExistLink: STA should send TDLS setup req even if
6284 * direct link already exists
6285 */
6286 send_resp(dut, conn, SIGMA_ERROR,
6287 "ErrorCode,Unsupported TDLSmode value");
6288 return 0;
6289 }
6290 }
6291
6292 val = get_param(cmd, "FakePubKey");
6293 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
6294 send_resp(dut, conn, SIGMA_ERROR,
6295 "ErrorCode,Failed to enable FakePubKey");
6296 return 0;
6297 }
6298
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08006299#ifdef NL80211_SUPPORT
6300 val = get_param(cmd, "FrgmntSupport");
6301 if (val) {
6302 if (strcasecmp(val, "Enable") == 0) {
6303 if (sta_set_he_fragmentation(dut, intf,
6304 HE_FRAG_LEVEL1)) {
6305 send_resp(dut, conn, SIGMA_ERROR,
6306 "ErrorCode,Failed to enable HE Fragmentation");
6307 return 0;
6308 }
6309 } else if (strcasecmp(val, "Disable") == 0) {
6310 if (sta_set_he_fragmentation(dut, intf,
6311 HE_FRAG_DISABLE)) {
6312 send_resp(dut, conn, SIGMA_ERROR,
6313 "ErrorCode,Failed to disable HE Fragmentation");
6314 return 0;
6315 }
6316 }
6317 }
6318#endif /* NL80211_SUPPORT */
6319
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306320 val = get_param(cmd, "IncludeMSCSDescriptor");
6321 if (val && strcasecmp(val, "1") == 0) {
6322 char buf[128];
6323 int len;
6324
6325 len = snprintf(buf, sizeof(buf),
Veerendranath Jakkam62cde372020-08-19 18:03:06 +05306326 "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=60000 frame_classifier=045F%032x",
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306327 0);
6328
6329 if (len < 0 || len >= sizeof(buf)) {
6330 sigma_dut_print(dut, DUT_MSG_ERROR,
6331 "Failed to build MSCS Descriptor IE");
6332 return ERROR_SEND_STATUS;
6333 }
6334
6335 if (wpa_command(intf, buf) != 0) {
6336 send_resp(dut, conn, SIGMA_ERROR,
6337 "ErrorCode,Failed to include MSCS descriptor");
6338 return STATUS_SENT_ERROR;
6339 }
6340 }
6341
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306342 val = get_param(cmd, "SCSSupport");
6343 if (val) {
6344 char buf[30];
6345 int disable_scs, len;
6346
6347 if (strcasecmp(val, "Enable") == 0) {
6348 disable_scs = 0;
6349 } else if (strcasecmp(val, "Disable") == 0) {
6350 disable_scs = 1;
6351 } else {
6352 sigma_dut_print(dut, DUT_MSG_ERROR,
6353 "Invalid SCSsupport parameter");
6354 return INVALID_SEND_STATUS;
6355 }
6356
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306357 if (disable_scs || dut->prev_disable_scs_support) {
6358 len = snprintf(buf, sizeof(buf),
6359 "SET disable_scs_support %d",
6360 disable_scs);
6361 if (len < 0 || len >= sizeof(buf) ||
6362 wpa_command(intf, buf) != 0) {
6363 send_resp(dut, conn, SIGMA_ERROR,
6364 "ErrorCode,Failed to update SCS support");
6365 return STATUS_SENT_ERROR;
6366 }
6367 dut->prev_disable_scs_support = disable_scs;
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306368 }
6369 }
6370
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306371 val = get_param(cmd, "MSCSSupport");
6372 if (val) {
6373 char buf[30];
6374 int disable_mscs, len;
6375
6376 if (strcasecmp(val, "Enable") == 0) {
6377 disable_mscs = 0;
6378 } else if (strcasecmp(val, "Disable") == 0) {
6379 disable_mscs = 1;
6380 } else {
6381 sigma_dut_print(dut, DUT_MSG_ERROR,
6382 "Invalid MSCSsupport parameter");
6383 return INVALID_SEND_STATUS;
6384 }
6385
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306386 if (disable_mscs || dut->prev_disable_mscs_support) {
6387 len = snprintf(buf, sizeof(buf),
6388 "SET disable_mscs_support %d",
6389 disable_mscs);
6390 if (len < 0 || len >= sizeof(buf) ||
6391 wpa_command(intf, buf) != 0) {
6392 send_resp(dut, conn, SIGMA_ERROR,
6393 "ErrorCode,Failed to update MSCS support");
6394 return STATUS_SENT_ERROR;
6395 }
6396 dut->prev_disable_mscs_support = disable_mscs;
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306397 }
6398 }
6399
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05306400 val = get_param(cmd, "DSCPPolicyCapability");
6401 if (val) {
6402 char buf[35];
6403 int len;
6404
6405 if (strcasecmp(val, "Enable") == 0) {
6406 len = snprintf(buf, sizeof(buf),
6407 "SET enable_dscp_policy_capa 1");
6408 } else if (strcasecmp(val, "Disable") == 0) {
6409 len = snprintf(buf, sizeof(buf),
6410 "SET enable_dscp_policy_capa 0");
6411 } else {
6412 sigma_dut_print(dut, DUT_MSG_ERROR,
6413 "Invalid DSCP policy parameter");
6414 return INVALID_SEND_STATUS;
6415 }
6416
6417 if (len < 0 || len >= sizeof(buf) ||
6418 wpa_command(intf, buf) != 0) {
6419 send_resp(dut, conn, SIGMA_ERROR,
6420 "ErrorCode,Failed to update DSCP policy capability");
6421 return STATUS_SENT_ERROR;
6422 }
6423 }
6424
6425 val = get_param(cmd, "DSCPPolicyRespParams");
6426 if (val) {
6427 if (strcasecmp(val, "RejectAll") == 0) {
6428 dut->reject_dscp_policies = 1;
6429 dut->dscp_reject_resp_code = DSCP_POLICY_REJECT;
6430 } else if (strcasecmp(val, "AcceptAll") == 0) {
6431 dut->reject_dscp_policies = 0;
6432 }
6433 }
6434
6435 val = get_param(cmd, "DSCPPolicyResp_StatusCode");
6436 if (val)
6437 dut->dscp_reject_resp_code = atoi(val);
6438
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006439 return 1;
6440}
6441
6442
6443static const char * ath_get_radio_name(const char *radio_name)
6444{
6445 if (radio_name == NULL)
6446 return "wifi0";
6447 if (strcmp(radio_name, "wifi1") == 0)
6448 return "wifi1";
6449 if (strcmp(radio_name, "wifi2") == 0)
6450 return "wifi2";
6451 return "wifi0";
6452}
6453
6454
6455static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
6456 const char *val)
6457{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006458 unsigned int vht_mcsmap = 0;
6459 int txchainmask = 0;
6460 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6461
6462 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6463 if (dut->testbed_flag_txsp == 1) {
6464 vht_mcsmap = 0xfffc;
6465 dut->testbed_flag_txsp = 0;
6466 } else {
6467 vht_mcsmap = 0xfffe;
6468 }
6469 txchainmask = 1;
6470 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6471 if (dut->testbed_flag_txsp == 1) {
6472 vht_mcsmap = 0xfff0;
6473 dut->testbed_flag_txsp = 0;
6474 } else {
6475 vht_mcsmap = 0xfffa;
6476 }
6477 txchainmask = 3;
6478 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6479 if (dut->testbed_flag_txsp == 1) {
6480 vht_mcsmap = 0xffc0;
6481 dut->testbed_flag_txsp = 0;
6482 } else {
6483 vht_mcsmap = 0xffea;
6484 }
6485 txchainmask = 7;
6486 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6487 if (dut->testbed_flag_txsp == 1) {
6488 vht_mcsmap = 0xff00;
6489 dut->testbed_flag_txsp = 0;
6490 } else {
6491 vht_mcsmap = 0xffaa;
6492 }
6493 txchainmask = 15;
6494 } else {
6495 if (dut->testbed_flag_txsp == 1) {
6496 vht_mcsmap = 0xffc0;
6497 dut->testbed_flag_txsp = 0;
6498 } else {
6499 vht_mcsmap = 0xffea;
6500 }
6501 }
6502
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006503 if (txchainmask)
6504 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006505
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006506 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006507}
6508
6509
6510static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
6511 const char *val)
6512{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006513 unsigned int vht_mcsmap = 0;
6514 int rxchainmask = 0;
6515 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6516
6517 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6518 if (dut->testbed_flag_rxsp == 1) {
6519 vht_mcsmap = 0xfffc;
6520 dut->testbed_flag_rxsp = 0;
6521 } else {
6522 vht_mcsmap = 0xfffe;
6523 }
6524 rxchainmask = 1;
6525 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6526 if (dut->testbed_flag_rxsp == 1) {
6527 vht_mcsmap = 0xfff0;
6528 dut->testbed_flag_rxsp = 0;
6529 } else {
6530 vht_mcsmap = 0xfffa;
6531 }
6532 rxchainmask = 3;
6533 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6534 if (dut->testbed_flag_rxsp == 1) {
6535 vht_mcsmap = 0xffc0;
6536 dut->testbed_flag_rxsp = 0;
6537 } else {
6538 vht_mcsmap = 0xffea;
6539 }
6540 rxchainmask = 7;
6541 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6542 if (dut->testbed_flag_rxsp == 1) {
6543 vht_mcsmap = 0xff00;
6544 dut->testbed_flag_rxsp = 0;
6545 } else {
6546 vht_mcsmap = 0xffaa;
6547 }
6548 rxchainmask = 15;
6549 } else {
6550 if (dut->testbed_flag_rxsp == 1) {
6551 vht_mcsmap = 0xffc0;
6552 dut->testbed_flag_rxsp = 0;
6553 } else {
6554 vht_mcsmap = 0xffea;
6555 }
6556 }
6557
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006558 if (rxchainmask)
6559 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006560
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006561 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006562}
6563
6564
6565void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
6566{
6567 if (strcasecmp(val, "enable") == 0) {
6568 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
6569 != 0) {
6570 sigma_dut_print(dut, DUT_MSG_ERROR,
6571 "Disable BB_VHTSIGB_CRC_CALC failed");
6572 }
6573
6574 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
6575 != 0) {
6576 sigma_dut_print(dut, DUT_MSG_ERROR,
6577 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6578 }
6579 } else {
6580 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
6581 != 0) {
6582 sigma_dut_print(dut, DUT_MSG_ERROR,
6583 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6584 }
6585
6586 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
6587 != 0) {
6588 sigma_dut_print(dut, DUT_MSG_ERROR,
6589 "Enable BB_VHTSIGB_CRC_CALC failed");
6590 }
6591 }
6592}
6593
6594
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006595static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
6596 const char *val)
6597{
6598 char buf[60];
6599
Shivani Baranwal2a572842021-09-16 12:27:15 +05306600#ifdef NL80211_SUPPORT
6601 enum nl80211_chan_width qca_channel_width;
6602
6603 if (strcmp(val, "20") == 0) {
6604 qca_channel_width = NL80211_CHAN_WIDTH_20;
6605 dut->chwidth = 0;
6606 } else if (strcmp(val, "40") == 0) {
6607 qca_channel_width = NL80211_CHAN_WIDTH_40;
6608 dut->chwidth = 1;
6609 } else if (strcmp(val, "80") == 0) {
6610 qca_channel_width = NL80211_CHAN_WIDTH_80;
6611 dut->chwidth = 2;
6612 } else if (strcmp(val, "160") == 0) {
6613 qca_channel_width = NL80211_CHAN_WIDTH_160;
6614 dut->chwidth = 3;
6615 } else if (strcasecmp(val, "Auto") == 0) {
6616 return 0;
6617 } else {
6618 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6619 val);
6620 return -1;
6621 }
6622 if (sta_config_params(dut, intf, STA_SET_CHAN_WIDTH,
6623 qca_channel_width) == 0)
6624 return 0;
6625#endif /* NL80211_SUPPORT */
6626
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006627 if (strcmp(val, "20") == 0) {
6628 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
6629 dut->chwidth = 0;
6630 } else if (strcmp(val, "40") == 0) {
6631 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
6632 dut->chwidth = 1;
6633 } else if (strcmp(val, "80") == 0) {
6634 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
6635 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05306636 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006637 buf[0] = '\0';
6638 } else {
6639 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6640 val);
6641 return -1;
6642 }
6643
6644 if (buf[0] != '\0' && system(buf) != 0) {
6645 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
6646 return -1;
6647 }
6648
6649 return 0;
6650}
6651
6652
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006653static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
6654 const char *intf, int addbareject)
6655{
6656#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306657 return wcn_wifi_test_config_set_u8(
6658 dut, intf,
6659 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
6660 !addbareject);
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006661#else /* NL80211_SUPPORT */
6662 sigma_dut_print(dut, DUT_MSG_ERROR,
6663 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
6664 return -1;
6665#endif /* NL80211_SUPPORT */
6666}
6667
6668
6669static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
6670 int addbareject)
6671{
6672 int ret;
6673
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006674 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006675 case DRIVER_WCN:
6676 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
6677 if (ret) {
6678 sigma_dut_print(dut, DUT_MSG_ERROR,
6679 "nlvendor_sta_set_addba_reject failed, ret:%d",
6680 ret);
6681 return ret;
6682 }
6683 break;
6684 default:
6685 sigma_dut_print(dut, DUT_MSG_ERROR,
6686 "errorCode,Unsupported ADDBA_REJECT with the current driver");
6687 ret = -1;
6688 break;
6689 }
6690
6691 return ret;
6692}
6693
6694
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006695static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
6696 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006697{
6698#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306699 return wcn_wifi_test_config_set_u8(
6700 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
6701 enable);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006702#else /* NL80211_SUPPORT */
6703 sigma_dut_print(dut, DUT_MSG_ERROR,
6704 "Disable addba not possible without NL80211_SUPPORT defined");
6705 return -1;
6706#endif /* NL80211_SUPPORT */
6707}
6708
6709
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306710#ifdef NL80211_SUPPORT
6711static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6712{
6713 struct nl_msg *msg;
6714 int ret = 0;
6715 int ifindex;
6716
6717 ifindex = if_nametoindex(intf);
6718 if (ifindex == 0) {
6719 sigma_dut_print(dut, DUT_MSG_ERROR,
6720 "%s: Index for interface %s failed",
6721 __func__, intf);
6722 return -1;
6723 }
6724
6725 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6726 NL80211_CMD_SET_WIPHY)) ||
6727 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
6728 sigma_dut_print(dut, DUT_MSG_ERROR,
6729 "%s: err in adding RTS threshold",
6730 __func__);
6731 nlmsg_free(msg);
6732 return -1;
6733 }
6734
6735 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6736 if (ret) {
6737 sigma_dut_print(dut, DUT_MSG_ERROR,
6738 "%s: err in send_and_recv_msgs, ret=%d",
6739 __func__, ret);
6740 }
6741 return ret;
6742}
6743#endif /* NL80211_SUPPORT */
6744
6745
6746static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6747{
6748 char buf[100];
6749
6750#ifdef NL80211_SUPPORT
6751 if (nl80211_sta_set_rts(dut, intf, val) == 0)
6752 return 0;
6753 sigma_dut_print(dut, DUT_MSG_DEBUG,
6754 "Fall back to using iwconfig for setting RTS threshold");
6755#endif /* NL80211_SUPPORT */
6756
6757 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
6758 if (system(buf) != 0) {
6759 sigma_dut_print(dut, DUT_MSG_ERROR,
6760 "Failed to set RTS threshold %d", val);
6761 return -1;
6762 }
6763 return 0;
6764}
6765
6766
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006767static enum sigma_cmd_result
6768cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
6769 struct sigma_conn *conn, struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006770{
6771 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006772 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006773 char buf[128];
6774 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006775
6776 val = get_param(cmd, "40_INTOLERANT");
6777 if (val) {
6778 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6779 /* TODO: iwpriv ht40intol through wpa_supplicant */
6780 send_resp(dut, conn, SIGMA_ERROR,
6781 "ErrorCode,40_INTOLERANT not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006782 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006783 }
6784 }
6785
6786 val = get_param(cmd, "ADDBA_REJECT");
6787 if (val) {
6788 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6789 /* reject any ADDBA with status "decline" */
6790 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006791 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006792 } else {
6793 /* accept ADDBA */
6794 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006795 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006796 }
6797 }
6798
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006799 if (addbareject >= 0 &&
6800 sta_set_addba_reject(dut, intf, addbareject) < 0) {
6801 send_resp(dut, conn, SIGMA_ERROR,
6802 "ErrorCode,set addba_reject failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006803 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006804 }
6805
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006806 val = get_param(cmd, "AMPDU");
6807 if (val) {
6808 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6809 /* enable AMPDU Aggregation */
6810 if (ampdu == 0) {
6811 send_resp(dut, conn, SIGMA_ERROR,
6812 "ErrorCode,Mismatch in "
6813 "addba_reject/ampdu - "
6814 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006815 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006816 }
6817 ampdu = 1;
6818 } else {
6819 /* disable AMPDU Aggregation */
6820 if (ampdu == 1) {
6821 send_resp(dut, conn, SIGMA_ERROR,
6822 "ErrorCode,Mismatch in "
6823 "addba_reject/ampdu - "
6824 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006825 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006826 }
6827 ampdu = 0;
6828 }
6829 }
6830
6831 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006832 int ret;
6833
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006834 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
6835 ampdu ? "Enabling" : "Disabling");
6836 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07006837 if (wpa_command(intf, buf) < 0 &&
6838 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006839 send_resp(dut, conn, SIGMA_ERROR,
6840 "ErrorCode,set aggr failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006841 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006842 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006843
6844 if (ampdu == 0) {
6845 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006846 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006847 if (ret) {
6848 sigma_dut_print(dut, DUT_MSG_ERROR,
6849 "Failed to disable addba, ret:%d",
6850 ret);
6851 }
6852 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006853 }
6854
6855 val = get_param(cmd, "AMSDU");
6856 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006857 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006858 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006859 case DRIVER_WCN:
6860 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006861 break;
6862 default:
6863 if (strcmp(val, "1") == 0 ||
6864 strcasecmp(val, "Enable") == 0) {
6865 /* Enable AMSDU Aggregation */
6866 send_resp(dut, conn, SIGMA_ERROR,
6867 "ErrorCode,AMSDU aggregation not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006868 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006869 }
6870 break;
6871 }
6872 }
6873
6874 val = get_param(cmd, "STBC_RX");
6875 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006876 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006877 case DRIVER_ATHEROS:
6878 ath_sta_set_stbc(dut, intf, val);
6879 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05306880 case DRIVER_WCN:
6881 wcn_sta_set_stbc(dut, intf, val);
6882 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006883 default:
6884 send_resp(dut, conn, SIGMA_ERROR,
6885 "ErrorCode,STBC_RX not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006886 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006887 }
6888 }
6889
6890 val = get_param(cmd, "WIDTH");
6891 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006892 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006893 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006894 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006895 send_resp(dut, conn, SIGMA_ERROR,
6896 "ErrorCode,Failed to set WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006897 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006898 }
6899 break;
6900 case DRIVER_ATHEROS:
6901 if (ath_set_width(dut, conn, intf, val) < 0)
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006902 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006903 break;
6904 default:
6905 sigma_dut_print(dut, DUT_MSG_ERROR,
6906 "Setting WIDTH not supported");
6907 break;
6908 }
6909 }
6910
6911 val = get_param(cmd, "SMPS");
6912 if (val) {
6913 /* TODO: Dynamic/0, Static/1, No Limit/2 */
6914 send_resp(dut, conn, SIGMA_ERROR,
6915 "ErrorCode,SMPS not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006916 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006917 }
6918
6919 val = get_param(cmd, "TXSP_STREAM");
6920 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006921 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006922 case DRIVER_WCN:
6923 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6924 send_resp(dut, conn, SIGMA_ERROR,
6925 "ErrorCode,Failed to set TXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006926 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006927 }
6928 break;
6929 case DRIVER_ATHEROS:
6930 ath_sta_set_txsp_stream(dut, intf, val);
6931 break;
6932 default:
6933 sigma_dut_print(dut, DUT_MSG_ERROR,
6934 "Setting TXSP_STREAM not supported");
6935 break;
6936 }
6937 }
6938
6939 val = get_param(cmd, "RXSP_STREAM");
6940 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006941 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006942 case DRIVER_WCN:
6943 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6944 send_resp(dut, conn, SIGMA_ERROR,
6945 "ErrorCode,Failed to set RXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006946 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006947 }
6948 break;
6949 case DRIVER_ATHEROS:
6950 ath_sta_set_rxsp_stream(dut, intf, val);
6951 break;
6952 default:
6953 sigma_dut_print(dut, DUT_MSG_ERROR,
6954 "Setting RXSP_STREAM not supported");
6955 break;
6956 }
6957 }
6958
6959 val = get_param(cmd, "DYN_BW_SGNL");
6960 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006961 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006962 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08006963 if (strcasecmp(val, "enable") == 0) {
6964 snprintf(buf, sizeof(buf),
6965 "iwpriv %s cwmenable 1", intf);
6966 if (system(buf) != 0) {
6967 sigma_dut_print(dut, DUT_MSG_ERROR,
6968 "iwpriv cwmenable 1 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006969 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006970 }
6971 } else if (strcasecmp(val, "disable") == 0) {
6972 snprintf(buf, sizeof(buf),
6973 "iwpriv %s cwmenable 0", intf);
6974 if (system(buf) != 0) {
6975 sigma_dut_print(dut, DUT_MSG_ERROR,
6976 "iwpriv cwmenable 0 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006977 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006978 }
6979 } else {
6980 sigma_dut_print(dut, DUT_MSG_ERROR,
6981 "Unsupported DYN_BW_SGL");
6982 }
6983
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006984 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
6985 if (system(buf) != 0) {
6986 sigma_dut_print(dut, DUT_MSG_ERROR,
6987 "Failed to set cts_cbw in DYN_BW_SGNL");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006988 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006989 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006990 break;
6991 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07006992 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006993 ath_config_dyn_bw_sig(dut, intf, val);
6994 break;
6995 default:
6996 sigma_dut_print(dut, DUT_MSG_ERROR,
6997 "Failed to set DYN_BW_SGNL");
6998 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006999 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007000 }
7001
7002 val = get_param(cmd, "RTS_FORCE");
7003 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07007004 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007005 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307006 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007007 sigma_dut_print(dut, DUT_MSG_ERROR,
7008 "Failed to set RTS_FORCE 64");
7009 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03007010 res = snprintf(buf, sizeof(buf),
7011 "wifitool %s beeliner_fw_test 100 1",
7012 intf);
7013 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08007014 sigma_dut_print(dut, DUT_MSG_ERROR,
7015 "wifitool beeliner_fw_test 100 1 failed");
7016 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007017 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307018 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007019 sigma_dut_print(dut, DUT_MSG_ERROR,
7020 "Failed to set RTS_FORCE 2347");
7021 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007022 } else {
7023 send_resp(dut, conn, SIGMA_ERROR,
7024 "ErrorCode,RTS_FORCE value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007025 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007026 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007027 }
7028
7029 val = get_param(cmd, "CTS_WIDTH");
7030 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007031 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007032 case DRIVER_WCN:
7033 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
7034 send_resp(dut, conn, SIGMA_ERROR,
7035 "ErrorCode,Failed to set CTS_WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007036 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007037 }
7038 break;
7039 case DRIVER_ATHEROS:
7040 ath_set_cts_width(dut, intf, val);
7041 break;
7042 default:
7043 sigma_dut_print(dut, DUT_MSG_ERROR,
7044 "Setting CTS_WIDTH not supported");
7045 break;
7046 }
7047 }
7048
7049 val = get_param(cmd, "BW_SGNL");
7050 if (val) {
7051 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007052 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007053 } else if (strcasecmp(val, "Disable") == 0) {
7054 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007055 } else {
7056 send_resp(dut, conn, SIGMA_ERROR,
7057 "ErrorCode,BW_SGNL value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007058 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007059 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007060 }
7061
7062 val = get_param(cmd, "Band");
7063 if (val) {
7064 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
7065 /* STA supports all bands by default */
7066 } else {
7067 send_resp(dut, conn, SIGMA_ERROR,
7068 "ErrorCode,Unsupported Band");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007069 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007070 }
7071 }
7072
7073 val = get_param(cmd, "zero_crc");
7074 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007075 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007076 case DRIVER_ATHEROS:
7077 ath_set_zero_crc(dut, val);
7078 break;
7079 default:
7080 break;
7081 }
7082 }
7083
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007084 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007085}
7086
7087
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007088static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7089{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007090 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007091#ifdef __linux__
7092 case DRIVER_WIL6210:
7093 return wil6210_set_force_mcs(dut, force, mcs);
7094#endif /* __linux__ */
7095 default:
7096 sigma_dut_print(dut, DUT_MSG_ERROR,
7097 "Unsupported sta_set_force_mcs with the current driver");
7098 return -1;
7099 }
7100}
7101
7102
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007103static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
7104{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007105 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007106#ifdef __linux__
7107 case DRIVER_WIL6210:
7108 return wil6210_force_rsn_ie(dut, state);
7109#endif /* __linux__ */
7110 default:
7111 sigma_dut_print(dut, DUT_MSG_ERROR,
7112 "Unsupported sta_60g_force_rsn_ie with the current driver");
7113 return -1;
7114 }
7115}
7116
7117
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007118static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
7119 struct sigma_cmd *cmd)
7120{
7121 const char *val;
7122 char buf[100];
7123
7124 val = get_param(cmd, "MSDUSize");
7125 if (val) {
7126 int mtu;
7127
7128 dut->amsdu_size = atoi(val);
7129 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
7130 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
7131 sigma_dut_print(dut, DUT_MSG_ERROR,
7132 "MSDUSize %d is above max %d or below min %d",
7133 dut->amsdu_size,
7134 IEEE80211_MAX_DATA_LEN_DMG,
7135 IEEE80211_SNAP_LEN_DMG);
7136 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007137 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007138 }
7139
7140 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
7141 sigma_dut_print(dut, DUT_MSG_DEBUG,
7142 "Setting amsdu_size to %d", mtu);
7143 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007144 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007145
7146 if (system(buf) != 0) {
7147 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7148 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007149 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007150 }
7151 }
7152
7153 val = get_param(cmd, "BAckRcvBuf");
7154 if (val) {
7155 dut->back_rcv_buf = atoi(val);
7156 if (dut->back_rcv_buf == 0) {
7157 sigma_dut_print(dut, DUT_MSG_ERROR,
7158 "Failed to convert %s or value is 0",
7159 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007160 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007161 }
7162
7163 sigma_dut_print(dut, DUT_MSG_DEBUG,
7164 "Setting BAckRcvBuf to %s", val);
7165 }
7166
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007167 val = get_param(cmd, "MCS_FixedRate");
7168 if (val) {
7169 if (sta_set_force_mcs(dut, 1, atoi(val))) {
7170 sigma_dut_print(dut, DUT_MSG_ERROR,
7171 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007172 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007173 }
7174 }
7175
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007176 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007177}
7178
7179
7180static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
7181 struct sigma_cmd *cmd)
7182{
7183 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007184 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007185 const char *val;
7186 char buf[100];
7187
7188 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007189 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007190 if (wpa_command(ifname, "PING") != 0) {
7191 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007192 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007193 }
7194
7195 wpa_command(ifname, "FLUSH");
7196 net_id = add_network_common(dut, conn, ifname, cmd);
7197 if (net_id < 0) {
7198 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
7199 return net_id;
7200 }
7201
7202 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
7203 if (set_network(ifname, net_id, "mode", "2") < 0) {
7204 sigma_dut_print(dut, DUT_MSG_ERROR,
7205 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007206 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007207 }
7208
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02007209 if (set_network(ifname, net_id, "pbss", "1") < 0)
7210 return -2;
7211
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007212 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007213 "Supplicant set network with mode 2. network_id %d",
7214 net_id);
7215
7216 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
7217 sigma_dut_print(dut, DUT_MSG_INFO,
7218 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007219 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007220 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007221
7222 val = get_param(cmd, "Security");
7223 if (val && strcasecmp(val, "OPEN") == 0) {
7224 dut->ap_key_mgmt = AP_OPEN;
7225 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
7226 sigma_dut_print(dut, DUT_MSG_ERROR,
7227 "Failed to set supplicant to %s security",
7228 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007229 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007230 }
7231 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
7232 dut->ap_key_mgmt = AP_WPA2_PSK;
7233 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
7234 sigma_dut_print(dut, DUT_MSG_ERROR,
7235 "Failed to set supplicant to %s security",
7236 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007237 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007238 }
7239
7240 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
7241 sigma_dut_print(dut, DUT_MSG_ERROR,
7242 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007243 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007244 }
7245 } else if (val) {
7246 sigma_dut_print(dut, DUT_MSG_ERROR,
7247 "Requested Security %s is not supported on 60GHz",
7248 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007249 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007250 }
7251
7252 val = get_param(cmd, "Encrypt");
7253 if (val && strcasecmp(val, "AES-GCMP") == 0) {
7254 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
7255 sigma_dut_print(dut, DUT_MSG_ERROR,
7256 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007257 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007258 }
7259 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
7260 sigma_dut_print(dut, DUT_MSG_ERROR,
7261 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007262 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007263 }
7264 } else if (val) {
7265 sigma_dut_print(dut, DUT_MSG_ERROR,
7266 "Requested Encrypt %s is not supported on 60 GHz",
7267 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007268 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007269 }
7270
7271 val = get_param(cmd, "PSK");
7272 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
7273 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
7274 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007275 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007276 }
7277
7278 /* Convert 60G channel to freq */
7279 switch (dut->ap_channel) {
7280 case 1:
7281 val = "58320";
7282 break;
7283 case 2:
7284 val = "60480";
7285 break;
7286 case 3:
7287 val = "62640";
7288 break;
7289 default:
7290 sigma_dut_print(dut, DUT_MSG_ERROR,
7291 "Failed to configure channel %d. Not supported",
7292 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007293 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007294 }
7295
7296 if (set_network(ifname, net_id, "frequency", val) < 0) {
7297 sigma_dut_print(dut, DUT_MSG_ERROR,
7298 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007299 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007300 }
7301
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02007302 if (dut->eap_fragment) {
7303 sigma_dut_print(dut, DUT_MSG_DEBUG,
7304 "Set EAP fragment size to 128 bytes.");
7305 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
7306 return ERROR_SEND_STATUS;
7307 }
7308
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007309 sigma_dut_print(dut, DUT_MSG_DEBUG,
7310 "Supplicant set network with frequency");
7311
7312 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
7313 if (wpa_command(ifname, buf) < 0) {
7314 sigma_dut_print(dut, DUT_MSG_INFO,
7315 "Failed to select network id %d on %s",
7316 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007317 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007318 }
7319
7320 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
7321
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007322 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007323}
7324
7325
Lior David67543f52017-01-03 19:04:22 +02007326static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
7327{
7328 char buf[128], fname[128];
7329 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03007330 int res;
Lior David67543f52017-01-03 19:04:22 +02007331
7332 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
7333 sigma_dut_print(dut, DUT_MSG_ERROR,
7334 "failed to get wil6210 debugfs dir");
7335 return -1;
7336 }
7337
Jouni Malinen3aa72862019-05-29 23:14:51 +03007338 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
7339 if (res < 0 || res >= sizeof(fname))
7340 return -1;
Lior David67543f52017-01-03 19:04:22 +02007341 f = fopen(fname, "w");
7342 if (!f) {
7343 sigma_dut_print(dut, DUT_MSG_ERROR,
7344 "failed to open: %s", fname);
7345 return -1;
7346 }
7347
7348 fprintf(f, "%d\n", abft_len);
7349 fclose(f);
7350
7351 return 0;
7352}
7353
7354
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02007355int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
7356 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02007357{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007358 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02007359 case DRIVER_WIL6210:
7360 return wil6210_set_abft_len(dut, abft_len);
7361 default:
7362 sigma_dut_print(dut, DUT_MSG_ERROR,
7363 "set abft_len not supported");
7364 return -1;
7365 }
7366}
7367
7368
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007369static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
7370 struct sigma_cmd *cmd)
7371{
7372 const char *val;
Lior David67543f52017-01-03 19:04:22 +02007373 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007374
7375 if (dut->dev_role != DEVROLE_PCP) {
7376 send_resp(dut, conn, SIGMA_INVALID,
7377 "ErrorCode,Invalid DevRole");
7378 return 0;
7379 }
7380
7381 val = get_param(cmd, "SSID");
7382 if (val) {
7383 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
7384 send_resp(dut, conn, SIGMA_INVALID,
7385 "ErrorCode,Invalid SSID");
7386 return -1;
7387 }
7388
Peng Xub8fc5cc2017-05-10 17:27:28 -07007389 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007390 }
7391
7392 val = get_param(cmd, "CHANNEL");
7393 if (val) {
7394 const char *pos;
7395
7396 dut->ap_channel = atoi(val);
7397 pos = strchr(val, ';');
7398 if (pos) {
7399 pos++;
7400 dut->ap_channel_1 = atoi(pos);
7401 }
7402 }
7403
7404 switch (dut->ap_channel) {
7405 case 1:
7406 case 2:
7407 case 3:
7408 break;
7409 default:
7410 sigma_dut_print(dut, DUT_MSG_ERROR,
7411 "Channel %d is not supported", dut->ap_channel);
7412 send_resp(dut, conn, SIGMA_ERROR,
7413 "Requested channel is not supported");
7414 return -1;
7415 }
7416
7417 val = get_param(cmd, "BCNINT");
7418 if (val)
7419 dut->ap_bcnint = atoi(val);
7420
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007421 val = get_param(cmd, "AllocType");
7422 if (val) {
7423 send_resp(dut, conn, SIGMA_ERROR,
7424 "ErrorCode,AllocType is not supported yet");
7425 return -1;
7426 }
7427
7428 val = get_param(cmd, "PercentBI");
7429 if (val) {
7430 send_resp(dut, conn, SIGMA_ERROR,
7431 "ErrorCode,PercentBI is not supported yet");
7432 return -1;
7433 }
7434
7435 val = get_param(cmd, "CBAPOnly");
7436 if (val) {
7437 send_resp(dut, conn, SIGMA_ERROR,
7438 "ErrorCode,CBAPOnly is not supported yet");
7439 return -1;
7440 }
7441
7442 val = get_param(cmd, "AMPDU");
7443 if (val) {
7444 if (strcasecmp(val, "Enable") == 0)
7445 dut->ap_ampdu = 1;
7446 else if (strcasecmp(val, "Disable") == 0)
7447 dut->ap_ampdu = 2;
7448 else {
7449 send_resp(dut, conn, SIGMA_ERROR,
7450 "ErrorCode,AMPDU value is not Enable nor Disabled");
7451 return -1;
7452 }
7453 }
7454
7455 val = get_param(cmd, "AMSDU");
7456 if (val) {
7457 if (strcasecmp(val, "Enable") == 0)
7458 dut->ap_amsdu = 1;
7459 else if (strcasecmp(val, "Disable") == 0)
7460 dut->ap_amsdu = 2;
7461 }
7462
7463 val = get_param(cmd, "NumMSDU");
7464 if (val) {
7465 send_resp(dut, conn, SIGMA_ERROR,
7466 "ErrorCode, NumMSDU is not supported yet");
7467 return -1;
7468 }
7469
7470 val = get_param(cmd, "ABFTLRang");
7471 if (val) {
7472 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02007473 "ABFTLRang parameter %s", val);
7474 if (strcmp(val, "Gt1") == 0)
7475 abft_len = 2; /* 2 slots in this case */
7476 }
7477
7478 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
7479 send_resp(dut, conn, SIGMA_ERROR,
7480 "ErrorCode, Can't set ABFT length");
7481 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007482 }
7483
7484 if (sta_pcp_start(dut, conn, cmd) < 0) {
7485 send_resp(dut, conn, SIGMA_ERROR,
7486 "ErrorCode, Can't start PCP role");
7487 return -1;
7488 }
7489
7490 return sta_set_60g_common(dut, conn, cmd);
7491}
7492
7493
7494static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
7495 struct sigma_cmd *cmd)
7496{
7497 const char *val = get_param(cmd, "DiscoveryMode");
7498
7499 if (dut->dev_role != DEVROLE_STA) {
7500 send_resp(dut, conn, SIGMA_INVALID,
7501 "ErrorCode,Invalid DevRole");
7502 return 0;
7503 }
7504
7505 if (val) {
7506 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
7507 /* Ignore Discovery mode till Driver expose API. */
7508#if 0
7509 if (strcasecmp(val, "1") == 0) {
7510 send_resp(dut, conn, SIGMA_INVALID,
7511 "ErrorCode,DiscoveryMode 1 not supported");
7512 return 0;
7513 }
7514
7515 if (strcasecmp(val, "0") == 0) {
7516 /* OK */
7517 } else {
7518 send_resp(dut, conn, SIGMA_INVALID,
7519 "ErrorCode,DiscoveryMode not supported");
7520 return 0;
7521 }
7522#endif
7523 }
7524
7525 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007526 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007527 return sta_set_60g_common(dut, conn, cmd);
7528}
7529
7530
Jouni Malinenf7222712019-06-13 01:50:21 +03007531static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
7532 struct sigma_conn *conn,
7533 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007534{
7535 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02007536 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05307537
Jouni Malinened77e672018-01-10 16:45:13 +02007538 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08007539 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02007540 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05307541 wpa_command(intf, "DISCONNECT");
7542 return 1;
7543 }
7544
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007545 disconnect_station(dut);
7546 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
7547 * due to cached results. */
7548 wpa_command(intf, "SET ignore_old_scan_res 1");
7549 wpa_command(intf, "BSS_FLUSH");
7550 return 1;
7551}
7552
7553
Jouni Malinenf7222712019-06-13 01:50:21 +03007554static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
7555 struct sigma_conn *conn,
7556 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007557{
7558 const char *intf = get_param(cmd, "Interface");
7559 const char *bssid = get_param(cmd, "bssid");
7560 const char *val = get_param(cmd, "CHANNEL");
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007561 const char *freq_val = get_param(cmd, "ChnlFreq");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007562 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307563 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05307564 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007565 int res;
7566 int chan = 0;
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007567 int freq = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007568 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05307569 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007570 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007571
7572 if (bssid == NULL) {
7573 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
7574 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007575 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007576 }
7577
7578 if (val)
7579 chan = atoi(val);
7580
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007581 if (freq_val)
7582 freq = atoi(freq_val);
7583
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007584 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
7585 /* The current network may be from sta_associate or
7586 * sta_hs2_associate
7587 */
7588 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
7589 0 ||
7590 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007591 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007592 }
7593
7594 ctrl = open_wpa_mon(intf);
7595 if (ctrl == NULL) {
7596 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7597 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007598 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007599 }
7600
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007601 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05307602 sizeof(result)) < 0 ||
7603 strncmp(result, "COMPLETED", 9) != 0) {
7604 sigma_dut_print(dut, DUT_MSG_DEBUG,
7605 "sta_reassoc: Not connected");
7606 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007607 } else if (dut->sta_ft_ds) {
7608 sigma_dut_print(dut, DUT_MSG_DEBUG,
7609 "sta_reassoc: Use FT-over-DS");
7610 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05307611 }
7612
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307613 if (dut->rsne_override) {
7614#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007615 if (get_driver_type(dut) == DRIVER_WCN &&
7616 dut->config_rsnie == 0) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05307617 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307618 dut->config_rsnie = 1;
7619 }
7620#endif /* NL80211_SUPPORT */
7621 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
7622 dut->rsne_override);
7623 if (wpa_command(intf, buf) < 0) {
7624 send_resp(dut, conn, SIGMA_ERROR,
7625 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
7626 return 0;
7627 }
7628 }
7629
Shivani Baranwal7aa48602021-09-29 10:53:38 +05307630 if (ft_ds && get_driver_type(dut) != DRIVER_WCN) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007631 if (chan || freq) {
7632 if (!freq)
7633 freq = channel_to_freq(dut, chan);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007634 if (!freq) {
7635 sigma_dut_print(dut, DUT_MSG_ERROR,
7636 "Invalid channel number provided: %d",
7637 chan);
7638 send_resp(dut, conn, SIGMA_INVALID,
7639 "ErrorCode,Invalid channel number");
7640 goto close_mon_conn;
7641 }
7642 res = snprintf(buf, sizeof(buf),
7643 "SCAN TYPE=ONLY freq=%d", freq);
7644 } else {
7645 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7646 }
7647 if (res < 0 || res >= (int) sizeof(buf)) {
7648 send_resp(dut, conn, SIGMA_ERROR,
7649 "ErrorCode,snprintf failed");
7650 goto close_mon_conn;
7651 }
7652 if (wpa_command(intf, buf) < 0) {
7653 sigma_dut_print(dut, DUT_MSG_INFO,
7654 "Failed to start scan");
7655 send_resp(dut, conn, SIGMA_ERROR,
7656 "ErrorCode,scan failed");
7657 goto close_mon_conn;
7658 }
7659
7660 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7661 buf, sizeof(buf));
7662 if (res < 0) {
7663 sigma_dut_print(dut, DUT_MSG_INFO,
7664 "Scan did not complete");
7665 send_resp(dut, conn, SIGMA_ERROR,
7666 "ErrorCode,scan did not complete");
7667 goto close_mon_conn;
7668 }
7669
7670 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
7671 if (res > 0 && res < (int) sizeof(buf))
7672 res = wpa_command(intf, buf);
7673
7674 if (res < 0 || res >= (int) sizeof(buf)) {
7675 send_resp(dut, conn, SIGMA_ERROR,
7676 "errorCode,FT_DS command failed");
7677 status = STATUS_SENT_ERROR;
7678 goto close_mon_conn;
7679 }
7680 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007681 if (chan || freq) {
7682 if (!freq)
7683 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05307684 if (!freq) {
7685 sigma_dut_print(dut, DUT_MSG_ERROR,
7686 "Invalid channel number provided: %d",
7687 chan);
7688 send_resp(dut, conn, SIGMA_INVALID,
7689 "ErrorCode,Invalid channel number");
7690 goto close_mon_conn;
7691 }
7692 res = snprintf(buf, sizeof(buf),
7693 "SCAN TYPE=ONLY freq=%d", freq);
7694 } else {
7695 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7696 }
7697 if (res < 0 || res >= (int) sizeof(buf)) {
7698 send_resp(dut, conn, SIGMA_ERROR,
7699 "ErrorCode,snprintf failed");
7700 goto close_mon_conn;
7701 }
7702 if (wpa_command(intf, buf) < 0) {
7703 sigma_dut_print(dut, DUT_MSG_INFO,
7704 "Failed to start scan");
7705 send_resp(dut, conn, SIGMA_ERROR,
7706 "ErrorCode,scan failed");
7707 goto close_mon_conn;
7708 }
7709
7710 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7711 buf, sizeof(buf));
7712 if (res < 0) {
7713 sigma_dut_print(dut, DUT_MSG_INFO,
7714 "Scan did not complete");
7715 send_resp(dut, conn, SIGMA_ERROR,
7716 "ErrorCode,scan did not complete");
7717 goto close_mon_conn;
7718 }
7719
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007720 if (set_network(intf, dut->infra_network_id, "bssid", "any")
7721 < 0) {
7722 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7723 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007724 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05307725 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007726 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307727 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007728 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307729 if (res < 0 || res >= (int) sizeof(buf) ||
7730 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007731 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307732 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05307733 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007734 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007735 sigma_dut_print(dut, DUT_MSG_INFO,
7736 "sta_reassoc: Run %s successful", buf);
7737 } else if (wpa_command(intf, "REASSOCIATE")) {
7738 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
7739 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05307740 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007741 }
7742
7743 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
7744 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05307745 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007746 send_resp(dut, conn, SIGMA_ERROR,
7747 "errorCode,Connection did not complete");
7748 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05307749 goto close_mon_conn;
7750 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007751 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007752
Ashwini Patil467efef2017-05-25 12:18:27 +05307753close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007754 wpa_ctrl_detach(ctrl);
7755 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05307756 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007757}
7758
7759
7760static void hs2_clear_credentials(const char *intf)
7761{
7762 wpa_command(intf, "REMOVE_CRED all");
7763}
7764
7765
Lior Davidcc88b562017-01-03 18:52:09 +02007766#ifdef __linux__
7767static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
7768 unsigned int *aid)
7769{
Lior David0fe101e2017-03-09 16:09:50 +02007770 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02007771
Lior David0fe101e2017-03-09 16:09:50 +02007772 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02007773}
7774#endif /* __linux__ */
7775
7776
7777static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
7778 unsigned int *aid)
7779{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007780 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02007781#ifdef __linux__
7782 case DRIVER_WIL6210:
7783 return wil6210_get_aid(dut, bssid, aid);
7784#endif /* __linux__ */
7785 default:
7786 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
7787 return -1;
7788 }
7789}
7790
7791
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007792static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7793 struct sigma_cmd *cmd)
7794{
7795 char buf[MAX_CMD_LEN];
7796 char bss_list[MAX_CMD_LEN];
7797 const char *parameter = get_param(cmd, "Parameter");
7798
7799 if (parameter == NULL)
7800 return -1;
7801
Lior Davidcc88b562017-01-03 18:52:09 +02007802 if (strcasecmp(parameter, "AID") == 0) {
7803 unsigned int aid = 0;
7804 char bssid[20];
7805
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007806 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02007807 bssid, sizeof(bssid)) < 0) {
7808 sigma_dut_print(dut, DUT_MSG_ERROR,
7809 "could not get bssid");
7810 return -2;
7811 }
7812
7813 if (sta_get_aid_60g(dut, bssid, &aid))
7814 return -2;
7815
7816 snprintf(buf, sizeof(buf), "aid,%d", aid);
7817 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
7818 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7819 return 0;
7820 }
7821
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007822 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
7823 char *bss_line;
7824 char *bss_id = NULL;
7825 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307826 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007827
7828 if (ifname == NULL) {
7829 sigma_dut_print(dut, DUT_MSG_INFO,
7830 "For get DiscoveredDevList need Interface name.");
7831 return -1;
7832 }
7833
7834 /*
7835 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
7836 * of BSSIDs in "bssid=<BSSID>\n"
7837 */
7838 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
7839 bss_list,
7840 sizeof(bss_list)) < 0) {
7841 sigma_dut_print(dut, DUT_MSG_ERROR,
7842 "Failed to get bss list");
7843 return -1;
7844 }
7845
7846 sigma_dut_print(dut, DUT_MSG_DEBUG,
7847 "bss list for ifname:%s is:%s",
7848 ifname, bss_list);
7849
7850 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307851 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007852 while (bss_line) {
7853 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
7854 bss_id) {
7855 int len;
7856
7857 len = snprintf(buf + strlen(buf),
7858 sizeof(buf) - strlen(buf),
7859 ",%s", bss_id);
7860 free(bss_id);
7861 bss_id = NULL;
7862 if (len < 0) {
7863 sigma_dut_print(dut,
7864 DUT_MSG_ERROR,
7865 "Failed to read BSSID");
7866 send_resp(dut, conn, SIGMA_ERROR,
7867 "ErrorCode,Failed to read BSS ID");
7868 return 0;
7869 }
7870
7871 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
7872 sigma_dut_print(dut,
7873 DUT_MSG_ERROR,
7874 "Response buf too small for list");
7875 send_resp(dut, conn,
7876 SIGMA_ERROR,
7877 "ErrorCode,Response buf too small for list");
7878 return 0;
7879 }
7880 }
7881
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307882 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007883 }
7884
7885 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
7886 buf);
7887 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7888 return 0;
7889 }
7890
7891 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7892 return 0;
7893}
7894
7895
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007896static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
7897 struct sigma_cmd *cmd)
7898{
7899 char buf[MAX_CMD_LEN];
7900 const char *parameter = get_param(cmd, "Parameter");
7901
7902 if (!parameter)
7903 return -1;
7904
7905 if (strcasecmp(parameter, "RSSI") == 0) {
7906 char rssi[10];
7907
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007908 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007909 rssi, sizeof(rssi)) < 0) {
7910 sigma_dut_print(dut, DUT_MSG_ERROR,
7911 "Could not get RSSI");
7912 return -2;
7913 }
7914
7915 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
7916 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
7917 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7918 return 0;
7919 }
7920
7921 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7922 return 0;
7923}
7924
7925
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05307926#ifdef NL80211_SUPPORT
7927
7928struct station_info {
7929 uint64_t filled;
7930 uint32_t beacon_mic_error_count;
7931 uint32_t beacon_replay_count;
7932};
7933
7934
7935static int qca_get_sta_info_handler(struct nl_msg *msg, void *arg)
7936{
7937 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7938 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7939 struct station_info *data = arg;
7940 struct nlattr *info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
7941 static struct nla_policy info_policy[
7942 QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = {
7943 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT] = {
7944 .type = NLA_U32
7945 },
7946 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT] = {
7947 .type = NLA_U32
7948 },
7949 };
7950
7951 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7952 genlmsg_attrlen(gnlh, 0), NULL);
7953
7954 if (!tb[NL80211_ATTR_VENDOR_DATA])
7955 return NL_SKIP;
7956
7957 if (nla_parse_nested(info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
7958 tb[NL80211_ATTR_VENDOR_DATA], info_policy)) {
7959 return NL_SKIP;
7960 }
7961
7962 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]) {
7963 data->filled |=
7964 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT);
7965 data->beacon_mic_error_count =
7966 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]);
7967 }
7968
7969 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]) {
7970 data->filled |=
7971 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT);
7972 data->beacon_replay_count =
7973 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]);
7974 }
7975
7976 return NL_SKIP;
7977}
7978
7979
7980static int qca_nl80211_get_sta_info(struct sigma_dut *dut, const char *intf,
7981 struct station_info *sta_data)
7982{
7983 struct nl_msg *msg;
7984 int ifindex, ret;
7985
7986 ifindex = if_nametoindex(intf);
7987 if (ifindex == 0) {
7988 sigma_dut_print(dut, DUT_MSG_ERROR,
7989 "%s: Index for interface %s not found",
7990 __func__, intf);
7991 return -1;
7992 }
7993
7994 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7995 NL80211_CMD_VENDOR)) ||
7996 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7997 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7998 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7999 QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
8000 sigma_dut_print(dut, DUT_MSG_ERROR,
8001 "%s: err in adding vendor_cmd", __func__);
8002 nlmsg_free(msg);
8003 return -1;
8004 }
8005
8006 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg,
8007 qca_get_sta_info_handler, sta_data);
8008 if (ret) {
8009 sigma_dut_print(dut, DUT_MSG_ERROR,
8010 "%s: err in send_and_recv_msgs, ret=%d",
8011 __func__, ret);
8012 }
8013 return ret;
8014}
8015#endif /* NL80211_SUPPORT */
8016
8017
8018static int get_bip_mic_error_count(struct sigma_dut *dut,
8019 const char *ifname,
8020 unsigned int *count)
8021{
8022#ifdef NL80211_SUPPORT
8023 struct station_info sta_data;
8024#endif /* NL80211_SUPPORT */
8025
8026 if (get_driver_type(dut) != DRIVER_WCN) {
8027 sigma_dut_print(dut, DUT_MSG_ERROR,
8028 "BIP MIC error count not supported");
8029 return -1;
8030 }
8031
8032#ifdef NL80211_SUPPORT
8033 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8034 !(sta_data.filled &
8035 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT))) {
8036 sigma_dut_print(dut, DUT_MSG_ERROR,
8037 "BIP MIC error count fetching failed");
8038 return -1;
8039 }
8040
8041 *count = sta_data.beacon_mic_error_count;
8042 return 0;
8043#else /* NL80211_SUPPORT */
8044 sigma_dut_print(dut, DUT_MSG_ERROR,
8045 "BIP MIC error count cannot be fetched without NL80211_SUPPORT defined");
8046 return -1;
8047#endif /* NL80211_SUPPORT */
8048}
8049
8050
8051static int get_cmac_replay_count(struct sigma_dut *dut, const char *ifname,
8052 unsigned int *count)
8053{
8054#ifdef NL80211_SUPPORT
8055 struct station_info sta_data;
8056#endif /* NL80211_SUPPORT */
8057
8058 if (get_driver_type(dut) != DRIVER_WCN) {
8059 sigma_dut_print(dut, DUT_MSG_ERROR,
8060 "CMAC reply count not supported");
8061 return -1;
8062 }
8063
8064#ifdef NL80211_SUPPORT
8065 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8066 !(sta_data.filled &
8067 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT))) {
8068 sigma_dut_print(dut, DUT_MSG_ERROR,
8069 "CMAC replay count fetching failed");
8070 return -1;
8071 }
8072
8073 *count = sta_data.beacon_replay_count;
8074 return 0;
8075#else /* NL80211_SUPPORT */
8076 sigma_dut_print(dut, DUT_MSG_ERROR,
8077 "CMAC replay count cannot be fetched without NL80211_SUPPORT defined");
8078 return -1;
8079#endif /* NL80211_SUPPORT */
8080}
8081
8082
8083static enum sigma_cmd_result sta_get_parameter_wpa3(struct sigma_dut *dut,
8084 struct sigma_conn *conn,
8085 struct sigma_cmd *cmd)
8086{
8087 char buf[MAX_CMD_LEN];
8088 const char *ifname = get_param(cmd, "interface");
8089 const char *parameter = get_param(cmd, "Parameter");
8090 unsigned int val;
8091
8092 if (!ifname || !parameter)
8093 return INVALID_SEND_STATUS;
8094
8095 if (strcasecmp(parameter, "BIPMICErrors") == 0) {
8096 if (get_bip_mic_error_count(dut, ifname, &val)) {
8097 send_resp(dut, conn, SIGMA_ERROR,
8098 "ErrorCode,Failed to get BIPMICErrors");
8099 return STATUS_SENT_ERROR;
8100 }
8101 snprintf(buf, sizeof(buf), "BIPMICErrors,%d", val);
8102 sigma_dut_print(dut, DUT_MSG_INFO, "BIPMICErrors %s", buf);
8103 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8104 return STATUS_SENT;
8105 }
8106
8107 if (strcasecmp(parameter, "CMACReplays") == 0) {
8108 if (get_cmac_replay_count(dut, ifname, &val)) {
8109 send_resp(dut, conn, SIGMA_ERROR,
8110 "ErrorCode,Failed to get CMACReplays");
8111 return STATUS_SENT_ERROR;
8112 }
8113 snprintf(buf, sizeof(buf), "CMACReplays,%d", val);
8114 sigma_dut_print(dut, DUT_MSG_INFO, "CMACReplays %s", buf);
8115 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8116 return STATUS_SENT;
8117 }
8118
8119 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8120 return STATUS_SENT_ERROR;
8121}
8122
8123
Jouni Malinenca0abd32020-02-09 20:18:10 +02008124static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
8125 struct sigma_conn *conn,
8126 struct sigma_cmd *cmd)
8127{
8128 const char *intf = get_param(cmd, "Interface");
8129 char buf[4096], bssid[20], resp[200], *pos, *tmp;
8130
8131 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
8132 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8133 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
8134 send_resp(dut, conn, SIGMA_ERROR,
8135 "ErrorCode,PMKSA_GET not supported");
8136 return STATUS_SENT_ERROR;
8137 }
8138
8139 if (strncmp(buf, "FAIL", 4) == 0 ||
8140 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
8141 send_resp(dut, conn, SIGMA_ERROR,
8142 "ErrorCode,Could not find current network");
8143 return STATUS_SENT_ERROR;
8144 }
8145
8146 pos = buf;
8147 while (pos) {
8148 if (strncmp(pos, bssid, 17) == 0) {
8149 pos = strchr(pos, ' ');
8150 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308151 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008152 pos++;
8153 pos = strchr(pos, ' ');
8154 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308155 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008156 pos++;
8157 tmp = strchr(pos, ' ');
8158 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308159 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008160 *tmp = '\0';
8161 break;
8162 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02008163 pos = strchr(pos, '\n');
8164 if (pos)
8165 pos++;
8166 }
8167
8168 if (!pos) {
8169 send_resp(dut, conn, SIGMA_ERROR,
8170 "ErrorCode,PMK not available");
8171 return STATUS_SENT_ERROR;
8172 }
8173
8174 snprintf(resp, sizeof(resp), "PMK,%s", pos);
8175 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8176 return STATUS_SENT;
8177}
8178
8179
Jouni Malinenf7222712019-06-13 01:50:21 +03008180static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
8181 struct sigma_conn *conn,
8182 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008183{
8184 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02008185 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008186
Jouni Malinenca0abd32020-02-09 20:18:10 +02008187 if (!parameter)
8188 return INVALID_SEND_STATUS;
8189
8190 if (strcasecmp(parameter, "PMK") == 0)
8191 return sta_get_pmk(dut, conn, cmd);
8192
8193 if (!program)
8194 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008195
8196 if (strcasecmp(program, "P2PNFC") == 0)
8197 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
8198
8199 if (strcasecmp(program, "60ghz") == 0)
8200 return sta_get_parameter_60g(dut, conn, cmd);
8201
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07008202 if (strcasecmp(program, "he") == 0)
8203 return sta_get_parameter_he(dut, conn, cmd);
8204
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008205#ifdef ANDROID_NAN
8206 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07008207 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008208#endif /* ANDROID_NAN */
8209
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008210#ifdef MIRACAST
8211 if (strcasecmp(program, "WFD") == 0 ||
8212 strcasecmp(program, "DisplayR2") == 0)
8213 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
8214#endif /* MIRACAST */
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05308215 if (strcasecmp(program, "WPA3") == 0)
8216 return sta_get_parameter_wpa3(dut, conn, cmd);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008217
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008218 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8219 return 0;
8220}
8221
8222
8223static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
8224 const char *type)
8225{
8226 char buf[100];
8227
8228 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008229 run_iwpriv(dut, intf, "chwidth 2");
8230 run_iwpriv(dut, intf, "mode 11ACVHT80");
8231 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008232 }
8233
8234 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008235 run_iwpriv(dut, intf, "chwidth 0");
8236 run_iwpriv(dut, intf, "mode 11naht40");
8237 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008238 }
8239
8240 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008241 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008242
8243 /* Reset CTS width */
8244 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
8245 intf);
8246 if (system(buf) != 0) {
8247 sigma_dut_print(dut, DUT_MSG_ERROR,
8248 "wifitool %s beeliner_fw_test 54 0 failed",
8249 intf);
8250 }
8251
8252 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008253 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008254
8255 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
8256 if (system(buf) != 0) {
8257 sigma_dut_print(dut, DUT_MSG_ERROR,
8258 "iwpriv rts failed");
8259 }
8260 }
8261
8262 if (type && strcasecmp(type, "Testbed") == 0) {
8263 dut->testbed_flag_txsp = 1;
8264 dut->testbed_flag_rxsp = 1;
8265 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008266 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008267
8268 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008269 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008270
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008271 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008272
8273 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008274 run_iwpriv(dut, intf, "tx_stbc 0");
8275 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008276
8277 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008278 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008279 }
8280
8281 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008282 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07008283 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008284
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008285 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008286 }
8287}
8288
8289
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008290#ifdef NL80211_SUPPORT
8291static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
8292 enum he_mcs_config mcs)
8293{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308294 return wcn_wifi_test_config_set_u8(
8295 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS, mcs);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008296}
8297#endif /* NL80211_SUPPORT */
8298
8299
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008300static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
8301 const char *intf, int enable)
8302{
8303#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308304 return wcn_wifi_test_config_set_u8(
8305 dut, intf,
8306 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
8307 enable);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008308#else /* NL80211_SUPPORT */
8309 sigma_dut_print(dut, DUT_MSG_ERROR,
8310 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
8311 return -1;
8312#endif /* NL80211_SUPPORT */
8313}
8314
8315
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008316static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
8317 const char *intf, int enable)
8318{
8319#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308320 return wcn_wifi_test_config_set_u8(
8321 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
8322 enable);
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008323#else /* NL80211_SUPPORT */
8324 sigma_dut_print(dut, DUT_MSG_ERROR,
8325 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
8326 return -1;
8327#endif /* NL80211_SUPPORT */
8328}
8329
8330
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008331#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008332
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008333static int sta_set_he_testbed_def(struct sigma_dut *dut,
8334 const char *intf, int cfg)
8335{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308336 return wcn_wifi_test_config_set_u8(
8337 dut, intf,
8338 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
8339 cfg);
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008340}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008341
8342
8343static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
8344{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308345 return wcn_wifi_test_config_set_u8(
8346 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
8347 cfg);
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008348}
8349
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008350#endif /* NL80211_SUPPORT */
8351
8352
Qiwei Caib6806972020-01-15 13:52:11 +08008353int sta_set_addba_buf_size(struct sigma_dut *dut,
8354 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008355{
8356#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308357 return wcn_wifi_test_config_set_u16(
8358 dut, intf,
8359 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE, bufsize);
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008360#else /* NL80211_SUPPORT */
8361 sigma_dut_print(dut, DUT_MSG_ERROR,
8362 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
8363 return -1;
8364#endif /* NL80211_SUPPORT */
8365}
8366
8367
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008368static int sta_set_scan_unicast_probe(struct sigma_dut *dut,
8369 const char *intf, int val)
8370{
8371#ifdef NL80211_SUPPORT
8372 return wcn_wifi_test_config_set_u8(
8373 dut, intf,
8374 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA,
8375 val);
8376#else /* NL80211_SUPPORT */
8377 sigma_dut_print(dut, DUT_MSG_ERROR,
8378 "Unicast RA in Probe Request frame cannot be set without NL80211_SUPPORT defined");
8379 return -1;
8380#endif /* NL80211_SUPPORT */
8381}
8382
8383
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07008384static int sta_set_rx_ctrl_multi_bss(struct sigma_dut *dut, const char *intf,
8385 int enable)
8386{
8387#ifdef NL80211_SUPPORT
8388 return wcn_wifi_test_config_set_u8(
8389 dut, intf,
8390 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS,
8391 enable);
8392#else /* NL80211_SUPPORT */
8393 sigma_dut_print(dut, DUT_MSG_ERROR,
8394 "Rx ctrl frame to Multi-BSS cannot be changed without NL80211_SUPPORT defined");
8395 return -1;
8396#endif /* NL80211_SUPPORT */
8397}
8398
8399
8400static int sta_set_bcast_twt_support(struct sigma_dut *dut, const char *intf,
8401 int enable)
8402{
8403#ifdef NL80211_SUPPORT
8404 return wcn_wifi_test_config_set_u8(
8405 dut, intf,
8406 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT,
8407 enable);
8408#else /* NL80211_SUPPORT */
8409 sigma_dut_print(dut, DUT_MSG_ERROR,
8410 "BCAST TWT cannot be changed without NL80211_SUPPORT defined");
8411 return -1;
8412#endif /* NL80211_SUPPORT */
8413}
8414
8415
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008416static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
8417 int enable)
8418{
8419#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308420 return wcn_wifi_test_config_set_u8(
8421 dut, intf,
8422 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
8423 enable);
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008424#else /* NL80211_SUPPORT */
8425 sigma_dut_print(dut, DUT_MSG_ERROR,
8426 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
8427 return -1;
8428#endif /* NL80211_SUPPORT */
8429}
8430
8431
Arif Hussain9765f7d2018-07-03 08:28:26 -07008432static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
8433 int val)
8434{
8435#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308436 return wcn_wifi_test_config_set_u8(
8437 dut, intf,
8438 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
8439 val);
Arif Hussain9765f7d2018-07-03 08:28:26 -07008440#else /* NL80211_SUPPORT */
8441 sigma_dut_print(dut, DUT_MSG_ERROR,
8442 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
8443 return -1;
8444#endif /* NL80211_SUPPORT */
8445}
8446
8447
Arif Hussain68d23f52018-07-11 13:39:08 -07008448#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008449static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
8450 enum qca_wlan_he_mac_padding_dur val)
8451{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308452 return wcn_wifi_test_config_set_u8(
8453 dut, intf,
8454 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR, val);
Arif Hussain68d23f52018-07-11 13:39:08 -07008455}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008456#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008457
8458
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008459static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
8460 int val)
8461{
8462#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308463 return wcn_wifi_test_config_set_u8(
8464 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
8465 val);
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008466#else /* NL80211_SUPPORT */
8467 sigma_dut_print(dut, DUT_MSG_ERROR,
8468 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
8469 return -1;
8470#endif /* NL80211_SUPPORT */
8471}
8472
8473
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008474static int sta_set_mgmt_data_tx_disable_cfg(struct sigma_dut *dut,
8475 const char *intf, int val)
8476{
8477#ifdef NL80211_SUPPORT
8478 return wcn_wifi_test_config_set_u8(
8479 dut, intf,
8480 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX,
8481 val);
8482#else /* NL80211_SUPPORT */
8483 sigma_dut_print(dut, DUT_MSG_ERROR,
8484 "Tx disable config cannot be set without NL80211_SUPPORT defined");
8485 return -1;
8486#endif /* NL80211_SUPPORT */
8487}
8488
8489
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -07008490static int sta_set_keep_alive_data_cfg(struct sigma_dut *dut, const char *intf,
8491 int val)
8492{
8493#ifdef NL80211_SUPPORT
8494 return wcn_wifi_test_config_set_u8(
8495 dut, intf,
8496 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE,
8497 val);
8498#else /* NL80211_SUPPORT */
8499 sigma_dut_print(dut, DUT_MSG_ERROR,
8500 "Keep alive data type cannot be set without NL80211_SUPPORT defined");
8501 return -1;
8502#endif /* NL80211_SUPPORT */
8503}
8504
8505
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008506#ifdef NL80211_SUPPORT
8507static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
8508{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308509 return wcn_wifi_test_config_set_flag(
8510 dut, intf,
8511 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG);
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008512}
8513#endif /* NL80211_SUPPORT */
8514
8515
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008516static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
8517 int val)
8518{
8519#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308520 return wcn_wifi_test_config_set_u8(
8521 dut, intf,
8522 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA, val);
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008523#else /* NL80211_SUPPORT */
8524 sigma_dut_print(dut, DUT_MSG_ERROR,
8525 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
8526 return -1;
8527#endif /* NL80211_SUPPORT */
8528}
8529
8530
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008531static int sta_set_er_su_ppdu_type_tx(struct sigma_dut *dut, const char *intf,
8532 int val)
8533{
8534#ifdef NL80211_SUPPORT
8535 return wcn_wifi_test_config_set_u8(
8536 dut, intf,
8537 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE, val);
8538#else /* NL80211_SUPPORT */
8539 sigma_dut_print(dut, DUT_MSG_ERROR,
8540 "ER-SU PPDU type cannot be set without NL80211_SUPPORT defined");
8541 return -1;
8542#endif /* NL80211_SUPPORT */
8543}
8544
8545
8546static int sta_set_ru_242_tone_tx(struct sigma_dut *dut, const char *intf,
8547 int val)
8548{
8549#ifdef NL80211_SUPPORT
8550 return wcn_wifi_test_config_set_u8(
8551 dut, intf,
8552 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RU_242_TONE_TX, val);
8553#else /* NL80211_SUPPORT */
8554 sigma_dut_print(dut, DUT_MSG_ERROR,
8555 "RU 242 tone cannot be set without NL80211_SUPPORT defined");
8556 return -1;
8557#endif /* NL80211_SUPPORT */
8558}
8559
8560
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008561static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
8562 int val)
8563{
8564#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308565 return wcn_wifi_test_config_set_u8(
8566 dut, intf,
8567 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP, val);
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008568#else /* NL80211_SUPPORT */
8569 sigma_dut_print(dut, DUT_MSG_ERROR,
8570 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
8571 return -1;
8572#endif /* NL80211_SUPPORT */
8573}
8574
8575
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008576#ifdef NL80211_SUPPORT
8577
8578struct features_info {
8579 unsigned char flags[8];
8580 size_t flags_len;
8581};
8582
8583static int features_info_handler(struct nl_msg *msg, void *arg)
8584{
8585 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8586 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8587 struct features_info *info = arg;
8588 struct nlattr *nl_vend, *attr;
8589
8590 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8591 genlmsg_attrlen(gnlh, 0), NULL);
8592
8593 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
8594 if (nl_vend) {
8595 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
8596
8597 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
8598 nla_data(nl_vend), nla_len(nl_vend), NULL);
8599
8600 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
8601 if (attr) {
8602 int len = nla_len(attr);
8603
Vamsi Krishna79a91132021-08-16 21:40:22 +05308604 if (info && len <= sizeof(info->flags)) {
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008605 memcpy(info->flags, nla_data(attr), len);
8606 info->flags_len = len;
8607 }
8608 }
8609 }
8610
8611 return NL_SKIP;
8612}
8613
8614
8615static int check_feature(enum qca_wlan_vendor_features feature,
8616 struct features_info *info)
8617{
8618 size_t idx = feature / 8;
8619
Vamsi Krishna79a91132021-08-16 21:40:22 +05308620 if (!info)
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008621 return 0;
8622
8623 return (idx < info->flags_len) &&
8624 (info->flags[idx] & BIT(feature % 8));
8625}
8626
8627#endif /* NL80211_SUPPORT */
8628
8629
8630static void sta_get_twt_feature_async_supp(struct sigma_dut *dut,
8631 const char *intf)
8632{
8633#ifdef NL80211_SUPPORT
8634 struct nl_msg *msg;
8635 struct features_info info = { 0 };
8636 int ifindex, ret;
8637
8638 ifindex = if_nametoindex(intf);
8639 if (ifindex == 0) {
8640 sigma_dut_print(dut, DUT_MSG_ERROR,
8641 "%s: Index for interface %s failed",
8642 __func__, intf);
8643 return;
8644 }
8645
8646 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8647 NL80211_CMD_VENDOR)) ||
8648 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8649 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8650 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8651 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
8652 sigma_dut_print(dut, DUT_MSG_ERROR,
8653 "%s: err in adding vendor_cmd and vendor_data",
8654 __func__);
8655 nlmsg_free(msg);
8656 return;
8657 }
8658
8659 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, features_info_handler,
8660 &info);
8661 if (ret) {
8662 sigma_dut_print(dut, DUT_MSG_ERROR,
8663 "%s: err in send_and_recv_msgs, ret=%d",
8664 __func__, ret);
8665 return;
8666 }
8667
8668 if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info))
8669 dut->sta_async_twt_supp = 1;
8670 else
8671 dut->sta_async_twt_supp = 0;
8672
8673 sigma_dut_print(dut, DUT_MSG_DEBUG,
8674 "%s: sta_async_twt_supp %d",
8675 __func__, dut->sta_async_twt_supp);
8676#else /* NL80211_SUPPORT */
8677 sigma_dut_print(dut, DUT_MSG_INFO,
8678 "TWT async supp get cannot be done without NL80211_SUPPORT defined");
8679 dut->sta_async_twt_supp = 0;
8680#endif /* NL80211_SUPPORT */
8681}
8682
8683
Arif Hussain480d5f42019-03-12 14:40:42 -07008684static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
8685 int val)
8686{
8687#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308688 return wcn_wifi_test_config_set_u8(
8689 dut, intf,
8690 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT, val);
Arif Hussain480d5f42019-03-12 14:40:42 -07008691#else /* NL80211_SUPPORT */
8692 sigma_dut_print(dut, DUT_MSG_ERROR,
8693 "TWT Request cannot be changed without NL80211_SUPPORT defined");
8694 return -1;
8695#endif /* NL80211_SUPPORT */
8696}
8697
8698
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07008699static int sta_set_bss_max_idle_period(struct sigma_dut *dut, const char *intf,
8700 int val)
8701{
8702#ifdef NL80211_SUPPORT
8703 return wcn_wifi_test_config_set_u16(
8704 dut, intf,
8705 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD, val);
8706#else /* NL80211_SUPPORT */
8707 sigma_dut_print(dut, DUT_MSG_ERROR,
8708 "BSS max idle period cannot be set without NL80211_SUPPORT defined");
8709 return -1;
8710#endif /* NL80211_SUPPORT */
8711}
8712
8713
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07008714static int sta_set_bss_max_idle_support(struct sigma_dut *dut, const char *intf,
8715 int val)
8716{
8717#ifdef NL80211_SUPPORT
8718 return wcn_wifi_test_config_set_u8(
8719 dut, intf,
8720 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE,
8721 val);
8722#else /* NL80211_SUPPORT */
8723 sigma_dut_print(dut, DUT_MSG_ERROR,
8724 "BSS max idle support cannot be set without NL80211_SUPPORT defined");
8725 return -1;
8726#endif /* NL80211_SUPPORT */
8727}
8728
8729
Srinivas Girigowda0525e292020-11-12 13:28:21 -08008730static int sta_set_fullbw_ulmumimo(struct sigma_dut *dut, const char *intf,
8731 int val)
8732{
8733#ifdef NL80211_SUPPORT
8734 return wcn_wifi_test_config_set_u8(
8735 dut, intf,
8736 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO, val);
8737#else /* NL80211_SUPPORT */
8738 sigma_dut_print(dut, DUT_MSG_ERROR,
8739 "Full BW UL MU MIMO cannot be changed without NL80211_SUPPORT defined");
8740 return -1;
8741#endif /* NL80211_SUPPORT */
8742}
8743
8744
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07008745static int sta_set_punctured_preamble_rx(struct sigma_dut *dut,
8746 const char *intf, int val)
8747{
8748#ifdef NL80211_SUPPORT
8749 return wcn_wifi_test_config_set_u8(
8750 dut, intf,
8751 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PUNCTURED_PREAMBLE_RX,
8752 val);
8753#else /* NL80211_SUPPORT */
8754 sigma_dut_print(dut, DUT_MSG_ERROR,
8755 "Punctured preamble Rx cannot be set without NL80211_SUPPORT defined");
8756 return -1;
8757#endif /* NL80211_SUPPORT */
8758}
8759
8760
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -08008761int wcn_set_he_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8762{
8763 #ifdef NL80211_SUPPORT
8764 struct nlattr *attr;
8765 struct nlattr *attr1;
8766 int ifindex, ret;
8767 struct nl_msg *msg;
8768
8769 ifindex = if_nametoindex(intf);
8770 if (ifindex == 0) {
8771 sigma_dut_print(dut, DUT_MSG_ERROR,
8772 "%s: Index for interface %s failed",
8773 __func__, intf);
8774 return -1;
8775 }
8776
8777 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8778 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8779 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8780 sigma_dut_print(dut, DUT_MSG_ERROR,
8781 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8782 __func__);
8783 nlmsg_free(msg);
8784 return -1;
8785 }
8786
8787 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting HE GI %d",
8788 __func__, gi_val);
8789
8790 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8791 if (!attr1) {
8792 sigma_dut_print(dut, DUT_MSG_ERROR,
8793 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8794 __func__);
8795 nlmsg_free(msg);
8796 return -1;
8797 }
8798 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8799 nla_nest_end(msg, attr1);
8800
8801 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8802 if (!attr1) {
8803 sigma_dut_print(dut, DUT_MSG_ERROR,
8804 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8805 __func__);
8806 nlmsg_free(msg);
8807 return -1;
8808 }
8809 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8810 nla_nest_end(msg, attr1);
8811
8812 nla_nest_end(msg, attr);
8813 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8814 if (ret) {
8815 sigma_dut_print(dut, DUT_MSG_ERROR,
8816 "%s: send_and_recv_msgs failed, ret=%d",
8817 __func__, ret);
8818 }
8819 return ret;
8820#else /* NL80211_SUPPORT */
8821 return -1;
8822#endif /* NL80211_SUPPORT */
8823}
8824
8825
8826static int sta_set_vht_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8827{
8828 #ifdef NL80211_SUPPORT
8829 struct nlattr *attr;
8830 struct nlattr *attr1;
8831 int ifindex, ret;
8832 struct nl_msg *msg;
8833
8834 ifindex = if_nametoindex(intf);
8835 if (ifindex == 0) {
8836 sigma_dut_print(dut, DUT_MSG_ERROR,
8837 "%s: Index for interface %s failed",
8838 __func__, intf);
8839 return -1;
8840 }
8841
8842 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8843 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8844 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8845 sigma_dut_print(dut, DUT_MSG_ERROR,
8846 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8847 __func__);
8848 nlmsg_free(msg);
8849 return -1;
8850 }
8851
8852 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting VHT GI %d",
8853 __func__, gi_val);
8854
8855 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8856 if (!attr1) {
8857 sigma_dut_print(dut, DUT_MSG_ERROR,
8858 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8859 __func__);
8860 nlmsg_free(msg);
8861 return -1;
8862 }
8863 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8864 nla_nest_end(msg, attr1);
8865
8866 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8867 if (!attr1) {
8868 sigma_dut_print(dut, DUT_MSG_ERROR,
8869 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8870 __func__);
8871 nlmsg_free(msg);
8872 return -1;
8873 }
8874 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8875 nla_nest_end(msg, attr1);
8876 nla_nest_end(msg, attr);
8877
8878 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8879 if (ret) {
8880 sigma_dut_print(dut, DUT_MSG_ERROR,
8881 "%s: send_and_recv_msgs failed, ret=%d",
8882 __func__, ret);
8883 }
8884 return ret;
8885#else /* NL80211_SUPPORT */
8886 return -1;
8887#endif /* NL80211_SUPPORT */
8888}
8889
8890
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008891static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
8892 const char *type)
8893{
8894 char buf[60];
8895
8896 if (dut->program == PROGRAM_HE) {
8897 /* resetting phymode to auto in case of HE program */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05308898 sta_set_phymode(dut, intf, "auto");
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008899
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07008900 /* reset the rate to Auto rate */
8901 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
8902 intf);
8903 if (system(buf) != 0) {
8904 sigma_dut_print(dut, DUT_MSG_ERROR,
8905 "iwpriv %s set_11ax_rate 0xff failed",
8906 intf);
8907 }
8908
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07008909 /* reset the LDPC setting */
8910 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
8911 if (system(buf) != 0) {
8912 sigma_dut_print(dut, DUT_MSG_ERROR,
8913 "iwpriv %s ldpc 1 failed", intf);
8914 }
8915
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008916 /* reset the power save setting */
Vinita S. Malooa8b62722020-04-23 01:45:41 +05308917 set_power_save_wcn(dut, intf, 2);
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008918
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008919 /* remove all network profiles */
8920 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008921
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008922 /* Configure ADDBA Req/Rsp buffer size to be 64 */
8923 sta_set_addba_buf_size(dut, intf, 64);
8924
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008925 if (dut->sta_async_twt_supp == -1)
8926 sta_get_twt_feature_async_supp(dut, intf);
8927
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008928 sta_set_scan_unicast_probe(dut, intf, 0);
8929
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008930#ifdef NL80211_SUPPORT
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08008931 nl80211_close_event_sock(dut);
8932
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008933 /* Reset the device HE capabilities to its default supported
8934 * configuration. */
8935 sta_set_he_testbed_def(dut, intf, 0);
8936
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008937 /* Disable noackpolicy for all AC */
8938 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
8939 sigma_dut_print(dut, DUT_MSG_ERROR,
8940 "Disable of noackpolicy for all AC failed");
8941 }
8942#endif /* NL80211_SUPPORT */
8943
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08008944 /* Enable WMM by default */
8945 if (wcn_sta_set_wmm(dut, intf, "on")) {
8946 sigma_dut_print(dut, DUT_MSG_ERROR,
8947 "Enable of WMM in sta_reset_default_wcn failed");
8948 }
8949
8950 /* Disable ADDBA_REJECT by default */
8951 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
8952 sigma_dut_print(dut, DUT_MSG_ERROR,
8953 "Disable of addba_reject in sta_reset_default_wcn failed");
8954 }
8955
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08008956 /* Enable sending of ADDBA by default */
8957 if (nlvendor_config_send_addba(dut, intf, 1)) {
8958 sigma_dut_print(dut, DUT_MSG_ERROR,
8959 "Enable sending of ADDBA in sta_reset_default_wcn failed");
8960 }
8961
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08008962 /* Enable AMPDU by default */
8963 iwpriv_sta_set_ampdu(dut, intf, 1);
8964
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008965#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08008966 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008967 sigma_dut_print(dut, DUT_MSG_ERROR,
8968 "Set LTF config to default in sta_reset_default_wcn failed");
8969 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07008970
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08008971 /* set the beamformee NSTS(maximum number of
8972 * space-time streams) to default DUT config
8973 */
8974 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07008975 sigma_dut_print(dut, DUT_MSG_ERROR,
8976 "Failed to set BeamformeeSTS");
8977 }
Arif Hussain68d23f52018-07-11 13:39:08 -07008978
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008979 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, 0)) {
8980 sigma_dut_print(dut, DUT_MSG_ERROR,
8981 "Failed to reset mgmt/data Tx disable config");
8982 }
8983
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008984 if (sta_set_mac_padding_duration(
8985 dut, intf,
8986 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008987 sigma_dut_print(dut, DUT_MSG_ERROR,
8988 "Failed to set MAC padding duration");
8989 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008990
8991 if (sta_set_mu_edca_override(dut, intf, 0)) {
8992 sigma_dut_print(dut, DUT_MSG_ERROR,
8993 "ErrorCode,Failed to set MU EDCA override disable");
8994 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008995
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008996 if (sta_set_ru_242_tone_tx(dut, intf, 0)) {
8997 sigma_dut_print(dut, DUT_MSG_ERROR,
8998 "Failed to set RU 242 tone Tx");
8999 }
9000
9001 if (sta_set_er_su_ppdu_type_tx(dut, intf, 0)) {
9002 sigma_dut_print(dut, DUT_MSG_ERROR,
9003 "Failed to set ER-SU PPDU type Tx");
9004 }
9005
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07009006 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
9007 sigma_dut_print(dut, DUT_MSG_ERROR,
9008 "Failed to set OM ctrl supp");
9009 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07009010
9011 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
9012 sigma_dut_print(dut, DUT_MSG_ERROR,
9013 "Failed to set Tx SU PPDU enable");
9014 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009015
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009016 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
9017 sigma_dut_print(dut, DUT_MSG_ERROR,
9018 "failed to send TB PPDU Tx cfg");
9019 }
9020
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009021 if (sta_set_he_om_ctrl_reset(dut, intf)) {
9022 sigma_dut_print(dut, DUT_MSG_ERROR,
9023 "Failed to set OM ctrl reset");
9024 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009025
9026 /* +HTC-HE support default on */
9027 if (sta_set_he_htc_supp(dut, intf, 1)) {
9028 sigma_dut_print(dut, DUT_MSG_ERROR,
9029 "Setting of +HTC-HE support failed");
9030 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009031#endif /* NL80211_SUPPORT */
9032
Arif Hussain8d5b27b2018-05-14 14:31:03 -07009033 if (sta_set_tx_beamformee(dut, intf, 1)) {
9034 sigma_dut_print(dut, DUT_MSG_ERROR,
9035 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
9036 }
9037
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009038 wpa_command(intf, "SET oce 1");
9039
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009040 /* Set nss to 1 and MCS 0-7 in case of testbed */
9041 if (type && strcasecmp(type, "Testbed") == 0) {
9042#ifdef NL80211_SUPPORT
9043 int ret;
9044#endif /* NL80211_SUPPORT */
9045
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009046 wpa_command(intf, "SET oce 0");
9047
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009048 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
9049 if (system(buf) != 0) {
9050 sigma_dut_print(dut, DUT_MSG_ERROR,
9051 "iwpriv %s nss failed", intf);
9052 }
9053
9054#ifdef NL80211_SUPPORT
9055 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
9056 if (ret) {
9057 sigma_dut_print(dut, DUT_MSG_ERROR,
9058 "Setting of MCS failed, ret:%d",
9059 ret);
9060 }
9061#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08009062
9063 /* Disable STBC as default */
9064 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08009065
9066 /* Disable AMSDU as default */
9067 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009068
9069#ifdef NL80211_SUPPORT
9070 /* HE fragmentation default off */
9071 if (sta_set_he_fragmentation(dut, intf,
9072 HE_FRAG_DISABLE)) {
9073 sigma_dut_print(dut, DUT_MSG_ERROR,
9074 "Setting of HE fragmentation failed");
9075 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009076
9077 /* set the beamformee NSTS(maximum number of
9078 * space-time streams) to default testbed config
9079 */
9080 if (sta_set_beamformee_sts(dut, intf, 3)) {
9081 sigma_dut_print(dut, DUT_MSG_ERROR,
9082 "Failed to set BeamformeeSTS");
9083 }
9084
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07009085 if (sta_set_punctured_preamble_rx(dut, intf, 0)) {
9086 sigma_dut_print(dut, DUT_MSG_ERROR,
9087 "Failed to reset PreamblePunctRx support");
9088 }
9089
Kiran Kumar Lokere727687f2021-06-24 00:35:49 -07009090 if (sta_set_bss_max_idle_period(dut, intf, 0)) {
9091 sigma_dut_print(dut, DUT_MSG_ERROR,
9092 "Failed to reset BSS max idle period");
9093 }
9094
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009095 /* +HTC-HE support default off */
9096 if (sta_set_he_htc_supp(dut, intf, 0)) {
9097 sigma_dut_print(dut, DUT_MSG_ERROR,
9098 "Setting of +HTC-HE support failed");
9099 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08009100
9101 /* Set device HE capabilities to testbed default
9102 * configuration. */
9103 if (sta_set_he_testbed_def(dut, intf, 1)) {
9104 sigma_dut_print(dut, DUT_MSG_DEBUG,
9105 "Failed to set HE defaults");
9106 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08009107
9108 /* Disable VHT support in 2.4 GHz for testbed */
9109 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009110#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08009111
9112 /* Enable WEP/TKIP with HE capability in testbed */
9113 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
9114 sigma_dut_print(dut, DUT_MSG_ERROR,
9115 "Enabling HE config with WEP/TKIP failed");
9116 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009117 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009118
9119 /* Defaults in case of DUT */
9120 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07009121 /* Enable STBC by default */
9122 wcn_sta_set_stbc(dut, intf, "1");
9123
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009124 /* set nss to 2 */
9125 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
9126 if (system(buf) != 0) {
9127 sigma_dut_print(dut, DUT_MSG_ERROR,
9128 "iwpriv %s nss 2 failed", intf);
9129 }
Arif Hussainac6c5112018-05-25 17:34:00 -07009130 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009131
9132#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07009133 /* Set HE_MCS to 0-11 */
9134 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009135 sigma_dut_print(dut, DUT_MSG_ERROR,
9136 "Setting of MCS failed");
9137 }
9138#endif /* NL80211_SUPPORT */
9139
9140 /* Disable WEP/TKIP with HE capability in DUT */
9141 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
9142 sigma_dut_print(dut, DUT_MSG_ERROR,
9143 "Enabling HE config with WEP/TKIP failed");
9144 }
9145 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009146 }
9147}
9148
9149
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309150static int sta_set_client_privacy(struct sigma_dut *dut,
9151 struct sigma_conn *conn, const char *intf,
9152 int enable)
9153{
9154 if (enable &&
9155 (wpa_command(intf, "SET mac_addr 1") < 0 ||
9156 wpa_command(intf, "SET rand_addr_lifetime 1") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309157 (wpa_command(intf, "MAC_RAND_SCAN enable=1 all") < 0 &&
9158 wpa_command(intf, "SET preassoc_mac_addr 1") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309159 wpa_command(intf, "SET gas_rand_mac_addr 1") < 0 ||
9160 wpa_command(intf, "SET gas_rand_addr_lifetime 1") < 0))
9161 return -1;
9162
9163 if (!enable &&
9164 (wpa_command(intf, "SET mac_addr 0") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309165 (wpa_command(intf, "MAC_RAND_SCAN enable=0 all") < 0 &&
9166 wpa_command(intf, "SET preassoc_mac_addr 0") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309167 wpa_command(intf, "SET gas_rand_mac_addr 0") < 0))
9168 return -1;
9169
9170 dut->client_privacy = enable;
9171 return 0;
9172}
9173
9174
Jouni Malinenf7222712019-06-13 01:50:21 +03009175static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
9176 struct sigma_conn *conn,
9177 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009178{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009179 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009180 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009181 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009182 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309183 const char *dev_role = get_param(cmd, "DevRole");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309184 char resp[20];
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309185 char buf[100];
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309186 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009187
Shivani Baranwal31182012021-12-07 21:11:13 +05309188#ifdef ANDROID
9189 kill_pid(dut, concat_sigma_tmpdir(dut, "/sigma_dut-dnsmasq.pid",
9190 buf, sizeof(buf)));
9191#endif /* ANDROID */
9192
Jouni Malinenb21f0542019-11-04 17:53:38 +02009193 if (dut->station_ifname_2g &&
9194 strcmp(dut->station_ifname_2g, intf) == 0)
9195 dut->use_5g = 0;
9196 else if (dut->station_ifname_5g &&
9197 strcmp(dut->station_ifname_5g, intf) == 0)
9198 dut->use_5g = 1;
9199
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009200 if (!program)
9201 program = get_param(cmd, "prog");
9202 dut->program = sigma_program_to_enum(program);
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05309203
9204 if (dut->program == PROGRAM_WFD && dut->user_config_timeout)
9205 dut->default_timeout = dut->user_config_timeout;
9206
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009207 dut->device_type = STA_unknown;
9208 type = get_param(cmd, "type");
9209 if (type && strcasecmp(type, "Testbed") == 0)
9210 dut->device_type = STA_testbed;
9211 if (type && strcasecmp(type, "DUT") == 0)
9212 dut->device_type = STA_dut;
9213
9214 if (dut->program == PROGRAM_TDLS) {
9215 /* Clear TDLS testing mode */
9216 wpa_command(intf, "SET tdls_disabled 0");
9217 wpa_command(intf, "SET tdls_testing 0");
9218 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009219 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05309220 /* Enable the WCN driver in TDLS Explicit trigger mode
9221 */
9222 wpa_command(intf, "SET tdls_external_control 0");
9223 wpa_command(intf, "SET tdls_trigger_control 0");
9224 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009225 }
9226
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009227#ifdef MIRACAST
9228 if (dut->program == PROGRAM_WFD ||
9229 dut->program == PROGRAM_DISPLAYR2)
9230 miracast_sta_reset_default(dut, conn, cmd);
9231#endif /* MIRACAST */
9232
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009233 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009234 case DRIVER_ATHEROS:
9235 sta_reset_default_ath(dut, intf, type);
9236 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009237 case DRIVER_WCN:
9238 sta_reset_default_wcn(dut, intf, type);
9239 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009240 default:
9241 break;
9242 }
9243
9244#ifdef ANDROID_NAN
9245 if (dut->program == PROGRAM_NAN)
9246 nan_cmd_sta_reset_default(dut, conn, cmd);
9247#endif /* ANDROID_NAN */
9248
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05309249 if (dut->program == PROGRAM_LOC &&
9250 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
9251 return ERROR_SEND_STATUS;
9252
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009253 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
9254 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009255 unlink("SP/wi-fi.org/pps.xml");
9256 if (system("rm -r SP/*") != 0) {
9257 }
9258 unlink("next-client-cert.pem");
9259 unlink("next-client-key.pem");
9260 }
9261
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009262 /* For WPS program of the 60 GHz band the band type needs to be saved */
9263 if (dut->program == PROGRAM_WPS) {
9264 if (band && strcasecmp(band, "60GHz") == 0) {
9265 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009266 /* For 60 GHz enable WPS for WPS TCs */
9267 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009268 } else {
9269 dut->band = WPS_BAND_NON_60G;
9270 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009271 } else if (dut->program == PROGRAM_60GHZ) {
9272 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
9273 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009274 }
9275
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02009276 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009277 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009278 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009279
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009280 sigma_dut_print(dut, DUT_MSG_INFO,
9281 "WPS 60 GHz program, wps_disable = %d",
9282 dut->wps_disable);
9283
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009284 if (!dev_role) {
9285 send_resp(dut, conn, SIGMA_ERROR,
9286 "errorCode,Missing DevRole argument");
9287 return 0;
9288 }
9289
9290 if (strcasecmp(dev_role, "STA") == 0)
9291 dut->dev_role = DEVROLE_STA;
9292 else if (strcasecmp(dev_role, "PCP") == 0)
9293 dut->dev_role = DEVROLE_PCP;
9294 else {
9295 send_resp(dut, conn, SIGMA_ERROR,
9296 "errorCode,Unknown DevRole");
9297 return 0;
9298 }
9299
9300 if (dut->device_type == STA_unknown) {
9301 sigma_dut_print(dut, DUT_MSG_ERROR,
9302 "Device type is not STA testbed or DUT");
9303 send_resp(dut, conn, SIGMA_ERROR,
9304 "errorCode,Unknown device type");
9305 return 0;
9306 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009307
9308 sigma_dut_print(dut, DUT_MSG_DEBUG,
9309 "Setting msdu_size to MAX: 7912");
9310 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009311 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009312
9313 if (system(buf) != 0) {
9314 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9315 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009316 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009317 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009318
9319 if (sta_set_force_mcs(dut, 0, 1)) {
9320 sigma_dut_print(dut, DUT_MSG_ERROR,
9321 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009322 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009323 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009324 }
9325
9326 wpa_command(intf, "WPS_ER_STOP");
9327 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05309328 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009329 wpa_command(intf, "SET radio_disabled 0");
9330
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02009331 dut->wps_forced_version = 0;
9332
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009333 if (dut->wsc_fragment) {
9334 dut->wsc_fragment = 0;
9335 wpa_command(intf, "SET device_name Test client");
9336 wpa_command(intf, "SET manufacturer ");
9337 wpa_command(intf, "SET model_name ");
9338 wpa_command(intf, "SET model_number ");
9339 wpa_command(intf, "SET serial_number ");
9340 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02009341 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
9342 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
9343 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
9344 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009345
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009346 if (dut->tmp_mac_addr && dut->set_macaddr) {
9347 dut->tmp_mac_addr = 0;
9348 if (system(dut->set_macaddr) != 0) {
9349 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
9350 "temporary MAC address");
9351 }
9352 }
9353
9354 set_ps(intf, dut, 0);
9355
Jouni Malinenba630452018-06-22 11:49:59 +03009356 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009357 dut->program == PROGRAM_HS2_R3 || dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009358 wpa_command(intf, "SET interworking 1");
9359 wpa_command(intf, "SET hs20 1");
9360 }
9361
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009362 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03009363 dut->program == PROGRAM_HS2_R3 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009364 dut->program == PROGRAM_HS2_R4 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009365 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009366 wpa_command(intf, "SET pmf 1");
9367 } else {
9368 wpa_command(intf, "SET pmf 0");
9369 }
9370
9371 hs2_clear_credentials(intf);
9372 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
9373 wpa_command(intf, "SET access_network_type 15");
9374
9375 static_ip_file(0, NULL, NULL, NULL);
9376 kill_dhcp_client(dut, intf);
9377 clear_ip_addr(dut, intf);
9378
9379 dut->er_oper_performed = 0;
9380 dut->er_oper_bssid[0] = '\0';
9381
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009382 if (dut->program == PROGRAM_LOC) {
9383 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009384 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009385 }
9386
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07009387 if (dut->program == PROGRAM_MBO || dut->program == PROGRAM_HE) {
Ashwini Patil00402582017-04-13 12:29:39 +05309388 free(dut->non_pref_ch_list);
9389 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309390 free(dut->btm_query_cand_list);
9391 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05309392 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05309393 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05309394 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05309395 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05309396 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05309397 }
9398
Jouni Malinen3c367e82017-06-23 17:01:47 +03009399 free(dut->rsne_override);
9400 dut->rsne_override = NULL;
9401
Jouni Malinen68143132017-09-02 02:34:08 +03009402 free(dut->sae_commit_override);
9403 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03009404 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02009405 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03009406
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009407 dut->sta_associate_wait_connect = 0;
9408 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03009409 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009410 dut->sta_tod_policy = 0;
9411
Jouni Malinend86e5822017-08-29 03:55:32 +03009412 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02009413 free(dut->dpp_peer_uri);
9414 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02009415 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02009416 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03009417 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinend86e5822017-08-29 03:55:32 +03009418
Jouni Malinenfac9cad2017-10-10 18:35:55 +03009419 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
9420
vamsi krishnaa2799492017-12-05 14:28:01 +05309421 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309422 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05309423 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05309424 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
9425 dut->fils_hlp = 0;
9426#ifdef ANDROID
9427 hlp_thread_cleanup(dut);
9428#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05309429 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309430
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309431 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309432 wpa_command(intf, "SET interworking 1");
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309433 wpa_command(intf, "SET enable_dscp_policy_capa 1");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05309434 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309435 dut->reject_dscp_policies = 0;
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +05309436 dut->num_dscp_status = 0;
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309437 snprintf(buf, sizeof(buf),
9438 "ip -6 route replace fe80::/64 dev %s table local",
9439 intf);
9440 if (system(buf) != 0)
9441 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
9442 buf);
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05309443
9444 stop_dscp_policy_mon_thread(dut);
9445 clear_all_dscp_policies(dut);
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309446 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309447
Jouni Malinen8179fee2019-03-28 03:19:47 +02009448 dut->akm_values = 0;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05309449
9450#ifdef NL80211_SUPPORT
9451 if (get_driver_type(dut) == DRIVER_WCN)
9452 sta_config_params(dut, intf, STA_SET_FT_DS, 0);
9453#endif /* NL80211_SUPPORT */
9454
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03009455 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02009456
Sunil Dutt076081f2018-02-05 19:45:50 +05309457#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009458 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05309459 dut->config_rsnie == 1) {
9460 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309461 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05309462 }
9463#endif /* NL80211_SUPPORT */
9464
Sunil Duttfebf8a82018-02-09 18:50:13 +05309465 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
9466 dut->dev_role = DEVROLE_STA_CFON;
9467 return sta_cfon_reset_default(dut, conn, cmd);
9468 }
9469
Jouni Malinen439352d2018-09-13 03:42:23 +03009470 wpa_command(intf, "SET setband AUTO");
9471
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309472 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
9473 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
9474
9475 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
9476 sizeof(resp));
9477 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
9478
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309479 if (sta_set_client_privacy(dut, conn, intf,
9480 dut->program == PROGRAM_WPA3 &&
9481 dut->device_type == STA_dut &&
9482 dut->client_privacy_default)) {
9483 sigma_dut_print(dut, DUT_MSG_ERROR,
9484 "Failed to set client privacy functionality");
9485 /* sta_reset_default command is not really supposed to fail,
9486 * so allow this to continue. */
9487 }
9488
Veerendranath Jakkamca239592021-10-11 20:48:00 +05309489 if (get_driver_type(dut) == DRIVER_WCN)
9490 wcn_set_ignore_h2e_rsnxe(dut, intf, 0);
9491
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05309492 dut->saquery_oci_freq = 0;
Shivani Baranwalebde8f62021-10-19 12:26:02 +05309493 dut->prev_disable_scs_support = 0;
9494 dut->prev_disable_mscs_support = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309495
Sunil Duttfebf8a82018-02-09 18:50:13 +05309496 if (dut->program != PROGRAM_VHT)
9497 return cmd_sta_p2p_reset(dut, conn, cmd);
9498
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08009499 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009500}
9501
9502
Jouni Malinenf7222712019-06-13 01:50:21 +03009503static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
9504 struct sigma_conn *conn,
9505 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009506{
9507 const char *program = get_param(cmd, "Program");
9508
9509 if (program == NULL)
9510 return -1;
9511#ifdef ANDROID_NAN
9512 if (strcasecmp(program, "NAN") == 0)
9513 return nan_cmd_sta_get_events(dut, conn, cmd);
9514#endif /* ANDROID_NAN */
9515 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9516 return 0;
9517}
9518
9519
Jouni Malinen82905202018-04-29 17:20:10 +03009520static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
9521 struct sigma_cmd *cmd)
9522{
9523 const char *url = get_param(cmd, "url");
9524 const char *method = get_param(cmd, "method");
9525 pid_t pid;
9526 int status;
9527
9528 if (!url || !method)
9529 return -1;
9530
9531 /* TODO: Add support for method,post */
9532 if (strcasecmp(method, "get") != 0) {
9533 send_resp(dut, conn, SIGMA_ERROR,
9534 "ErrorCode,Unsupported method");
9535 return 0;
9536 }
9537
9538 pid = fork();
9539 if (pid < 0) {
9540 perror("fork");
9541 return -1;
9542 }
9543
9544 if (pid == 0) {
9545 char * argv[5] = { "wget", "-O", "/dev/null",
9546 (char *) url, NULL };
9547
9548 execv("/usr/bin/wget", argv);
9549 perror("execv");
9550 exit(0);
9551 return -1;
9552 }
9553
9554 if (waitpid(pid, &status, 0) < 0) {
9555 perror("waitpid");
9556 return -1;
9557 }
9558
9559 if (WIFEXITED(status)) {
9560 const char *errmsg;
9561
9562 if (WEXITSTATUS(status) == 0)
9563 return 1;
9564 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
9565 WEXITSTATUS(status));
9566 switch (WEXITSTATUS(status)) {
9567 case 4:
9568 errmsg = "errmsg,Network failure";
9569 break;
9570 case 8:
9571 errmsg = "errmsg,Server issued an error response";
9572 break;
9573 default:
9574 errmsg = "errmsg,Unknown failure from wget";
9575 break;
9576 }
9577 send_resp(dut, conn, SIGMA_ERROR, errmsg);
9578 return 0;
9579 }
9580
9581 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
9582 return 0;
9583}
9584
9585
Jouni Malinenf7222712019-06-13 01:50:21 +03009586static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
9587 struct sigma_conn *conn,
9588 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009589{
9590 const char *program = get_param(cmd, "Prog");
9591
Jouni Malinen82905202018-04-29 17:20:10 +03009592 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009593 return -1;
9594#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03009595 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009596 return nan_cmd_sta_exec_action(dut, conn, cmd);
9597#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03009598
9599 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009600 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03009601
9602 if (get_param(cmd, "url"))
9603 return sta_exec_action_url(dut, conn, cmd);
9604
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009605 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9606 return 0;
9607}
9608
9609
Jouni Malinenf7222712019-06-13 01:50:21 +03009610static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
9611 struct sigma_conn *conn,
9612 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009613{
9614 const char *intf = get_param(cmd, "Interface");
9615 const char *val, *mcs32, *rate;
9616
9617 val = get_param(cmd, "GREENFIELD");
9618 if (val) {
9619 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
9620 /* Enable GD */
9621 send_resp(dut, conn, SIGMA_ERROR,
9622 "ErrorCode,GF not supported");
9623 return 0;
9624 }
9625 }
9626
9627 val = get_param(cmd, "SGI20");
9628 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009629 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009630 case DRIVER_ATHEROS:
9631 ath_sta_set_sgi(dut, intf, val);
9632 break;
9633 default:
9634 send_resp(dut, conn, SIGMA_ERROR,
9635 "ErrorCode,SGI20 not supported");
9636 return 0;
9637 }
9638 }
9639
9640 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
9641 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
9642 if (mcs32 && rate) {
9643 /* TODO */
9644 send_resp(dut, conn, SIGMA_ERROR,
9645 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
9646 return 0;
9647 } else if (mcs32 && !rate) {
9648 /* TODO */
9649 send_resp(dut, conn, SIGMA_ERROR,
9650 "ErrorCode,MCS32 not supported");
9651 return 0;
9652 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009653 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009654 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07009655 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009656 ath_sta_set_11nrates(dut, intf, rate);
9657 break;
9658 default:
9659 send_resp(dut, conn, SIGMA_ERROR,
9660 "ErrorCode,MCS32_FIXEDRATE not supported");
9661 return 0;
9662 }
9663 }
9664
9665 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9666}
9667
9668
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009669static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
9670 int mcs_config)
9671{
9672#ifdef NL80211_SUPPORT
9673 int ret;
9674
9675 switch (mcs_config) {
9676 case HE_80_MCS0_7:
9677 case HE_80_MCS0_9:
9678 case HE_80_MCS0_11:
9679 ret = sta_set_he_mcs(dut, intf, mcs_config);
9680 if (ret) {
9681 sigma_dut_print(dut, DUT_MSG_ERROR,
9682 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
9683 mcs_config, ret);
9684 }
9685 break;
9686 default:
9687 sigma_dut_print(dut, DUT_MSG_ERROR,
9688 "cmd_set_max_he_mcs: Invalid mcs %d",
9689 mcs_config);
9690 break;
9691 }
9692#else /* NL80211_SUPPORT */
9693 sigma_dut_print(dut, DUT_MSG_ERROR,
9694 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
9695#endif /* NL80211_SUPPORT */
9696}
9697
9698
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009699struct wait_event {
9700 struct sigma_dut *dut;
9701 int cmd;
9702 unsigned int twt_op;
9703};
9704
9705#ifdef NL80211_SUPPORT
9706
9707static int twt_event_handler(struct nl_msg *msg, void *arg)
9708{
9709 struct wait_event *wait = arg;
9710 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9711 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9712 uint32_t subcmd;
9713 uint8_t *data = NULL;
9714 size_t len = 0;
9715 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
9716 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
9717 int cmd_id;
9718 unsigned char val;
9719
9720 if (!wait)
9721 return NL_SKIP;
9722
9723 if (gnlh->cmd != NL80211_CMD_VENDOR) {
9724 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9725 "%s: NL cmd is not vendor %d", __func__,
9726 gnlh->cmd);
9727 return NL_SKIP;
9728 }
9729
9730 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9731 genlmsg_attrlen(gnlh, 0), NULL);
9732
9733 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
9734 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9735 "%s: vendor ID not found", __func__);
9736 return NL_SKIP;
9737 }
9738 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
9739
9740 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
9741 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9742 "%s: Not a TWT_cmd %d", __func__, subcmd);
9743 return NL_SKIP;
9744 }
9745 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9746 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
9747 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
9748 } else {
9749 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9750 "%s: vendor data not present", __func__);
9751 return NL_SKIP;
9752 }
9753 if (!data || !len) {
9754 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9755 "Invalid vendor data or len");
9756 return NL_SKIP;
9757 }
9758 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
9759 "event data len %ld", len);
9760 hex_dump(wait->dut, data, len);
9761 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
9762 (struct nlattr *) data, len, NULL)) {
9763 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9764 "vendor data parse error");
9765 return NL_SKIP;
9766 }
9767
9768 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
9769 if (val != wait->twt_op) {
9770 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9771 "Invalid TWT operation, expected %d, rcvd %d",
9772 wait->twt_op, val);
9773 return NL_SKIP;
9774 }
9775 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
9776 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
9777 NULL)) {
9778 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9779 "nla_parse failed for TWT event");
9780 return NL_SKIP;
9781 }
9782
9783 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
9784 if (!twt_status[cmd_id]) {
9785 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9786 "%s TWT resp status missing", __func__);
9787 wait->cmd = -1;
9788 } else {
9789 val = nla_get_u8(twt_status[cmd_id]);
9790 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
9791 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9792 "%s TWT resp status %d", __func__, val);
9793 wait->cmd = -1;
9794 } else {
9795 wait->cmd = 1;
9796 }
9797 }
9798
9799 return NL_SKIP;
9800}
9801
9802
9803static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
9804 unsigned int timeout)
9805{
9806 fd_set read_fd_set;
9807 int retval;
9808 int sock_fd;
9809 struct timeval time_out;
9810
9811 time_out.tv_sec = timeout;
9812 time_out.tv_usec = 0;
9813
9814 FD_ZERO(&read_fd_set);
9815
9816 if (!sock)
9817 return -1;
9818
9819 sock_fd = nl_socket_get_fd(sock);
9820 FD_SET(sock_fd, &read_fd_set);
9821
9822 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
9823
9824 if (retval == 0)
9825 sigma_dut_print(dut, DUT_MSG_ERROR,
9826 "%s: TWT event response timedout", __func__);
9827
9828 if (retval < 0)
9829 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
9830 __func__, retval);
9831
9832 return retval;
9833}
9834
9835
9836#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
9837
9838static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
9839{
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009840 struct nl_cb *cb = NULL;
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009841 int err_code = 0, select_retval = 0;
9842 struct wait_event wait_info;
9843
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009844 if (dut->nl_ctx->event_sock)
9845 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009846 if (!cb) {
9847 sigma_dut_print(dut, DUT_MSG_ERROR,
9848 "event callback not found");
9849 return ERROR_SEND_STATUS;
9850 }
9851
9852 wait_info.cmd = 0;
9853 wait_info.dut = dut;
9854 wait_info.twt_op = twt_op;
9855
9856 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
9857
9858 while (!wait_info.cmd) {
9859 select_retval = wait_on_nl_socket(
9860 dut->nl_ctx->event_sock, dut,
9861 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
9862
9863 if (select_retval > 0) {
9864 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
9865 if (err_code < 0) {
9866 sigma_dut_print(dut, DUT_MSG_ERROR,
9867 "%s: nl rcv failed, err_code %d",
9868 __func__, err_code);
9869 break;
9870 }
9871 } else {
9872 sigma_dut_print(dut, DUT_MSG_ERROR,
9873 "%s: wait on socket failed %d",
9874 __func__, select_retval);
9875 err_code = 1;
9876 break;
9877 }
9878
9879 }
9880 nl_cb_put(cb);
9881
9882 if (wait_info.cmd < 0)
9883 err_code = 1;
9884
9885 sigma_dut_print(dut, DUT_MSG_DEBUG,
9886 "%s: rcvd cmd %d, err_code %d, s_ret %d",
9887 __func__, wait_info.cmd, err_code, select_retval);
9888
9889 return err_code;
9890}
9891
9892#endif /* NL80211_SUPPORT */
9893
9894
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009895static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
9896 struct sigma_cmd *cmd)
9897{
9898#ifdef NL80211_SUPPORT
9899 struct nlattr *attr, *attr1;
9900 struct nl_msg *msg;
9901 int ifindex, ret;
9902 const char *intf = get_param(cmd, "Interface");
9903
9904 ifindex = if_nametoindex(intf);
9905 if (ifindex == 0) {
9906 sigma_dut_print(dut, DUT_MSG_ERROR,
9907 "%s: Index for interface %s failed",
9908 __func__, intf);
9909 return ERROR_SEND_STATUS;
9910 }
9911
9912 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9913 NL80211_CMD_VENDOR)) ||
9914 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9915 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9916 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9917 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9918 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9919 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9920 QCA_WLAN_TWT_SUSPEND) ||
9921 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07009922 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009923 sigma_dut_print(dut, DUT_MSG_ERROR,
9924 "%s: err in adding vendor_cmd and vendor_data",
9925 __func__);
9926 nlmsg_free(msg);
9927 return ERROR_SEND_STATUS;
9928 }
9929 nla_nest_end(msg, attr1);
9930 nla_nest_end(msg, attr);
9931
9932 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9933 if (ret) {
9934 sigma_dut_print(dut, DUT_MSG_ERROR,
9935 "%s: err in send_and_recv_msgs, ret=%d",
9936 __func__, ret);
9937 }
9938
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009939 if (!dut->sta_async_twt_supp)
9940 return ret;
9941
9942 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009943#else /* NL80211_SUPPORT */
9944 sigma_dut_print(dut, DUT_MSG_ERROR,
9945 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9946 return ERROR_SEND_STATUS;
9947#endif /* NL80211_SUPPORT */
9948}
9949
9950
9951static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
9952 struct sigma_cmd *cmd,
9953 unsigned int suspend_duration)
9954{
9955#ifdef NL80211_SUPPORT
9956 struct nlattr *attr, *attr1;
9957 struct nl_msg *msg;
9958 int ifindex, ret;
9959 const char *intf = get_param(cmd, "Interface");
9960 int next_twt_size = 1;
9961
9962 ifindex = if_nametoindex(intf);
9963 if (ifindex == 0) {
9964 sigma_dut_print(dut, DUT_MSG_ERROR,
9965 "%s: Index for interface %s failed",
9966 __func__, intf);
9967 return ERROR_SEND_STATUS;
9968 }
9969
9970 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9971 NL80211_CMD_VENDOR)) ||
9972 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9973 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9974 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9975 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9976 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9977 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9978 QCA_WLAN_TWT_NUDGE) ||
9979 !(attr1 = nla_nest_start(msg,
9980 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
9981 (suspend_duration &&
9982 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
9983 suspend_duration)) ||
9984 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009985 next_twt_size) ||
9986 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009987 sigma_dut_print(dut, DUT_MSG_ERROR,
9988 "%s: err in adding vendor_cmd and vendor_data",
9989 __func__);
9990 nlmsg_free(msg);
9991 return ERROR_SEND_STATUS;
9992 }
9993 nla_nest_end(msg, attr1);
9994 nla_nest_end(msg, attr);
9995
9996 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9997 if (ret) {
9998 sigma_dut_print(dut, DUT_MSG_ERROR,
9999 "%s: err in send_and_recv_msgs, ret=%d",
10000 __func__, ret);
10001 }
10002
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010003 if (!dut->sta_async_twt_supp)
10004 return ret;
10005
10006 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010007#else /* NL80211_SUPPORT */
10008 sigma_dut_print(dut, DUT_MSG_ERROR,
10009 "TWT suspend cannot be done without NL80211_SUPPORT defined");
10010 return ERROR_SEND_STATUS;
10011#endif /* NL80211_SUPPORT */
10012}
10013
10014
10015static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
10016 struct sigma_conn *conn,
10017 struct sigma_cmd *cmd)
10018{
10019 const char *val;
10020
10021 val = get_param(cmd, "TWT_SuspendDuration");
10022 if (val) {
10023 unsigned int suspend_duration;
10024
10025 suspend_duration = atoi(val);
10026 suspend_duration = suspend_duration * 1000 * 1000;
10027 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
10028 }
10029
10030 return sta_twt_send_suspend(dut, conn, cmd);
10031}
10032
10033
10034static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
10035 struct sigma_cmd *cmd)
10036{
10037#ifdef NL80211_SUPPORT
10038 struct nlattr *attr, *attr1;
10039 struct nl_msg *msg;
10040 int ifindex, ret;
10041 const char *intf = get_param(cmd, "Interface");
10042 int next2_twt_size = 1;
10043 unsigned int resume_duration = 0;
10044 const char *val;
10045
10046 ifindex = if_nametoindex(intf);
10047 if (ifindex == 0) {
10048 sigma_dut_print(dut, DUT_MSG_ERROR,
10049 "%s: Index for interface %s failed",
10050 __func__, intf);
10051 return ERROR_SEND_STATUS;
10052 }
10053
10054 val = get_param(cmd, "TWT_ResumeDuration");
10055 if (val) {
10056 resume_duration = atoi(val);
10057 resume_duration = resume_duration * 1000 * 1000;
10058 }
10059
10060 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10061 NL80211_CMD_VENDOR)) ||
10062 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10063 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10064 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10065 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10066 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10067 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10068 QCA_WLAN_TWT_RESUME) ||
10069 !(attr1 = nla_nest_start(msg,
10070 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10071 (resume_duration &&
10072 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
10073 resume_duration)) ||
10074 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
10075 next2_twt_size)) {
10076 sigma_dut_print(dut, DUT_MSG_ERROR,
10077 "%s: err in adding vendor_cmd and vendor_data",
10078 __func__);
10079 nlmsg_free(msg);
10080 return ERROR_SEND_STATUS;
10081 }
10082 nla_nest_end(msg, attr1);
10083 nla_nest_end(msg, attr);
10084
10085 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10086 if (ret) {
10087 sigma_dut_print(dut, DUT_MSG_ERROR,
10088 "%s: err in send_and_recv_msgs, ret=%d",
10089 __func__, ret);
10090 }
10091
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010092 if (!dut->sta_async_twt_supp)
10093 return ret;
10094
10095 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010096#else /* NL80211_SUPPORT */
10097 sigma_dut_print(dut, DUT_MSG_ERROR,
10098 "TWT resume cannot be done without NL80211_SUPPORT defined");
10099 return ERROR_SEND_STATUS;
10100#endif /* NL80211_SUPPORT */
10101}
10102
10103
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010104#define TWT_REQUEST_CMD 0
10105#define TWT_SUGGEST_CMD 1
10106#define TWT_DEMAND_CMD 2
10107
Arif Hussain480d5f42019-03-12 14:40:42 -070010108static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
10109 struct sigma_cmd *cmd)
10110{
10111#ifdef NL80211_SUPPORT
10112 struct nlattr *params;
10113 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010114 struct nl_msg *msg;
10115 int ifindex, ret;
10116 const char *val;
10117 const char *intf = get_param(cmd, "Interface");
10118 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
10119 wake_interval_mantissa = 512;
10120 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010121 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010122 int bcast_twt = 0;
10123 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -070010124
10125 ifindex = if_nametoindex(intf);
10126 if (ifindex == 0) {
10127 sigma_dut_print(dut, DUT_MSG_ERROR,
10128 "%s: Index for interface %s failed",
10129 __func__, intf);
10130 return -1;
10131 }
10132
10133 val = get_param(cmd, "FlowType");
10134 if (val) {
10135 flow_type = atoi(val);
10136 if (flow_type != 0 && flow_type != 1) {
10137 sigma_dut_print(dut, DUT_MSG_ERROR,
10138 "TWT: Invalid FlowType %d", flow_type);
10139 return -1;
10140 }
10141 }
10142
10143 val = get_param(cmd, "TWT_Trigger");
10144 if (val) {
10145 twt_trigger = atoi(val);
10146 if (twt_trigger != 0 && twt_trigger != 1) {
10147 sigma_dut_print(dut, DUT_MSG_ERROR,
10148 "TWT: Invalid TWT_Trigger %d",
10149 twt_trigger);
10150 return -1;
10151 }
10152 }
10153
10154 val = get_param(cmd, "Protection");
10155 if (val) {
10156 protection = atoi(val);
10157 if (protection != 0 && protection != 1) {
10158 sigma_dut_print(dut, DUT_MSG_ERROR,
10159 "TWT: Invalid Protection %d",
10160 protection);
10161 return -1;
10162 }
10163 }
10164
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010165 val = get_param(cmd, "SetupCommand");
10166 if (val) {
10167 cmd_type = atoi(val);
10168 if (cmd_type == TWT_REQUEST_CMD)
10169 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
10170 else if (cmd_type == TWT_SUGGEST_CMD)
10171 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
10172 else if (cmd_type == TWT_DEMAND_CMD)
10173 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
10174 else
10175 sigma_dut_print(dut, DUT_MSG_ERROR,
10176 "Default suggest is used for cmd %d",
10177 cmd_type);
10178 }
10179
Arif Hussain480d5f42019-03-12 14:40:42 -070010180 val = get_param(cmd, "TargetWakeTime");
10181 if (val)
10182 target_wake_time = atoi(val);
10183
10184 val = get_param(cmd, "WakeIntervalMantissa");
10185 if (val)
10186 wake_interval_mantissa = atoi(val);
10187
10188 val = get_param(cmd, "WakeIntervalExp");
10189 if (val)
10190 wake_interval_exp = atoi(val);
10191
10192 val = get_param(cmd, "NominalMinWakeDur");
10193 if (val)
10194 nominal_min_wake_dur = atoi(val);
10195
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010196 val = get_param(cmd, "BTWT_ID");
10197 if (val) {
10198 bcast_twt_id = atoi(val);
10199 bcast_twt = 1;
10200 }
10201
10202 val = get_param(cmd, "BTWT_Persistence");
10203 if (val) {
10204 bcast_twt_persis = atoi(val);
10205 bcast_twt = 1;
10206 }
10207
10208 val = get_param(cmd, "BTWT_Recommendation");
10209 if (val) {
10210 bcast_twt_recommdn = atoi(val);
10211 bcast_twt = 1;
10212 }
10213
10214 if (bcast_twt)
10215 sigma_dut_print(dut, DUT_MSG_DEBUG,
10216 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
10217 bcast_twt_id, bcast_twt_recommdn,
10218 bcast_twt_persis);
10219
Arif Hussain480d5f42019-03-12 14:40:42 -070010220 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10221 NL80211_CMD_VENDOR)) ||
10222 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10223 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10224 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010225 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010226 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010227 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10228 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010229 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010230 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010231 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
10232 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010233 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010234 (twt_trigger &&
10235 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010236 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
10237 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010238 (protection &&
10239 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010240 (bcast_twt &&
10241 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10242 (bcast_twt &&
10243 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10244 bcast_twt_id)) ||
10245 (bcast_twt &&
10246 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
10247 bcast_twt_persis)) ||
10248 (bcast_twt &&
10249 nla_put_u8(msg,
10250 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
10251 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010252 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
10253 target_wake_time) ||
10254 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
10255 nominal_min_wake_dur) ||
10256 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
10257 wake_interval_mantissa)) {
10258 sigma_dut_print(dut, DUT_MSG_ERROR,
10259 "%s: err in adding vendor_cmd and vendor_data",
10260 __func__);
10261 nlmsg_free(msg);
10262 return -1;
10263 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010264 nla_nest_end(msg, params);
10265 nla_nest_end(msg, attr);
10266
10267 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10268 if (ret) {
10269 sigma_dut_print(dut, DUT_MSG_ERROR,
10270 "%s: err in send_and_recv_msgs, ret=%d",
10271 __func__, ret);
10272 }
10273
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010274 if (!dut->sta_async_twt_supp)
10275 return ret;
10276
10277 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -070010278#else /* NL80211_SUPPORT */
10279 sigma_dut_print(dut, DUT_MSG_ERROR,
10280 "TWT request cannot be done without NL80211_SUPPORT defined");
10281 return -1;
10282#endif /* NL80211_SUPPORT */
10283}
10284
10285
10286static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
10287 struct sigma_cmd *cmd)
10288{
10289 #ifdef NL80211_SUPPORT
10290 struct nlattr *params;
10291 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010292 int ifindex, ret;
10293 struct nl_msg *msg;
10294 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010295 int bcast_twt = 0;
10296 int bcast_twt_id = 0;
10297 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -070010298
10299 ifindex = if_nametoindex(intf);
10300 if (ifindex == 0) {
10301 sigma_dut_print(dut, DUT_MSG_ERROR,
10302 "%s: Index for interface %s failed",
10303 __func__, intf);
10304 return -1;
10305 }
10306
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010307 val = get_param(cmd, "BTWT_ID");
10308 if (val) {
10309 bcast_twt_id = atoi(val);
10310 bcast_twt = 1;
10311 }
10312
Arif Hussain480d5f42019-03-12 14:40:42 -070010313 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10314 NL80211_CMD_VENDOR)) ||
10315 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10316 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10317 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010318 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010319 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010320 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10321 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010322 !(params = nla_nest_start(
10323 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010324 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010325 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
10326 (bcast_twt &&
10327 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10328 (bcast_twt &&
10329 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10330 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -070010331 sigma_dut_print(dut, DUT_MSG_ERROR,
10332 "%s: err in adding vendor_cmd and vendor_data",
10333 __func__);
10334 nlmsg_free(msg);
10335 return -1;
10336 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010337 nla_nest_end(msg, params);
10338 nla_nest_end(msg, attr);
10339
10340 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10341 if (ret) {
10342 sigma_dut_print(dut, DUT_MSG_ERROR,
10343 "%s: err in send_and_recv_msgs, ret=%d",
10344 __func__, ret);
10345 }
10346
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010347 if (!dut->sta_async_twt_supp)
10348 return ret;
10349
10350 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -070010351#else /* NL80211_SUPPORT */
10352 sigma_dut_print(dut, DUT_MSG_ERROR,
10353 "TWT teardown cannot be done without NL80211_SUPPORT defined");
10354 return -1;
10355#endif /* NL80211_SUPPORT */
10356}
10357
10358
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080010359static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
10360 struct sigma_cmd *cmd)
10361{
10362#ifdef NL80211_SUPPORT
10363 struct nlattr *params;
10364 struct nlattr *attr;
10365 struct nlattr *attr1;
10366 struct nl_msg *msg;
10367 int ifindex, ret;
10368 const char *val;
10369 const char *intf = get_param(cmd, "Interface");
10370 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
10371 ulmu_data_dis = 0;
10372
10373 ifindex = if_nametoindex(intf);
10374 if (ifindex == 0) {
10375 sigma_dut_print(dut, DUT_MSG_ERROR,
10376 "%s: Index for interface %s failed",
10377 __func__, intf);
10378 return -1;
10379 }
10380 val = get_param(cmd, "OMCtrl_RxNSS");
10381 if (val)
10382 rx_nss = atoi(val);
10383
10384 val = get_param(cmd, "OMCtrl_ChnlWidth");
10385 if (val)
10386 ch_bw = atoi(val);
10387
10388 val = get_param(cmd, "OMCtrl_ULMUDisable");
10389 if (val)
10390 ulmu_dis = atoi(val);
10391
10392 val = get_param(cmd, "OMCtrl_TxNSTS");
10393 if (val)
10394 tx_nsts = atoi(val);
10395
10396 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
10397 if (val)
10398 ulmu_data_dis = atoi(val);
10399
10400 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10401 NL80211_CMD_VENDOR)) ||
10402 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10403 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10404 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10405 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10406 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10407 !(params = nla_nest_start(
10408 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
10409 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10410 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
10411 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
10412 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
10413 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
10414 ulmu_data_dis) ||
10415 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
10416 ulmu_dis)) {
10417 sigma_dut_print(dut, DUT_MSG_ERROR,
10418 "%s: err in adding vendor_cmd and vendor_data",
10419 __func__);
10420 nlmsg_free(msg);
10421 return -1;
10422 }
10423 nla_nest_end(msg, attr1);
10424 nla_nest_end(msg, params);
10425 nla_nest_end(msg, attr);
10426
10427 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10428 if (ret) {
10429 sigma_dut_print(dut, DUT_MSG_ERROR,
10430 "%s: err in send_and_recv_msgs, ret=%d",
10431 __func__, ret);
10432 }
10433
10434 return ret;
10435#else /* NL80211_SUPPORT */
10436 sigma_dut_print(dut, DUT_MSG_ERROR,
10437 "OMI TX cannot be processed without NL80211_SUPPORT defined");
10438 return -1;
10439#endif /* NL80211_SUPPORT */
10440}
10441
10442
Jouni Malinen224e3902021-06-09 16:41:27 +030010443static enum sigma_cmd_result
10444cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10445 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010446{
10447 const char *intf = get_param(cmd, "Interface");
10448 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -070010449 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010450 int tkip = -1;
10451 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010452 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010453
Arif Hussaina37e9552018-06-20 17:05:59 -070010454 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010455 val = get_param(cmd, "SGI80");
10456 if (val) {
10457 int sgi80;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010458 enum nl80211_txrate_gi gi_val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010459
10460 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010461 if (sgi80)
10462 gi_val = NL80211_TXRATE_FORCE_LGI;
10463 else
10464 gi_val = NL80211_TXRATE_FORCE_SGI;
10465 if (sta_set_vht_gi(dut, intf, (u8) gi_val)) {
10466 sigma_dut_print(dut, DUT_MSG_INFO,
10467 "sta_set_vht_gi failed, using iwpriv");
10468 run_iwpriv(dut, intf, "shortgi %d", sgi80);
10469 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010470 }
10471
10472 val = get_param(cmd, "TxBF");
10473 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010474 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010475 case DRIVER_WCN:
10476 if (sta_set_tx_beamformee(dut, intf, 1)) {
10477 send_resp(dut, conn, SIGMA_ERROR,
10478 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010479 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010480 }
10481 break;
10482 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010483 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010484 send_resp(dut, conn, SIGMA_ERROR,
10485 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010486 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010487 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010488 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010489 send_resp(dut, conn, SIGMA_ERROR,
10490 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010491 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010492 }
10493 break;
10494 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010495 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010496 "Unsupported driver type");
10497 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010498 }
10499 }
10500
10501 val = get_param(cmd, "MU_TxBF");
10502 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010503 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010504 case DRIVER_ATHEROS:
10505 ath_sta_set_txsp_stream(dut, intf, "1SS");
10506 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010507 run_iwpriv(dut, intf, "vhtmubfee 1");
10508 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +053010509 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010510 case DRIVER_WCN:
10511 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
10512 send_resp(dut, conn, SIGMA_ERROR,
10513 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +030010514 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010515 }
Sunil Duttae9e5d12018-06-29 11:50:47 +053010516 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010517 default:
10518 sigma_dut_print(dut, DUT_MSG_ERROR,
10519 "Setting SP_STREAM not supported");
10520 break;
10521 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010522 }
10523
10524 val = get_param(cmd, "LDPC");
10525 if (val) {
10526 int ldpc;
10527
10528 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010529 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
10530 if (iwpriv_status)
10531 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010532 }
10533
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010534 val = get_param(cmd, "BCC");
10535 if (val) {
10536 int bcc;
10537
10538 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10539 /* use LDPC iwpriv itself to set bcc coding, bcc coding
10540 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010541 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
10542 if (iwpriv_status)
10543 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010544 }
10545
Arif Hussain7b47d2d2018-05-09 10:44:02 -070010546 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
10547 if (val && dut->sta_nss == 1)
10548 cmd_set_max_he_mcs(dut, intf, atoi(val));
10549
10550 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
10551 if (val && dut->sta_nss == 2)
10552 cmd_set_max_he_mcs(dut, intf, atoi(val));
10553
Arif Hussainac6c5112018-05-25 17:34:00 -070010554 val = get_param(cmd, "MCS_FixedRate");
10555 if (val) {
10556#ifdef NL80211_SUPPORT
10557 int mcs, ratecode = 0;
10558 enum he_mcs_config mcs_config;
10559 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +030010560 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -070010561
10562 ratecode = (0x07 & dut->sta_nss) << 5;
10563 mcs = atoi(val);
10564 /* Add the MCS to the ratecode */
10565 if (mcs >= 0 && mcs <= 11) {
10566 ratecode += mcs;
10567 if (dut->device_type == STA_testbed &&
10568 mcs > 7 && mcs <= 11) {
10569 if (mcs <= 9)
10570 mcs_config = HE_80_MCS0_9;
10571 else
10572 mcs_config = HE_80_MCS0_11;
10573 ret = sta_set_he_mcs(dut, intf, mcs_config);
10574 if (ret) {
10575 sigma_dut_print(dut, DUT_MSG_ERROR,
10576 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10577 mcs, mcs_config, ret);
10578 }
10579 }
10580 snprintf(buf, sizeof(buf),
10581 "iwpriv %s set_11ax_rate 0x%03x",
10582 intf, ratecode);
10583 if (system(buf) != 0) {
10584 sigma_dut_print(dut, DUT_MSG_ERROR,
10585 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
10586 ratecode);
10587 }
10588 } else {
10589 sigma_dut_print(dut, DUT_MSG_ERROR,
10590 "MCS_FixedRate: HE MCS %d not supported",
10591 mcs);
10592 }
10593#else /* NL80211_SUPPORT */
10594 sigma_dut_print(dut, DUT_MSG_ERROR,
10595 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
10596#endif /* NL80211_SUPPORT */
10597 }
10598
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010599 val = get_param(cmd, "opt_md_notif_ie");
10600 if (val) {
10601 char *result = NULL;
10602 char delim[] = ";";
10603 char token[30];
10604 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010605 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010606
Peng Xub8fc5cc2017-05-10 17:27:28 -070010607 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010608 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010609
10610 /* Extract the NSS information */
10611 if (result) {
10612 value = atoi(result);
10613 switch (value) {
10614 case 1:
10615 config_val = 1;
10616 break;
10617 case 2:
10618 config_val = 3;
10619 break;
10620 case 3:
10621 config_val = 7;
10622 break;
10623 case 4:
10624 config_val = 15;
10625 break;
10626 default:
10627 config_val = 3;
10628 break;
10629 }
10630
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010631 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
10632 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010633
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010634 }
10635
10636 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010637 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010638 if (result) {
10639 value = atoi(result);
10640 switch (value) {
10641 case 20:
10642 config_val = 0;
10643 break;
10644 case 40:
10645 config_val = 1;
10646 break;
10647 case 80:
10648 config_val = 2;
10649 break;
10650 case 160:
10651 config_val = 3;
10652 break;
10653 default:
10654 config_val = 2;
10655 break;
10656 }
10657
10658 dut->chwidth = config_val;
10659
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010660 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010661 }
10662
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010663 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010664 }
10665
10666 val = get_param(cmd, "nss_mcs_cap");
10667 if (val) {
10668 int nss, mcs;
10669 char token[20];
10670 char *result = NULL;
10671 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010672 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010673
Peng Xub8fc5cc2017-05-10 17:27:28 -070010674 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010675 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010676 if (!result) {
10677 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010678 "NSS not specified");
10679 send_resp(dut, conn, SIGMA_ERROR,
10680 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010681 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010682 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010683 nss = atoi(result);
10684
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010685 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -070010686 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010687
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010688 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010689 if (result == NULL) {
10690 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010691 "MCS not specified");
10692 send_resp(dut, conn, SIGMA_ERROR,
10693 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010694 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010695 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010696 result = strtok_r(result, "-", &saveptr);
10697 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010698 if (!result) {
10699 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010700 "MCS not specified");
10701 send_resp(dut, conn, SIGMA_ERROR,
10702 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010703 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010704 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010705 mcs = atoi(result);
10706
Arif Hussaina37e9552018-06-20 17:05:59 -070010707 if (program && strcasecmp(program, "HE") == 0) {
10708#ifdef NL80211_SUPPORT
10709 enum he_mcs_config mcs_config;
10710 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010711
Arif Hussaina37e9552018-06-20 17:05:59 -070010712 if (mcs >= 0 && mcs <= 7) {
10713 mcs_config = HE_80_MCS0_7;
10714 } else if (mcs > 7 && mcs <= 9) {
10715 mcs_config = HE_80_MCS0_9;
10716 } else if (mcs > 9 && mcs <= 11) {
10717 mcs_config = HE_80_MCS0_11;
10718 } else {
10719 sigma_dut_print(dut, DUT_MSG_ERROR,
10720 "nss_mcs_cap: HE: Invalid mcs: %d",
10721 mcs);
10722 send_resp(dut, conn, SIGMA_ERROR,
10723 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010724 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010725 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010726
10727 ret = sta_set_he_mcs(dut, intf, mcs_config);
10728 if (ret) {
10729 sigma_dut_print(dut, DUT_MSG_ERROR,
10730 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
10731 mcs_config, ret);
10732 send_resp(dut, conn, SIGMA_ERROR,
10733 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010734 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010735 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010736#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010737 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010738 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
10739#endif /* NL80211_SUPPORT */
10740 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010741 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -070010742
10743 switch (nss) {
10744 case 1:
10745 switch (mcs) {
10746 case 7:
10747 vht_mcsmap = 0xfffc;
10748 break;
10749 case 8:
10750 vht_mcsmap = 0xfffd;
10751 break;
10752 case 9:
10753 vht_mcsmap = 0xfffe;
10754 break;
10755 default:
10756 vht_mcsmap = 0xfffe;
10757 break;
10758 }
10759 break;
10760 case 2:
10761 switch (mcs) {
10762 case 7:
10763 vht_mcsmap = 0xfff0;
10764 break;
10765 case 8:
10766 vht_mcsmap = 0xfff5;
10767 break;
10768 case 9:
10769 vht_mcsmap = 0xfffa;
10770 break;
10771 default:
10772 vht_mcsmap = 0xfffa;
10773 break;
10774 }
10775 break;
10776 case 3:
10777 switch (mcs) {
10778 case 7:
10779 vht_mcsmap = 0xffc0;
10780 break;
10781 case 8:
10782 vht_mcsmap = 0xffd5;
10783 break;
10784 case 9:
10785 vht_mcsmap = 0xffea;
10786 break;
10787 default:
10788 vht_mcsmap = 0xffea;
10789 break;
10790 }
10791 break;
10792 default:
10793 vht_mcsmap = 0xffea;
10794 break;
10795 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010796 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010797 }
10798 }
10799
10800 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
10801
10802 val = get_param(cmd, "Vht_tkip");
10803 if (val)
10804 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10805
10806 val = get_param(cmd, "Vht_wep");
10807 if (val)
10808 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10809
10810 if (tkip != -1 || wep != -1) {
10811 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010812 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010813 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010814 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010815 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +030010816 send_resp(dut, conn, SIGMA_ERROR,
10817 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
10818 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010819 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010820 }
10821
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -070010822 val = get_param(cmd, "TWTSchedSTASupport");
10823 if (val) {
10824 int set_val;
10825
10826 switch (get_driver_type(dut)) {
10827 case DRIVER_WCN:
10828 if (strcasecmp(val, "Enable") == 0) {
10829 set_val = 1;
10830 } else if (strcasecmp(val, "Disable") == 0) {
10831 set_val = 0;
10832 } else {
10833 send_resp(dut, conn, SIGMA_ERROR,
10834 "ErrorCode,Invalid TWTSchedSTASupport");
10835 return STATUS_SENT_ERROR;
10836 }
10837
10838 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
10839 send_resp(dut, conn, SIGMA_ERROR,
10840 "ErrorCode,Failed to set TWTSchedSTASupport");
10841 return STATUS_SENT_ERROR;
10842 }
10843 break;
10844 default:
10845 sigma_dut_print(dut, DUT_MSG_ERROR,
10846 "Setting TWTSchedSTASupport not supported");
10847 break;
10848 }
10849 }
10850
10851 val = get_param(cmd, "MBSSID_RxCtrl");
10852 if (val) {
10853 int set_val;
10854
10855 switch (get_driver_type(dut)) {
10856 case DRIVER_WCN:
10857 if (strcasecmp(val, "Enable") == 0) {
10858 set_val = 1;
10859 } else if (strcasecmp(val, "Disable") == 0) {
10860 set_val = 0;
10861 } else {
10862 send_resp(dut, conn, SIGMA_ERROR,
10863 "ErrorCode,Invalid MBSSID_RxCtrl");
10864 return STATUS_SENT_ERROR;
10865 }
10866
10867 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
10868 send_resp(dut, conn, SIGMA_ERROR,
10869 "ErrorCode,Failed to set MBSSID_RxCtrl");
10870 return STATUS_SENT_ERROR;
10871 }
10872 break;
10873 default:
10874 sigma_dut_print(dut, DUT_MSG_ERROR,
10875 "Setting MBSSID_RxCtrl not supported");
10876 break;
10877 }
10878 }
10879
Arif Hussain55f00da2018-07-03 08:28:26 -070010880 val = get_param(cmd, "txBandwidth");
10881 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010882 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -070010883 case DRIVER_WCN:
10884 if (wcn_sta_set_width(dut, intf, val) < 0) {
10885 send_resp(dut, conn, SIGMA_ERROR,
10886 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010887 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010888 }
10889 break;
10890 case DRIVER_ATHEROS:
10891 if (ath_set_width(dut, conn, intf, val) < 0) {
10892 send_resp(dut, conn, SIGMA_ERROR,
10893 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010894 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010895 }
10896 break;
10897 default:
10898 sigma_dut_print(dut, DUT_MSG_ERROR,
10899 "Setting txBandwidth not supported");
10900 break;
10901 }
10902 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010903
Arif Hussain9765f7d2018-07-03 08:28:26 -070010904 val = get_param(cmd, "BeamformeeSTS");
10905 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010906 if (sta_set_tx_beamformee(dut, intf, 1)) {
10907 send_resp(dut, conn, SIGMA_ERROR,
10908 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010909 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010910 }
10911
Arif Hussain9765f7d2018-07-03 08:28:26 -070010912 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
10913 send_resp(dut, conn, SIGMA_ERROR,
10914 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010915 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -070010916 }
10917 }
10918
Arif Hussain68d23f52018-07-11 13:39:08 -070010919 val = get_param(cmd, "Trig_MAC_Padding_Dur");
10920 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010921#ifdef NL80211_SUPPORT
10922 enum qca_wlan_he_mac_padding_dur set_val;
10923
10924 switch (atoi(val)) {
10925 case 16:
10926 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
10927 break;
10928 case 8:
10929 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
10930 break;
10931 default:
10932 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
10933 break;
10934 }
10935 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -070010936 send_resp(dut, conn, SIGMA_ERROR,
10937 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +030010938 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -070010939 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010940#else /* NL80211_SUPPORT */
10941 sigma_dut_print(dut, DUT_MSG_ERROR,
10942 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
10943#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -070010944 }
10945
Arif Hussain480d5f42019-03-12 14:40:42 -070010946 val = get_param(cmd, "TWT_ReqSupport");
10947 if (val) {
10948 int set_val;
10949
10950 if (strcasecmp(val, "Enable") == 0) {
10951 set_val = 1;
10952 } else if (strcasecmp(val, "Disable") == 0) {
10953 set_val = 0;
10954 } else {
10955 send_resp(dut, conn, SIGMA_ERROR,
10956 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010957 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010958 }
10959
10960 if (sta_set_twt_req_support(dut, intf, set_val)) {
10961 sigma_dut_print(dut, DUT_MSG_ERROR,
10962 "Failed to set TWT req support %d",
10963 set_val);
10964 send_resp(dut, conn, SIGMA_ERROR,
10965 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010966 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010967 }
10968 }
10969
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -070010970 val = get_param(cmd, "PreamblePunctRx");
10971 if (val && get_driver_type(dut) == DRIVER_WCN) {
10972 int set_val;
10973
10974 if (strcasecmp(val, "Enable") == 0) {
10975 set_val = 1;
10976 } else if (strcasecmp(val, "Disable") == 0) {
10977 set_val = 0;
10978 } else {
10979 send_resp(dut, conn, SIGMA_ERROR,
10980 "ErrorCode,Invalid PreamblePunctRx");
10981 return STATUS_SENT_ERROR;
10982 }
10983
10984 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
10985 sigma_dut_print(dut, DUT_MSG_ERROR,
10986 "Failed to set PreamblePunctRx support %d",
10987 set_val);
10988 send_resp(dut, conn, SIGMA_ERROR,
10989 "ErrorCode,Failed to set PreamblePunctRx");
10990 return STATUS_SENT_ERROR;
10991 }
10992 }
10993
Srinivas Girigowda0525e292020-11-12 13:28:21 -080010994 val = get_param(cmd, "FullBW_ULMUMIMO");
10995 if (val) {
10996 int set_val;
10997
10998 if (strcasecmp(val, "Enable") == 0) {
10999 set_val = 1;
11000 } else if (strcasecmp(val, "Disable") == 0) {
11001 set_val = 0;
11002 } else {
11003 send_resp(dut, conn, SIGMA_ERROR,
11004 "ErrorCode,Invalid FullBW_ULMUMIMO");
11005 return STATUS_SENT_ERROR;
11006 }
11007
11008 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
11009 sigma_dut_print(dut, DUT_MSG_ERROR,
11010 "Failed to set FullBW_ULMUMIMO %d",
11011 set_val);
11012 send_resp(dut, conn, SIGMA_ERROR,
11013 "ErrorCode,Failed to set FullBW_ULMUMIMO");
11014 return STATUS_SENT_ERROR;
11015 }
11016 }
11017
Srinivas Girigowda6707f032020-10-26 15:24:46 -070011018 val = get_param(cmd, "TWTInfoFrameTx");
11019 if (val) {
11020 if (strcasecmp(val, "Enable") == 0) {
11021 /* No-op */
11022 } else if (strcasecmp(val, "Disable") == 0) {
11023 /* No-op */
11024 } else {
11025 send_resp(dut, conn, SIGMA_ERROR,
11026 "ErrorCode,Invalid TWTInfoFrameTx");
11027 return STATUS_SENT_ERROR;
11028 }
11029 }
11030
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011031 val = get_param(cmd, "MU_EDCA");
11032 if (val && (strcasecmp(val, "Override") == 0)) {
11033 if (sta_set_mu_edca_override(dut, intf, 1)) {
11034 send_resp(dut, conn, SIGMA_ERROR,
11035 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +030011036 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011037 }
11038 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011039
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070011040 val = get_param(cmd, "PPDUTxType");
11041 if (val && strcasecmp(val, "ER-SU") == 0) {
11042 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
11043 send_resp(dut, conn, SIGMA_ERROR,
11044 "ErrorCode,Failed to set ER-SU PPDU type Tx");
11045 return STATUS_SENT_ERROR;
11046 }
11047 }
11048
11049 val = get_param(cmd, "RUAllocTone");
11050 if (val && strcasecmp(val, "242") == 0) {
11051 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
11052 send_resp(dut, conn, SIGMA_ERROR,
11053 "ErrorCode,Failed to set RU 242 tone Tx");
11054 return STATUS_SENT_ERROR;
11055 }
11056 }
11057
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011058 val = get_param(cmd, "OMControl");
11059 if (val) {
11060 int set_val = 1;
11061
11062 if (strcasecmp(val, "Enable") == 0)
11063 set_val = 1;
11064 else if (strcasecmp(val, "Disable") == 0)
11065 set_val = 0;
11066
11067 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
11068 send_resp(dut, conn, SIGMA_ERROR,
11069 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +030011070 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011071 }
11072 }
11073
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -070011074 val = get_param(cmd, "BSSMaxIdlePeriod");
11075 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
11076 send_resp(dut, conn, SIGMA_ERROR,
11077 "ErrorCode,Failed to set BSS max idle period");
11078 return STATUS_SENT_ERROR;
11079 }
11080
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -070011081 val = get_param(cmd, "BSS_max_idle");
11082 if (val) {
11083 int set_val = 0;
11084
11085 if (strcasecmp(val, "Enable") == 0)
11086 set_val = 1;
11087 else if (strcasecmp(val, "Disable") == 0)
11088 set_val = 0;
11089 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
11090 send_resp(dut, conn, SIGMA_ERROR,
11091 "ErrorCode,Failed to set BSS max idle support");
11092 return STATUS_SENT_ERROR;
11093 }
11094 }
11095
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011096 val = get_param(cmd, "ADDBAResp_BufSize");
11097 if (val) {
11098 int buf_size;
11099
11100 if (strcasecmp(val, "gt64") == 0)
11101 buf_size = 256;
11102 else
11103 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011104 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011105 sta_set_addba_buf_size(dut, intf, buf_size)) {
11106 send_resp(dut, conn, SIGMA_ERROR,
11107 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011108 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011109 }
11110 }
11111
11112 val = get_param(cmd, "ADDBAReq_BufSize");
11113 if (val) {
11114 int buf_size;
11115
11116 if (strcasecmp(val, "gt64") == 0)
11117 buf_size = 256;
11118 else
11119 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011120 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011121 sta_set_addba_buf_size(dut, intf, buf_size)) {
11122 send_resp(dut, conn, SIGMA_ERROR,
11123 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011124 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011125 }
11126 }
11127
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011128 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11129}
11130
11131
11132static int sta_set_wireless_60g(struct sigma_dut *dut,
11133 struct sigma_conn *conn,
11134 struct sigma_cmd *cmd)
11135{
11136 const char *dev_role = get_param(cmd, "DevRole");
11137
11138 if (!dev_role) {
11139 send_resp(dut, conn, SIGMA_INVALID,
11140 "ErrorCode,DevRole not specified");
11141 return 0;
11142 }
11143
11144 if (strcasecmp(dev_role, "PCP") == 0)
11145 return sta_set_60g_pcp(dut, conn, cmd);
11146 if (strcasecmp(dev_role, "STA") == 0)
11147 return sta_set_60g_sta(dut, conn, cmd);
11148 send_resp(dut, conn, SIGMA_INVALID,
11149 "ErrorCode,DevRole not supported");
11150 return 0;
11151}
11152
11153
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011154static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
11155 struct sigma_cmd *cmd)
11156{
11157 int status;
11158 const char *intf = get_param(cmd, "Interface");
11159 const char *val = get_param(cmd, "DevRole");
11160
11161 if (val && strcasecmp(val, "STA-CFON") == 0) {
11162 status = sta_cfon_set_wireless(dut, conn, cmd);
11163 if (status)
11164 return status;
11165 }
11166 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11167}
11168
11169
Jouni Malinen67433fc2020-06-26 22:50:33 +030011170static enum sigma_cmd_result
11171sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
11172 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011173{
11174 const char *intf = get_param(cmd, "Interface");
11175 const char *val;
11176
11177 val = get_param(cmd, "ocvc");
11178 if (val)
11179 dut->ocvc = atoi(val);
11180
Jouni Malinen67433fc2020-06-26 22:50:33 +030011181 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +053011182 if (val && dut->client_privacy != atoi(val) &&
11183 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
11184 send_resp(dut, conn, SIGMA_ERROR,
11185 "errorCode,Failed to configure random MAC address use");
11186 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +030011187 }
11188
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011189 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11190}
11191
11192
Jouni Malinenf7222712019-06-13 01:50:21 +030011193static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
11194 struct sigma_conn *conn,
11195 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011196{
11197 const char *val;
11198
11199 val = get_param(cmd, "Program");
11200 if (val) {
11201 if (strcasecmp(val, "11n") == 0)
11202 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080011203 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011204 return cmd_sta_set_wireless_vht(dut, conn, cmd);
11205 if (strcasecmp(val, "60ghz") == 0)
11206 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011207 if (strcasecmp(val, "OCE") == 0)
11208 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020011209 /* sta_set_wireless in WPS program is only used for 60G */
11210 if (is_60g_sigma_dut(dut))
11211 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011212 if (strcasecmp(val, "WPA3") == 0)
11213 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011214 send_resp(dut, conn, SIGMA_ERROR,
11215 "ErrorCode,Program value not supported");
11216 } else {
11217 send_resp(dut, conn, SIGMA_ERROR,
11218 "ErrorCode,Program argument not available");
11219 }
11220
11221 return 0;
11222}
11223
11224
11225static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
11226 int tid)
11227{
11228 char buf[100];
11229 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
11230
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053011231 if (tid < 0 ||
11232 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
11233 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
11234 return;
11235 }
11236
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011237 /*
11238 * Two ways to ensure that addba request with a
11239 * non zero TID could be sent out. EV 117296
11240 */
11241 snprintf(buf, sizeof(buf),
11242 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
11243 tid);
11244 if (system(buf) != 0) {
11245 sigma_dut_print(dut, DUT_MSG_ERROR,
11246 "Ping did not send out");
11247 }
11248
11249 snprintf(buf, sizeof(buf),
11250 "iwconfig %s | grep Access | awk '{print $6}' > %s",
11251 intf, VI_QOS_TMP_FILE);
11252 if (system(buf) != 0)
11253 return;
11254
11255 snprintf(buf, sizeof(buf),
11256 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
11257 intf, VI_QOS_TMP_FILE);
11258 if (system(buf) != 0)
11259 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
11260
11261 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
11262 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
11263 if (system(buf) != 0) {
11264 sigma_dut_print(dut, DUT_MSG_ERROR,
11265 "VI_QOS_TEMP_FILE generation error failed");
11266 }
11267 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11268 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11269 if (system(buf) != 0) {
11270 sigma_dut_print(dut, DUT_MSG_ERROR,
11271 "VI_QOS_FILE generation failed");
11272 }
11273
11274 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11275 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11276 if (system(buf) != 0) {
11277 sigma_dut_print(dut, DUT_MSG_ERROR,
11278 "VI_QOS_FILE generation failed");
11279 }
11280
11281 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
11282 if (system(buf) != 0) {
11283 }
11284}
11285
11286
11287static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11288 struct sigma_cmd *cmd)
11289{
11290 const char *intf = get_param(cmd, "Interface");
11291 const char *val;
11292 int tid = 0;
11293 char buf[100];
11294
11295 val = get_param(cmd, "TID");
11296 if (val) {
11297 tid = atoi(val);
11298 if (tid)
11299 ath_sta_inject_frame(dut, intf, tid);
11300 }
11301
11302 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011303 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011304
11305 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
11306 if (system(buf) != 0) {
11307 sigma_dut_print(dut, DUT_MSG_ERROR,
11308 "wifitool senddelba failed");
11309 }
11310
11311 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
11312 if (system(buf) != 0) {
11313 sigma_dut_print(dut, DUT_MSG_ERROR,
11314 "wifitool sendaddba failed");
11315 }
11316
11317 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11318
11319 return 1;
11320}
11321
11322
Lior David9981b512017-01-20 13:16:40 +020011323#ifdef __linux__
11324
11325static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
11326 int agg_size)
11327{
11328 char dir[128], buf[128];
11329 FILE *f;
11330 regex_t re;
11331 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030011332 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020011333
11334 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
11335 sigma_dut_print(dut, DUT_MSG_ERROR,
11336 "failed to get wil6210 debugfs dir");
11337 return -1;
11338 }
11339
Jouni Malinen3aa72862019-05-29 23:14:51 +030011340 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
11341 if (res < 0 || res >= sizeof(buf))
11342 return -1;
Lior David9981b512017-01-20 13:16:40 +020011343 f = fopen(buf, "r");
11344 if (!f) {
11345 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011346 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030011347 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
11348 if (res < 0 || res >= sizeof(buf))
11349 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011350 f = fopen(buf, "r");
11351 if (!f) {
11352 sigma_dut_print(dut, DUT_MSG_ERROR,
11353 "failed to open: %s", buf);
11354 return -1;
11355 }
Lior David9981b512017-01-20 13:16:40 +020011356 }
11357
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011358 /* can be either VRING tx... or RING... */
11359 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020011360 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
11361 goto out;
11362 }
11363
11364 /* find TX VRING for the mac address */
11365 found = 0;
11366 while (fgets(buf, sizeof(buf), f)) {
11367 if (strcasestr(buf, dest_mac)) {
11368 found = 1;
11369 break;
11370 }
11371 }
11372
11373 if (!found) {
11374 sigma_dut_print(dut, DUT_MSG_ERROR,
11375 "no TX VRING for %s", dest_mac);
11376 goto out;
11377 }
11378
11379 /* extract VRING ID, "VRING tx_<id> = {" */
11380 if (!fgets(buf, sizeof(buf), f)) {
11381 sigma_dut_print(dut, DUT_MSG_ERROR,
11382 "no VRING start line for %s", dest_mac);
11383 goto out;
11384 }
11385
11386 rc = regexec(&re, buf, 2, m, 0);
11387 regfree(&re);
11388 if (rc || m[1].rm_so < 0) {
11389 sigma_dut_print(dut, DUT_MSG_ERROR,
11390 "no VRING TX ID for %s", dest_mac);
11391 goto out;
11392 }
11393 buf[m[1].rm_eo] = 0;
11394 vring_id = atoi(&buf[m[1].rm_so]);
11395
11396 /* send the addba command */
11397 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011398 res = snprintf(buf, sizeof(buf), "%s/back", dir);
11399 if (res < 0 || res >= sizeof(buf))
11400 return -1;
Lior David9981b512017-01-20 13:16:40 +020011401 f = fopen(buf, "w");
11402 if (!f) {
11403 sigma_dut_print(dut, DUT_MSG_ERROR,
11404 "failed to open: %s", buf);
11405 return -1;
11406 }
11407
11408 fprintf(f, "add %d %d\n", vring_id, agg_size);
11409
11410 ret = 0;
11411
11412out:
11413 fclose(f);
11414
11415 return ret;
11416}
11417
11418
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011419int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11420 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011421{
11422 const char *val;
11423 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011424
11425 val = get_param(cmd, "TID");
11426 if (val) {
11427 tid = atoi(val);
11428 if (tid != 0) {
11429 sigma_dut_print(dut, DUT_MSG_ERROR,
11430 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
11431 tid);
11432 }
11433 }
11434
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011435 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011436 if (!val) {
11437 sigma_dut_print(dut, DUT_MSG_ERROR,
11438 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011439 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011440 }
11441
Lior David9981b512017-01-20 13:16:40 +020011442 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011443 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011444
11445 return 1;
11446}
11447
Lior David9981b512017-01-20 13:16:40 +020011448#endif /* __linux__ */
11449
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011450
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011451static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11452 struct sigma_cmd *cmd)
11453{
11454#ifdef NL80211_SUPPORT
11455 const char *intf = get_param(cmd, "Interface");
11456 const char *val;
11457 int tid = -1;
11458 int bufsize = 64;
11459 struct nl_msg *msg;
11460 int ret = 0;
11461 struct nlattr *params;
11462 int ifindex;
11463
11464 val = get_param(cmd, "TID");
11465 if (val)
11466 tid = atoi(val);
11467
11468 if (tid == -1) {
11469 send_resp(dut, conn, SIGMA_ERROR,
11470 "ErrorCode,sta_send_addba tid invalid");
11471 return 0;
11472 }
11473
11474 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11475
11476 ifindex = if_nametoindex(intf);
11477 if (ifindex == 0) {
11478 sigma_dut_print(dut, DUT_MSG_ERROR,
11479 "%s: Index for interface %s failed",
11480 __func__, intf);
11481 send_resp(dut, conn, SIGMA_ERROR,
11482 "ErrorCode,sta_send_addba interface invalid");
11483 return 0;
11484 }
11485
11486 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11487 NL80211_CMD_VENDOR)) ||
11488 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
11489 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
11490 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
11491 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
11492 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
11493 nla_put_u8(msg,
11494 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
11495 QCA_WLAN_ADD_BA) ||
11496 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
11497 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070011498 nla_put_u16(msg,
11499 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
11500 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011501 sigma_dut_print(dut, DUT_MSG_ERROR,
11502 "%s: err in adding vendor_cmd and vendor_data",
11503 __func__);
11504 nlmsg_free(msg);
11505 send_resp(dut, conn, SIGMA_ERROR,
11506 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
11507 return 0;
11508 }
11509 nla_nest_end(msg, params);
11510
11511 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11512 if (ret) {
11513 sigma_dut_print(dut, DUT_MSG_ERROR,
11514 "%s: err in send_and_recv_msgs, ret=%d",
11515 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053011516 if (ret == -EOPNOTSUPP)
11517 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011518 send_resp(dut, conn, SIGMA_ERROR,
11519 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
11520 return 0;
11521 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011522#else /* NL80211_SUPPORT */
11523 sigma_dut_print(dut, DUT_MSG_ERROR,
11524 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011525#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053011526
11527 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011528}
11529
11530
Jouni Malinenf7222712019-06-13 01:50:21 +030011531static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
11532 struct sigma_conn *conn,
11533 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011534{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011535 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011536 case DRIVER_ATHEROS:
11537 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011538 case DRIVER_WCN:
11539 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020011540#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011541 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011542 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020011543#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011544 default:
11545 /*
11546 * There is no driver specific implementation for other drivers.
11547 * Ignore the command and report COMPLETE since the following
11548 * throughput test operation will end up sending ADDBA anyway.
11549 */
11550 return 1;
11551 }
11552}
11553
11554
11555int inject_eth_frame(int s, const void *data, size_t len,
11556 unsigned short ethtype, char *dst, char *src)
11557{
11558 struct iovec iov[4] = {
11559 {
11560 .iov_base = dst,
11561 .iov_len = ETH_ALEN,
11562 },
11563 {
11564 .iov_base = src,
11565 .iov_len = ETH_ALEN,
11566 },
11567 {
11568 .iov_base = &ethtype,
11569 .iov_len = sizeof(unsigned short),
11570 },
11571 {
11572 .iov_base = (void *) data,
11573 .iov_len = len,
11574 }
11575 };
11576 struct msghdr msg = {
11577 .msg_name = NULL,
11578 .msg_namelen = 0,
11579 .msg_iov = iov,
11580 .msg_iovlen = 4,
11581 .msg_control = NULL,
11582 .msg_controllen = 0,
11583 .msg_flags = 0,
11584 };
11585
11586 return sendmsg(s, &msg, 0);
11587}
11588
11589#if defined(__linux__) || defined(__QNXNTO__)
11590
11591int inject_frame(int s, const void *data, size_t len, int encrypt)
11592{
11593#define IEEE80211_RADIOTAP_F_WEP 0x04
11594#define IEEE80211_RADIOTAP_F_FRAG 0x08
11595 unsigned char rtap_hdr[] = {
11596 0x00, 0x00, /* radiotap version */
11597 0x0e, 0x00, /* radiotap length */
11598 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
11599 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
11600 0x00, /* padding */
11601 0x00, 0x00, /* RX and TX flags to indicate that */
11602 0x00, 0x00, /* this is the injected frame directly */
11603 };
11604 struct iovec iov[2] = {
11605 {
11606 .iov_base = &rtap_hdr,
11607 .iov_len = sizeof(rtap_hdr),
11608 },
11609 {
11610 .iov_base = (void *) data,
11611 .iov_len = len,
11612 }
11613 };
11614 struct msghdr msg = {
11615 .msg_name = NULL,
11616 .msg_namelen = 0,
11617 .msg_iov = iov,
11618 .msg_iovlen = 2,
11619 .msg_control = NULL,
11620 .msg_controllen = 0,
11621 .msg_flags = 0,
11622 };
11623
11624 if (encrypt)
11625 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
11626
11627 return sendmsg(s, &msg, 0);
11628}
11629
11630
11631int open_monitor(const char *ifname)
11632{
11633#ifdef __QNXNTO__
11634 struct sockaddr_dl ll;
11635 int s;
11636
11637 memset(&ll, 0, sizeof(ll));
11638 ll.sdl_family = AF_LINK;
11639 ll.sdl_index = if_nametoindex(ifname);
11640 if (ll.sdl_index == 0) {
11641 perror("if_nametoindex");
11642 return -1;
11643 }
11644 s = socket(PF_INET, SOCK_RAW, 0);
11645#else /* __QNXNTO__ */
11646 struct sockaddr_ll ll;
11647 int s;
11648
11649 memset(&ll, 0, sizeof(ll));
11650 ll.sll_family = AF_PACKET;
11651 ll.sll_ifindex = if_nametoindex(ifname);
11652 if (ll.sll_ifindex == 0) {
11653 perror("if_nametoindex");
11654 return -1;
11655 }
11656 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
11657#endif /* __QNXNTO__ */
11658 if (s < 0) {
11659 perror("socket[PF_PACKET,SOCK_RAW]");
11660 return -1;
11661 }
11662
11663 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
11664 perror("monitor socket bind");
11665 close(s);
11666 return -1;
11667 }
11668
11669 return s;
11670}
11671
11672
11673static int hex2num(char c)
11674{
11675 if (c >= '0' && c <= '9')
11676 return c - '0';
11677 if (c >= 'a' && c <= 'f')
11678 return c - 'a' + 10;
11679 if (c >= 'A' && c <= 'F')
11680 return c - 'A' + 10;
11681 return -1;
11682}
11683
11684
11685int hwaddr_aton(const char *txt, unsigned char *addr)
11686{
11687 int i;
11688
11689 for (i = 0; i < 6; i++) {
11690 int a, b;
11691
11692 a = hex2num(*txt++);
11693 if (a < 0)
11694 return -1;
11695 b = hex2num(*txt++);
11696 if (b < 0)
11697 return -1;
11698 *addr++ = (a << 4) | b;
11699 if (i < 5 && *txt++ != ':')
11700 return -1;
11701 }
11702
11703 return 0;
11704}
11705
11706#endif /* defined(__linux__) || defined(__QNXNTO__) */
11707
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011708
11709#ifdef NL80211_SUPPORT
11710static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
11711 const u8 *data, size_t data_len, int freq)
11712{
11713 struct nl_msg *msg;
11714 int ret = 0;
11715 int ifindex;
11716
11717 ifindex = if_nametoindex(intf);
11718 if (ifindex == 0) {
11719 sigma_dut_print(dut, DUT_MSG_ERROR,
11720 "%s: Index for interface %s failed",
11721 __func__, intf);
11722 return -1;
11723 }
11724
11725 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11726 NL80211_CMD_FRAME)) ||
11727 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11728 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
11729 sigma_dut_print(dut, DUT_MSG_ERROR,
11730 "%s: Error in adding NL80211_CMD_FRAME",
11731 __func__);
11732 nlmsg_free(msg);
11733 return -1;
11734 }
11735
11736 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11737 if (ret) {
11738 sigma_dut_print(dut, DUT_MSG_ERROR,
11739 "nl80211: Frame command failed: ret=%d (%s) req=%u",
11740 ret, strerror(-ret), freq);
11741 return -1;
11742 }
11743
11744 return 0;
11745}
11746#endif /* NL80211_SUPPORT */
11747
11748
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011749enum send_frame_type {
11750 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
11751};
11752enum send_frame_protection {
11753 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
11754};
11755
11756
11757static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011758 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011759 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011760 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011761{
11762#ifdef __linux__
11763 unsigned char buf[1000], *pos;
11764 int s, res;
11765 char bssid[20], addr[20];
11766 char result[32], ssid[100];
11767 size_t ssid_len;
11768
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011769 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011770 sizeof(result)) < 0 ||
11771 strncmp(result, "COMPLETED", 9) != 0) {
11772 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
11773 return 0;
11774 }
11775
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011776 if (get_wpa_status(get_station_ifname(dut), "bssid",
11777 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011778 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11779 "current BSSID");
11780 return 0;
11781 }
11782
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011783 if (get_wpa_status(get_station_ifname(dut), "address",
11784 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011785 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11786 "own MAC address");
11787 return 0;
11788 }
11789
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011790 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011791 < 0) {
11792 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11793 "current SSID");
11794 return 0;
11795 }
11796 ssid_len = strlen(ssid);
11797
11798 pos = buf;
11799
11800 /* Frame Control */
11801 switch (frame) {
11802 case DISASSOC:
11803 *pos++ = 0xa0;
11804 break;
11805 case DEAUTH:
11806 *pos++ = 0xc0;
11807 break;
11808 case SAQUERY:
11809 *pos++ = 0xd0;
11810 break;
11811 case AUTH:
11812 *pos++ = 0xb0;
11813 break;
11814 case ASSOCREQ:
11815 *pos++ = 0x00;
11816 break;
11817 case REASSOCREQ:
11818 *pos++ = 0x20;
11819 break;
11820 case DLS_REQ:
11821 *pos++ = 0xd0;
11822 break;
11823 }
11824
11825 if (protected == INCORRECT_KEY)
11826 *pos++ = 0x40; /* Set Protected field to 1 */
11827 else
11828 *pos++ = 0x00;
11829
11830 /* Duration */
11831 *pos++ = 0x00;
11832 *pos++ = 0x00;
11833
11834 /* addr1 = DA (current AP) */
11835 hwaddr_aton(bssid, pos);
11836 pos += 6;
11837 /* addr2 = SA (own address) */
11838 hwaddr_aton(addr, pos);
11839 pos += 6;
11840 /* addr3 = BSSID (current AP) */
11841 hwaddr_aton(bssid, pos);
11842 pos += 6;
11843
11844 /* Seq# (to be filled by driver/mac80211) */
11845 *pos++ = 0x00;
11846 *pos++ = 0x00;
11847
11848 if (protected == INCORRECT_KEY) {
11849 /* CCMP parameters */
11850 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
11851 pos += 8;
11852 }
11853
11854 if (protected == INCORRECT_KEY) {
11855 switch (frame) {
11856 case DEAUTH:
11857 /* Reason code (encrypted) */
11858 memcpy(pos, "\xa7\x39", 2);
11859 pos += 2;
11860 break;
11861 case DISASSOC:
11862 /* Reason code (encrypted) */
11863 memcpy(pos, "\xa7\x39", 2);
11864 pos += 2;
11865 break;
11866 case SAQUERY:
11867 /* Category|Action|TransID (encrypted) */
11868 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
11869 pos += 4;
11870 break;
11871 default:
11872 return -1;
11873 }
11874
11875 /* CCMP MIC */
11876 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
11877 pos += 8;
11878 } else {
11879 switch (frame) {
11880 case DEAUTH:
11881 /* reason code = 8 */
11882 *pos++ = 0x08;
11883 *pos++ = 0x00;
11884 break;
11885 case DISASSOC:
11886 /* reason code = 8 */
11887 *pos++ = 0x08;
11888 *pos++ = 0x00;
11889 break;
11890 case SAQUERY:
11891 /* Category - SA Query */
11892 *pos++ = 0x08;
11893 /* SA query Action - Request */
11894 *pos++ = 0x00;
11895 /* Transaction ID */
11896 *pos++ = 0x12;
11897 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011898 if (dut->saquery_oci_freq) {
11899 /* OCI IE - Extended ID */
11900 *pos++ = 0xFF;
11901 *pos++ = 0x04;
11902 *pos++ = 0x36;
11903 /* Operating Class */
11904 *pos++ = 0x74;
11905 /* Primary Channel */
11906 *pos++ = freq_to_channel(dut->saquery_oci_freq);
11907 /* Frequency Segment 1 Channel Number */
11908 *pos++ = 0x00;
11909 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011910 break;
11911 case AUTH:
11912 /* Auth Alg (Open) */
11913 *pos++ = 0x00;
11914 *pos++ = 0x00;
11915 /* Seq# */
11916 *pos++ = 0x01;
11917 *pos++ = 0x00;
11918 /* Status code */
11919 *pos++ = 0x00;
11920 *pos++ = 0x00;
11921 break;
11922 case ASSOCREQ:
11923 /* Capability Information */
11924 *pos++ = 0x31;
11925 *pos++ = 0x04;
11926 /* Listen Interval */
11927 *pos++ = 0x0a;
11928 *pos++ = 0x00;
11929 /* SSID */
11930 *pos++ = 0x00;
11931 *pos++ = ssid_len;
11932 memcpy(pos, ssid, ssid_len);
11933 pos += ssid_len;
11934 /* Supported Rates */
11935 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11936 10);
11937 pos += 10;
11938 /* Extended Supported Rates */
11939 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11940 pos += 6;
11941 /* RSN */
11942 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
11943 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
11944 "\x00\x00\x00\x00\x0f\xac\x06", 28);
11945 pos += 28;
11946 break;
11947 case REASSOCREQ:
11948 /* Capability Information */
11949 *pos++ = 0x31;
11950 *pos++ = 0x04;
11951 /* Listen Interval */
11952 *pos++ = 0x0a;
11953 *pos++ = 0x00;
11954 /* Current AP */
11955 hwaddr_aton(bssid, pos);
11956 pos += 6;
11957 /* SSID */
11958 *pos++ = 0x00;
11959 *pos++ = ssid_len;
11960 memcpy(pos, ssid, ssid_len);
11961 pos += ssid_len;
11962 /* Supported Rates */
11963 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11964 10);
11965 pos += 10;
11966 /* Extended Supported Rates */
11967 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11968 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011969 /* RSNE - Group and Pairwise ciphers */
11970 memcpy(pos,
11971 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
11972 14);
11973 pos += 14;
11974 /* RSNE - AKM Suite count */
11975 *pos++ = 0x01;
11976 *pos++ = 0x00;
11977 /* RSNE - AKM Suites */
11978 if (dut->program == PROGRAM_WPA3)
11979 memcpy(pos, "\x00\x0f\xac\x08", 4);
11980 else
11981 memcpy(pos, "\x00\x0f\xac\x02", 4);
11982 pos += 4;
11983 /* RSNE - Capabilities */
11984 *pos++ = 0xc0;
11985 if (dut->ocvc)
11986 *pos++ = 0x40;
11987 else
11988 *pos++ = 0x00;
11989 /* RSNE - PMKID list and Group Management Ciphers */
11990 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
11991 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011992 break;
11993 case DLS_REQ:
11994 /* Category - DLS */
11995 *pos++ = 0x02;
11996 /* DLS Action - Request */
11997 *pos++ = 0x00;
11998 /* Destination MACAddress */
11999 if (dest)
12000 hwaddr_aton(dest, pos);
12001 else
12002 memset(pos, 0, 6);
12003 pos += 6;
12004 /* Source MACAddress */
12005 hwaddr_aton(addr, pos);
12006 pos += 6;
12007 /* Capability Information */
12008 *pos++ = 0x10; /* Privacy */
12009 *pos++ = 0x06; /* QoS */
12010 /* DLS Timeout Value */
12011 *pos++ = 0x00;
12012 *pos++ = 0x01;
12013 /* Supported rates */
12014 *pos++ = 0x01;
12015 *pos++ = 0x08;
12016 *pos++ = 0x0c; /* 6 Mbps */
12017 *pos++ = 0x12; /* 9 Mbps */
12018 *pos++ = 0x18; /* 12 Mbps */
12019 *pos++ = 0x24; /* 18 Mbps */
12020 *pos++ = 0x30; /* 24 Mbps */
12021 *pos++ = 0x48; /* 36 Mbps */
12022 *pos++ = 0x60; /* 48 Mbps */
12023 *pos++ = 0x6c; /* 54 Mbps */
12024 /* TODO: Extended Supported Rates */
12025 /* TODO: HT Capabilities */
12026 break;
12027 }
12028 }
12029
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012030 if (use_monitor) {
12031 s = open_monitor("sigmadut");
12032 if (s < 0) {
12033 send_resp(dut, conn, SIGMA_ERROR,
12034 "errorCode,Failed to open monitor socket");
12035 return 0;
12036 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012037
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012038 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
12039 if (res < 0) {
12040 send_resp(dut, conn, SIGMA_ERROR,
12041 "errorCode,Failed to inject frame");
12042 close(s);
12043 return 0;
12044 }
12045 if (res < pos - buf) {
12046 send_resp(dut, conn, SIGMA_ERROR,
12047 "errorCode,Only partial frame sent");
12048 close(s);
12049 return 0;
12050 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012051
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012052 close(s);
12053 } else {
12054#ifdef NL80211_SUPPORT
12055 int freq;
12056 char freq_str[10];
12057
12058 if (get_wpa_status(get_station_ifname(dut), "freq",
12059 freq_str, sizeof(freq_str)) < 0) {
12060 send_resp(dut, conn, SIGMA_ERROR,
12061 "errorCode,Could not get current operating frequency");
12062 return 0;
12063 }
12064 freq = atoi(freq_str);
12065
12066 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
12067 send_resp(dut, conn, SIGMA_ERROR,
12068 "errorCode,Failed to inject frame");
12069 return 0;
12070 }
12071#else /* NL80211_SUPPORT */
12072 send_resp(dut, conn, SIGMA_ERROR,
12073 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
12074 return 0;
12075#endif /* NL80211_SUPPORT */
12076 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012077
12078 return 1;
12079#else /* __linux__ */
12080 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
12081 "yet supported");
12082 return 0;
12083#endif /* __linux__ */
12084}
12085
12086
12087static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
12088 struct sigma_conn *conn,
12089 struct sigma_cmd *cmd)
12090{
12091 const char *intf = get_param(cmd, "Interface");
12092 const char *sta, *val;
12093 unsigned char addr[ETH_ALEN];
12094 char buf[100];
12095
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012096 if (!intf)
12097 return -1;
12098
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012099 sta = get_param(cmd, "peer");
12100 if (sta == NULL)
12101 sta = get_param(cmd, "station");
12102 if (sta == NULL) {
12103 send_resp(dut, conn, SIGMA_ERROR,
12104 "ErrorCode,Missing peer address");
12105 return 0;
12106 }
12107 if (hwaddr_aton(sta, addr) < 0) {
12108 send_resp(dut, conn, SIGMA_ERROR,
12109 "ErrorCode,Invalid peer address");
12110 return 0;
12111 }
12112
12113 val = get_param(cmd, "type");
12114 if (val == NULL)
12115 return -1;
12116
12117 if (strcasecmp(val, "DISCOVERY") == 0) {
12118 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
12119 if (wpa_command(intf, buf) < 0) {
12120 send_resp(dut, conn, SIGMA_ERROR,
12121 "ErrorCode,Failed to send TDLS discovery");
12122 return 0;
12123 }
12124 return 1;
12125 }
12126
12127 if (strcasecmp(val, "SETUP") == 0) {
12128 int status = 0, timeout = 0;
12129
12130 val = get_param(cmd, "Status");
12131 if (val)
12132 status = atoi(val);
12133
12134 val = get_param(cmd, "Timeout");
12135 if (val)
12136 timeout = atoi(val);
12137
12138 if (status != 0 && status != 37) {
12139 send_resp(dut, conn, SIGMA_ERROR,
12140 "ErrorCode,Unsupported status value");
12141 return 0;
12142 }
12143
12144 if (timeout != 0 && timeout != 301) {
12145 send_resp(dut, conn, SIGMA_ERROR,
12146 "ErrorCode,Unsupported timeout value");
12147 return 0;
12148 }
12149
12150 if (status && timeout) {
12151 send_resp(dut, conn, SIGMA_ERROR,
12152 "ErrorCode,Unsupported timeout+status "
12153 "combination");
12154 return 0;
12155 }
12156
12157 if (status == 37 &&
12158 wpa_command(intf, "SET tdls_testing 0x200")) {
12159 send_resp(dut, conn, SIGMA_ERROR,
12160 "ErrorCode,Failed to enable "
12161 "decline setup response test mode");
12162 return 0;
12163 }
12164
12165 if (timeout == 301) {
12166 int res;
12167 if (dut->no_tpk_expiration)
12168 res = wpa_command(intf,
12169 "SET tdls_testing 0x108");
12170 else
12171 res = wpa_command(intf,
12172 "SET tdls_testing 0x8");
12173 if (res) {
12174 send_resp(dut, conn, SIGMA_ERROR,
12175 "ErrorCode,Failed to set short TPK "
12176 "lifetime");
12177 return 0;
12178 }
12179 }
12180
12181 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
12182 if (wpa_command(intf, buf) < 0) {
12183 send_resp(dut, conn, SIGMA_ERROR,
12184 "ErrorCode,Failed to send TDLS setup");
12185 return 0;
12186 }
12187 return 1;
12188 }
12189
12190 if (strcasecmp(val, "TEARDOWN") == 0) {
12191 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
12192 if (wpa_command(intf, buf) < 0) {
12193 send_resp(dut, conn, SIGMA_ERROR,
12194 "ErrorCode,Failed to send TDLS teardown");
12195 return 0;
12196 }
12197 return 1;
12198 }
12199
12200 send_resp(dut, conn, SIGMA_ERROR,
12201 "ErrorCode,Unsupported TDLS frame");
12202 return 0;
12203}
12204
12205
12206static int sta_ap_known(const char *ifname, const char *bssid)
12207{
12208 char buf[4096];
12209
Jouni Malinendd32f192018-09-15 02:55:19 +030012210 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012211 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
12212 return 0;
12213 if (strncmp(buf, "id=", 3) != 0)
12214 return 0;
12215 return 1;
12216}
12217
12218
12219static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
12220 const char *bssid)
12221{
12222 int res;
12223 struct wpa_ctrl *ctrl;
12224 char buf[256];
12225
12226 if (sta_ap_known(ifname, bssid))
12227 return 0;
12228 sigma_dut_print(dut, DUT_MSG_DEBUG,
12229 "AP not in BSS table - start scan");
12230
12231 ctrl = open_wpa_mon(ifname);
12232 if (ctrl == NULL) {
12233 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12234 "wpa_supplicant monitor connection");
12235 return -1;
12236 }
12237
12238 if (wpa_command(ifname, "SCAN") < 0) {
12239 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
12240 wpa_ctrl_detach(ctrl);
12241 wpa_ctrl_close(ctrl);
12242 return -1;
12243 }
12244
12245 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12246 buf, sizeof(buf));
12247
12248 wpa_ctrl_detach(ctrl);
12249 wpa_ctrl_close(ctrl);
12250
12251 if (res < 0) {
12252 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
12253 return -1;
12254 }
12255
12256 if (sta_ap_known(ifname, bssid))
12257 return 0;
12258 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
12259 return -1;
12260}
12261
12262
12263static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
12264 struct sigma_conn *conn,
12265 struct sigma_cmd *cmd,
12266 const char *intf)
12267{
12268 char buf[200];
12269
12270 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
12271 if (system(buf) != 0) {
12272 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
12273 "ndsend");
12274 return 0;
12275 }
12276
12277 return 1;
12278}
12279
12280
12281static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
12282 struct sigma_conn *conn,
12283 struct sigma_cmd *cmd,
12284 const char *intf)
12285{
12286 char buf[200];
12287 const char *ip = get_param(cmd, "SenderIP");
12288
Peng Xu26b356d2017-10-04 17:58:16 -070012289 if (!ip)
12290 return 0;
12291
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012292 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
12293 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12294 if (system(buf) == 0) {
12295 sigma_dut_print(dut, DUT_MSG_INFO,
12296 "Neighbor Solicitation got a response "
12297 "for %s@%s", ip, intf);
12298 }
12299
12300 return 1;
12301}
12302
12303
12304static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
12305 struct sigma_conn *conn,
12306 struct sigma_cmd *cmd,
12307 const char *ifname)
12308{
12309 char buf[200];
12310 const char *ip = get_param(cmd, "SenderIP");
12311
12312 if (ip == NULL) {
12313 send_resp(dut, conn, SIGMA_ERROR,
12314 "ErrorCode,Missing SenderIP parameter");
12315 return 0;
12316 }
12317 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
12318 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12319 if (system(buf) != 0) {
12320 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
12321 "for %s@%s", ip, ifname);
12322 }
12323
12324 return 1;
12325}
12326
12327
12328static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
12329 struct sigma_conn *conn,
12330 struct sigma_cmd *cmd,
12331 const char *ifname)
12332{
12333 char buf[200];
12334 char ip[16];
12335 int s;
Peng Xub3756882017-10-04 14:39:09 -070012336 struct ifreq ifr;
12337 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012338
12339 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070012340 if (s < 0) {
12341 perror("socket");
12342 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012343 }
12344
Peng Xub3756882017-10-04 14:39:09 -070012345 memset(&ifr, 0, sizeof(ifr));
12346 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
12347 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
12348 sigma_dut_print(dut, DUT_MSG_INFO,
12349 "Failed to get %s IP address: %s",
12350 ifname, strerror(errno));
12351 close(s);
12352 return -1;
12353 }
12354 close(s);
12355
12356 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
12357 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
12358
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012359 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
12360 ip);
12361 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12362 if (system(buf) != 0) {
12363 }
12364
12365 return 1;
12366}
12367
12368
12369static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
12370 struct sigma_conn *conn,
12371 struct sigma_cmd *cmd,
12372 const char *ifname)
12373{
12374 char buf[200], addr[20];
12375 char dst[ETH_ALEN], src[ETH_ALEN];
12376 short ethtype = htons(ETH_P_ARP);
12377 char *pos;
12378 int s, res;
12379 const char *val;
12380 struct sockaddr_in taddr;
12381
12382 val = get_param(cmd, "dest");
12383 if (val)
12384 hwaddr_aton(val, (unsigned char *) dst);
12385
12386 val = get_param(cmd, "DestIP");
12387 if (val)
12388 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070012389 else
12390 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012391
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012392 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012393 sizeof(addr)) < 0)
12394 return -2;
12395 hwaddr_aton(addr, (unsigned char *) src);
12396
12397 pos = buf;
12398 *pos++ = 0x00;
12399 *pos++ = 0x01;
12400 *pos++ = 0x08;
12401 *pos++ = 0x00;
12402 *pos++ = 0x06;
12403 *pos++ = 0x04;
12404 *pos++ = 0x00;
12405 *pos++ = 0x02;
12406 memcpy(pos, src, ETH_ALEN);
12407 pos += ETH_ALEN;
12408 memcpy(pos, &taddr.sin_addr, 4);
12409 pos += 4;
12410 memcpy(pos, dst, ETH_ALEN);
12411 pos += ETH_ALEN;
12412 memcpy(pos, &taddr.sin_addr, 4);
12413 pos += 4;
12414
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012415 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012416 if (s < 0) {
12417 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
12418 "monitor socket");
12419 return 0;
12420 }
12421
12422 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
12423 if (res < 0) {
12424 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
12425 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053012426 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012427 return 0;
12428 }
12429
12430 close(s);
12431
12432 return 1;
12433}
12434
12435
12436static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
12437 struct sigma_conn *conn,
12438 struct sigma_cmd *cmd,
12439 const char *intf, const char *dest)
12440{
12441 char buf[100];
12442
12443 if (if_nametoindex("sigmadut") == 0) {
12444 snprintf(buf, sizeof(buf),
12445 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012446 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012447 if (system(buf) != 0 ||
12448 if_nametoindex("sigmadut") == 0) {
12449 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12450 "monitor interface with '%s'", buf);
12451 return -2;
12452 }
12453 }
12454
12455 if (system("ifconfig sigmadut up") != 0) {
12456 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12457 "monitor interface up");
12458 return -2;
12459 }
12460
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012461 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012462}
12463
12464
12465static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
12466 struct sigma_conn *conn,
12467 struct sigma_cmd *cmd)
12468{
12469 const char *intf = get_param(cmd, "Interface");
12470 const char *dest = get_param(cmd, "Dest");
12471 const char *type = get_param(cmd, "FrameName");
12472 const char *val;
12473 char buf[200], *pos, *end;
12474 int count, count2;
12475
12476 if (type == NULL)
12477 type = get_param(cmd, "Type");
12478
12479 if (intf == NULL || dest == NULL || type == NULL)
12480 return -1;
12481
12482 if (strcasecmp(type, "NeighAdv") == 0)
12483 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
12484
12485 if (strcasecmp(type, "NeighSolicitReq") == 0)
12486 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
12487
12488 if (strcasecmp(type, "ARPProbe") == 0)
12489 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
12490
12491 if (strcasecmp(type, "ARPAnnounce") == 0)
12492 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
12493
12494 if (strcasecmp(type, "ARPReply") == 0)
12495 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
12496
12497 if (strcasecmp(type, "DLS-request") == 0 ||
12498 strcasecmp(type, "DLSrequest") == 0)
12499 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
12500 dest);
12501
12502 if (strcasecmp(type, "ANQPQuery") != 0 &&
12503 strcasecmp(type, "Query") != 0) {
12504 send_resp(dut, conn, SIGMA_ERROR,
12505 "ErrorCode,Unsupported HS 2.0 send frame type");
12506 return 0;
12507 }
12508
12509 if (sta_scan_ap(dut, intf, dest) < 0) {
12510 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
12511 "the requested AP");
12512 return 0;
12513 }
12514
12515 pos = buf;
12516 end = buf + sizeof(buf);
12517 count = 0;
12518 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
12519
12520 val = get_param(cmd, "ANQP_CAP_LIST");
12521 if (val && atoi(val)) {
12522 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
12523 count++;
12524 }
12525
12526 val = get_param(cmd, "VENUE_NAME");
12527 if (val && atoi(val)) {
12528 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
12529 count++;
12530 }
12531
12532 val = get_param(cmd, "NETWORK_AUTH_TYPE");
12533 if (val && atoi(val)) {
12534 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
12535 count++;
12536 }
12537
12538 val = get_param(cmd, "ROAMING_CONS");
12539 if (val && atoi(val)) {
12540 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
12541 count++;
12542 }
12543
12544 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
12545 if (val && atoi(val)) {
12546 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
12547 count++;
12548 }
12549
12550 val = get_param(cmd, "NAI_REALM_LIST");
12551 if (val && atoi(val)) {
12552 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
12553 count++;
12554 }
12555
12556 val = get_param(cmd, "3GPP_INFO");
12557 if (val && atoi(val)) {
12558 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
12559 count++;
12560 }
12561
12562 val = get_param(cmd, "DOMAIN_LIST");
12563 if (val && atoi(val)) {
12564 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
12565 count++;
12566 }
12567
Jouni Malinen34cf9532018-04-29 19:26:33 +030012568 val = get_param(cmd, "Venue_URL");
12569 if (val && atoi(val)) {
12570 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
12571 count++;
12572 }
12573
Jouni Malinend3bca5d2018-04-29 17:25:23 +030012574 val = get_param(cmd, "Advice_Of_Charge");
12575 if (val && atoi(val)) {
12576 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
12577 count++;
12578 }
12579
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012580 if (count && wpa_command(intf, buf)) {
12581 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
12582 return 0;
12583 }
12584
12585 pos = buf;
12586 end = buf + sizeof(buf);
12587 count2 = 0;
12588 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
12589
12590 val = get_param(cmd, "HS_CAP_LIST");
12591 if (val && atoi(val)) {
12592 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
12593 count2++;
12594 }
12595
12596 val = get_param(cmd, "OPER_NAME");
12597 if (val && atoi(val)) {
12598 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
12599 count2++;
12600 }
12601
12602 val = get_param(cmd, "WAN_METRICS");
12603 if (!val)
12604 val = get_param(cmd, "WAN_MAT");
12605 if (!val)
12606 val = get_param(cmd, "WAN_MET");
12607 if (val && atoi(val)) {
12608 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
12609 count2++;
12610 }
12611
12612 val = get_param(cmd, "CONNECTION_CAPABILITY");
12613 if (val && atoi(val)) {
12614 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
12615 count2++;
12616 }
12617
12618 val = get_param(cmd, "OP_CLASS");
12619 if (val && atoi(val)) {
12620 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
12621 count2++;
12622 }
12623
12624 val = get_param(cmd, "OSU_PROVIDER_LIST");
12625 if (val && atoi(val)) {
12626 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
12627 count2++;
12628 }
12629
Jouni Malinenf67afec2018-04-29 19:24:58 +030012630 val = get_param(cmd, "OPER_ICON_METADATA");
12631 if (!val)
12632 val = get_param(cmd, "OPERATOR_ICON_METADATA");
12633 if (val && atoi(val)) {
12634 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
12635 count2++;
12636 }
12637
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012638 if (count && count2) {
12639 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
12640 "second query");
12641 sleep(1);
12642 }
12643
12644 if (count2 && wpa_command(intf, buf)) {
12645 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
12646 "failed");
12647 return 0;
12648 }
12649
12650 val = get_param(cmd, "NAI_HOME_REALM_LIST");
12651 if (val) {
12652 if (count || count2) {
12653 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12654 "sending out second query");
12655 sleep(1);
12656 }
12657
12658 if (strcmp(val, "1") == 0)
12659 val = "mail.example.com";
12660 snprintf(buf, end - pos,
12661 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
12662 dest, val);
12663 if (wpa_command(intf, buf)) {
12664 send_resp(dut, conn, SIGMA_ERROR,
12665 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
12666 "failed");
12667 return 0;
12668 }
12669 }
12670
12671 val = get_param(cmd, "ICON_REQUEST");
12672 if (val) {
12673 if (count || count2) {
12674 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12675 "sending out second query");
12676 sleep(1);
12677 }
12678
12679 snprintf(buf, end - pos,
12680 "HS20_ICON_REQUEST %s %s", dest, val);
12681 if (wpa_command(intf, buf)) {
12682 send_resp(dut, conn, SIGMA_ERROR,
12683 "ErrorCode,HS20_ICON_REQUEST failed");
12684 return 0;
12685 }
12686 }
12687
12688 return 1;
12689}
12690
12691
12692static int ath_sta_send_frame_vht(struct sigma_dut *dut,
12693 struct sigma_conn *conn,
12694 struct sigma_cmd *cmd)
12695{
12696 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012697 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012698 int chwidth, nss;
12699
12700 val = get_param(cmd, "framename");
12701 if (!val)
12702 return -1;
12703 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12704
12705 /* Command sequence to generate Op mode notification */
12706 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012707 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012708
12709 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012710 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012711
12712 /* Extract Channel width */
12713 val = get_param(cmd, "Channel_width");
12714 if (val) {
12715 switch (atoi(val)) {
12716 case 20:
12717 chwidth = 0;
12718 break;
12719 case 40:
12720 chwidth = 1;
12721 break;
12722 case 80:
12723 chwidth = 2;
12724 break;
12725 case 160:
12726 chwidth = 3;
12727 break;
12728 default:
12729 chwidth = 2;
12730 break;
12731 }
12732
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012733 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012734 }
12735
12736 /* Extract NSS */
12737 val = get_param(cmd, "NSS");
12738 if (val) {
12739 switch (atoi(val)) {
12740 case 1:
12741 nss = 1;
12742 break;
12743 case 2:
12744 nss = 3;
12745 break;
12746 case 3:
12747 nss = 7;
12748 break;
12749 default:
12750 /* We do not support NSS > 3 */
12751 nss = 3;
12752 break;
12753 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012754 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012755 }
12756
12757 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012758 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012759 }
12760
12761 return 1;
12762}
12763
12764
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012765static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
12766 enum send_frame_protection protected)
12767{
12768#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012769 return wcn_wifi_test_config_set_u8(
12770 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
12771 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012772#else /* NL80211_SUPPORT */
12773 sigma_dut_print(dut, DUT_MSG_ERROR,
12774 "PMF config cannot be set without NL80211_SUPPORT defined");
12775 return -1;
12776#endif /* NL80211_SUPPORT */
12777}
12778
12779
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012780static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
12781 struct sigma_conn *conn,
12782 struct sigma_cmd *cmd)
12783{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012784 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012785 case DRIVER_ATHEROS:
12786 return ath_sta_send_frame_vht(dut, conn, cmd);
12787 default:
12788 send_resp(dut, conn, SIGMA_ERROR,
12789 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
12790 return 0;
12791 }
12792}
12793
12794
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012795static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
12796{
12797#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012798 return wcn_wifi_test_config_set_flag(
12799 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012800#else /* NL80211_SUPPORT */
12801 sigma_dut_print(dut, DUT_MSG_ERROR,
12802 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
12803 return -1;
12804#endif /* NL80211_SUPPORT */
12805}
12806
12807
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012808static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
12809 struct sigma_cmd *cmd)
12810{
12811 const char *val;
12812 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012813 enum send_frame_protection protected;
12814 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012815
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012816 if (!intf)
12817 return -1;
12818
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012819 val = get_param(cmd, "framename");
12820 if (!val)
12821 return -1;
12822 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12823
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012824 pmf = get_param(cmd, "PMFProtected");
12825 if (!pmf)
12826 pmf = get_param(cmd, "Protected");
12827 if (pmf) {
12828 if (strcasecmp(pmf, "Correct-key") == 0 ||
12829 strcasecmp(pmf, "CorrectKey") == 0) {
12830 protected = CORRECT_KEY;
12831 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
12832 protected = INCORRECT_KEY;
12833 } else if (strcasecmp(pmf, "Unprotected") == 0) {
12834 protected = UNPROTECTED;
12835 } else {
12836 send_resp(dut, conn, SIGMA_ERROR,
12837 "errorCode,Unsupported PMFProtected");
12838 return STATUS_SENT_ERROR;
12839 }
12840 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
12841 protected);
12842 wcn_sta_set_pmf_config(dut, intf, protected);
12843 }
12844
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012845 /* Command sequence to generate Op mode notification */
12846 if (val && strcasecmp(val, "action") == 0) {
12847 val = get_param(cmd, "PPDUTxType");
12848 if (val && strcasecmp(val, "TB") == 0) {
12849 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
12850 sigma_dut_print(dut, DUT_MSG_ERROR,
12851 "failed to send TB PPDU Tx cfg");
12852 send_resp(dut, conn, SIGMA_ERROR,
12853 "ErrorCode,set TB PPDU Tx cfg failed");
12854 return 0;
12855 }
12856 return 1;
12857 }
12858
12859 sigma_dut_print(dut, DUT_MSG_ERROR,
12860 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012861
12862 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012863 }
12864
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012865 if (strcasecmp(val, "disassoc") == 0)
12866 wcn_sta_send_disassoc(dut, intf);
12867
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012868 return 1;
12869}
12870
12871
12872static int cmd_sta_send_frame_he(struct sigma_dut *dut,
12873 struct sigma_conn *conn,
12874 struct sigma_cmd *cmd)
12875{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012876 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012877 case DRIVER_WCN:
12878 return wcn_sta_send_frame_he(dut, conn, cmd);
12879 default:
12880 send_resp(dut, conn, SIGMA_ERROR,
12881 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
12882 return 0;
12883 }
12884}
12885
12886
Lior David0fe101e2017-03-09 16:09:50 +020012887#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012888
12889static int
12890wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
12891 const char *frame_name, const char *dest_mac)
12892{
12893 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
12894 const char *ssid = get_param(cmd, "ssid");
12895 const char *countstr = get_param(cmd, "count");
12896 const char *channelstr = get_param(cmd, "channel");
12897 const char *group_id = get_param(cmd, "groupid");
12898 const char *client_id = get_param(cmd, "clientmac");
12899 int count, channel, freq, i;
12900 const char *fname;
12901 char frame[1024], src_mac[20], group_id_attr[25],
12902 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
12903 const char *group_ssid;
12904 const int group_ssid_prefix_len = 9;
12905 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
12906 size_t framelen = sizeof(frame);
12907 struct template_frame_tag tags[2];
12908 size_t tags_total = ARRAY_SIZE(tags);
12909 int tag_index, len, dst_len;
12910
12911 if (!countstr || !channelstr) {
12912 sigma_dut_print(dut, DUT_MSG_ERROR,
12913 "Missing argument: count, channel");
12914 return -1;
12915 }
12916 if (isprobereq && !ssid) {
12917 sigma_dut_print(dut, DUT_MSG_ERROR,
12918 "Missing argument: ssid");
12919 return -1;
12920 }
12921 if (!isprobereq && (!group_id || !client_id)) {
12922 sigma_dut_print(dut, DUT_MSG_ERROR,
12923 "Missing argument: group_id, client_id");
12924 return -1;
12925 }
12926
12927 count = atoi(countstr);
12928 channel = atoi(channelstr);
12929 freq = channel_to_freq(dut, channel);
12930
12931 if (!freq) {
12932 sigma_dut_print(dut, DUT_MSG_ERROR,
12933 "invalid channel: %s", channelstr);
12934 return -1;
12935 }
12936
12937 if (isprobereq) {
12938 if (strcasecmp(ssid, "wildcard") == 0) {
12939 fname = "probe_req_wildcard.txt";
12940 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
12941 fname = "probe_req_P2P_Wildcard.txt";
12942 } else {
12943 sigma_dut_print(dut, DUT_MSG_ERROR,
12944 "invalid probe request type");
12945 return -1;
12946 }
12947 } else {
12948 fname = "P2P_device_discovery_req.txt";
12949 }
12950
12951 if (parse_template_frame_file(dut, fname, frame, &framelen,
12952 tags, &tags_total)) {
12953 sigma_dut_print(dut, DUT_MSG_ERROR,
12954 "invalid frame template: %s", fname);
12955 return -1;
12956 }
12957
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012958 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012959 src_mac, sizeof(src_mac)) < 0 ||
12960 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
12961 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
12962 return -1;
12963 /* Use wildcard BSSID, since we are in PBSS */
12964 memset(&hdr->addr3, 0xFF, ETH_ALEN);
12965
12966 if (!isprobereq) {
12967 tag_index = find_template_frame_tag(tags, tags_total, 1);
12968 if (tag_index < 0) {
12969 sigma_dut_print(dut, DUT_MSG_ERROR,
12970 "can't find device id attribute");
12971 return -1;
12972 }
12973 if (parse_mac_address(dut, client_id,
12974 (unsigned char *) client_mac)) {
12975 sigma_dut_print(dut, DUT_MSG_ERROR,
12976 "invalid client_id: %s", client_id);
12977 return -1;
12978 }
12979 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
12980 framelen - tags[tag_index].offset,
12981 IEEE80211_P2P_ATTR_DEVICE_ID,
12982 client_mac, ETH_ALEN)) {
12983 sigma_dut_print(dut, DUT_MSG_ERROR,
12984 "fail to replace device id attribute");
12985 return -1;
12986 }
12987
12988 /*
12989 * group_id arg contains device MAC address followed by
12990 * space and SSID (DIRECT-somessid).
12991 * group id attribute contains device address (6 bytes)
12992 * followed by SSID prefix DIRECT-XX (9 bytes)
12993 */
12994 if (strlen(group_id) < sizeof(device_macstr)) {
12995 sigma_dut_print(dut, DUT_MSG_ERROR,
12996 "group_id arg too short");
12997 return -1;
12998 }
12999 memcpy(device_macstr, group_id, sizeof(device_macstr));
13000 device_macstr[sizeof(device_macstr) - 1] = '\0';
13001 if (parse_mac_address(dut, device_macstr,
13002 (unsigned char *) group_id_attr)) {
13003 sigma_dut_print(dut, DUT_MSG_ERROR,
13004 "fail to parse device address from group_id");
13005 return -1;
13006 }
13007 group_ssid = strchr(group_id, ' ');
13008 if (!group_ssid) {
13009 sigma_dut_print(dut, DUT_MSG_ERROR,
13010 "invalid group_id arg, no ssid");
13011 return -1;
13012 }
13013 group_ssid++;
13014 len = strlen(group_ssid);
13015 if (len < group_ssid_prefix_len) {
13016 sigma_dut_print(dut, DUT_MSG_ERROR,
13017 "group_id SSID too short");
13018 return -1;
13019 }
13020 dst_len = sizeof(group_id_attr) - ETH_ALEN;
13021 if (len > dst_len) {
13022 sigma_dut_print(dut, DUT_MSG_ERROR,
13023 "group_id SSID (%s) too long",
13024 group_ssid);
13025 return -1;
13026 }
13027
13028 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
13029 tag_index = find_template_frame_tag(tags, tags_total, 2);
13030 if (tag_index < 0) {
13031 sigma_dut_print(dut, DUT_MSG_ERROR,
13032 "can't find group id attribute");
13033 return -1;
13034 }
13035 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13036 framelen - tags[tag_index].offset,
13037 IEEE80211_P2P_ATTR_GROUP_ID,
13038 group_id_attr,
13039 sizeof(group_id_attr))) {
13040 sigma_dut_print(dut, DUT_MSG_ERROR,
13041 "fail to replace group id attribute");
13042 return -1;
13043 }
13044 }
13045
13046 for (i = 0; i < count; i++) {
13047 if (wil6210_transmit_frame(dut, freq,
13048 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
13049 frame, framelen)) {
13050 sigma_dut_print(dut, DUT_MSG_ERROR,
13051 "fail to transmit probe request frame");
13052 return -1;
13053 }
13054 }
13055
13056 return 0;
13057}
13058
13059
Lior David0fe101e2017-03-09 16:09:50 +020013060int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
13061 struct sigma_cmd *cmd)
13062{
13063 const char *frame_name = get_param(cmd, "framename");
13064 const char *mac = get_param(cmd, "dest_mac");
13065
13066 if (!frame_name || !mac) {
13067 sigma_dut_print(dut, DUT_MSG_ERROR,
13068 "framename and dest_mac must be provided");
13069 return -1;
13070 }
13071
13072 if (strcasecmp(frame_name, "brp") == 0) {
13073 const char *l_rx = get_param(cmd, "L-RX");
13074 int l_rx_i;
13075
13076 if (!l_rx) {
13077 sigma_dut_print(dut, DUT_MSG_ERROR,
13078 "L-RX must be provided");
13079 return -1;
13080 }
13081 l_rx_i = atoi(l_rx);
13082
13083 sigma_dut_print(dut, DUT_MSG_INFO,
13084 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
13085 mac, l_rx);
13086 if (l_rx_i != 16) {
13087 sigma_dut_print(dut, DUT_MSG_ERROR,
13088 "unsupported L-RX: %s", l_rx);
13089 return -1;
13090 }
13091
13092 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
13093 return -1;
13094 } else if (strcasecmp(frame_name, "ssw") == 0) {
13095 sigma_dut_print(dut, DUT_MSG_INFO,
13096 "dev_send_frame: SLS, dest_mac %s", mac);
13097 if (wil6210_send_sls(dut, mac))
13098 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013099 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
13100 (strcasecmp(frame_name, "devdiscreq") == 0)) {
13101 sigma_dut_print(dut, DUT_MSG_INFO,
13102 "dev_send_frame: %s, dest_mac %s", frame_name,
13103 mac);
13104 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
13105 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020013106 } else {
13107 sigma_dut_print(dut, DUT_MSG_ERROR,
13108 "unsupported frame type: %s", frame_name);
13109 return -1;
13110 }
13111
13112 return 1;
13113}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013114
Lior David0fe101e2017-03-09 16:09:50 +020013115#endif /* __linux__ */
13116
13117
13118static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
13119 struct sigma_conn *conn,
13120 struct sigma_cmd *cmd)
13121{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013122 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020013123#ifdef __linux__
13124 case DRIVER_WIL6210:
13125 return wil6210_send_frame_60g(dut, conn, cmd);
13126#endif /* __linux__ */
13127 default:
13128 send_resp(dut, conn, SIGMA_ERROR,
13129 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
13130 return 0;
13131 }
13132}
13133
13134
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013135static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13136 const char *intf, struct sigma_cmd *cmd)
13137{
13138 const char *val, *addr;
13139 char buf[100];
13140
13141 addr = get_param(cmd, "DestMac");
13142 if (!addr) {
13143 send_resp(dut, conn, SIGMA_INVALID,
13144 "ErrorCode,AP MAC address is missing");
13145 return 0;
13146 }
13147
13148 val = get_param(cmd, "ANQPQuery_ID");
13149 if (!val) {
13150 send_resp(dut, conn, SIGMA_INVALID,
13151 "ErrorCode,Missing ANQPQuery_ID");
13152 return 0;
13153 }
13154
13155 if (strcasecmp(val, "NeighborReportReq") == 0) {
13156 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
13157 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
13158 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
13159 } else {
13160 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
13161 val);
13162 send_resp(dut, conn, SIGMA_INVALID,
13163 "ErrorCode,Invalid ANQPQuery_ID");
13164 return 0;
13165 }
13166
Ashwini Patild174f2c2017-04-13 16:49:46 +053013167 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
13168 * (Address3 = Wildcard BSSID when sent to not-associated AP;
13169 * if associated, AP BSSID).
13170 */
13171 if (wpa_command(intf, "SET gas_address3 1") < 0) {
13172 send_resp(dut, conn, SIGMA_ERROR,
13173 "ErrorCode,Failed to set gas_address3");
13174 return 0;
13175 }
13176
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013177 if (wpa_command(intf, buf) < 0) {
13178 send_resp(dut, conn, SIGMA_ERROR,
13179 "ErrorCode,Failed to send ANQP query");
13180 return 0;
13181 }
13182
13183 return 1;
13184}
13185
13186
13187static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
13188 struct sigma_conn *conn,
13189 const char *intf,
13190 struct sigma_cmd *cmd)
13191{
13192 const char *val = get_param(cmd, "FrameName");
13193
13194 if (val && strcasecmp(val, "ANQPQuery") == 0)
13195 return mbo_send_anqp_query(dut, conn, intf, cmd);
13196
13197 return 2;
13198}
13199
13200
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013201static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
13202 struct sigma_conn *conn,
13203 const char *intf,
13204 struct sigma_cmd *cmd)
13205{
13206 const char *val = get_param(cmd, "framename");
13207
13208 if (!val)
13209 return INVALID_SEND_STATUS;
13210
13211 if (strcasecmp(val, "SAQueryReq") == 0) {
13212 val = get_param(cmd, "OCIChannel");
13213
13214 if (!val) {
13215 send_resp(dut, conn, SIGMA_ERROR,
13216 "errorCode,OCIChannel not present");
13217 return STATUS_SENT_ERROR;
13218 }
13219
13220 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
13221 if (!dut->saquery_oci_freq) {
13222 send_resp(dut, conn, SIGMA_ERROR,
13223 "errorCode,Invalid OCIChannel number");
13224 return STATUS_SENT_ERROR;
13225 }
13226
13227 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
13228 NULL, 0);
13229 }
13230
13231 if (strcasecmp(val, "reassocreq") == 0)
13232 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
13233 CORRECT_KEY, NULL, 0);
13234
Veerendranath9f81dfb2020-08-10 01:21:29 -070013235 if (strcasecmp(val, "ANQPQuery") == 0) {
13236 char buf[50];
13237 const char *dest = get_param(cmd, "DestMac");
13238 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013239 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070013240 int len, freq;
13241
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013242 if (freq_str)
13243 freq = atoi(freq_str);
13244 else
13245 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
13246
Veerendranath9f81dfb2020-08-10 01:21:29 -070013247 if (!dest || !freq)
13248 return INVALID_SEND_STATUS;
13249
13250 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
13251 dest, freq);
13252 if (len < 0 || len >= sizeof(buf)) {
13253 sigma_dut_print(dut, DUT_MSG_ERROR,
13254 "Failed to allocate buf");
13255 return ERROR_SEND_STATUS;
13256 }
13257
13258 if (wpa_command(intf, buf) != 0) {
13259 send_resp(dut, conn, SIGMA_ERROR,
13260 "ErrorCode,Failed to send ANQP Query frame");
13261 return STATUS_SENT_ERROR;
13262 }
13263
13264 sigma_dut_print(dut, DUT_MSG_DEBUG,
13265 "ANQP Query sent: %s", buf);
13266
13267 return SUCCESS_SEND_STATUS;
13268 }
13269
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013270 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
13271 return STATUS_SENT_ERROR;
13272}
13273
13274
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013275static int
13276get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13277 char *pos, int rem_len, int num_of_scs_desc,
13278 int num_of_tclas_elem)
13279{
13280 const char *val;
13281 int ipv6;
13282 int len, total_len = 0;
13283
13284 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
13285 num_of_tclas_elem);
13286 if (!val) {
13287 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
13288 __func__);
13289 return -1;
13290 }
13291
13292 if (strcmp(val, "6") == 0) {
13293 ipv6 = 1;
13294 } else if (strcmp(val, "4") == 0) {
13295 ipv6 = 0;
13296 } else {
13297 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
13298 __func__);
13299 return -1;
13300 }
13301
13302 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
13303 if (len < 0 || len >= rem_len)
13304 return -1;
13305
13306 pos += len;
13307 rem_len -= len;
13308 total_len += len;
13309
13310 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
13311 num_of_scs_desc, num_of_tclas_elem);
13312 if (val) {
13313 len = snprintf(pos, rem_len, " src_ip=%s", val);
13314 if (len < 0 || len >= rem_len)
13315 return -1;
13316
13317 pos += len;
13318 rem_len -= len;
13319 total_len += len;
13320 }
13321
13322 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
13323 num_of_scs_desc, num_of_tclas_elem);
13324 if (val) {
13325 len = snprintf(pos, rem_len, " dst_ip=%s", val);
13326 if (len < 0 || len >= rem_len)
13327 return -1;
13328
13329 pos += len;
13330 rem_len -= len;
13331 total_len += len;
13332 }
13333
13334 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
13335 num_of_tclas_elem);
13336 if (val) {
13337 len = snprintf(pos, rem_len, " src_port=%s", val);
13338 if (len < 0 || len >= rem_len)
13339 return -1;
13340
13341 pos += len;
13342 rem_len -= len;
13343 total_len += len;
13344 }
13345
13346 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
13347 num_of_scs_desc, num_of_tclas_elem);
13348 if (val) {
13349 len = snprintf(pos, rem_len, " dst_port=%s", val);
13350 if (len < 0 || len >= rem_len)
13351 return -1;
13352
13353 pos += len;
13354 rem_len -= len;
13355 total_len += len;
13356 }
13357
13358 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
13359 num_of_tclas_elem);
13360 if (val) {
13361 len = snprintf(pos, rem_len, " dscp=%s", val);
13362 if (len < 0 || len >= rem_len)
13363 return -1;
13364
13365 pos += len;
13366 rem_len -= len;
13367 total_len += len;
13368 }
13369
13370 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
13371 num_of_scs_desc, num_of_tclas_elem);
13372 if (val) {
13373 char *prot;
13374
13375 switch (atoi(val)) {
13376 case 17:
13377 prot = "udp";
13378 break;
13379 case 6:
13380 prot = "tcp";
13381 break;
13382 case 50:
13383 prot = "esp";
13384 break;
13385 default:
13386 sigma_dut_print(dut, DUT_MSG_ERROR,
13387 "Invalid protocol %d", atoi(val));
13388 return -1;
13389 }
13390
13391 if (ipv6)
13392 len = snprintf(pos, rem_len, " next_header=%s", prot);
13393 else
13394 len = snprintf(pos, rem_len, " protocol=%s", prot);
13395 if (len < 0 || len >= rem_len)
13396 return -1;
13397
13398 pos += len;
13399 rem_len -= len;
13400 total_len += len;
13401 }
13402
13403 return total_len;
13404}
13405
13406
13407static int
13408get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13409 char *pos, int rem_len, int num_of_scs_desc,
13410 int num_of_tclas_elem)
13411{
13412 const char *val;
13413 int len, total_len = 0;
13414
13415 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
13416 num_of_scs_desc, num_of_tclas_elem);
13417 if (val) {
13418 len = snprintf(pos, rem_len, " prot_instance=%s",
13419 val);
13420 if (len < 0 || len >= rem_len)
13421 return -1;
13422
13423 pos += len;
13424 rem_len -= len;
13425 total_len += len;
13426 }
13427
13428 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
13429 num_of_scs_desc, num_of_tclas_elem);
13430 if (val) {
13431 char *prot;
13432
13433 switch (atoi(val)) {
13434 case 17:
13435 prot = "udp";
13436 break;
13437 case 6:
13438 prot = "tcp";
13439 break;
13440 case 50:
13441 prot = "esp";
13442 break;
13443 default:
13444 sigma_dut_print(dut, DUT_MSG_ERROR,
13445 "Invalid protocol %d",
13446 atoi(val));
13447 return -1;
13448 }
13449
13450 len = snprintf(pos, rem_len, " prot_number=%s", prot);
13451 if (len < 0 || len >= rem_len)
13452 return -1;
13453
13454 pos += len;
13455 rem_len -= len;
13456 total_len += len;
13457 }
13458
13459 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
13460 num_of_scs_desc, num_of_tclas_elem);
13461 if (val) {
13462 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
13463 if (len < 0 || len >= rem_len)
13464 return -1;
13465
13466 pos += len;
13467 rem_len -= len;
13468 total_len += len;
13469 }
13470
13471 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
13472 num_of_tclas_elem);
13473 if (val && strlen(val) >= 2) {
13474 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
13475 if (len < 0 || len >= rem_len)
13476 return -1;
13477
13478 pos += len;
13479 rem_len -= len;
13480 total_len += len;
13481 }
13482
13483 return total_len;
13484}
13485
13486
13487static enum sigma_cmd_result
13488cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
13489 const char *intf, struct sigma_cmd *cmd)
13490{
13491 char buf[4096], *pos;
13492 const char *val, *scs_id, *classifier_type;
13493 int len, rem_len, total_bytes;
13494 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
13495
13496 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
13497 if (!scs_id) {
13498 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
13499 return INVALID_SEND_STATUS;
13500 }
13501
13502 rem_len = sizeof(buf);
13503 pos = buf;
13504
13505 len = snprintf(buf, sizeof(buf), "SCS");
13506 if (len < 0 || len > rem_len)
13507 goto fail;
13508
13509 pos += len;
13510 rem_len -= len;
13511
13512 while (scs_id) {
13513 num_of_scs_desc++;
13514
13515 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
13516 num_of_scs_desc);
13517 if (!val)
13518 return INVALID_SEND_STATUS;
13519
13520 if (strcasecmp(val, "Add") == 0) {
13521 len = snprintf(pos, rem_len, " scs_id=%s add",
13522 scs_id);
13523 } else if (strcasecmp(val, "Change") == 0) {
13524 len = snprintf(pos, rem_len, " scs_id=%s change",
13525 scs_id);
13526 } else if (strcasecmp(val, "Remove") == 0) {
13527 len = snprintf(pos, rem_len, " scs_id=%s remove",
13528 scs_id);
13529 if (len < 0 || len >= rem_len)
13530 goto fail;
13531
13532 pos += len;
13533 rem_len -= len;
13534 goto scs_desc_end;
13535 } else {
13536 sigma_dut_print(dut, DUT_MSG_ERROR,
13537 "%s: request type - %s is invalid",
13538 __func__, val);
13539 return INVALID_SEND_STATUS;
13540 }
13541
13542 if (len < 0 || len >= rem_len)
13543 goto fail;
13544
13545 pos += len;
13546 rem_len -= len;
13547
13548 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
13549 num_of_scs_desc);
13550 if (!val) {
13551 sigma_dut_print(dut, DUT_MSG_ERROR,
13552 "IntraAccess Priority empty");
13553 return INVALID_SEND_STATUS;
13554 }
13555
13556 len = snprintf(pos, rem_len, " scs_up=%s", val);
13557 if (len < 0 || len >= rem_len)
13558 goto fail;
13559
13560 pos += len;
13561 rem_len -= len;
13562
13563 classifier_type = get_param_fmt(cmd,
13564 "TCLASElem_ClassifierType_%d_1",
13565 num_of_scs_desc);
13566 if (!classifier_type) {
13567 sigma_dut_print(dut, DUT_MSG_ERROR,
13568 "classifier type missing");
13569 return INVALID_SEND_STATUS;
13570 }
13571
13572 while (classifier_type) {
13573 num_of_tclas_elem++;
13574
13575 len = snprintf(pos, rem_len, " classifier_type=%s",
13576 classifier_type);
13577 if (len < 0 || len >= rem_len)
13578 goto fail;
13579
13580 pos += len;
13581 rem_len -= len;
13582
13583 if (strcmp(classifier_type, "10") == 0) {
13584 total_bytes = get_type10_frame_classifier(
13585 dut, cmd, pos, rem_len,
13586 num_of_scs_desc,
13587 num_of_tclas_elem);
13588 } else if (strcmp(classifier_type, "4") == 0) {
13589 total_bytes = get_type4_frame_classifier(
13590 dut, cmd, pos, rem_len,
13591 num_of_scs_desc,
13592 num_of_tclas_elem);
13593 } else {
13594 sigma_dut_print(dut, DUT_MSG_ERROR,
13595 "classifier_type invalid");
13596 goto fail;
13597 }
13598
13599 if (total_bytes < 0)
13600 goto fail;
13601
13602 pos += total_bytes;
13603 rem_len -= total_bytes;
13604
13605 classifier_type = get_param_fmt(
13606 cmd, "TCLASElem_ClassifierType_%d_%d",
13607 num_of_scs_desc, num_of_tclas_elem + 1);
13608 }
13609
13610 if (num_of_tclas_elem > 1) {
13611 val = get_param_fmt(cmd,
13612 "TCLASProcessingElem_Processing_%d",
13613 num_of_scs_desc);
13614 if (!val) {
13615 sigma_dut_print(dut, DUT_MSG_ERROR,
13616 "Tclas_processing element %d empty",
13617 num_of_scs_desc);
13618 goto fail;
13619 }
13620
13621 len = snprintf(pos, rem_len,
13622 " tclas_processing=%s", val);
13623 if (len < 0 || len >= rem_len)
13624 goto fail;
13625
13626 pos += len;
13627 rem_len -= len;
13628 }
13629scs_desc_end:
13630 num_of_tclas_elem = 0;
13631 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
13632 num_of_scs_desc + 1);
13633 }
13634
13635 if (wpa_command(intf, buf) != 0) {
13636 send_resp(dut, conn, SIGMA_ERROR,
13637 "ErrorCode,Failed to send SCS frame request");
13638 return STATUS_SENT_ERROR;
13639 }
13640
13641 sigma_dut_print(dut, DUT_MSG_DEBUG,
13642 "SCS frame request sent: %s", buf);
13643
13644 return SUCCESS_SEND_STATUS;
13645fail:
13646 sigma_dut_print(dut, DUT_MSG_ERROR,
13647 "Failed to create SCS frame request");
13648 return ERROR_SEND_STATUS;
13649}
13650
13651
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013652static enum sigma_cmd_result
13653cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
13654 const char *intf, struct sigma_cmd *cmd)
13655{
13656 char buf[128], *pos;
13657 const char *val, *classifier_type = "04", *type;
13658 int len, rem_len;
13659 u8 up_bitmap;
13660
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013661 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013662 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013663 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013664 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013665 return INVALID_SEND_STATUS;
13666 }
13667
13668 rem_len = sizeof(buf);
13669 pos = buf;
13670 if (strcasecmp(type, "add") == 0) {
13671 len = snprintf(pos, rem_len, "MSCS add");
13672 } else if (strcasecmp(type, "update") == 0) {
13673 len = snprintf(pos, rem_len, "MSCS change");
13674 } else if (strcasecmp(type, "remove") == 0) {
13675 if (wpa_command(intf, "MSCS remove") != 0) {
13676 send_resp(dut, conn, SIGMA_ERROR,
13677 "ErrorCode,Failed to send MSCS frame req");
13678 return STATUS_SENT_ERROR;
13679 }
13680 return SUCCESS_SEND_STATUS;
13681 } else {
13682 sigma_dut_print(dut, DUT_MSG_ERROR,
13683 "%s: request type invalid", __func__);
13684 return INVALID_SEND_STATUS;
13685 }
13686
13687 if (len < 0 || len >= rem_len)
13688 goto fail;
13689
13690 pos += len;
13691 rem_len -= len;
13692
13693 val = get_param(cmd, "User_Priority_Bitmap");
13694 if (!val) {
13695 sigma_dut_print(dut, DUT_MSG_ERROR,
13696 "%s: user priority bitmap empty", __func__);
13697 return INVALID_SEND_STATUS;
13698 }
13699
13700 switch (atoi(val)) {
13701 case 0:
13702 up_bitmap = 0x00;
13703 break;
13704 case 1:
13705 up_bitmap = 0xF0;
13706 break;
13707 case 2:
13708 up_bitmap = 0xF6;
13709 break;
13710 default:
13711 sigma_dut_print(dut, DUT_MSG_ERROR,
13712 "%s: Unknown User_Priority_Bitmap value %d",
13713 __func__, atoi(val));
13714 return INVALID_SEND_STATUS;
13715 }
13716
13717 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
13718 if (len < 0 || len >= rem_len)
13719 goto fail;
13720
13721 pos += len;
13722 rem_len -= len;
13723
13724 val = get_param(cmd, "User_Priority_Limit");
13725 if (!val) {
13726 sigma_dut_print(dut, DUT_MSG_ERROR,
13727 "%s: invalid user priority limit", __func__);
13728 return INVALID_SEND_STATUS;
13729 }
13730
13731 len = snprintf(pos, rem_len, " up_limit=%s", val);
13732 if (len < 0 || len >= rem_len)
13733 goto fail;
13734
13735 pos += len;
13736 rem_len -= len;
13737
13738 val = get_param(cmd, "Stream_Timeout");
13739 if (!val)
13740 val = get_param(cmd, "Stream_Timtout");
13741 if (!val) {
13742 sigma_dut_print(dut, DUT_MSG_ERROR,
13743 "%s: invalid stream timeout", __func__);
13744 return INVALID_SEND_STATUS;
13745 }
13746
13747 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
13748 if (len < 0 || len >= rem_len)
13749 goto fail;
13750
13751 pos += len;
13752 rem_len -= len;
13753
13754 val = get_param(cmd, "TCLAS_Mask");
13755 if (!val) {
13756 sigma_dut_print(dut, DUT_MSG_ERROR,
13757 "%s: invalid tclas mask", __func__);
13758 return INVALID_SEND_STATUS;
13759 }
13760
13761 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
13762 classifier_type, strtol(val, NULL, 2), 0);
13763 if (len < 0 || len >= rem_len)
13764 goto fail;
13765
13766 if (wpa_command(intf, buf) != 0) {
13767 send_resp(dut, conn, SIGMA_ERROR,
13768 "ErrorCode,Failed to send MSCS frame req");
13769 return STATUS_SENT_ERROR;
13770 }
13771
13772 sigma_dut_print(dut, DUT_MSG_DEBUG,
13773 "MSCS frame request sent: %s", buf);
13774
13775 return SUCCESS_SEND_STATUS;
13776fail:
13777 sigma_dut_print(dut, DUT_MSG_ERROR,
13778 "Failed to create MSCS frame req");
13779 return ERROR_SEND_STATUS;
13780}
13781
13782
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013783static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013784cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13785 const char *intf, struct sigma_cmd *cmd)
13786{
13787 char buf[150], *pos;
13788 const char *val;
13789 int len, rem_len;
13790
13791 rem_len = sizeof(buf);
13792 pos = buf;
13793
13794 len = snprintf(pos, rem_len, "DSCP_QUERY");
13795 if (len < 0 || len >= rem_len)
13796 goto fail;
13797
13798 pos += len;
13799 rem_len -= len;
13800
13801 val = get_param(cmd, "Wildcard");
13802 if (val && strcasecmp(val, "Yes") == 0) {
13803 len = snprintf(pos, rem_len, " wildcard");
13804 if (len < 0 || len >= rem_len)
13805 goto fail;
13806 } else if (strlen(dut->qm_domain_name)) {
13807 len = snprintf(pos, rem_len, " domain_name=%s",
13808 dut->qm_domain_name);
13809 if (len < 0 || len >= rem_len)
13810 goto fail;
13811 } else {
13812 sigma_dut_print(dut, DUT_MSG_ERROR,
13813 "Invalid DSCP Query configuration");
13814 return INVALID_SEND_STATUS;
13815 }
13816
13817 if (wpa_command(intf, buf) != 0) {
13818 send_resp(dut, conn, SIGMA_ERROR,
13819 "ErrorCode,Failed to send DSCP policy query frame");
13820 return STATUS_SENT_ERROR;
13821 }
13822
13823 sigma_dut_print(dut, DUT_MSG_DEBUG,
13824 "DSCP policy query frame sent: %s", buf);
13825 return SUCCESS_SEND_STATUS;
13826fail:
13827 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
13828 return ERROR_SEND_STATUS;
13829}
13830
13831
13832static enum sigma_cmd_result
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013833cmd_sta_send_frame_dscp_response(struct sigma_dut *dut, struct sigma_conn *conn,
13834 const char *intf, struct sigma_cmd *cmd)
13835{
13836 char buf[256], *pos, *item, *list, *saveptr;
13837 const char *val;
13838 int len, rem_len;
13839
13840 pos = buf;
13841 rem_len = sizeof(buf);
13842
13843 len = snprintf(pos, rem_len, "DSCP_RESP");
13844 if (snprintf_error(rem_len, len)) {
13845 sigma_dut_print(dut, DUT_MSG_ERROR,
13846 "Failed to create DSCP Policy Response command");
13847 return ERROR_SEND_STATUS;
13848 }
13849
13850 pos += len;
13851 rem_len -= len;
13852
13853 val = get_param(cmd, "PolicyID_List");
13854 if (!val) {
13855 sigma_dut_print(dut, DUT_MSG_ERROR,
13856 "DSCP policy ID list missing");
13857 return INVALID_SEND_STATUS;
13858 }
13859
13860 list = strdup(val);
13861 if (!list)
13862 return ERROR_SEND_STATUS;
13863
13864 item = strtok_r(list, "_", &saveptr);
13865 while (item) {
13866 unsigned int i;
13867 int policy_id = atoi(item);
13868
13869 for (i = 0; i < dut->num_dscp_status; i++)
13870 if (dut->dscp_status[i].id == policy_id)
13871 break;
13872
13873 if (i == dut->num_dscp_status) {
13874 free(list);
13875 send_resp(dut, conn, SIGMA_ERROR,
13876 "ErrorCode,DSCP policy id not found in status list");
13877 return STATUS_SENT_ERROR;
13878 }
13879
13880 len = snprintf(pos, rem_len, " policy_id=%d status=%d",
13881 policy_id, dut->dscp_status[i].status);
13882 if (snprintf_error(rem_len, len)) {
13883 free(list);
13884 sigma_dut_print(dut, DUT_MSG_ERROR,
13885 "Failed to write DSCP policy list");
13886 return ERROR_SEND_STATUS;
13887 }
13888
13889 pos += len;
13890 rem_len -= len;
13891
13892 if (dut->dscp_status[i].status)
13893 remove_dscp_policy(dut, policy_id);
13894
13895 item = strtok_r(NULL, "_", &saveptr);
13896 }
13897
13898 free(list);
13899
13900 if (wpa_command(intf, buf) != 0) {
13901 send_resp(dut, conn, SIGMA_ERROR,
13902 "ErrorCode,Failed to send DSCP Policy Response frame");
13903 return STATUS_SENT_ERROR;
13904 }
13905
13906 sigma_dut_print(dut, DUT_MSG_DEBUG,
13907 "DSCP Policy Response frame sent: %s", buf);
13908 return SUCCESS_SEND_STATUS;
13909}
13910
13911
13912static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013913cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
13914 const char *intf, struct sigma_cmd *cmd)
13915{
13916 const char *val;
13917
13918 val = get_param(cmd, "FrameName");
13919 if (val) {
13920 if (strcasecmp(val, "MSCSReq") == 0)
13921 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
13922 if (strcasecmp(val, "SCSReq") == 0)
13923 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013924 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
13925 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
13926 cmd);
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013927 if (strcasecmp(val, "DSCPPolicyResponse") == 0)
13928 return cmd_sta_send_frame_dscp_response(dut, conn, intf,
13929 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013930
13931 sigma_dut_print(dut, DUT_MSG_ERROR,
13932 "%s: frame name - %s is invalid",
13933 __func__, val);
13934 }
13935
13936 return INVALID_SEND_STATUS;
13937}
13938
13939
Jouni Malinenf7222712019-06-13 01:50:21 +030013940enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
13941 struct sigma_conn *conn,
13942 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013943{
13944 const char *intf = get_param(cmd, "Interface");
13945 const char *val;
13946 enum send_frame_type frame;
13947 enum send_frame_protection protected;
13948 char buf[100];
13949 unsigned char addr[ETH_ALEN];
13950 int res;
13951
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030013952 if (!intf)
13953 return -1;
13954
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013955 val = get_param(cmd, "program");
13956 if (val == NULL)
13957 val = get_param(cmd, "frame");
13958 if (val && strcasecmp(val, "TDLS") == 0)
13959 return cmd_sta_send_frame_tdls(dut, conn, cmd);
13960 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030013961 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020013962 strcasecmp(val, "HS2-R3") == 0 ||
13963 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013964 return cmd_sta_send_frame_hs2(dut, conn, cmd);
13965 if (val && strcasecmp(val, "VHT") == 0)
13966 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070013967 if (val && strcasecmp(val, "HE") == 0)
13968 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070013969 if (val && strcasecmp(val, "LOC") == 0)
13970 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020013971 if (val && strcasecmp(val, "60GHz") == 0)
13972 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013973 if (val && strcasecmp(val, "MBO") == 0) {
13974 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
13975 if (res != 2)
13976 return res;
13977 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013978 if (val && strcasecmp(val, "WPA3") == 0)
13979 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013980 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013981 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013982
13983 val = get_param(cmd, "TD_DISC");
13984 if (val) {
13985 if (hwaddr_aton(val, addr) < 0)
13986 return -1;
13987 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
13988 if (wpa_command(intf, buf) < 0) {
13989 send_resp(dut, conn, SIGMA_ERROR,
13990 "ErrorCode,Failed to send TDLS discovery");
13991 return 0;
13992 }
13993 return 1;
13994 }
13995
13996 val = get_param(cmd, "TD_Setup");
13997 if (val) {
13998 if (hwaddr_aton(val, addr) < 0)
13999 return -1;
14000 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
14001 if (wpa_command(intf, buf) < 0) {
14002 send_resp(dut, conn, SIGMA_ERROR,
14003 "ErrorCode,Failed to start TDLS setup");
14004 return 0;
14005 }
14006 return 1;
14007 }
14008
14009 val = get_param(cmd, "TD_TearDown");
14010 if (val) {
14011 if (hwaddr_aton(val, addr) < 0)
14012 return -1;
14013 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
14014 if (wpa_command(intf, buf) < 0) {
14015 send_resp(dut, conn, SIGMA_ERROR,
14016 "ErrorCode,Failed to tear down TDLS link");
14017 return 0;
14018 }
14019 return 1;
14020 }
14021
14022 val = get_param(cmd, "TD_ChannelSwitch");
14023 if (val) {
14024 /* TODO */
14025 send_resp(dut, conn, SIGMA_ERROR,
14026 "ErrorCode,TD_ChannelSwitch not yet supported");
14027 return 0;
14028 }
14029
14030 val = get_param(cmd, "TD_NF");
14031 if (val) {
14032 /* TODO */
14033 send_resp(dut, conn, SIGMA_ERROR,
14034 "ErrorCode,TD_NF not yet supported");
14035 return 0;
14036 }
14037
14038 val = get_param(cmd, "PMFFrameType");
14039 if (val == NULL)
14040 val = get_param(cmd, "FrameName");
14041 if (val == NULL)
14042 val = get_param(cmd, "Type");
14043 if (val == NULL)
14044 return -1;
14045 if (strcasecmp(val, "disassoc") == 0)
14046 frame = DISASSOC;
14047 else if (strcasecmp(val, "deauth") == 0)
14048 frame = DEAUTH;
14049 else if (strcasecmp(val, "saquery") == 0)
14050 frame = SAQUERY;
14051 else if (strcasecmp(val, "auth") == 0)
14052 frame = AUTH;
14053 else if (strcasecmp(val, "assocreq") == 0)
14054 frame = ASSOCREQ;
14055 else if (strcasecmp(val, "reassocreq") == 0)
14056 frame = REASSOCREQ;
14057 else if (strcasecmp(val, "neigreq") == 0) {
14058 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
14059
14060 val = get_param(cmd, "ssid");
14061 if (val == NULL)
14062 return -1;
14063
14064 res = send_neighbor_request(dut, intf, val);
14065 if (res) {
14066 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14067 "Failed to send neighbor report request");
14068 return 0;
14069 }
14070
14071 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053014072 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
14073 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014074 sigma_dut_print(dut, DUT_MSG_DEBUG,
14075 "Got Transition Management Query");
14076
Ashwini Patil5acd7382017-04-13 15:55:04 +053014077 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014078 if (res) {
14079 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14080 "Failed to send Transition Management Query");
14081 return 0;
14082 }
14083
14084 return 1;
14085 } else {
14086 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14087 "PMFFrameType");
14088 return 0;
14089 }
14090
14091 val = get_param(cmd, "PMFProtected");
14092 if (val == NULL)
14093 val = get_param(cmd, "Protected");
14094 if (val == NULL)
14095 return -1;
14096 if (strcasecmp(val, "Correct-key") == 0 ||
14097 strcasecmp(val, "CorrectKey") == 0)
14098 protected = CORRECT_KEY;
14099 else if (strcasecmp(val, "IncorrectKey") == 0)
14100 protected = INCORRECT_KEY;
14101 else if (strcasecmp(val, "Unprotected") == 0)
14102 protected = UNPROTECTED;
14103 else {
14104 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14105 "PMFProtected");
14106 return 0;
14107 }
14108
14109 if (protected != UNPROTECTED &&
14110 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
14111 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
14112 "PMFProtected for auth/assocreq/reassocreq");
14113 return 0;
14114 }
14115
14116 if (if_nametoindex("sigmadut") == 0) {
14117 snprintf(buf, sizeof(buf),
14118 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014119 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014120 if (system(buf) != 0 ||
14121 if_nametoindex("sigmadut") == 0) {
14122 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
14123 "monitor interface with '%s'", buf);
14124 return -2;
14125 }
14126 }
14127
14128 if (system("ifconfig sigmadut up") != 0) {
14129 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
14130 "monitor interface up");
14131 return -2;
14132 }
14133
Veerendranath Jakkam49774122020-07-05 09:52:18 +053014134 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014135}
14136
14137
14138static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
14139 struct sigma_conn *conn,
14140 struct sigma_cmd *cmd,
14141 const char *ifname)
14142{
14143 char buf[200];
14144 const char *val;
14145
14146 val = get_param(cmd, "ClearARP");
14147 if (val && atoi(val) == 1) {
14148 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
14149 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14150 if (system(buf) != 0) {
14151 send_resp(dut, conn, SIGMA_ERROR,
14152 "errorCode,Failed to clear ARP cache");
14153 return 0;
14154 }
14155 }
14156
14157 return 1;
14158}
14159
14160
14161int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
14162 struct sigma_cmd *cmd)
14163{
14164 const char *intf = get_param(cmd, "Interface");
14165 const char *val;
14166
14167 if (intf == NULL)
14168 return -1;
14169
14170 val = get_param(cmd, "program");
14171 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014172 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014173 strcasecmp(val, "HS2-R3") == 0 ||
14174 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014175 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
14176
14177 return -1;
14178}
14179
14180
Jouni Malinenf7222712019-06-13 01:50:21 +030014181static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
14182 struct sigma_conn *conn,
14183 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014184{
14185 const char *intf = get_param(cmd, "Interface");
14186 const char *mac = get_param(cmd, "MAC");
14187
14188 if (intf == NULL || mac == NULL)
14189 return -1;
14190
14191 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
14192 "interface %s to %s", intf, mac);
14193
14194 if (dut->set_macaddr) {
14195 char buf[128];
14196 int res;
14197 if (strcasecmp(mac, "default") == 0) {
14198 res = snprintf(buf, sizeof(buf), "%s",
14199 dut->set_macaddr);
14200 dut->tmp_mac_addr = 0;
14201 } else {
14202 res = snprintf(buf, sizeof(buf), "%s %s",
14203 dut->set_macaddr, mac);
14204 dut->tmp_mac_addr = 1;
14205 }
14206 if (res < 0 || res >= (int) sizeof(buf))
14207 return -1;
14208 if (system(buf) != 0) {
14209 send_resp(dut, conn, SIGMA_ERROR,
14210 "errorCode,Failed to set MAC "
14211 "address");
14212 return 0;
14213 }
14214 return 1;
14215 }
14216
14217 if (strcasecmp(mac, "default") == 0)
14218 return 1;
14219
14220 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14221 "command");
14222 return 0;
14223}
14224
14225
14226static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
14227 struct sigma_conn *conn, const char *intf,
14228 int val)
14229{
14230 char buf[200];
14231 int res;
14232
14233 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
14234 intf, val);
14235 if (res < 0 || res >= (int) sizeof(buf))
14236 return -1;
14237 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14238 if (system(buf) != 0) {
14239 send_resp(dut, conn, SIGMA_ERROR,
14240 "errorCode,Failed to configure offchannel mode");
14241 return 0;
14242 }
14243
14244 return 1;
14245}
14246
14247
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014248static int off_chan_val(enum sec_ch_offset off)
14249{
14250 switch (off) {
14251 case SEC_CH_NO:
14252 return 0;
14253 case SEC_CH_40ABOVE:
14254 return 40;
14255 case SEC_CH_40BELOW:
14256 return -40;
14257 }
14258
14259 return 0;
14260}
14261
14262
14263static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
14264 const char *intf, int off_ch_num,
14265 enum sec_ch_offset sec)
14266{
14267 char buf[200];
14268 int res;
14269
14270 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
14271 intf, off_ch_num);
14272 if (res < 0 || res >= (int) sizeof(buf))
14273 return -1;
14274 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14275 if (system(buf) != 0) {
14276 send_resp(dut, conn, SIGMA_ERROR,
14277 "errorCode,Failed to set offchan");
14278 return 0;
14279 }
14280
14281 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
14282 intf, off_chan_val(sec));
14283 if (res < 0 || res >= (int) sizeof(buf))
14284 return -1;
14285 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14286 if (system(buf) != 0) {
14287 send_resp(dut, conn, SIGMA_ERROR,
14288 "errorCode,Failed to set sec chan offset");
14289 return 0;
14290 }
14291
14292 return 1;
14293}
14294
14295
14296static int tdls_set_offchannel_offset(struct sigma_dut *dut,
14297 struct sigma_conn *conn,
14298 const char *intf, int off_ch_num,
14299 enum sec_ch_offset sec)
14300{
14301 char buf[200];
14302 int res;
14303
14304 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
14305 off_ch_num);
14306 if (res < 0 || res >= (int) sizeof(buf))
14307 return -1;
14308 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14309
14310 if (wpa_command(intf, buf) < 0) {
14311 send_resp(dut, conn, SIGMA_ERROR,
14312 "ErrorCode,Failed to set offchan");
14313 return 0;
14314 }
14315 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
14316 off_chan_val(sec));
14317 if (res < 0 || res >= (int) sizeof(buf))
14318 return -1;
14319
14320 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14321
14322 if (wpa_command(intf, buf) < 0) {
14323 send_resp(dut, conn, SIGMA_ERROR,
14324 "ErrorCode,Failed to set sec chan offset");
14325 return 0;
14326 }
14327
14328 return 1;
14329}
14330
14331
14332static int tdls_set_offchannel_mode(struct sigma_dut *dut,
14333 struct sigma_conn *conn,
14334 const char *intf, int val)
14335{
14336 char buf[200];
14337 int res;
14338
14339 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
14340 val);
14341 if (res < 0 || res >= (int) sizeof(buf))
14342 return -1;
14343 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14344
14345 if (wpa_command(intf, buf) < 0) {
14346 send_resp(dut, conn, SIGMA_ERROR,
14347 "ErrorCode,Failed to configure offchannel mode");
14348 return 0;
14349 }
14350
14351 return 1;
14352}
14353
14354
14355static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
14356 struct sigma_conn *conn,
14357 struct sigma_cmd *cmd)
14358{
14359 const char *val;
14360 enum {
14361 CHSM_NOT_SET,
14362 CHSM_ENABLE,
14363 CHSM_DISABLE,
14364 CHSM_REJREQ,
14365 CHSM_UNSOLRESP
14366 } chsm = CHSM_NOT_SET;
14367 int off_ch_num = -1;
14368 enum sec_ch_offset sec_ch = SEC_CH_NO;
14369 int res;
14370
14371 val = get_param(cmd, "Uapsd");
14372 if (val) {
14373 char buf[100];
14374 if (strcasecmp(val, "Enable") == 0)
14375 snprintf(buf, sizeof(buf), "SET ps 99");
14376 else if (strcasecmp(val, "Disable") == 0)
14377 snprintf(buf, sizeof(buf), "SET ps 98");
14378 else {
14379 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14380 "Unsupported uapsd parameter value");
14381 return 0;
14382 }
14383 if (wpa_command(intf, buf)) {
14384 send_resp(dut, conn, SIGMA_ERROR,
14385 "ErrorCode,Failed to change U-APSD "
14386 "powersave mode");
14387 return 0;
14388 }
14389 }
14390
14391 val = get_param(cmd, "TPKTIMER");
14392 if (val && strcasecmp(val, "DISABLE") == 0) {
14393 if (wpa_command(intf, "SET tdls_testing 0x100")) {
14394 send_resp(dut, conn, SIGMA_ERROR,
14395 "ErrorCode,Failed to enable no TPK "
14396 "expiration test mode");
14397 return 0;
14398 }
14399 dut->no_tpk_expiration = 1;
14400 }
14401
14402 val = get_param(cmd, "ChSwitchMode");
14403 if (val) {
14404 if (strcasecmp(val, "Enable") == 0 ||
14405 strcasecmp(val, "Initiate") == 0)
14406 chsm = CHSM_ENABLE;
14407 else if (strcasecmp(val, "Disable") == 0 ||
14408 strcasecmp(val, "passive") == 0)
14409 chsm = CHSM_DISABLE;
14410 else if (strcasecmp(val, "RejReq") == 0)
14411 chsm = CHSM_REJREQ;
14412 else if (strcasecmp(val, "UnSolResp") == 0)
14413 chsm = CHSM_UNSOLRESP;
14414 else {
14415 send_resp(dut, conn, SIGMA_ERROR,
14416 "ErrorCode,Unknown ChSwitchMode value");
14417 return 0;
14418 }
14419 }
14420
14421 val = get_param(cmd, "OffChNum");
14422 if (val) {
14423 off_ch_num = atoi(val);
14424 if (off_ch_num == 0) {
14425 send_resp(dut, conn, SIGMA_ERROR,
14426 "ErrorCode,Invalid OffChNum");
14427 return 0;
14428 }
14429 }
14430
14431 val = get_param(cmd, "SecChOffset");
14432 if (val) {
14433 if (strcmp(val, "20") == 0)
14434 sec_ch = SEC_CH_NO;
14435 else if (strcasecmp(val, "40above") == 0)
14436 sec_ch = SEC_CH_40ABOVE;
14437 else if (strcasecmp(val, "40below") == 0)
14438 sec_ch = SEC_CH_40BELOW;
14439 else {
14440 send_resp(dut, conn, SIGMA_ERROR,
14441 "ErrorCode,Unknown SecChOffset value");
14442 return 0;
14443 }
14444 }
14445
14446 if (chsm == CHSM_NOT_SET) {
14447 /* no offchannel changes requested */
14448 return 1;
14449 }
14450
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014451 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
14452 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014453 send_resp(dut, conn, SIGMA_ERROR,
14454 "ErrorCode,Unknown interface");
14455 return 0;
14456 }
14457
14458 switch (chsm) {
14459 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030014460 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014461 break;
14462 case CHSM_ENABLE:
14463 if (off_ch_num < 0) {
14464 send_resp(dut, conn, SIGMA_ERROR,
14465 "ErrorCode,Missing OffChNum argument");
14466 return 0;
14467 }
14468 if (wifi_chip_type == DRIVER_WCN) {
14469 res = tdls_set_offchannel_offset(dut, conn, intf,
14470 off_ch_num, sec_ch);
14471 } else {
14472 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14473 sec_ch);
14474 }
14475 if (res != 1)
14476 return res;
14477 if (wifi_chip_type == DRIVER_WCN)
14478 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
14479 else
14480 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
14481 break;
14482 case CHSM_DISABLE:
14483 if (wifi_chip_type == DRIVER_WCN)
14484 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
14485 else
14486 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
14487 break;
14488 case CHSM_REJREQ:
14489 if (wifi_chip_type == DRIVER_WCN)
14490 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
14491 else
14492 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
14493 break;
14494 case CHSM_UNSOLRESP:
14495 if (off_ch_num < 0) {
14496 send_resp(dut, conn, SIGMA_ERROR,
14497 "ErrorCode,Missing OffChNum argument");
14498 return 0;
14499 }
14500 if (wifi_chip_type == DRIVER_WCN) {
14501 res = tdls_set_offchannel_offset(dut, conn, intf,
14502 off_ch_num, sec_ch);
14503 } else {
14504 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14505 sec_ch);
14506 }
14507 if (res != 1)
14508 return res;
14509 if (wifi_chip_type == DRIVER_WCN)
14510 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
14511 else
14512 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
14513 break;
14514 }
14515
14516 return res;
14517}
14518
14519
14520static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14521 struct sigma_conn *conn,
14522 struct sigma_cmd *cmd)
14523{
14524 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014525 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014526
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070014527 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080014528
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014529 val = get_param(cmd, "nss_mcs_opt");
14530 if (val) {
14531 /* String (nss_operating_mode; mcs_operating_mode) */
14532 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014533 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014534
14535 token = strdup(val);
14536 if (!token)
14537 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014538 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014539 if (!result) {
14540 sigma_dut_print(dut, DUT_MSG_ERROR,
14541 "VHT NSS not specified");
14542 goto failed;
14543 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014544 if (strcasecmp(result, "def") != 0) {
14545 nss = atoi(result);
14546 if (nss == 4)
14547 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014548 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014549 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014550
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014551 }
14552
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014553 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014554 if (!result) {
14555 sigma_dut_print(dut, DUT_MSG_ERROR,
14556 "VHT MCS not specified");
14557 goto failed;
14558 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014559 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014560 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014561 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014562 } else {
14563 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014564 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014565 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014566 }
14567 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014568 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014569 }
14570
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014571 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014572 return 1;
14573failed:
14574 free(token);
14575 return 0;
14576}
14577
14578
14579static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14580 struct sigma_conn *conn,
14581 struct sigma_cmd *cmd)
14582{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014583 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014584 case DRIVER_ATHEROS:
14585 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
14586 default:
14587 send_resp(dut, conn, SIGMA_ERROR,
14588 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
14589 return 0;
14590 }
14591}
14592
14593
Jouni Malinen1702fe32021-06-08 19:08:01 +030014594static enum sigma_cmd_result
14595wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14596 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014597{
14598 const char *val;
14599 char *token = NULL, *result;
14600 char buf[60];
14601
14602 val = get_param(cmd, "nss_mcs_opt");
14603 if (val) {
14604 /* String (nss_operating_mode; mcs_operating_mode) */
14605 int nss, mcs, ratecode;
14606 char *saveptr;
14607
14608 token = strdup(val);
14609 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014610 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014611
14612 result = strtok_r(token, ";", &saveptr);
14613 if (!result) {
14614 sigma_dut_print(dut, DUT_MSG_ERROR,
14615 "HE NSS not specified");
14616 goto failed;
14617 }
14618 nss = 1;
14619 if (strcasecmp(result, "def") != 0)
14620 nss = atoi(result);
14621
14622 result = strtok_r(NULL, ";", &saveptr);
14623 if (!result) {
14624 sigma_dut_print(dut, DUT_MSG_ERROR,
14625 "HE MCS not specified");
14626 goto failed;
14627 }
14628 mcs = 7;
14629 if (strcasecmp(result, "def") != 0)
14630 mcs = atoi(result);
14631
Arif Hussain557bf412018-05-25 17:29:36 -070014632 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014633 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070014634 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014635 } else if (nss > 2) {
14636 sigma_dut_print(dut, DUT_MSG_ERROR,
14637 "HE NSS %d not supported", nss);
14638 goto failed;
14639 }
14640
Arif Hussain557bf412018-05-25 17:29:36 -070014641 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
14642 if (system(buf) != 0) {
14643 sigma_dut_print(dut, DUT_MSG_ERROR,
14644 "nss_mcs_opt: iwpriv %s nss %d failed",
14645 intf, nss);
14646 goto failed;
14647 }
Arif Hussainac6c5112018-05-25 17:34:00 -070014648 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070014649
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014650 /* Add the MCS to the ratecode */
14651 if (mcs >= 0 && mcs <= 11) {
14652 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070014653#ifdef NL80211_SUPPORT
14654 if (dut->device_type == STA_testbed) {
14655 enum he_mcs_config mcs_config;
14656 int ret;
14657
14658 if (mcs <= 7)
14659 mcs_config = HE_80_MCS0_7;
14660 else if (mcs <= 9)
14661 mcs_config = HE_80_MCS0_9;
14662 else
14663 mcs_config = HE_80_MCS0_11;
14664 ret = sta_set_he_mcs(dut, intf, mcs_config);
14665 if (ret) {
14666 sigma_dut_print(dut, DUT_MSG_ERROR,
14667 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
14668 mcs, mcs_config, ret);
14669 goto failed;
14670 }
14671 }
14672#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014673 } else {
14674 sigma_dut_print(dut, DUT_MSG_ERROR,
14675 "HE MCS %d not supported", mcs);
14676 goto failed;
14677 }
14678 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
14679 intf, ratecode);
14680 if (system(buf) != 0) {
14681 sigma_dut_print(dut, DUT_MSG_ERROR,
14682 "iwpriv setting of 11ax rates failed");
14683 goto failed;
14684 }
14685 free(token);
14686 }
14687
14688 val = get_param(cmd, "GI");
14689 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014690 int fix_rate_sgi;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014691 u8 he_gi_val = 0;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014692
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014693 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014694 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014695 fix_rate_sgi = 1;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014696 he_gi_val = NL80211_RATE_INFO_HE_GI_0_8;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014697 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014698 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
14699 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014700 fix_rate_sgi = 2;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014701 he_gi_val = NL80211_RATE_INFO_HE_GI_1_6;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014702 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014703 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
14704 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014705 fix_rate_sgi = 3;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014706 he_gi_val = NL80211_RATE_INFO_HE_GI_3_2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014707 } else {
14708 send_resp(dut, conn, SIGMA_ERROR,
14709 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014710 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014711 }
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014712 if (wcn_set_he_gi(dut, intf, he_gi_val)) {
14713 sigma_dut_print(dut, DUT_MSG_INFO,
14714 "wcn_set_he_gi failed, using iwpriv");
14715 if (system(buf) != 0) {
14716 send_resp(dut, conn, SIGMA_ERROR,
14717 "errorCode,Failed to set shortgi");
14718 return STATUS_SENT_ERROR;
14719 }
14720 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
14721 intf, fix_rate_sgi);
14722 if (system(buf) != 0) {
14723 send_resp(dut, conn, SIGMA_ERROR,
14724 "errorCode,Failed to set fix rate shortgi");
14725 return STATUS_SENT_ERROR;
14726 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014727 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014728 }
14729
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014730 val = get_param(cmd, "LTF");
14731 if (val) {
14732#ifdef NL80211_SUPPORT
14733 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014734 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014735 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014736 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014737 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014738 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014739 } else {
14740 send_resp(dut, conn, SIGMA_ERROR,
14741 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014742 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014743 }
14744#else /* NL80211_SUPPORT */
14745 sigma_dut_print(dut, DUT_MSG_ERROR,
14746 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014747 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014748#endif /* NL80211_SUPPORT */
14749 }
14750
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070014751 val = get_param(cmd, "KeepAlive");
14752 if (val) {
14753 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
14754
14755 if (strcasecmp(val, "Data") == 0)
14756 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
14757 else if (strcasecmp(val, "Mgmt") == 0)
14758 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
14759
14760 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
14761 send_resp(dut, conn, SIGMA_ERROR,
14762 "ErrorCode,Failed to set keep alive type config");
14763 return STATUS_SENT_ERROR;
14764 }
14765 }
14766
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014767 val = get_param(cmd, "TxSUPPDU");
14768 if (val) {
14769 int set_val = 1;
14770
14771 if (strcasecmp(val, "Enable") == 0)
14772 set_val = 1;
14773 else if (strcasecmp(val, "Disable") == 0)
14774 set_val = 0;
14775
14776 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
14777 send_resp(dut, conn, SIGMA_ERROR,
14778 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014779 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014780 }
14781 }
14782
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070014783 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
14784 if (val) {
14785 int set_val = 0;
14786
14787 if (strcasecmp(val, "Enable") == 0)
14788 set_val = 0;
14789 else if (strcasecmp(val, "Disable") == 0)
14790 set_val = 1;
14791
14792 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
14793 send_resp(dut, conn, SIGMA_ERROR,
14794 "ErrorCode,Failed to set mgmt/data Tx disable config");
14795 return STATUS_SENT_ERROR;
14796 }
14797 }
14798
Arif Hussain480d5f42019-03-12 14:40:42 -070014799 val = get_param(cmd, "TWT_Setup");
14800 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014801#ifdef NL80211_SUPPORT
14802 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14803 sigma_dut_print(dut, DUT_MSG_ERROR,
14804 "Failed to open nl80211 event socket");
14805#endif /* NL80211_SUPPORT */
Arif Hussain480d5f42019-03-12 14:40:42 -070014806 if (strcasecmp(val, "Request") == 0) {
Kiran Kumar Lokereafac46a2021-11-29 14:03:20 -080014807 if (set_power_save_wcn(dut, intf, 1) < 0)
14808 sigma_dut_print(dut, DUT_MSG_ERROR,
14809 "Failed to enable power save");
Arif Hussain480d5f42019-03-12 14:40:42 -070014810 if (sta_twt_request(dut, conn, cmd)) {
14811 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014812 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014813 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014814 }
14815 } else if (strcasecmp(val, "Teardown") == 0) {
14816 if (sta_twt_teardown(dut, conn, cmd)) {
14817 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014818 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014819 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014820 }
14821 }
14822 }
14823
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014824 val = get_param(cmd, "TWT_Operation");
14825 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014826#ifdef NL80211_SUPPORT
14827 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14828 sigma_dut_print(dut, DUT_MSG_ERROR,
14829 "Failed to open nl80211 event socket");
14830#endif /* NL80211_SUPPORT */
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014831 if (strcasecmp(val, "Suspend") == 0) {
14832 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
14833 send_resp(dut, conn, SIGMA_ERROR,
14834 "ErrorCode,TWT suspend failed");
14835 return STATUS_SENT_ERROR;
14836 }
14837 } else if (strcasecmp(val, "Resume") == 0) {
14838 if (sta_twt_resume(dut, conn, cmd)) {
14839 send_resp(dut, conn, SIGMA_ERROR,
14840 "ErrorCode,TWT resume failed");
14841 return STATUS_SENT_ERROR;
14842 }
14843 }
14844 }
14845
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080014846 val = get_param(cmd, "transmitOMI");
14847 if (val && sta_transmit_omi(dut, conn, cmd)) {
14848 send_resp(dut, conn, SIGMA_ERROR,
14849 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014850 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070014851 }
14852
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014853 val = get_param(cmd, "Powersave");
14854 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014855 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014856
14857 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014858 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014859 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014860 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014861 } else {
14862 sigma_dut_print(dut, DUT_MSG_ERROR,
14863 "Unsupported Powersave value '%s'",
14864 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014865 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014866 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014867 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014868 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014869 }
14870
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080014871 val = get_param(cmd, "MU_EDCA");
14872 if (val) {
14873 if (strcasecmp(val, "Override") == 0) {
14874 if (sta_set_mu_edca_override(dut, intf, 1)) {
14875 send_resp(dut, conn, SIGMA_ERROR,
14876 "errorCode,MU EDCA override set failed");
14877 return STATUS_SENT;
14878 }
14879 } else if (strcasecmp(val, "Disable") == 0) {
14880 if (sta_set_mu_edca_override(dut, intf, 0)) {
14881 send_resp(dut, conn, SIGMA_ERROR,
14882 "errorCode,MU EDCA override disable failed");
14883 return STATUS_SENT;
14884 }
14885 }
14886 }
14887
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070014888 val = get_param(cmd, "RUAllocTone");
14889 if (val && strcasecmp(val, "242") == 0) {
14890 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
14891 send_resp(dut, conn, SIGMA_ERROR,
14892 "ErrorCode,Failed to set RU 242 tone Tx");
14893 return STATUS_SENT_ERROR;
14894 }
14895 }
14896
14897 val = get_param(cmd, "PPDUTxType");
14898 if (val && strcasecmp(val, "ER-SU") == 0) {
14899 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
14900 send_resp(dut, conn, SIGMA_ERROR,
14901 "ErrorCode,Failed to set ER-SU PPDU type Tx");
14902 return STATUS_SENT_ERROR;
14903 }
14904 }
14905
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070014906 val = get_param(cmd, "Ch_Pref");
14907 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14908 return STATUS_SENT;
14909
14910 val = get_param(cmd, "Cellular_Data_Cap");
14911 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14912 return STATUS_SENT;
14913
Jouni Malinen1702fe32021-06-08 19:08:01 +030014914 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014915
14916failed:
14917 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014918 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014919}
14920
14921
Jouni Malinen1702fe32021-06-08 19:08:01 +030014922static enum sigma_cmd_result
14923cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14924 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014925{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014926 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014927 case DRIVER_WCN:
14928 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
14929 default:
14930 send_resp(dut, conn, SIGMA_ERROR,
14931 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014932 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014933 }
14934}
14935
14936
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014937static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
14938 struct sigma_conn *conn,
14939 struct sigma_cmd *cmd)
14940{
14941 const char *val;
14942
14943 val = get_param(cmd, "powersave");
14944 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014945 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014946
14947 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014948 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014949 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014950 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014951 } else {
14952 sigma_dut_print(dut, DUT_MSG_ERROR,
14953 "Unsupported power save config");
14954 return -1;
14955 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014956 if (set_power_save_wcn(dut, intf, ps) < 0)
14957 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014958 return 1;
14959 }
14960
14961 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
14962
14963 return 0;
14964}
14965
14966
Ashwini Patil5acd7382017-04-13 15:55:04 +053014967static int btm_query_candidate_list(struct sigma_dut *dut,
14968 struct sigma_conn *conn,
14969 struct sigma_cmd *cmd)
14970{
14971 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
14972 int len, ret;
14973 char buf[10];
14974
14975 /*
14976 * Neighbor Report elements format:
14977 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
14978 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
14979 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
14980 */
14981
14982 bssid = get_param(cmd, "Nebor_BSSID");
14983 if (!bssid) {
14984 send_resp(dut, conn, SIGMA_INVALID,
14985 "errorCode,Nebor_BSSID is missing");
14986 return 0;
14987 }
14988
14989 info = get_param(cmd, "Nebor_Bssid_Info");
14990 if (!info) {
14991 sigma_dut_print(dut, DUT_MSG_INFO,
14992 "Using default value for Nebor_Bssid_Info: %s",
14993 DEFAULT_NEIGHBOR_BSSID_INFO);
14994 info = DEFAULT_NEIGHBOR_BSSID_INFO;
14995 }
14996
14997 op_class = get_param(cmd, "Nebor_Op_Class");
14998 if (!op_class) {
14999 send_resp(dut, conn, SIGMA_INVALID,
15000 "errorCode,Nebor_Op_Class is missing");
15001 return 0;
15002 }
15003
15004 ch = get_param(cmd, "Nebor_Op_Ch");
15005 if (!ch) {
15006 send_resp(dut, conn, SIGMA_INVALID,
15007 "errorCode,Nebor_Op_Ch is missing");
15008 return 0;
15009 }
15010
15011 phy_type = get_param(cmd, "Nebor_Phy_Type");
15012 if (!phy_type) {
15013 sigma_dut_print(dut, DUT_MSG_INFO,
15014 "Using default value for Nebor_Phy_Type: %s",
15015 DEFAULT_NEIGHBOR_PHY_TYPE);
15016 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
15017 }
15018
15019 /* Parse optional subelements */
15020 buf[0] = '\0';
15021 pref = get_param(cmd, "Nebor_Pref");
15022 if (pref) {
15023 /* hexdump for preferrence subelement */
15024 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
15025 if (ret < 0 || ret >= (int) sizeof(buf)) {
15026 sigma_dut_print(dut, DUT_MSG_ERROR,
15027 "snprintf failed for optional subelement ret: %d",
15028 ret);
15029 send_resp(dut, conn, SIGMA_ERROR,
15030 "errorCode,snprintf failed for subelement");
15031 return 0;
15032 }
15033 }
15034
15035 if (!dut->btm_query_cand_list) {
15036 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
15037 if (!dut->btm_query_cand_list) {
15038 send_resp(dut, conn, SIGMA_ERROR,
15039 "errorCode,Failed to allocate memory for btm_query_cand_list");
15040 return 0;
15041 }
15042 }
15043
15044 len = strlen(dut->btm_query_cand_list);
15045 ret = snprintf(dut->btm_query_cand_list + len,
15046 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
15047 bssid, info, op_class, ch, phy_type, buf);
15048 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
15049 sigma_dut_print(dut, DUT_MSG_ERROR,
15050 "snprintf failed for neighbor report list ret: %d",
15051 ret);
15052 send_resp(dut, conn, SIGMA_ERROR,
15053 "errorCode,snprintf failed for neighbor report");
15054 free(dut->btm_query_cand_list);
15055 dut->btm_query_cand_list = NULL;
15056 return 0;
15057 }
15058
15059 return 1;
15060}
15061
15062
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015063int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
15064 struct sigma_ese_alloc *allocs, int *allocs_size)
15065{
15066 int max_count = *allocs_size;
15067 int count = 0, i;
15068 const char *val;
15069
15070 do {
15071 val = get_param_indexed(cmd, "AllocID", count);
15072 if (val)
15073 count++;
15074 } while (val);
15075
15076 if (count == 0 || count > max_count) {
15077 sigma_dut_print(dut, DUT_MSG_ERROR,
15078 "Invalid number of allocations(%d)", count);
15079 return -1;
15080 }
15081
15082 for (i = 0; i < count; i++) {
15083 val = get_param_indexed(cmd, "PercentBI", i);
15084 if (!val) {
15085 sigma_dut_print(dut, DUT_MSG_ERROR,
15086 "Missing PercentBI parameter at index %d",
15087 i);
15088 return -1;
15089 }
15090 allocs[i].percent_bi = atoi(val);
15091
15092 val = get_param_indexed(cmd, "SrcAID", i);
15093 if (val)
15094 allocs[i].src_aid = strtol(val, NULL, 0);
15095 else
15096 allocs[i].src_aid = ESE_BCAST_AID;
15097
15098 val = get_param_indexed(cmd, "DestAID", i);
15099 if (val)
15100 allocs[i].dst_aid = strtol(val, NULL, 0);
15101 else
15102 allocs[i].dst_aid = ESE_BCAST_AID;
15103
15104 allocs[i].type = ESE_CBAP;
15105 sigma_dut_print(dut, DUT_MSG_INFO,
15106 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
15107 i, allocs[i].percent_bi, allocs[i].src_aid,
15108 allocs[i].dst_aid);
15109 }
15110
15111 *allocs_size = count;
15112 return 0;
15113}
15114
15115
15116static int sta_set_60g_ese(struct sigma_dut *dut, int count,
15117 struct sigma_ese_alloc *allocs)
15118{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015119 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015120#ifdef __linux__
15121 case DRIVER_WIL6210:
15122 if (wil6210_set_ese(dut, count, allocs))
15123 return -1;
15124 return 1;
15125#endif /* __linux__ */
15126 default:
15127 sigma_dut_print(dut, DUT_MSG_ERROR,
15128 "Unsupported sta_set_60g_ese with the current driver");
15129 return -1;
15130 }
15131}
15132
15133
15134static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
15135 struct sigma_conn *conn,
15136 struct sigma_cmd *cmd)
15137{
15138 const char *val;
15139
15140 val = get_param(cmd, "ExtSchIE");
15141 if (val && !strcasecmp(val, "Enable")) {
15142 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
15143 int count = MAX_ESE_ALLOCS;
15144
15145 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
15146 return -1;
15147 return sta_set_60g_ese(dut, count, allocs);
15148 }
15149
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015150 val = get_param(cmd, "MCS_FixedRate");
15151 if (val) {
15152 int sta_mcs = atoi(val);
15153
15154 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
15155 sta_mcs);
15156 wil6210_set_force_mcs(dut, 1, sta_mcs);
15157
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015158 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015159 }
15160
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015161 send_resp(dut, conn, SIGMA_ERROR,
15162 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015163 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015164}
15165
15166
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015167static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
15168 const char *oci_frametype, uint32_t oci_freq)
15169{
15170#ifdef NL80211_SUPPORT
15171 struct nl_msg *msg;
15172 int ret = 0;
15173 struct nlattr *params;
15174 struct nlattr *attr;
15175 int ifindex;
15176 u8 frame_type;
15177
15178 ifindex = if_nametoindex(intf);
15179 if (ifindex == 0) {
15180 sigma_dut_print(dut, DUT_MSG_ERROR,
15181 "%s: Index for interface %s failed",
15182 __func__, intf);
15183 return -1;
15184 }
15185
15186 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15187 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
15188 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15189 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
15190 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15191 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
15192 } else {
15193 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
15194 __func__, oci_frametype);
15195 return -1;
15196 }
15197
15198
15199 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
15200 NL80211_CMD_VENDOR)) ||
15201 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
15202 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
15203 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
15204 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
15205 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
15206 !(params = nla_nest_start(
15207 msg,
15208 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
15209 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
15210 frame_type) ||
15211 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
15212 oci_freq)) {
15213 sigma_dut_print(dut, DUT_MSG_ERROR,
15214 "%s: err in adding vendor_cmd and vendor_data",
15215 __func__);
15216 nlmsg_free(msg);
15217 return -1;
15218 }
15219 nla_nest_end(msg, params);
15220 nla_nest_end(msg, attr);
15221
15222 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
15223 if (ret) {
15224 sigma_dut_print(dut, DUT_MSG_ERROR,
15225 "%s: err in send_and_recv_msgs, ret=%d",
15226 __func__, ret);
15227 }
15228 return ret;
15229#else /* NL80211_SUPPORT */
15230 sigma_dut_print(dut, DUT_MSG_ERROR,
15231 "OCI override not possible without NL80211_SUPPORT defined");
15232 return -1;
15233#endif /* NL80211_SUPPORT */
15234}
15235
15236
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015237static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
15238 uint8_t ignore_csa)
15239{
15240#ifdef NL80211_SUPPORT
15241 return wcn_wifi_test_config_set_u8(
15242 dut, intf,
15243 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
15244#else /* NL80211_SUPPORT */
15245 sigma_dut_print(dut, DUT_MSG_ERROR,
15246 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
15247 return -1;
15248#endif /* NL80211_SUPPORT */
15249}
15250
15251
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015252static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
15253 uint8_t rsnxe_used)
15254{
15255#ifdef NL80211_SUPPORT
15256 return wcn_wifi_test_config_set_u8(
15257 dut, intf,
15258 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
15259 rsnxe_used);
15260#else /* NL80211_SUPPORT */
15261 sigma_dut_print(dut, DUT_MSG_ERROR,
15262 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
15263 return -1;
15264#endif /* NL80211_SUPPORT */
15265}
15266
15267
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015268static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
15269 const char *intf,
15270 uint8_t ignore_sa_query_timeout)
15271{
15272#ifdef NL80211_SUPPORT
15273 return wcn_wifi_test_config_set_u8(
15274 dut, intf,
15275 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
15276 ignore_sa_query_timeout);
15277#else /* NL80211_SUPPORT */
15278 sigma_dut_print(dut, DUT_MSG_ERROR,
15279 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
15280 return -1;
15281#endif /* NL80211_SUPPORT */
15282}
15283
15284
Jouni Malinen6250cb02020-04-15 13:54:45 +030015285static enum sigma_cmd_result
15286cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
15287 struct sigma_conn *conn,
15288 struct sigma_cmd *cmd)
15289{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015290 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030015291
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053015292 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030015293 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015294 if (wifi_chip_type == DRIVER_WCN) {
15295 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
15296 send_resp(dut, conn, SIGMA_ERROR,
15297 "errorCode,Failed to set ft_rsnxe_used");
15298 return STATUS_SENT_ERROR;
15299 }
15300 return SUCCESS_SEND_STATUS;
15301 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030015302 send_resp(dut, conn, SIGMA_ERROR,
15303 "errorCode,Failed to set ft_rsnxe_used");
15304 return STATUS_SENT_ERROR;
15305 }
15306 return SUCCESS_SEND_STATUS;
15307 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015308
15309 oci_chan = get_param(cmd, "OCIChannel");
15310 oci_frametype = get_param(cmd, "OCIFrameType");
15311 if (oci_chan && oci_frametype) {
15312 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
15313 char buf[100];
15314
15315 if (!oci_freq) {
15316 send_resp(dut, conn, SIGMA_ERROR,
15317 "errorCode,Invalid OCIChannel number");
15318 return STATUS_SENT_ERROR;
15319 }
15320
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015321 if (wifi_chip_type == DRIVER_WCN &&
15322 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
15323 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
15324 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
15325 if (wcn_sta_override_oci(dut, intf, oci_frametype,
15326 oci_freq)) {
15327 send_resp(dut, conn, SIGMA_ERROR,
15328 "errorCode,Failed to override OCI");
15329 return STATUS_SENT_ERROR;
15330 }
15331 return SUCCESS_SEND_STATUS;
15332 }
15333
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015334 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
15335 snprintf(buf, sizeof(buf),
15336 "SET oci_freq_override_eapol %d", oci_freq);
15337 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15338 snprintf(buf, sizeof(buf),
15339 "SET oci_freq_override_saquery_req %d",
15340 oci_freq);
15341 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15342 snprintf(buf, sizeof(buf),
15343 "SET oci_freq_override_saquery_resp %d",
15344 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015345 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
15346 snprintf(buf, sizeof(buf),
15347 "SET oci_freq_override_eapol_g2 %d",
15348 oci_freq);
15349 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15350 snprintf(buf, sizeof(buf),
15351 "SET oci_freq_override_ft_assoc %d",
15352 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015353 } else {
15354 send_resp(dut, conn, SIGMA_ERROR,
15355 "errorCode,Unsupported OCIFrameType");
15356 return STATUS_SENT_ERROR;
15357 }
15358 if (wpa_command(intf, buf) < 0) {
15359 send_resp(dut, conn, SIGMA_ERROR,
15360 "errorCode,Failed to set oci_freq_override");
15361 return STATUS_SENT_ERROR;
15362 }
15363 return SUCCESS_SEND_STATUS;
15364 }
15365
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015366 val = get_param(cmd, "IgnoreCSA");
15367 if (val && atoi(val) == 1) {
15368 if (wifi_chip_type == DRIVER_WCN) {
15369 if (wcn_sta_ignore_csa(dut, intf, 1)) {
15370 send_resp(dut, conn, SIGMA_ERROR,
15371 "errorCode,Failed to set ignore CSA");
15372 return STATUS_SENT_ERROR;
15373 }
15374 return SUCCESS_SEND_STATUS;
15375 }
15376 }
15377
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015378 val = get_param(cmd, "Deauth_Per_SAQueryResp");
15379 if (val && atoi(val) == 0) {
15380 if (wifi_chip_type == DRIVER_WCN) {
15381 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
15382 send_resp(dut, conn, SIGMA_ERROR,
15383 "errorCode,Failed to set ignore SA Query timeout");
15384 return STATUS_SENT_ERROR;
15385 }
15386 return SUCCESS_SEND_STATUS;
15387 }
15388 }
15389
Jouni Malinen6250cb02020-04-15 13:54:45 +030015390 send_resp(dut, conn, SIGMA_ERROR,
15391 "errorCode,Unsupported WPA3 rfeature");
15392 return STATUS_SENT_ERROR;
15393}
15394
15395
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015396static enum sigma_cmd_result
15397cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
15398 struct sigma_conn *conn, struct sigma_cmd *cmd)
15399{
15400 const char *val;
15401
15402 val = get_param(cmd, "DomainName_Domain");
15403 if (val) {
15404 if (strlen(val) >= sizeof(dut->qm_domain_name))
15405 return ERROR_SEND_STATUS;
15406
15407 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
15408 return SUCCESS_SEND_STATUS;
15409 }
15410
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053015411 val = get_param(cmd, "DSCPPolicy_PolicyID");
15412 if (val) {
15413 unsigned int i;
15414 int policy_id = atoi(val);
15415
15416 val = get_param(cmd, "DSCPPolicy_RequestType");
15417
15418 if (!policy_id || !val)
15419 return INVALID_SEND_STATUS;
15420
15421 if (dut->num_dscp_status >= ARRAY_SIZE(dut->dscp_status)) {
15422 send_resp(dut, conn, SIGMA_ERROR,
15423 "errorCode,DSCP status list full");
15424 return STATUS_SENT_ERROR;
15425 }
15426
15427 for (i = 0; i < dut->num_dscp_status; i++)
15428 if (dut->dscp_status[i].id == policy_id)
15429 break;
15430
15431 /* New policy configured */
15432 if (i == dut->num_dscp_status) {
15433 dut->dscp_status[i].id = policy_id;
15434 dut->num_dscp_status++;
15435 }
15436
15437 dut->dscp_status[i].status = strcasecmp(val, "Remove") ?
15438 DSCP_POLICY_SUCCESS : DSCP_POLICY_REJECT;
15439
15440 return SUCCESS_SEND_STATUS;
15441 }
15442
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015443 send_resp(dut, conn, SIGMA_ERROR,
15444 "errorCode,Unsupported QM rfeature");
15445 return STATUS_SENT_ERROR;
15446}
15447
15448
Jouni Malinenf7222712019-06-13 01:50:21 +030015449static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
15450 struct sigma_conn *conn,
15451 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015452{
15453 const char *intf = get_param(cmd, "Interface");
15454 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015455 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015456
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015457 if (!prog)
15458 prog = get_param(cmd, "Program");
15459
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015460 if (intf == NULL || prog == NULL)
15461 return -1;
15462
Ashwini Patil5acd7382017-04-13 15:55:04 +053015463 /* BSS Transition candidate list for BTM query */
15464 val = get_param(cmd, "Nebor_BSSID");
15465 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
15466 return 0;
15467
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015468 if (strcasecmp(prog, "TDLS") == 0)
15469 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
15470
15471 if (strcasecmp(prog, "VHT") == 0)
15472 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
15473
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015474 if (strcasecmp(prog, "HE") == 0)
15475 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
15476
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015477 if (strcasecmp(prog, "MBO") == 0) {
15478 val = get_param(cmd, "Cellular_Data_Cap");
15479 if (val &&
15480 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
15481 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053015482
15483 val = get_param(cmd, "Ch_Pref");
15484 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
15485 return 0;
15486
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015487 return 1;
15488 }
15489
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015490 if (strcasecmp(prog, "60GHz") == 0)
15491 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
15492
Jouni Malinen6250cb02020-04-15 13:54:45 +030015493 if (strcasecmp(prog, "WPA3") == 0)
15494 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015495 if (strcasecmp(prog, "QM") == 0)
15496 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030015497
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015498 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
15499 return 0;
15500}
15501
15502
Jouni Malinenf7222712019-06-13 01:50:21 +030015503static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
15504 struct sigma_conn *conn,
15505 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015506{
15507 const char *intf = get_param(cmd, "Interface");
15508 const char *mode = get_param(cmd, "Mode");
15509 int res;
15510
15511 if (intf == NULL || mode == NULL)
15512 return -1;
15513
15514 if (strcasecmp(mode, "On") == 0)
15515 res = wpa_command(intf, "SET radio_disabled 0");
15516 else if (strcasecmp(mode, "Off") == 0)
15517 res = wpa_command(intf, "SET radio_disabled 1");
15518 else
15519 return -1;
15520
15521 if (res) {
15522 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15523 "radio mode");
15524 return 0;
15525 }
15526
15527 return 1;
15528}
15529
15530
Jouni Malinenf7222712019-06-13 01:50:21 +030015531static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
15532 struct sigma_conn *conn,
15533 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015534{
15535 const char *intf = get_param(cmd, "Interface");
15536 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015537 const char *prog = get_param(cmd, "program");
15538 const char *powersave = get_param(cmd, "powersave");
15539 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015540
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015541 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015542 return -1;
15543
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015544 if (prog && strcasecmp(prog, "60GHz") == 0) {
15545 /*
15546 * The CAPI mode parameter does not exist in 60G
15547 * unscheduled PS.
15548 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080015549 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015550 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015551 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020015552 strcasecmp(prog, "HE") == 0) {
15553 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015554 } else {
15555 if (mode == NULL)
15556 return -1;
15557
15558 if (strcasecmp(mode, "On") == 0)
15559 res = set_ps(intf, dut, 1);
15560 else if (strcasecmp(mode, "Off") == 0)
15561 res = set_ps(intf, dut, 0);
15562 else
15563 return -1;
15564 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015565
15566 if (res) {
15567 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15568 "power save mode");
15569 return 0;
15570 }
15571
15572 return 1;
15573}
15574
15575
Jouni Malinenf7222712019-06-13 01:50:21 +030015576static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
15577 struct sigma_conn *conn,
15578 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015579{
15580 const char *intf = get_param(cmd, "Interface");
15581 const char *val, *bssid;
15582 int res;
15583 char *buf;
15584 size_t buf_len;
15585
15586 val = get_param(cmd, "BSSID_FILTER");
15587 if (val == NULL)
15588 return -1;
15589
15590 bssid = get_param(cmd, "BSSID_List");
15591 if (atoi(val) == 0 || bssid == NULL) {
15592 /* Disable BSSID filter */
15593 if (wpa_command(intf, "SET bssid_filter ")) {
15594 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
15595 "to disable BSSID filter");
15596 return 0;
15597 }
15598
15599 return 1;
15600 }
15601
15602 buf_len = 100 + strlen(bssid);
15603 buf = malloc(buf_len);
15604 if (buf == NULL)
15605 return -1;
15606
15607 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
15608 res = wpa_command(intf, buf);
15609 free(buf);
15610 if (res) {
15611 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
15612 "BSSID filter");
15613 return 0;
15614 }
15615
15616 return 1;
15617}
15618
15619
Jouni Malinenf7222712019-06-13 01:50:21 +030015620static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
15621 struct sigma_conn *conn,
15622 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015623{
15624 const char *intf = get_param(cmd, "Interface");
15625 const char *val;
15626
15627 /* TODO: ARP */
15628
15629 val = get_param(cmd, "HS2_CACHE_PROFILE");
15630 if (val && strcasecmp(val, "All") == 0)
15631 hs2_clear_credentials(intf);
15632
15633 return 1;
15634}
15635
15636
Jouni Malinenf7222712019-06-13 01:50:21 +030015637static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
15638 struct sigma_conn *conn,
15639 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015640{
15641 const char *intf = get_param(cmd, "Interface");
15642 const char *key_type = get_param(cmd, "KeyType");
15643 char buf[100], resp[200];
15644
15645 if (key_type == NULL)
15646 return -1;
15647
15648 if (strcasecmp(key_type, "GTK") == 0) {
15649 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
15650 strncmp(buf, "FAIL", 4) == 0) {
15651 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15652 "not fetch current GTK");
15653 return 0;
15654 }
15655 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
15656 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15657 return 0;
15658 } else {
15659 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
15660 "KeyType");
15661 return 0;
15662 }
15663
15664 return 1;
15665}
15666
15667
15668static int hs2_set_policy(struct sigma_dut *dut)
15669{
15670#ifdef ANDROID
15671 system("ip rule del prio 23000");
15672 if (system("ip rule add from all lookup main prio 23000") != 0) {
15673 sigma_dut_print(dut, DUT_MSG_ERROR,
15674 "Failed to run:ip rule add from all lookup main prio");
15675 return -1;
15676 }
15677 if (system("ip route flush cache") != 0) {
15678 sigma_dut_print(dut, DUT_MSG_ERROR,
15679 "Failed to run ip route flush cache");
15680 return -1;
15681 }
15682 return 1;
15683#else /* ANDROID */
15684 return 0;
15685#endif /* ANDROID */
15686}
15687
15688
Jouni Malinenf7222712019-06-13 01:50:21 +030015689static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
15690 struct sigma_conn *conn,
15691 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015692{
15693 const char *intf = get_param(cmd, "Interface");
15694 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030015695 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015696 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030015697 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015698 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
15699 int tries = 0;
15700 int ignore_blacklist = 0;
15701 const char *events[] = {
15702 "CTRL-EVENT-CONNECTED",
15703 "INTERWORKING-BLACKLISTED",
15704 "INTERWORKING-NO-MATCH",
15705 NULL
15706 };
15707
15708 start_sta_mode(dut);
15709
Jouni Malinen439352d2018-09-13 03:42:23 +030015710 if (band) {
15711 if (strcmp(band, "2.4") == 0) {
15712 wpa_command(intf, "SET setband 2G");
15713 } else if (strcmp(band, "5") == 0) {
15714 wpa_command(intf, "SET setband 5G");
15715 } else {
15716 send_resp(dut, conn, SIGMA_ERROR,
15717 "errorCode,Unsupported band");
15718 return 0;
15719 }
15720 }
15721
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015722 blacklisted[0] = '\0';
15723 if (val && atoi(val))
15724 ignore_blacklist = 1;
15725
15726try_again:
15727 ctrl = open_wpa_mon(intf);
15728 if (ctrl == NULL) {
15729 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15730 "wpa_supplicant monitor connection");
15731 return -2;
15732 }
15733
15734 tries++;
15735 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
15736 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
15737 "Interworking connection");
15738 wpa_ctrl_detach(ctrl);
15739 wpa_ctrl_close(ctrl);
15740 return 0;
15741 }
15742
15743 buf[0] = '\0';
15744 while (1) {
15745 char *pos;
15746 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15747 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
15748 if (!pos)
15749 break;
15750 pos += 25;
15751 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
15752 pos);
15753 if (!blacklisted[0])
15754 memcpy(blacklisted, pos, strlen(pos) + 1);
15755 }
15756
15757 if (ignore_blacklist && blacklisted[0]) {
15758 char *end;
15759 end = strchr(blacklisted, ' ');
15760 if (end)
15761 *end = '\0';
15762 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
15763 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030015764 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
15765 blacklisted);
15766 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015767 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
15768 wpa_ctrl_detach(ctrl);
15769 wpa_ctrl_close(ctrl);
15770 return 0;
15771 }
15772 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15773 buf, sizeof(buf));
15774 }
15775
15776 wpa_ctrl_detach(ctrl);
15777 wpa_ctrl_close(ctrl);
15778
15779 if (res < 0) {
15780 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15781 "connect");
15782 return 0;
15783 }
15784
15785 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
15786 strstr(buf, "INTERWORKING-BLACKLISTED")) {
15787 if (tries < 2) {
15788 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
15789 goto try_again;
15790 }
15791 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
15792 "matching credentials found");
15793 return 0;
15794 }
15795
15796 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15797 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15798 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15799 "get current BSSID/SSID");
15800 return 0;
15801 }
15802
15803 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
15804 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15805 hs2_set_policy(dut);
15806 return 0;
15807}
15808
15809
Jouni Malinenf7222712019-06-13 01:50:21 +030015810static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
15811 struct sigma_conn *conn,
15812 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015813{
15814 const char *intf = get_param(cmd, "Interface");
15815 const char *display = get_param(cmd, "Display");
15816 struct wpa_ctrl *ctrl;
15817 char buf[300], params[400], *pos;
15818 char bssid[20];
15819 int info_avail = 0;
15820 unsigned int old_timeout;
15821 int res;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015822 const char *events[] = { "RX-VENUE-URL", "ANQP-QUERY-DONE", NULL };
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015823
15824 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
15825 send_resp(dut, conn, SIGMA_ERROR,
15826 "ErrorCode,Could not get current BSSID");
15827 return 0;
15828 }
15829 ctrl = open_wpa_mon(intf);
15830 if (!ctrl) {
15831 sigma_dut_print(dut, DUT_MSG_ERROR,
15832 "Failed to open wpa_supplicant monitor connection");
15833 return -2;
15834 }
15835
15836 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
15837 wpa_command(intf, buf);
15838
15839 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
15840 if (res < 0) {
15841 send_resp(dut, conn, SIGMA_ERROR,
15842 "ErrorCode,Could not complete GAS query");
15843 goto fail;
15844 }
15845
15846 old_timeout = dut->default_timeout;
15847 dut->default_timeout = 2;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015848 for (;;) {
15849 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15850 if (res < 0)
15851 break;
15852 if (strstr(buf, "ANQP-QUERY-DONE") != NULL) {
15853 res = -1;
15854 break;
15855 }
15856 pos = strchr(buf, ' ');
15857 if (!pos)
15858 continue;
15859 pos++;
15860 pos = strchr(pos, ' ');
15861 if (!pos)
15862 continue;
15863 pos++;
15864
15865 if (strncmp(pos, "https://", 8) == 0)
15866 break;
15867
15868 sigma_dut_print(dut, DUT_MSG_DEBUG,
15869 "Ignore non-HTTPS venue URL: %s", pos);
15870 }
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015871 dut->default_timeout = old_timeout;
15872 if (res < 0)
15873 goto done;
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015874 info_avail = 1;
15875 snprintf(params, sizeof(params), "browser %s", pos);
15876
15877 if (display && strcasecmp(display, "Yes") == 0) {
15878 pid_t pid;
15879
15880 pid = fork();
15881 if (pid < 0) {
15882 perror("fork");
15883 return -1;
15884 }
15885
15886 if (pid == 0) {
15887 run_hs20_osu(dut, params);
15888 exit(0);
15889 }
15890 }
15891
15892done:
15893 snprintf(buf, sizeof(buf), "Info_available,%s",
15894 info_avail ? "Yes" : "No");
15895 send_resp(dut, conn, SIGMA_COMPLETE, buf);
15896fail:
15897 wpa_ctrl_detach(ctrl);
15898 wpa_ctrl_close(ctrl);
15899 return 0;
15900}
15901
15902
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015903static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
15904 struct sigma_conn *conn,
15905 const char *ifname,
15906 struct sigma_cmd *cmd)
15907{
15908 const char *val;
15909 int id;
15910
15911 id = add_cred(ifname);
15912 if (id < 0)
15913 return -2;
15914 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15915
15916 val = get_param(cmd, "prefer");
15917 if (val && atoi(val) > 0)
15918 set_cred(ifname, id, "priority", "1");
15919
15920 val = get_param(cmd, "REALM");
15921 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
15922 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15923 "realm");
15924 return 0;
15925 }
15926
15927 val = get_param(cmd, "HOME_FQDN");
15928 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
15929 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15930 "home_fqdn");
15931 return 0;
15932 }
15933
15934 val = get_param(cmd, "Username");
15935 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
15936 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15937 "username");
15938 return 0;
15939 }
15940
15941 val = get_param(cmd, "Password");
15942 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
15943 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15944 "password");
15945 return 0;
15946 }
15947
15948 val = get_param(cmd, "ROOT_CA");
15949 if (val) {
15950 char fname[200];
15951 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
15952#ifdef __linux__
15953 if (!file_exists(fname)) {
15954 char msg[300];
15955 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
15956 "file (%s) not found", fname);
15957 send_resp(dut, conn, SIGMA_ERROR, msg);
15958 return 0;
15959 }
15960#endif /* __linux__ */
15961 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
15962 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15963 "not set root CA");
15964 return 0;
15965 }
15966 }
15967
15968 return 1;
15969}
15970
15971
15972static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
15973{
15974 FILE *in, *out;
15975 char buf[500];
15976 int found = 0;
15977
15978 in = fopen("devdetail.xml", "r");
15979 if (in == NULL)
15980 return -1;
15981 out = fopen("devdetail.xml.tmp", "w");
15982 if (out == NULL) {
15983 fclose(in);
15984 return -1;
15985 }
15986
15987 while (fgets(buf, sizeof(buf), in)) {
15988 char *pos = strstr(buf, "<IMSI>");
15989 if (pos) {
15990 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
15991 imsi);
15992 pos += 6;
15993 *pos = '\0';
15994 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
15995 found++;
15996 } else {
15997 fprintf(out, "%s", buf);
15998 }
15999 }
16000
16001 fclose(out);
16002 fclose(in);
16003 if (found)
16004 rename("devdetail.xml.tmp", "devdetail.xml");
16005 else
16006 unlink("devdetail.xml.tmp");
16007
16008 return 0;
16009}
16010
16011
16012static int sta_add_credential_sim(struct sigma_dut *dut,
16013 struct sigma_conn *conn,
16014 const char *ifname, struct sigma_cmd *cmd)
16015{
16016 const char *val, *imsi = NULL;
16017 int id;
16018 char buf[200];
16019 int res;
16020 const char *pos;
16021 size_t mnc_len;
16022 char plmn_mcc[4];
16023 char plmn_mnc[4];
16024
16025 id = add_cred(ifname);
16026 if (id < 0)
16027 return -2;
16028 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16029
16030 val = get_param(cmd, "prefer");
16031 if (val && atoi(val) > 0)
16032 set_cred(ifname, id, "priority", "1");
16033
16034 val = get_param(cmd, "PLMN_MCC");
16035 if (val == NULL) {
16036 send_resp(dut, conn, SIGMA_ERROR,
16037 "errorCode,Missing PLMN_MCC");
16038 return 0;
16039 }
16040 if (strlen(val) != 3) {
16041 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
16042 return 0;
16043 }
16044 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
16045
16046 val = get_param(cmd, "PLMN_MNC");
16047 if (val == NULL) {
16048 send_resp(dut, conn, SIGMA_ERROR,
16049 "errorCode,Missing PLMN_MNC");
16050 return 0;
16051 }
16052 if (strlen(val) != 2 && strlen(val) != 3) {
16053 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
16054 return 0;
16055 }
16056 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
16057
16058 val = get_param(cmd, "IMSI");
16059 if (val == NULL) {
16060 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
16061 "IMSI");
16062 return 0;
16063 }
16064
16065 imsi = pos = val;
16066
16067 if (strncmp(plmn_mcc, pos, 3) != 0) {
16068 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
16069 return 0;
16070 }
16071 pos += 3;
16072
16073 mnc_len = strlen(plmn_mnc);
16074 if (mnc_len < 2) {
16075 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
16076 return 0;
16077 }
16078
16079 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
16080 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
16081 return 0;
16082 }
16083 pos += mnc_len;
16084
16085 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
16086 if (res < 0 || res >= (int) sizeof(buf))
16087 return -1;
16088 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
16089 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16090 "not set IMSI");
16091 return 0;
16092 }
16093
16094 val = get_param(cmd, "Password");
16095 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
16096 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16097 "not set password");
16098 return 0;
16099 }
16100
Jouni Malinen9a742ff2022-01-27 00:43:14 +020016101 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
16102 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016103 /*
16104 * Set provisioning_sp for the test cases where SIM/USIM
16105 * provisioning is used.
16106 */
16107 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
16108 "wi-fi.org") < 0) {
16109 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16110 "not set provisioning_sp");
16111 return 0;
16112 }
16113
16114 update_devdetail_imsi(dut, imsi);
16115 }
16116
16117 return 1;
16118}
16119
16120
16121static int sta_add_credential_cert(struct sigma_dut *dut,
16122 struct sigma_conn *conn,
16123 const char *ifname,
16124 struct sigma_cmd *cmd)
16125{
16126 const char *val;
16127 int id;
16128
16129 id = add_cred(ifname);
16130 if (id < 0)
16131 return -2;
16132 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16133
16134 val = get_param(cmd, "prefer");
16135 if (val && atoi(val) > 0)
16136 set_cred(ifname, id, "priority", "1");
16137
16138 val = get_param(cmd, "REALM");
16139 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
16140 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16141 "realm");
16142 return 0;
16143 }
16144
16145 val = get_param(cmd, "HOME_FQDN");
16146 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
16147 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16148 "home_fqdn");
16149 return 0;
16150 }
16151
16152 val = get_param(cmd, "Username");
16153 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
16154 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16155 "username");
16156 return 0;
16157 }
16158
16159 val = get_param(cmd, "clientCertificate");
16160 if (val) {
16161 char fname[200];
16162 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16163#ifdef __linux__
16164 if (!file_exists(fname)) {
16165 char msg[300];
16166 snprintf(msg, sizeof(msg),
16167 "ErrorCode,clientCertificate "
16168 "file (%s) not found", fname);
16169 send_resp(dut, conn, SIGMA_ERROR, msg);
16170 return 0;
16171 }
16172#endif /* __linux__ */
16173 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
16174 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16175 "not set client_cert");
16176 return 0;
16177 }
16178 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
16179 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16180 "not set private_key");
16181 return 0;
16182 }
16183 }
16184
16185 val = get_param(cmd, "ROOT_CA");
16186 if (val) {
16187 char fname[200];
16188 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16189#ifdef __linux__
16190 if (!file_exists(fname)) {
16191 char msg[300];
16192 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16193 "file (%s) not found", fname);
16194 send_resp(dut, conn, SIGMA_ERROR, msg);
16195 return 0;
16196 }
16197#endif /* __linux__ */
16198 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16199 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16200 "not set root CA");
16201 return 0;
16202 }
16203 }
16204
16205 return 1;
16206}
16207
16208
Jouni Malinenf7222712019-06-13 01:50:21 +030016209static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
16210 struct sigma_conn *conn,
16211 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016212{
16213 const char *intf = get_param(cmd, "Interface");
16214 const char *type;
16215
16216 start_sta_mode(dut);
16217
16218 type = get_param(cmd, "Type");
16219 if (!type)
16220 return -1;
16221
16222 if (strcasecmp(type, "uname_pwd") == 0)
16223 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
16224
16225 if (strcasecmp(type, "sim") == 0)
16226 return sta_add_credential_sim(dut, conn, intf, cmd);
16227
16228 if (strcasecmp(type, "cert") == 0)
16229 return sta_add_credential_cert(dut, conn, intf, cmd);
16230
16231 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
16232 "type");
16233 return 0;
16234}
16235
16236
Jouni Malinenf7222712019-06-13 01:50:21 +030016237static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
16238 struct sigma_conn *conn,
16239 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016240{
16241 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016242 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070016243 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053016244 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016245 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016246 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016247 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016248 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016249
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020016250 start_sta_mode(dut);
16251
Arif Hussain66a4af02019-02-07 15:04:51 -080016252 val = get_param(cmd, "GetParameter");
16253 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016254 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080016255 buf, sizeof(buf)) < 0) {
16256 sigma_dut_print(dut, DUT_MSG_ERROR,
16257 "Could not get ssid bssid");
16258 return ERROR_SEND_STATUS;
16259 }
16260
16261 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
16262 send_resp(dut, conn, SIGMA_COMPLETE, buf);
16263 return STATUS_SENT;
16264 }
16265
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016266 val = get_param(cmd, "HESSID");
16267 if (val) {
16268 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
16269 if (res < 0 || res >= (int) sizeof(buf))
16270 return -1;
16271 wpa_command(intf, buf);
16272 }
16273
16274 val = get_param(cmd, "ACCS_NET_TYPE");
16275 if (val) {
16276 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
16277 val);
16278 if (res < 0 || res >= (int) sizeof(buf))
16279 return -1;
16280 wpa_command(intf, buf);
16281 }
16282
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016283 if (get_param(cmd, "RxMac"))
16284 sta_set_scan_unicast_probe(dut, intf, 1);
16285
vamsi krishna89ad8c62017-09-19 12:51:18 +053016286 bssid = get_param(cmd, "Bssid");
16287 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016288 if (!bssid)
16289 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053016290
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016291 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
16292 dut->device_type == STA_testbed) {
16293 ssid = NULL;
16294 wildcard_ssid = 1;
16295 }
16296
vamsi krishna89ad8c62017-09-19 12:51:18 +053016297 if (ssid) {
16298 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
16299 send_resp(dut, conn, SIGMA_ERROR,
16300 "ErrorCode,Too long SSID");
16301 return 0;
16302 }
16303 ascii2hexstr(ssid, ssid_hex);
16304 }
16305
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016306 short_ssid = get_param(cmd, "ShortSSID");
16307 if (short_ssid) {
16308 uint32_t short_ssid_hex;
16309
16310 short_ssid_hex = strtoul(short_ssid, NULL, 16);
16311 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
16312 (((short_ssid_hex >> 8) & 0xFF) << 16) |
16313 (((short_ssid_hex >> 16) & 0xFF) << 8) |
16314 ((short_ssid_hex >> 24) & 0xFF);
16315
16316 res = snprintf(buf, sizeof(buf),
16317 "VENDOR_ELEM_ADD 14 ff053a%08x",
16318 short_ssid_hex);
16319 if (res < 0 || res >= (int) sizeof(buf) ||
16320 wpa_command(intf, buf)) {
16321 send_resp(dut, conn, SIGMA_ERROR,
16322 "errorCode,Failed to add short SSID");
16323 return STATUS_SENT_ERROR;
16324 }
16325 }
16326
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016327 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053016328 if (scan_freq) {
16329 if (strcasecmp(scan_freq, "2G") == 0)
16330 scan_freq = "2412-2462";
16331 else if (strcasecmp(scan_freq, "5G") == 0)
16332 scan_freq = "5180-5925";
16333 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016334
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016335 val = get_param(cmd, "WaitCompletion");
16336 if (val && atoi(val) == 1) {
16337 ctrl = open_wpa_mon(intf);
16338 if (!ctrl) {
16339 send_resp(dut, conn, SIGMA_ERROR,
16340 "errorCode,Failed to open monitor socket");
16341 return STATUS_SENT_ERROR;
16342 }
16343 }
16344
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016345 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053016346 bssid ? " bssid=": "",
16347 bssid ? bssid : "",
16348 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016349 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016350 wildcard_ssid ? " wildcard_ssid=1" : "",
16351 scan_freq ? " freq=" : "",
16352 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016353 if (res < 0 || res >= (int) sizeof(buf)) {
16354 send_resp(dut, conn, SIGMA_ERROR,
16355 "errorCode,Could not build scan command");
16356 status = STATUS_SENT_ERROR;
16357 goto remove_s_ssid;
16358 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053016359
Veerendranathdc581b52020-08-10 03:29:08 -070016360 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
16361 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
16362 sigma_dut_print(dut, DUT_MSG_DEBUG,
16363 "Scan request rejected with busy status, abort ongoing scan and try again");
16364 wpa_command(intf, "ABORT_SCAN");
16365 res = wpa_command(intf, buf);
16366 }
16367
16368 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016369 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
16370 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016371 status = STATUS_SENT_ERROR;
16372 } else {
16373 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016374 }
16375
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016376remove_s_ssid:
16377 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
16378 sigma_dut_print(dut, DUT_MSG_ERROR,
16379 "Failed to delete vendor element");
16380
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016381 if (ctrl) {
16382 if (status == SUCCESS_SEND_STATUS) {
16383 res = get_wpa_cli_event(dut, ctrl,
16384 "CTRL-EVENT-SCAN-RESULTS",
16385 buf, sizeof(buf));
16386 if (res < 0) {
16387 send_resp(dut, conn, SIGMA_ERROR,
16388 "ErrorCode,scan did not complete");
16389 status = STATUS_SENT_ERROR;
16390 }
16391 }
16392
16393 wpa_ctrl_detach(ctrl);
16394 wpa_ctrl_close(ctrl);
16395 }
16396
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016397 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016398}
16399
16400
Jouni Malinenf7222712019-06-13 01:50:21 +030016401static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
16402 struct sigma_conn *conn,
16403 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016404{
16405 const char *intf = get_param(cmd, "Interface");
16406 const char *bssid;
16407 char buf[4096], *pos;
16408 int freq, chan;
16409 char *ssid;
16410 char resp[100];
16411 int res;
16412 struct wpa_ctrl *ctrl;
16413
16414 bssid = get_param(cmd, "BSSID");
16415 if (!bssid) {
16416 send_resp(dut, conn, SIGMA_INVALID,
16417 "errorCode,BSSID argument is missing");
16418 return 0;
16419 }
16420
16421 ctrl = open_wpa_mon(intf);
16422 if (!ctrl) {
16423 sigma_dut_print(dut, DUT_MSG_ERROR,
16424 "Failed to open wpa_supplicant monitor connection");
16425 return -1;
16426 }
16427
16428 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
16429 send_resp(dut, conn, SIGMA_ERROR,
16430 "errorCode,Could not start scan");
16431 wpa_ctrl_detach(ctrl);
16432 wpa_ctrl_close(ctrl);
16433 return 0;
16434 }
16435
16436 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
16437 buf, sizeof(buf));
16438
16439 wpa_ctrl_detach(ctrl);
16440 wpa_ctrl_close(ctrl);
16441
16442 if (res < 0) {
16443 send_resp(dut, conn, SIGMA_ERROR,
16444 "errorCode,Scan did not complete");
16445 return 0;
16446 }
16447
16448 snprintf(buf, sizeof(buf), "BSS %s", bssid);
16449 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
16450 strncmp(buf, "id=", 3) != 0) {
16451 send_resp(dut, conn, SIGMA_ERROR,
16452 "errorCode,Specified BSSID not found");
16453 return 0;
16454 }
16455
16456 pos = strstr(buf, "\nfreq=");
16457 if (!pos) {
16458 send_resp(dut, conn, SIGMA_ERROR,
16459 "errorCode,Channel not found");
16460 return 0;
16461 }
16462 freq = atoi(pos + 6);
16463 chan = freq_to_channel(freq);
16464
16465 pos = strstr(buf, "\nssid=");
16466 if (!pos) {
16467 send_resp(dut, conn, SIGMA_ERROR,
16468 "errorCode,SSID not found");
16469 return 0;
16470 }
16471 ssid = pos + 6;
16472 pos = strchr(ssid, '\n');
16473 if (pos)
16474 *pos = '\0';
16475 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
16476 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16477 return 0;
16478}
16479
16480
Jouni Malinenf7222712019-06-13 01:50:21 +030016481static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
16482 struct sigma_conn *conn,
16483 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016484{
16485#ifdef __linux__
16486 struct timeval tv;
16487 struct tm tm;
16488 time_t t;
16489 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016490 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016491
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016492 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016493
16494 memset(&tm, 0, sizeof(tm));
16495 val = get_param(cmd, "seconds");
16496 if (val)
16497 tm.tm_sec = atoi(val);
16498 val = get_param(cmd, "minutes");
16499 if (val)
16500 tm.tm_min = atoi(val);
16501 val = get_param(cmd, "hours");
16502 if (val)
16503 tm.tm_hour = atoi(val);
16504 val = get_param(cmd, "date");
16505 if (val)
16506 tm.tm_mday = atoi(val);
16507 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016508 if (val) {
16509 v = atoi(val);
16510 if (v < 1 || v > 12) {
16511 send_resp(dut, conn, SIGMA_INVALID,
16512 "errorCode,Invalid month");
16513 return 0;
16514 }
16515 tm.tm_mon = v - 1;
16516 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016517 val = get_param(cmd, "year");
16518 if (val) {
16519 int year = atoi(val);
16520#ifdef ANDROID
16521 if (year > 2035)
16522 year = 2035; /* years beyond 2035 not supported */
16523#endif /* ANDROID */
16524 tm.tm_year = year - 1900;
16525 }
16526 t = mktime(&tm);
16527 if (t == (time_t) -1) {
16528 send_resp(dut, conn, SIGMA_ERROR,
16529 "errorCode,Invalid date or time");
16530 return 0;
16531 }
16532
16533 memset(&tv, 0, sizeof(tv));
16534 tv.tv_sec = t;
16535
16536 if (settimeofday(&tv, NULL) < 0) {
16537 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
16538 strerror(errno));
16539 send_resp(dut, conn, SIGMA_ERROR,
16540 "errorCode,Failed to set time");
16541 return 0;
16542 }
16543
16544 return 1;
16545#endif /* __linux__ */
16546
16547 return -1;
16548}
16549
16550
Jouni Malinenf7222712019-06-13 01:50:21 +030016551static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
16552 struct sigma_conn *conn,
16553 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016554{
16555 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016556 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016557 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016558 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016559 int res;
16560 struct wpa_ctrl *ctrl;
16561
16562 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016563 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016564
16565 val = get_param(cmd, "ProdESSAssoc");
16566 if (val)
16567 prod_ess_assoc = atoi(val);
16568
16569 kill_dhcp_client(dut, intf);
16570 if (start_dhcp_client(dut, intf) < 0)
16571 return -2;
16572
16573 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
16574 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16575 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016576 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016577 prod_ess_assoc ? "" : "-N",
16578 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016579 name ? "'" : "",
16580 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
16581 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016582
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053016583 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016584 if (run_hs20_osu(dut, buf) < 0) {
16585 FILE *f;
16586
16587 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
16588
16589 f = fopen("hs20-osu-client.res", "r");
16590 if (f) {
16591 char resp[400], res[300], *pos;
16592 if (!fgets(res, sizeof(res), f))
16593 res[0] = '\0';
16594 pos = strchr(res, '\n');
16595 if (pos)
16596 *pos = '\0';
16597 fclose(f);
16598 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
16599 res);
16600 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
16601 if (system(resp) != 0) {
16602 }
16603 snprintf(resp, sizeof(resp),
16604 "SSID,,BSSID,,failureReason,%s", res);
16605 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16606 return 0;
16607 }
16608
16609 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16610 return 0;
16611 }
16612
16613 if (!prod_ess_assoc)
16614 goto report;
16615
16616 ctrl = open_wpa_mon(intf);
16617 if (ctrl == NULL) {
16618 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16619 "wpa_supplicant monitor connection");
16620 return -1;
16621 }
16622
16623 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
16624 buf, sizeof(buf));
16625
16626 wpa_ctrl_detach(ctrl);
16627 wpa_ctrl_close(ctrl);
16628
16629 if (res < 0) {
16630 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
16631 "network after OSU");
16632 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16633 return 0;
16634 }
16635
16636report:
16637 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
16638 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
16639 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
16640 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16641 return 0;
16642 }
16643
16644 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
16645 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016646 return 0;
16647}
16648
16649
Jouni Malinenf7222712019-06-13 01:50:21 +030016650static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
16651 struct sigma_conn *conn,
16652 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016653{
16654 const char *val;
16655 int timeout = 120;
16656
16657 val = get_param(cmd, "PolicyUpdate");
16658 if (val == NULL || atoi(val) == 0)
16659 return 1; /* No operation requested */
16660
16661 val = get_param(cmd, "Timeout");
16662 if (val)
16663 timeout = atoi(val);
16664
16665 if (timeout) {
16666 /* TODO: time out the command and return
16667 * PolicyUpdateStatus,TIMEOUT if needed. */
16668 }
16669
16670 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
16671 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16672 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
16673 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
16674 return 0;
16675 }
16676
16677 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
16678 return 0;
16679}
16680
16681
Jouni Malinenf7222712019-06-13 01:50:21 +030016682static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
16683 struct sigma_conn *conn,
16684 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016685{
16686 struct wpa_ctrl *ctrl;
16687 const char *intf = get_param(cmd, "Interface");
16688 const char *bssid = get_param(cmd, "Bssid");
16689 const char *ssid = get_param(cmd, "SSID");
16690 const char *security = get_param(cmd, "Security");
16691 const char *passphrase = get_param(cmd, "Passphrase");
16692 const char *pin = get_param(cmd, "PIN");
16693 char buf[1000];
16694 char ssid_hex[200], passphrase_hex[200];
16695 const char *keymgmt, *cipher;
16696
16697 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016698 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016699
16700 if (!bssid) {
16701 send_resp(dut, conn, SIGMA_ERROR,
16702 "ErrorCode,Missing Bssid argument");
16703 return 0;
16704 }
16705
16706 if (!ssid) {
16707 send_resp(dut, conn, SIGMA_ERROR,
16708 "ErrorCode,Missing SSID argument");
16709 return 0;
16710 }
16711
16712 if (!security) {
16713 send_resp(dut, conn, SIGMA_ERROR,
16714 "ErrorCode,Missing Security argument");
16715 return 0;
16716 }
16717
16718 if (!passphrase) {
16719 send_resp(dut, conn, SIGMA_ERROR,
16720 "ErrorCode,Missing Passphrase argument");
16721 return 0;
16722 }
16723
16724 if (!pin) {
16725 send_resp(dut, conn, SIGMA_ERROR,
16726 "ErrorCode,Missing PIN argument");
16727 return 0;
16728 }
16729
vamsi krishna8c9c1562017-05-12 15:51:46 +053016730 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
16731 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016732 send_resp(dut, conn, SIGMA_ERROR,
16733 "ErrorCode,Too long SSID/passphrase");
16734 return 0;
16735 }
16736
16737 ctrl = open_wpa_mon(intf);
16738 if (ctrl == NULL) {
16739 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16740 "wpa_supplicant monitor connection");
16741 return -2;
16742 }
16743
16744 if (strcasecmp(security, "wpa2-psk") == 0) {
16745 keymgmt = "WPA2PSK";
16746 cipher = "CCMP";
16747 } else {
16748 wpa_ctrl_detach(ctrl);
16749 wpa_ctrl_close(ctrl);
16750 send_resp(dut, conn, SIGMA_ERROR,
16751 "ErrorCode,Unsupported Security value");
16752 return 0;
16753 }
16754
16755 ascii2hexstr(ssid, ssid_hex);
16756 ascii2hexstr(passphrase, passphrase_hex);
16757 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
16758 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
16759
16760 if (wpa_command(intf, buf) < 0) {
16761 wpa_ctrl_detach(ctrl);
16762 wpa_ctrl_close(ctrl);
16763 send_resp(dut, conn, SIGMA_ERROR,
16764 "ErrorCode,Failed to start registrar");
16765 return 0;
16766 }
16767
16768 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
16769 dut->er_oper_performed = 1;
16770
16771 return wps_connection_event(dut, conn, ctrl, intf, 0);
16772}
16773
16774
Jouni Malinenf7222712019-06-13 01:50:21 +030016775static enum sigma_cmd_result
16776cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
16777 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016778{
16779 struct wpa_ctrl *ctrl;
16780 const char *intf = get_param(cmd, "Interface");
16781 const char *bssid = get_param(cmd, "Bssid");
16782 char buf[100];
16783
16784 if (!bssid) {
16785 send_resp(dut, conn, SIGMA_ERROR,
16786 "ErrorCode,Missing Bssid argument");
16787 return 0;
16788 }
16789
16790 ctrl = open_wpa_mon(intf);
16791 if (ctrl == NULL) {
16792 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16793 "wpa_supplicant monitor connection");
16794 return -2;
16795 }
16796
16797 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
16798
16799 if (wpa_command(intf, buf) < 0) {
16800 wpa_ctrl_detach(ctrl);
16801 wpa_ctrl_close(ctrl);
16802 send_resp(dut, conn, SIGMA_ERROR,
16803 "ErrorCode,Failed to start registrar");
16804 return 0;
16805 }
16806
16807 return wps_connection_event(dut, conn, ctrl, intf, 0);
16808}
16809
16810
Jouni Malinenf7222712019-06-13 01:50:21 +030016811static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
16812 struct sigma_conn *conn,
16813 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053016814{
16815 struct wpa_ctrl *ctrl;
16816 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016817 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016818 const char *config_method = get_param(cmd, "WPSConfigMethod");
16819 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053016820 int res;
16821 char buf[256];
16822 const char *events[] = {
16823 "CTRL-EVENT-CONNECTED",
16824 "WPS-OVERLAP-DETECTED",
16825 "WPS-TIMEOUT",
16826 "WPS-FAIL",
16827 NULL
16828 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016829 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053016830
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016831 /* 60G WPS tests do not pass Interface parameter */
16832 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016833 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016834
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016835 if (dut->mode == SIGMA_MODE_AP)
16836 return ap_wps_registration(dut, conn, cmd);
16837
16838 if (config_method) {
16839 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
16840 * sta_wps_enter_pin before calling start_wps_registration. */
16841 if (strcasecmp(config_method, "PBC") == 0)
16842 dut->wps_method = WFA_CS_WPS_PBC;
16843 }
16844 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
16845 send_resp(dut, conn, SIGMA_ERROR,
16846 "ErrorCode,WPS parameters not yet set");
16847 return STATUS_SENT;
16848 }
16849
16850 /* Make sure WPS is enabled (also for STA mode) */
16851 dut->wps_disable = 0;
16852
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016853 if (dut->band == WPS_BAND_60G && network_mode &&
16854 strcasecmp(network_mode, "PBSS") == 0) {
16855 sigma_dut_print(dut, DUT_MSG_DEBUG,
16856 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016857 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016858 return -2;
16859 }
16860
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016861 if (dut->force_rsn_ie) {
16862 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
16863 dut->force_rsn_ie);
16864 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
16865 sigma_dut_print(dut, DUT_MSG_INFO,
16866 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020016867 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016868 }
16869 }
16870
vamsi krishna9b144002017-09-20 13:28:13 +053016871 ctrl = open_wpa_mon(intf);
16872 if (!ctrl) {
16873 sigma_dut_print(dut, DUT_MSG_ERROR,
16874 "Failed to open wpa_supplicant monitor connection");
16875 return -2;
16876 }
16877
16878 role = get_param(cmd, "WpsRole");
16879 if (!role) {
16880 send_resp(dut, conn, SIGMA_INVALID,
16881 "ErrorCode,WpsRole not provided");
16882 goto fail;
16883 }
16884
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016885 if (strcasecmp(role, "Enrollee") != 0) {
16886 /* Registrar role for STA not supported */
16887 send_resp(dut, conn, SIGMA_ERROR,
16888 "ErrorCode,Unsupported WpsRole value");
16889 goto fail;
16890 }
16891
16892 if (is_60g_sigma_dut(dut)) {
16893 if (dut->wps_method == WFA_CS_WPS_PBC)
16894 snprintf(buf, sizeof(buf), "WPS_PBC");
16895 else /* WFA_CS_WPS_PIN_KEYPAD */
16896 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
16897 dut->wps_pin);
16898 if (wpa_command(intf, buf) < 0) {
16899 send_resp(dut, conn, SIGMA_ERROR,
16900 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053016901 goto fail;
16902 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016903 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16904 if (res < 0) {
16905 send_resp(dut, conn, SIGMA_ERROR,
16906 "ErrorCode,WPS connection did not complete");
16907 goto fail;
16908 }
16909 if (strstr(buf, "WPS-TIMEOUT")) {
16910 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
16911 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16912 send_resp(dut, conn, SIGMA_COMPLETE,
16913 "WpsState,OverlapSession");
16914 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16915 send_resp(dut, conn, SIGMA_COMPLETE,
16916 "WpsState,Successful");
16917 } else {
16918 send_resp(dut, conn, SIGMA_COMPLETE,
16919 "WpsState,Failure");
16920 }
16921 } else {
16922 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053016923 if (wpa_command(intf, "WPS_PBC") < 0) {
16924 send_resp(dut, conn, SIGMA_ERROR,
16925 "ErrorCode,Failed to enable PBC");
16926 goto fail;
16927 }
16928 } else {
16929 /* TODO: PIN method */
16930 send_resp(dut, conn, SIGMA_ERROR,
16931 "ErrorCode,Unsupported WpsConfigMethod value");
16932 goto fail;
16933 }
16934 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16935 if (res < 0) {
16936 send_resp(dut, conn, SIGMA_ERROR,
16937 "ErrorCode,WPS connection did not complete");
16938 goto fail;
16939 }
16940 if (strstr(buf, "WPS-TIMEOUT")) {
16941 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
16942 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16943 send_resp(dut, conn, SIGMA_ERROR,
16944 "ErrorCode,OverlapSession");
16945 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16946 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
16947 } else {
16948 send_resp(dut, conn, SIGMA_ERROR,
16949 "ErrorCode,WPS operation failed");
16950 }
vamsi krishna9b144002017-09-20 13:28:13 +053016951 }
16952
16953fail:
16954 wpa_ctrl_detach(ctrl);
16955 wpa_ctrl_close(ctrl);
16956 return 0;
16957}
16958
16959
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016960static int req_intf(struct sigma_cmd *cmd)
16961{
16962 return get_param(cmd, "interface") == NULL ? -1 : 0;
16963}
16964
16965
16966void sta_register_cmds(void)
16967{
16968 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
16969 cmd_sta_get_ip_config);
16970 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
16971 cmd_sta_set_ip_config);
16972 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
16973 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
16974 cmd_sta_get_mac_address);
16975 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
16976 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
16977 cmd_sta_verify_ip_connection);
16978 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
16979 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
16980 cmd_sta_set_encryption);
16981 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
16982 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
16983 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
16984 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
16985 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
16986 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
16987 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
16988 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
16989 cmd_sta_set_eapakaprime);
16990 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
16991 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
16992 /* TODO: sta_set_ibss */
16993 /* TODO: sta_set_mode */
16994 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
16995 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
16996 /* TODO: sta_up_load */
16997 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
16998 cmd_sta_preset_testparameters);
16999 /* TODO: sta_set_system */
17000 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
17001 /* TODO: sta_set_rifs_test */
17002 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
17003 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
17004 /* TODO: sta_send_coexist_mgmt */
17005 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
17006 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
17007 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
17008 sigma_dut_reg_cmd("sta_reset_default", req_intf,
17009 cmd_sta_reset_default);
17010 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
17011 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
17012 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
17013 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
17014 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020017015 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017016 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
17017 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
17018 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
17019 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
17020 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030017021 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
17022 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017023 sigma_dut_reg_cmd("sta_add_credential", req_intf,
17024 cmd_sta_add_credential);
17025 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020017026 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017027 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
17028 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
17029 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
17030 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
17031 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
17032 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030017033 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017034 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
17035 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020017036 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053017037 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017038}