blob: 029d2d8befdafa571429f32632f41458037929ee [file] [log] [blame]
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001/*
2 * Sigma Control API DUT (station/AP)
3 * Copyright (c) 2010-2011, Atheros Communications, Inc.
Jouni Malinen9d7e31d2017-12-22 18:55:04 +02004 * Copyright (c) 2011-2017, Qualcomm Atheros, Inc.
Jouni Malinen2feb9132021-11-16 00:53:06 +02005 * Copyright (c) 2018-2021, The Linux Foundation
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006 * All Rights Reserved.
7 * Licensed under the Clear BSD license. See README for more details.
8 */
9
10#include "sigma_dut.h"
11#include <sys/ioctl.h>
12#include <sys/stat.h>
Jouni Malinen82905202018-04-29 17:20:10 +030013#include <sys/wait.h>
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030014#include <ctype.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015#ifdef __linux__
Lior Davidcc88b562017-01-03 18:52:09 +020016#include <regex.h>
17#include <dirent.h>
Jouni Malinencd4e3c32015-10-29 12:39:56 +020018#include <sys/time.h>
19#include <netpacket/packet.h>
20#include <linux/if_ether.h>
21#ifdef ANDROID
22#include <cutils/properties.h>
23#include <android/log.h>
24#include "keystore_get.h"
25#else /* ANDROID */
26#include <ifaddrs.h>
27#endif /* ANDROID */
28#include <netdb.h>
29#endif /* __linux__ */
30#ifdef __QNXNTO__
31#include <net/if_dl.h>
32#endif /* __QNXNTO__ */
33#include "wpa_ctrl.h"
34#include "wpa_helpers.h"
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -070035#include "miracast.h"
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070036#include "qca-vendor_copy.h"
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080037#include "nl80211_copy.h"
Jouni Malinencd4e3c32015-10-29 12:39:56 +020038
39/* Temporary files for sta_send_addba */
40#define VI_QOS_TMP_FILE "/tmp/vi-qos.tmp"
41#define VI_QOS_FILE "/tmp/vi-qos.txt"
42#define VI_QOS_REFFILE "/etc/vi-qos.txt"
43
44/*
45 * MTU for Ethernet need to take into account 8-byte SNAP header
46 * to be added when encapsulating Ethernet frame into 802.11
47 */
48#ifndef IEEE80211_MAX_DATA_LEN_DMG
49#define IEEE80211_MAX_DATA_LEN_DMG 7920
50#endif
51#ifndef IEEE80211_SNAP_LEN_DMG
52#define IEEE80211_SNAP_LEN_DMG 8
53#endif
54
Ashwini Patil00402582017-04-13 12:29:39 +053055#define NON_PREF_CH_LIST_SIZE 100
Ashwini Patil5acd7382017-04-13 15:55:04 +053056#define NEIGHBOR_REPORT_SIZE 1000
57#define DEFAULT_NEIGHBOR_BSSID_INFO "17"
58#define DEFAULT_NEIGHBOR_PHY_TYPE "1"
Ashwini Patil00402582017-04-13 12:29:39 +053059
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030060#define WIL_DEFAULT_BI 100
61
62/* default remain on channel time for transmitting frames (milliseconds) */
63#define WIL_TRANSMIT_FRAME_DEFAULT_ROC 500
64#define IEEE80211_P2P_ATTR_DEVICE_ID 3
65#define IEEE80211_P2P_ATTR_GROUP_ID 15
66
67/* describes tagged bytes in template frame file */
68struct template_frame_tag {
69 int num;
70 int offset;
71 size_t len;
72};
73
Jouni Malinencd4e3c32015-10-29 12:39:56 +020074extern char *sigma_wpas_ctrl;
75extern char *sigma_cert_path;
76extern enum driver_type wifi_chip_type;
77extern char *sigma_radio_ifname[];
78
Lior David0fe101e2017-03-09 16:09:50 +020079#ifdef __linux__
80#define WIL_WMI_MAX_PAYLOAD 248
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020081#define WIL_WMI_ESE_CFG_CMDID 0xa01
Lior David0fe101e2017-03-09 16:09:50 +020082#define WIL_WMI_BF_TRIG_CMDID 0x83a
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020083#define WIL_WMI_UNIT_TEST_CMDID 0x900
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030084#define WIL_WMI_P2P_CFG_CMDID 0x910
85#define WIL_WMI_START_LISTEN_CMDID 0x914
86#define WIL_WMI_DISCOVERY_STOP_CMDID 0x917
Lior David0fe101e2017-03-09 16:09:50 +020087
88struct wil_wmi_header {
89 uint8_t mid;
90 uint8_t reserved;
91 uint16_t cmd;
92 uint32_t ts;
93} __attribute__((packed));
94
95enum wil_wmi_bf_trig_type {
96 WIL_WMI_SLS,
97 WIL_WMI_BRP_RX,
98 WIL_WMI_BRP_TX,
99};
100
101struct wil_wmi_bf_trig_cmd {
102 /* enum wil_wmi_bf_trig_type */
103 uint32_t bf_type;
104 /* cid when type == WMI_BRP_RX */
105 uint32_t sta_id;
106 uint32_t reserved;
107 /* mac address when type = WIL_WMI_SLS */
108 uint8_t dest_mac[6];
109} __attribute__((packed));
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200110
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200111enum wil_wmi_sched_scheme_advertisment {
112 WIL_WMI_ADVERTISE_ESE_DISABLED,
113 WIL_WMI_ADVERTISE_ESE_IN_BEACON,
114 WIL_WMI_ADVERTISE_ESE_IN_ANNOUNCE_FRAME,
115};
116
117enum wil_wmi_ese_slot_type {
118 WIL_WMI_ESE_SP,
119 WIL_WMI_ESE_CBAP,
120 WIL_WMI_ESE_ANNOUNCE_NO_ACK,
121};
122
123struct wil_wmi_ese_slot {
124 /* offset from start of BI in microseconds */
125 uint32_t tbtt_offset;
126 uint8_t flags;
127 /* enum wil_wmi_ese_slot_type */
128 uint8_t slot_type;
129 /* duration in microseconds */
130 uint16_t duration;
131 /* frame exchange sequence duration, microseconds */
132 uint16_t tx_op;
133 /* time between 2 blocks for periodic allocation(microseconds) */
134 uint16_t period;
135 /* number of blocks in periodic allocation */
136 uint8_t num_blocks;
137 /* for semi-active allocations */
138 uint8_t idle_period;
139 uint8_t src_aid;
140 uint8_t dst_aid;
141 uint32_t reserved;
142} __attribute__((packed));
143
144#define WIL_WMI_MAX_ESE_SLOTS 4
145struct wil_wmi_ese_cfg {
146 uint8_t serial_num;
147 /* wil_wmi_sched_scheme_advertisment */
148 uint8_t ese_advertisment;
149 uint16_t flags;
150 uint8_t num_allocs;
151 uint8_t reserved[3];
152 uint64_t start_tbtt;
153 /* allocations list */
154 struct wil_wmi_ese_slot slots[WIL_WMI_MAX_ESE_SLOTS];
155} __attribute__((packed));
156
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200157#define WIL_WMI_UT_FORCE_MCS 6
158struct wil_wmi_force_mcs {
159 /* WIL_WMI_UT_HW_SYSAPI */
160 uint16_t module_id;
161 /* WIL_WMI_UT_FORCE_MCS */
162 uint16_t subtype_id;
163 /* cid (ignored in oob_mode, affects all stations) */
164 uint32_t cid;
165 /* 1 to force MCS, 0 to restore default behavior */
166 uint32_t force_enable;
167 /* MCS index, 0-12 */
168 uint32_t mcs;
169} __attribute__((packed));
170
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200171#define WIL_WMI_UT_HW_SYSAPI 10
172#define WIL_WMI_UT_FORCE_RSN_IE 0x29
173struct wil_wmi_force_rsn_ie {
174 /* WIL_WMI_UT_HW_SYSAPI */
175 uint16_t module_id;
176 /* WIL_WMI_UT_FORCE_RSN_IE */
177 uint16_t subtype_id;
178 /* 0 = no change, 1 = remove if exists, 2 = add if does not exist */
179 uint32_t state;
180} __attribute__((packed));
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300181
182enum wil_wmi_discovery_mode {
183 WMI_DISCOVERY_MODE_NON_OFFLOAD,
184 WMI_DISCOVERY_MODE_OFFLOAD,
185 WMI_DISCOVERY_MODE_PEER2PEER,
186};
187
188struct wil_wmi_p2p_cfg_cmd {
189 /* enum wil_wmi_discovery_mode */
190 uint8_t discovery_mode;
191 /* 0-based (wireless channel - 1) */
192 uint8_t channel;
193 /* set to WIL_DEFAULT_BI */
194 uint16_t bcon_interval;
195} __attribute__((packed));
Lior David0fe101e2017-03-09 16:09:50 +0200196#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200197
198#ifdef ANDROID
199
200static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname);
201
202#define ANDROID_KEYSTORE_GET 'g'
203#define ANDROID_KEYSTORE_GET_PUBKEY 'b'
204
205static int android_keystore_get(char cmd, const char *key, unsigned char *val)
206{
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200207 /* Android 4.3 changed keystore design, so need to use keystore_get() */
208#ifndef KEYSTORE_MESSAGE_SIZE
209#define KEYSTORE_MESSAGE_SIZE 65535
210#endif /* KEYSTORE_MESSAGE_SIZE */
211
212 ssize_t len;
213 uint8_t *value = NULL;
214
215 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
216 "keystore command '%c' key '%s' --> keystore_get",
217 cmd, key);
218
219 len = keystore_get(key, strlen(key), &value);
220 if (len < 0) {
221 __android_log_print(ANDROID_LOG_DEBUG, "sigma_dut",
222 "keystore_get() failed");
223 return -1;
224 }
225
226 if (len > KEYSTORE_MESSAGE_SIZE)
227 len = KEYSTORE_MESSAGE_SIZE;
228 memcpy(val, value, len);
229 free(value);
230 return len;
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200231}
232#endif /* ANDROID */
233
234
Vinita S. Maloo0fcb57d2020-04-24 14:03:56 +0530235#ifdef NL80211_SUPPORT
236static int nl80211_sta_set_power_save(struct sigma_dut *dut,
237 const char *intf,
238 enum nl80211_ps_state ps_state)
239{
240 struct nl_msg *msg;
241 int ifindex, ret;
242
243 ifindex = if_nametoindex(intf);
244 if (ifindex == 0) {
245 sigma_dut_print(dut, DUT_MSG_ERROR,
246 "%s: Index for interface %s not found",
247 __func__, intf);
248 return -1;
249 }
250
251 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
252 NL80211_CMD_SET_POWER_SAVE);
253 if (!msg) {
254 sigma_dut_print(dut, DUT_MSG_ERROR,
255 "%s: err in creating nl80211 msg", __func__);
256 return -1;
257 }
258
259 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state)) {
260 sigma_dut_print(dut, DUT_MSG_ERROR,
261 "%s: err in populating nl80211 msg", __func__);
262 nlmsg_free(msg);
263 return -1;
264 }
265
266 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
267 if (ret) {
268 sigma_dut_print(dut, DUT_MSG_ERROR,
269 "%s: err in send_and_recv_msgs, ret=%d (%s)",
270 __func__, ret, strerror(-ret));
271 return -1;
272 }
273
274 return 0;
275}
276#endif /* NL80211_SUPPORT */
277
278
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530279static int set_power_save_wcn(struct sigma_dut *dut, const char *intf, int ps)
280{
281 char buf[100];
Vinita S. Maloo0fcb57d2020-04-24 14:03:56 +0530282#ifdef NL80211_SUPPORT
283 enum nl80211_ps_state ps_state;
284
285 ps_state = ps == 1 ? NL80211_PS_ENABLED : NL80211_PS_DISABLED;
286 if (nl80211_sta_set_power_save(dut, intf, ps_state) == 0)
287 return 0;
288#endif /* NL80211_SUPPORT */
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530289
290 snprintf(buf, sizeof(buf), "iwpriv %s setPower %d", intf, ps);
291 if (system(buf) != 0) {
292 sigma_dut_print(dut, DUT_MSG_ERROR,
293 "iwpriv setPower %d failed", ps);
294 return -1;
295 }
296 return 0;
297}
298
299
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200300int set_ps(const char *intf, struct sigma_dut *dut, int enabled)
301{
302#ifdef __linux__
303 char buf[100];
304
305 if (wifi_chip_type == DRIVER_WCN) {
306 if (enabled) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530307 if (set_power_save_wcn(dut, intf, 1) < 0) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530308 snprintf(buf, sizeof(buf),
309 "iwpriv wlan0 dump 906");
310 if (system(buf) != 0)
311 goto set_power_save;
312 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200313 } else {
Vinita S. Malooa8b62722020-04-23 01:45:41 +0530314 if (set_power_save_wcn(dut, intf, 2) < 0) {
Purushottam Kushwaha304561d2019-12-23 16:57:18 +0530315 snprintf(buf, sizeof(buf),
316 "iwpriv wlan0 dump 905");
317 if (system(buf) != 0)
318 goto set_power_save;
319 snprintf(buf, sizeof(buf),
320 "iwpriv wlan0 dump 912");
321 if (system(buf) != 0)
322 goto set_power_save;
323 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200324 }
325
326 return 0;
327 }
328
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530329set_power_save:
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200330 snprintf(buf, sizeof(buf), "./iw dev %s set power_save %s",
331 intf, enabled ? "on" : "off");
332 if (system(buf) != 0) {
333 snprintf(buf, sizeof(buf), "iw dev %s set power_save %s",
334 intf, enabled ? "on" : "off");
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530335 if (system(buf) != 0) {
336 sigma_dut_print(dut, DUT_MSG_ERROR,
337 "Failed to set power save %s",
338 enabled ? "on" : "off");
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200339 return -1;
Pradeep Reddy POTTETI625b3702016-09-20 17:09:58 +0530340 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200341 }
342
343 return 0;
344#else /* __linux__ */
345 return -1;
346#endif /* __linux__ */
347}
348
349
Lior Davidcc88b562017-01-03 18:52:09 +0200350#ifdef __linux__
Lior David0fe101e2017-03-09 16:09:50 +0200351
Lior Davidcc88b562017-01-03 18:52:09 +0200352static int wil6210_get_debugfs_dir(struct sigma_dut *dut, char *path,
353 size_t len)
354{
355 DIR *dir, *wil_dir;
356 struct dirent *entry;
357 int ret = -1;
358 const char *root_path = "/sys/kernel/debug/ieee80211";
359
360 dir = opendir(root_path);
361 if (!dir)
362 return -2;
363
364 while ((entry = readdir(dir))) {
365 if (strcmp(entry->d_name, ".") == 0 ||
366 strcmp(entry->d_name, "..") == 0)
367 continue;
368
369 if (snprintf(path, len, "%s/%s/wil6210",
370 root_path, entry->d_name) >= (int) len) {
371 ret = -3;
372 break;
373 }
374
375 wil_dir = opendir(path);
376 if (wil_dir) {
377 closedir(wil_dir);
378 ret = 0;
379 break;
380 }
381 }
382
383 closedir(dir);
384 return ret;
385}
Lior David0fe101e2017-03-09 16:09:50 +0200386
387
388static int wil6210_wmi_send(struct sigma_dut *dut, uint16_t command,
389 void *payload, uint16_t length)
390{
391 struct {
392 struct wil_wmi_header hdr;
393 char payload[WIL_WMI_MAX_PAYLOAD];
394 } __attribute__((packed)) cmd;
395 char buf[128], fname[128];
396 size_t towrite, written;
397 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300398 int res;
Lior David0fe101e2017-03-09 16:09:50 +0200399
400 if (length > WIL_WMI_MAX_PAYLOAD) {
401 sigma_dut_print(dut, DUT_MSG_ERROR,
402 "payload too large(%u, max %u)",
403 length, WIL_WMI_MAX_PAYLOAD);
404 return -1;
405 }
406
407 memset(&cmd.hdr, 0, sizeof(cmd.hdr));
408 cmd.hdr.cmd = command;
409 memcpy(cmd.payload, payload, length);
410
411 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
412 sigma_dut_print(dut, DUT_MSG_ERROR,
413 "failed to get wil6210 debugfs dir");
414 return -1;
415 }
416
Jouni Malinen3aa72862019-05-29 23:14:51 +0300417 res = snprintf(fname, sizeof(fname), "%s/wmi_send", buf);
418 if (res < 0 || res >= sizeof(fname))
419 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200420 f = fopen(fname, "wb");
421 if (!f) {
422 sigma_dut_print(dut, DUT_MSG_ERROR,
423 "failed to open: %s", fname);
424 return -1;
425 }
426
427 towrite = sizeof(cmd.hdr) + length;
428 written = fwrite(&cmd, 1, towrite, f);
429 fclose(f);
430 if (written != towrite) {
431 sigma_dut_print(dut, DUT_MSG_ERROR,
432 "failed to send wmi %u", command);
433 return -1;
434 }
435
436 return 0;
437}
438
439
440static int wil6210_get_sta_info_field(struct sigma_dut *dut, const char *bssid,
441 const char *pattern, unsigned int *field)
442{
443 char buf[128], fname[128];
444 FILE *f;
445 regex_t re;
446 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +0300447 int rc, ret = -1, res;
Lior David0fe101e2017-03-09 16:09:50 +0200448
449 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
450 sigma_dut_print(dut, DUT_MSG_ERROR,
451 "failed to get wil6210 debugfs dir");
452 return -1;
453 }
454
Jouni Malinen3aa72862019-05-29 23:14:51 +0300455 res = snprintf(fname, sizeof(fname), "%s/stations", buf);
456 if (res < 0 || res >= sizeof(fname))
457 return -1;
Lior David0fe101e2017-03-09 16:09:50 +0200458 f = fopen(fname, "r");
459 if (!f) {
460 sigma_dut_print(dut, DUT_MSG_ERROR,
461 "failed to open: %s", fname);
462 return -1;
463 }
464
465 if (regcomp(&re, pattern, REG_EXTENDED)) {
466 sigma_dut_print(dut, DUT_MSG_ERROR,
467 "regcomp failed: %s", pattern);
468 goto out;
469 }
470
471 /*
472 * find the entry for the mac address
473 * line is of the form: [n] 11:22:33:44:55:66 state AID aid
474 */
475 while (fgets(buf, sizeof(buf), f)) {
476 if (strcasestr(buf, bssid)) {
477 /* extract the field (CID/AID/state) */
478 rc = regexec(&re, buf, 2, m, 0);
479 if (!rc && (m[1].rm_so >= 0)) {
480 buf[m[1].rm_eo] = 0;
481 *field = atoi(&buf[m[1].rm_so]);
482 ret = 0;
483 break;
484 }
485 }
486 }
487
488 regfree(&re);
489 if (ret)
490 sigma_dut_print(dut, DUT_MSG_ERROR,
491 "could not extract field");
492
493out:
494 fclose(f);
495
496 return ret;
497}
498
499
500static int wil6210_get_cid(struct sigma_dut *dut, const char *bssid,
501 unsigned int *cid)
502{
503 const char *pattern = "\\[([0-9]+)\\]";
504
505 return wil6210_get_sta_info_field(dut, bssid, pattern, cid);
506}
507
508
509static int wil6210_send_brp_rx(struct sigma_dut *dut, const char *mac,
510 int l_rx)
511{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700512 struct wil_wmi_bf_trig_cmd cmd;
Lior David0fe101e2017-03-09 16:09:50 +0200513 unsigned int cid;
514
Rakesh Sunki556237d2017-03-30 14:49:31 -0700515 memset(&cmd, 0, sizeof(cmd));
516
Lior David0fe101e2017-03-09 16:09:50 +0200517 if (wil6210_get_cid(dut, mac, &cid))
518 return -1;
519
520 cmd.bf_type = WIL_WMI_BRP_RX;
521 cmd.sta_id = cid;
522 /* training length (l_rx) is ignored, FW always uses length 16 */
523 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
524 &cmd, sizeof(cmd));
525}
526
527
528static int wil6210_send_sls(struct sigma_dut *dut, const char *mac)
529{
Rakesh Sunki556237d2017-03-30 14:49:31 -0700530 struct wil_wmi_bf_trig_cmd cmd;
531
532 memset(&cmd, 0, sizeof(cmd));
Lior David0fe101e2017-03-09 16:09:50 +0200533
534 if (parse_mac_address(dut, mac, (unsigned char *)&cmd.dest_mac))
535 return -1;
536
537 cmd.bf_type = WIL_WMI_SLS;
538 return wil6210_wmi_send(dut, WIL_WMI_BF_TRIG_CMDID,
539 &cmd, sizeof(cmd));
540}
541
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200542
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +0200543int wil6210_set_ese(struct sigma_dut *dut, int count,
544 struct sigma_ese_alloc *allocs)
545{
546 struct wil_wmi_ese_cfg cmd = { };
547 int i;
548
549 if (count == 0 || count > WIL_WMI_MAX_ESE_SLOTS)
550 return -1;
551
552 if (dut->ap_bcnint <= 0) {
553 sigma_dut_print(dut, DUT_MSG_ERROR,
554 "invalid beacon interval(%d), check test",
555 dut->ap_bcnint);
556 return -1;
557 }
558
559 cmd.ese_advertisment = WIL_WMI_ADVERTISE_ESE_IN_BEACON;
560 cmd.flags = 0x1d;
561 cmd.num_allocs = count;
562 for (i = 0; i < count; i++) {
563 /*
564 * Convert percent from BI (BI specified in milliseconds)
565 * to absolute duration in microseconds.
566 */
567 cmd.slots[i].duration =
568 (allocs[i].percent_bi * dut->ap_bcnint * 1000) / 100;
569 switch (allocs[i].type) {
570 case ESE_CBAP:
571 cmd.slots[i].slot_type = WIL_WMI_ESE_CBAP;
572 break;
573 case ESE_SP:
574 cmd.slots[i].slot_type = WIL_WMI_ESE_SP;
575 break;
576 default:
577 sigma_dut_print(dut, DUT_MSG_ERROR,
578 "invalid slot type(%d) at index %d",
579 allocs[i].type, i);
580 return -1;
581 }
582 cmd.slots[i].src_aid = allocs[i].src_aid;
583 cmd.slots[i].dst_aid = allocs[i].dst_aid;
584 sigma_dut_print(dut, DUT_MSG_INFO,
585 "slot %d, duration %u, type %d, srcAID %u dstAID %u",
586 i, cmd.slots[i].duration,
587 cmd.slots[i].slot_type, cmd.slots[i].src_aid,
588 cmd.slots[i].dst_aid);
589 }
590
591 return wil6210_wmi_send(dut, WIL_WMI_ESE_CFG_CMDID, &cmd, sizeof(cmd));
592}
593
594
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +0200595int wil6210_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
596{
597 struct wil_wmi_force_mcs cmd = { };
598
599 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
600 cmd.subtype_id = WIL_WMI_UT_FORCE_MCS;
601 cmd.force_enable = (uint32_t) force;
602 cmd.mcs = (uint32_t) mcs;
603
604 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
605 &cmd, sizeof(cmd));
606}
607
608
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +0200609static int wil6210_force_rsn_ie(struct sigma_dut *dut, int state)
610{
611 struct wil_wmi_force_rsn_ie cmd = { };
612
613 cmd.module_id = WIL_WMI_UT_HW_SYSAPI;
614 cmd.subtype_id = WIL_WMI_UT_FORCE_RSN_IE;
615 cmd.state = (uint32_t) state;
616
617 return wil6210_wmi_send(dut, WIL_WMI_UNIT_TEST_CMDID,
618 &cmd, sizeof(cmd));
619}
620
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300621
622/*
623 * this function is also used to configure generic remain-on-channel
624 */
625static int wil6210_p2p_cfg(struct sigma_dut *dut, int freq)
626{
627 struct wil_wmi_p2p_cfg_cmd cmd = { };
628 int channel = freq_to_channel(freq);
629
630 if (channel < 0)
631 return -1;
632 cmd.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD;
633 cmd.channel = channel - 1;
634 cmd.bcon_interval = WIL_DEFAULT_BI;
635 cmd.discovery_mode = WMI_DISCOVERY_MODE_PEER2PEER;
636
637 return wil6210_wmi_send(dut, WIL_WMI_P2P_CFG_CMDID,
638 &cmd, sizeof(cmd));
639}
640
641
642static int wil6210_remain_on_channel(struct sigma_dut *dut, int freq)
643{
644 int ret = wil6210_p2p_cfg(dut, freq);
645
646 if (ret)
647 return ret;
648
649 ret = wil6210_wmi_send(dut, WIL_WMI_START_LISTEN_CMDID, NULL, 0);
650 if (!ret) {
651 /*
652 * wait a bit to allow FW to setup the radio
653 * especially important if we switch channels
654 */
655 usleep(500000);
656 }
657
658 return ret;
659}
660
661
662static int wil6210_stop_discovery(struct sigma_dut *dut)
663{
664 return wil6210_wmi_send(dut, WIL_WMI_DISCOVERY_STOP_CMDID, NULL, 0);
665}
666
667
668static int wil6210_transmit_frame(struct sigma_dut *dut, int freq,
669 int wait_duration,
670 const char *frame, size_t frame_len)
671{
672 char buf[128], fname[128];
673 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +0300674 int res = 0, r;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300675 size_t written;
676
677 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
678 sigma_dut_print(dut, DUT_MSG_ERROR,
679 "failed to get wil6210 debugfs dir");
680 return -1;
681 }
Jouni Malinen3aa72862019-05-29 23:14:51 +0300682 r = snprintf(fname, sizeof(fname), "%s/tx_mgmt", buf);
683 if (r < 0 || r >= sizeof(fname))
684 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +0300685
686 if (wil6210_remain_on_channel(dut, freq)) {
687 sigma_dut_print(dut, DUT_MSG_ERROR,
688 "failed to listen on channel");
689 return -1;
690 }
691
692 f = fopen(fname, "wb");
693 if (!f) {
694 sigma_dut_print(dut, DUT_MSG_ERROR,
695 "failed to open: %s", fname);
696 res = -1;
697 goto out_stop;
698 }
699 written = fwrite(frame, 1, frame_len, f);
700 fclose(f);
701
702 if (written != frame_len) {
703 sigma_dut_print(dut, DUT_MSG_ERROR,
704 "failed to transmit frame (got %zd, expected %zd)",
705 written, frame_len);
706 res = -1;
707 goto out_stop;
708 }
709
710 usleep(wait_duration * 1000);
711
712out_stop:
713 wil6210_stop_discovery(dut);
714 return res;
715}
716
717
718static int find_template_frame_tag(struct template_frame_tag *tags,
719 int total_tags, int tag_num)
720{
721 int i;
722
723 for (i = 0; i < total_tags; i++) {
724 if (tag_num == tags[i].num)
725 return i;
726 }
727
728 return -1;
729}
730
731
732static int replace_p2p_attribute(struct sigma_dut *dut, char *buf, size_t len,
733 int id, const char *value, size_t val_len)
734{
735 struct wfa_p2p_attribute *attr = (struct wfa_p2p_attribute *) buf;
736
737 if (len < 3 + val_len) {
738 sigma_dut_print(dut, DUT_MSG_ERROR,
739 "not enough space to replace P2P attribute");
740 return -1;
741 }
742
743 if (attr->len != val_len) {
744 sigma_dut_print(dut, DUT_MSG_ERROR,
745 "attribute length mismatch (need %zu have %hu)",
746 val_len, attr->len);
747 return -1;
748 }
749
750 if (attr->id != id) {
751 sigma_dut_print(dut, DUT_MSG_ERROR,
752 "incorrect attribute id (expected %d actual %d)",
753 id, attr->id);
754 return -1;
755 }
756
757 memcpy(attr->variable, value, val_len);
758
759 return 0;
760}
761
762
763static int parse_template_frame_file(struct sigma_dut *dut, const char *fname,
764 char *buf, size_t *length,
765 struct template_frame_tag *tags,
766 size_t *num_tags)
767{
768 char line[512];
769 FILE *f;
770 size_t offset = 0, tag_index = 0;
771 int num, index;
772 int in_tag = 0, tag_num = 0, tag_offset = 0;
773
774 if (*length < sizeof(struct ieee80211_hdr_3addr)) {
775 sigma_dut_print(dut, DUT_MSG_ERROR,
776 "supplied buffer is too small");
777 return -1;
778 }
779
780 f = fopen(fname, "r");
781 if (!f) {
782 sigma_dut_print(dut, DUT_MSG_ERROR,
783 "failed to open template file %s", fname);
784 return -1;
785 }
786
787 /*
788 * template file format: lines beginning with # are comments and
789 * ignored.
790 * It is possible to tag bytes in the frame to make it easy
791 * to replace fields in the template, espcially if they appear
792 * in variable-sized sections (such as IEs)
793 * This is done by a line beginning with $NUM where NUM is an integer
794 * tag number. It can be followed by space(s) and comment.
795 * The next line is considered the tagged bytes. The parser will fill
796 * the tag number, offset and length of the tagged bytes.
797 * rest of the lines contain frame bytes as sequence of hex digits,
798 * 2 digits for each byte. Spaces are allowed between bytes.
799 * On bytes lines only hex digits and spaces are allowed
800 */
801 while (!feof(f)) {
802 if (!fgets(line, sizeof(line), f))
803 break;
804 index = 0;
805 while (isspace((unsigned char) line[index]))
806 index++;
807 if (!line[index] || line[index] == '#')
808 continue;
809 if (line[index] == '$') {
810 if (tags) {
811 index++;
812 tag_num = strtol(&line[index], NULL, 0);
813 tag_offset = offset;
814 in_tag = 1;
815 }
816 continue;
817 }
818 while (line[index]) {
819 if (isspace((unsigned char) line[index])) {
820 index++;
821 continue;
822 }
823 num = hex_byte(&line[index]);
824 if (num < 0)
825 break;
826 buf[offset++] = num;
827 if (offset == *length)
828 goto out;
829 index += 2;
830 }
831
832 if (in_tag) {
833 if (tag_index < *num_tags) {
834 tags[tag_index].num = tag_num;
835 tags[tag_index].offset = tag_offset;
836 tags[tag_index].len = offset - tag_offset;
837 tag_index++;
838 } else {
839 sigma_dut_print(dut, DUT_MSG_INFO,
840 "too many tags, tag ignored");
841 }
842 in_tag = 0;
843 }
844 }
845
846 if (num_tags)
847 *num_tags = tag_index;
848out:
849 fclose(f);
850 if (offset < sizeof(struct ieee80211_hdr_3addr)) {
851 sigma_dut_print(dut, DUT_MSG_ERROR,
852 "template frame is too small");
853 return -1;
854 }
855
856 *length = offset;
857 return 0;
858}
859
Lior Davidcc88b562017-01-03 18:52:09 +0200860#endif /* __linux__ */
861
862
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200863static void static_ip_file(int proto, const char *addr, const char *mask,
864 const char *gw)
865{
866 if (proto) {
867 FILE *f = fopen("static-ip", "w");
868 if (f) {
869 fprintf(f, "%d %s %s %s\n", proto, addr,
870 mask ? mask : "N/A",
871 gw ? gw : "N/A");
872 fclose(f);
873 }
874 } else {
875 unlink("static-ip");
876 }
877}
878
879
880static int send_neighbor_request(struct sigma_dut *dut, const char *intf,
881 const char *ssid)
882{
883#ifdef __linux__
884 char buf[100];
885
886 snprintf(buf, sizeof(buf), "iwpriv %s neighbor %s",
887 intf, ssid);
888 sigma_dut_print(dut, DUT_MSG_INFO, "Request: %s", buf);
889
890 if (system(buf) != 0) {
891 sigma_dut_print(dut, DUT_MSG_ERROR,
892 "iwpriv neighbor request failed");
893 return -1;
894 }
895
896 sigma_dut_print(dut, DUT_MSG_INFO, "iwpriv neighbor request send");
897
898 return 0;
899#else /* __linux__ */
900 return -1;
901#endif /* __linux__ */
902}
903
904
905static int send_trans_mgmt_query(struct sigma_dut *dut, const char *intf,
Ashwini Patil5acd7382017-04-13 15:55:04 +0530906 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200907{
Ashwini Patil5acd7382017-04-13 15:55:04 +0530908 const char *val;
909 int reason_code = 0;
910 char buf[1024];
911
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200912 /*
913 * In the earlier builds we used WNM_QUERY and in later
914 * builds used WNM_BSS_QUERY.
915 */
916
Ashwini Patil5acd7382017-04-13 15:55:04 +0530917 val = get_param(cmd, "BTMQuery_Reason_Code");
918 if (val)
919 reason_code = atoi(val);
920
921 val = get_param(cmd, "Cand_List");
922 if (val && atoi(val) == 1 && dut->btm_query_cand_list) {
923 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d%s", reason_code,
924 dut->btm_query_cand_list);
925 free(dut->btm_query_cand_list);
926 dut->btm_query_cand_list = NULL;
927 } else {
928 snprintf(buf, sizeof(buf), "WNM_BSS_QUERY %d", reason_code);
929 }
930
931 if (wpa_command(intf, buf) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200932 sigma_dut_print(dut, DUT_MSG_ERROR,
933 "transition management query failed");
934 return -1;
935 }
936
937 sigma_dut_print(dut, DUT_MSG_DEBUG,
938 "transition management query sent");
939
940 return 0;
941}
942
943
944int is_ip_addr(const char *str)
945{
946 const char *pos = str;
947 struct in_addr addr;
948
949 while (*pos) {
950 if (*pos != '.' && (*pos < '0' || *pos > '9'))
951 return 0;
952 pos++;
953 }
954
955 return inet_aton(str, &addr);
956}
957
958
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200959int get_ip_config(struct sigma_dut *dut, const char *ifname, char *buf,
960 size_t buf_len)
961{
vamsi krishnaa11d0732018-05-16 12:19:48 +0530962 char tmp[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200963 char ip[16], mask[15], dns[16], sec_dns[16];
964 int is_dhcp = 0;
965 int s;
966#ifdef ANDROID
967 char prop[PROPERTY_VALUE_MAX];
vamsi krishnaa11d0732018-05-16 12:19:48 +0530968#else /* ANDROID */
969 FILE *f;
970#ifdef __linux__
971 const char *str_ps;
972#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200973#endif /* ANDROID */
974
975 ip[0] = '\0';
976 mask[0] = '\0';
977 dns[0] = '\0';
978 sec_dns[0] = '\0';
979
980 s = socket(PF_INET, SOCK_DGRAM, 0);
981 if (s >= 0) {
982 struct ifreq ifr;
983 struct sockaddr_in saddr;
984
985 memset(&ifr, 0, sizeof(ifr));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700986 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200987 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
988 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get "
989 "%s IP address: %s",
990 ifname, strerror(errno));
991 } else {
992 memcpy(&saddr, &ifr.ifr_addr,
993 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -0700994 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
Jouni Malinencd4e3c32015-10-29 12:39:56 +0200995 }
996
997 if (ioctl(s, SIOCGIFNETMASK, &ifr) == 0) {
998 memcpy(&saddr, &ifr.ifr_addr,
999 sizeof(struct sockaddr_in));
Peng Xub8fc5cc2017-05-10 17:27:28 -07001000 strlcpy(mask, inet_ntoa(saddr.sin_addr), sizeof(mask));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001001 }
1002 close(s);
1003 }
1004
1005#ifdef ANDROID
1006 snprintf(tmp, sizeof(tmp), "dhcp.%s.pid", ifname);
1007 if (property_get(tmp, prop, NULL) != 0 && atoi(prop) > 0) {
1008 snprintf(tmp, sizeof(tmp), "dhcp.%s.result", ifname);
1009 if (property_get(tmp, prop, NULL) != 0 &&
1010 strcmp(prop, "ok") == 0) {
1011 snprintf(tmp, sizeof(tmp), "dhcp.%s.ipaddress",
1012 ifname);
1013 if (property_get(tmp, prop, NULL) != 0 &&
1014 strcmp(ip, prop) == 0)
1015 is_dhcp = 1;
1016 }
1017 }
1018
1019 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns1", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -07001020 if (property_get(tmp, prop, NULL) != 0)
1021 strlcpy(dns, prop, sizeof(dns));
1022 else if (property_get("net.dns1", prop, NULL) != 0)
1023 strlcpy(dns, prop, sizeof(dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001024
1025 snprintf(tmp, sizeof(tmp), "dhcp.%s.dns2", ifname);
Peng Xub8fc5cc2017-05-10 17:27:28 -07001026 if (property_get(tmp, prop, NULL) != 0)
1027 strlcpy(sec_dns, prop, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001028#else /* ANDROID */
1029#ifdef __linux__
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001030 if (get_driver_type(dut) == DRIVER_OPENWRT)
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301031 str_ps = "ps -w";
1032 else
1033 str_ps = "ps ax";
1034 snprintf(tmp, sizeof(tmp),
1035 "%s | grep dhclient | grep -v grep | grep -q %s",
1036 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001037 if (system(tmp) == 0)
1038 is_dhcp = 1;
1039 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301040 snprintf(tmp, sizeof(tmp),
1041 "%s | grep udhcpc | grep -v grep | grep -q %s",
1042 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001043 if (system(tmp) == 0)
1044 is_dhcp = 1;
1045 else {
Sarvepalli, Rajesh Babua76c6442016-03-18 20:34:26 +05301046 snprintf(tmp, sizeof(tmp),
1047 "%s | grep dhcpcd | grep -v grep | grep -q %s",
1048 str_ps, ifname);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001049 if (system(tmp) == 0)
1050 is_dhcp = 1;
1051 }
1052 }
1053#endif /* __linux__ */
1054
1055 f = fopen("/etc/resolv.conf", "r");
1056 if (f) {
vamsi krishnaa11d0732018-05-16 12:19:48 +05301057 char *pos, *pos2;
1058
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001059 while (fgets(tmp, sizeof(tmp), f)) {
1060 if (strncmp(tmp, "nameserver", 10) != 0)
1061 continue;
1062 pos = tmp + 10;
1063 while (*pos == ' ' || *pos == '\t')
1064 pos++;
1065 pos2 = pos;
1066 while (*pos2) {
1067 if (*pos2 == '\n' || *pos2 == '\r') {
1068 *pos2 = '\0';
1069 break;
1070 }
1071 pos2++;
1072 }
Peng Xub8fc5cc2017-05-10 17:27:28 -07001073 if (!dns[0])
1074 strlcpy(dns, pos, sizeof(dns));
1075 else if (!sec_dns[0])
1076 strlcpy(sec_dns, pos, sizeof(sec_dns));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001077 }
1078 fclose(f);
1079 }
1080#endif /* ANDROID */
1081
1082 snprintf(buf, buf_len, "dhcp,%d,ip,%s,mask,%s,primary-dns,%s",
1083 is_dhcp, ip, mask, dns);
1084 buf[buf_len - 1] = '\0';
1085
1086 return 0;
1087}
1088
1089
1090
1091
1092int get_ipv6_config(struct sigma_dut *dut, const char *ifname, char *buf,
1093 size_t buf_len)
1094{
1095#ifdef __linux__
1096#ifdef ANDROID
1097 char cmd[200], result[1000], *pos, *end;
1098 FILE *f;
1099 size_t len;
1100
1101 snprintf(cmd, sizeof(cmd), "ip addr show dev %s scope global", ifname);
1102 f = popen(cmd, "r");
1103 if (f == NULL)
1104 return -1;
1105 len = fread(result, 1, sizeof(result) - 1, f);
1106 pclose(f);
1107 if (len == 0)
1108 return -1;
1109 result[len] = '\0';
1110 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s result: %s\n", cmd, result);
1111
1112 pos = strstr(result, "inet6 ");
1113 if (pos == NULL)
1114 return -1;
1115 pos += 6;
1116 end = strchr(pos, ' ');
1117 if (end)
1118 *end = '\0';
1119 end = strchr(pos, '/');
1120 if (end)
1121 *end = '\0';
1122 snprintf(buf, buf_len, "ip,%s", pos);
1123 buf[buf_len - 1] = '\0';
1124 return 0;
1125#else /* ANDROID */
1126 struct ifaddrs *ifaddr, *ifa;
1127 int res, found = 0;
1128 char host[NI_MAXHOST];
1129
1130 if (getifaddrs(&ifaddr) < 0) {
1131 perror("getifaddrs");
1132 return -1;
1133 }
1134
1135 for (ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
1136 if (strcasecmp(ifname, ifa->ifa_name) != 0)
1137 continue;
1138 if (ifa->ifa_addr == NULL ||
1139 ifa->ifa_addr->sa_family != AF_INET6)
1140 continue;
1141
1142 res = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6),
1143 host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1144 if (res != 0) {
1145 sigma_dut_print(dut, DUT_MSG_DEBUG, "getnameinfo: %s",
1146 gai_strerror(res));
1147 continue;
1148 }
1149 if (strncmp(host, "fe80::", 6) == 0)
1150 continue; /* skip link-local */
1151
1152 sigma_dut_print(dut, DUT_MSG_DEBUG, "ifaddr: %s", host);
1153 found = 1;
1154 break;
1155 }
1156
1157 freeifaddrs(ifaddr);
1158
1159 if (found) {
1160 char *pos;
1161 pos = strchr(host, '%');
1162 if (pos)
1163 *pos = '\0';
1164 snprintf(buf, buf_len, "ip,%s", host);
1165 buf[buf_len - 1] = '\0';
1166 return 0;
1167 }
1168
1169#endif /* ANDROID */
1170#endif /* __linux__ */
1171 return -1;
1172}
1173
1174
Jouni Malinenf7222712019-06-13 01:50:21 +03001175static enum sigma_cmd_result cmd_sta_get_ip_config(struct sigma_dut *dut,
1176 struct sigma_conn *conn,
1177 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001178{
1179 const char *intf = get_param(cmd, "Interface");
1180 const char *ifname;
1181 char buf[200];
1182 const char *val;
1183 int type = 1;
1184
1185 if (intf == NULL)
1186 return -1;
1187
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001188 if (strcmp(intf, get_main_ifname(dut)) == 0)
1189 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001190 else
1191 ifname = intf;
1192
1193 /*
1194 * UCC may assume the IP address to be available immediately after
1195 * association without trying to run sta_get_ip_config multiple times.
1196 * Sigma CAPI does not specify this command as a block command that
1197 * would wait for the address to become available, but to pass tests
1198 * more reliably, it looks like such a wait may be needed here.
1199 */
1200 if (wait_ip_addr(dut, ifname, 15) < 0) {
1201 sigma_dut_print(dut, DUT_MSG_INFO, "Could not get IP address "
1202 "for sta_get_ip_config");
1203 /*
1204 * Try to continue anyway since many UCC tests do not really
1205 * care about the return value from here..
1206 */
1207 }
1208
1209 val = get_param(cmd, "Type");
1210 if (val)
1211 type = atoi(val);
1212 if (type == 2 || dut->last_set_ip_config_ipv6) {
1213 int i;
1214
1215 /*
1216 * Since we do not have proper wait for IPv6 addresses, use a
1217 * fixed two second delay here as a workaround for UCC script
1218 * assuming IPv6 address is available when this command returns.
1219 * Some scripts did not use Type,2 properly for IPv6, so include
1220 * also the cases where the previous sta_set_ip_config indicated
1221 * use of IPv6.
1222 */
1223 sigma_dut_print(dut, DUT_MSG_INFO, "Wait up to extra ten seconds in sta_get_ip_config for IPv6 address");
1224 for (i = 0; i < 10; i++) {
1225 sleep(1);
1226 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) == 0)
1227 {
1228 sigma_dut_print(dut, DUT_MSG_INFO, "Found IPv6 address");
1229 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1230#ifdef ANDROID
1231 sigma_dut_print(dut, DUT_MSG_INFO,
1232 "Adding IPv6 rule on Android");
1233 add_ipv6_rule(dut, intf);
1234#endif /* ANDROID */
1235
1236 return 0;
1237 }
1238 }
1239 }
1240 if (type == 1) {
1241 if (get_ip_config(dut, ifname, buf, sizeof(buf)) < 0)
1242 return -2;
1243 } else if (type == 2) {
1244 if (get_ipv6_config(dut, ifname, buf, sizeof(buf)) < 0)
1245 return -2;
1246 } else {
1247 send_resp(dut, conn, SIGMA_ERROR,
1248 "errorCode,Unsupported address type");
1249 return 0;
1250 }
1251
1252 send_resp(dut, conn, SIGMA_COMPLETE, buf);
1253 return 0;
1254}
1255
1256
1257static void kill_dhcp_client(struct sigma_dut *dut, const char *ifname)
1258{
1259#ifdef __linux__
1260 char buf[200];
1261 char path[128];
1262 struct stat s;
1263
1264#ifdef ANDROID
1265 snprintf(path, sizeof(path), "/data/misc/dhcp/dhcpcd-%s.pid", ifname);
1266#else /* ANDROID */
1267 snprintf(path, sizeof(path), "/var/run/dhclient-%s.pid", ifname);
1268#endif /* ANDROID */
1269 if (stat(path, &s) == 0) {
1270 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1271 sigma_dut_print(dut, DUT_MSG_INFO,
1272 "Kill previous DHCP client: %s", buf);
1273 if (system(buf) != 0)
1274 sigma_dut_print(dut, DUT_MSG_INFO,
1275 "Failed to kill DHCP client");
1276 unlink(path);
1277 sleep(1);
1278 } else {
1279 snprintf(path, sizeof(path), "/var/run/dhcpcd-%s.pid", ifname);
1280
1281 if (stat(path, &s) == 0) {
1282 snprintf(buf, sizeof(buf), "kill `cat %s`", path);
1283 sigma_dut_print(dut, DUT_MSG_INFO,
1284 "Kill previous DHCP client: %s", buf);
1285 if (system(buf) != 0)
1286 sigma_dut_print(dut, DUT_MSG_INFO,
1287 "Failed to kill DHCP client");
1288 unlink(path);
1289 sleep(1);
1290 }
1291 }
1292#endif /* __linux__ */
1293}
1294
1295
1296static int start_dhcp_client(struct sigma_dut *dut, const char *ifname)
1297{
1298#ifdef __linux__
1299 char buf[200];
1300
1301#ifdef ANDROID
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301302 if (access("/system/bin/dhcpcd", F_OK) != -1) {
1303 snprintf(buf, sizeof(buf),
1304 "/system/bin/dhcpcd -b %s", ifname);
1305 } else if (access("/system/bin/dhcptool", F_OK) != -1) {
1306 snprintf(buf, sizeof(buf), "/system/bin/dhcptool %s &", ifname);
Ankita Bajaj8454e5d2019-04-05 16:04:55 +05301307 } else if (access("/vendor/bin/dhcpcd", F_OK) != -1) {
1308 snprintf(buf, sizeof(buf), "/vendor/bin/dhcpcd -b %s", ifname);
1309 } else if (access("/vendor/bin/dhcptool", F_OK) != -1) {
1310 snprintf(buf, sizeof(buf), "/vendor/bin/dhcptool %s", ifname);
Purushottam Kushwaha46d64262016-08-23 17:57:53 +05301311 } else {
1312 sigma_dut_print(dut, DUT_MSG_ERROR,
1313 "DHCP client program missing");
1314 return 0;
1315 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001316#else /* ANDROID */
1317 snprintf(buf, sizeof(buf),
1318 "dhclient -nw -pf /var/run/dhclient-%s.pid %s",
1319 ifname, ifname);
1320#endif /* ANDROID */
1321 sigma_dut_print(dut, DUT_MSG_INFO, "Start DHCP client: %s", buf);
1322 if (system(buf) != 0) {
1323 snprintf(buf, sizeof(buf), "dhcpcd -t 0 %s &", ifname);
1324 if (system(buf) != 0) {
1325 sigma_dut_print(dut, DUT_MSG_INFO,
1326 "Failed to start DHCP client");
1327#ifndef ANDROID
1328 return -1;
1329#endif /* ANDROID */
1330 }
1331 }
1332#endif /* __linux__ */
1333
1334 return 0;
1335}
1336
1337
1338static int clear_ip_addr(struct sigma_dut *dut, const char *ifname)
1339{
1340#ifdef __linux__
1341 char buf[200];
1342
1343 snprintf(buf, sizeof(buf), "ip addr flush dev %s", ifname);
1344 if (system(buf) != 0) {
1345 sigma_dut_print(dut, DUT_MSG_INFO,
1346 "Failed to clear IP addresses");
1347 return -1;
1348 }
1349#endif /* __linux__ */
1350
1351 return 0;
1352}
1353
1354
1355#ifdef ANDROID
1356static int add_ipv6_rule(struct sigma_dut *dut, const char *ifname)
1357{
1358 char cmd[200], *result, *pos;
1359 FILE *fp;
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301360 int tableid;
1361 size_t len, result_len = 1000;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001362
1363 snprintf(cmd, sizeof(cmd), "ip -6 route list table all | grep %s",
1364 ifname);
1365 fp = popen(cmd, "r");
1366 if (fp == NULL)
1367 return -1;
1368
1369 result = malloc(result_len);
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301370 if (result == NULL) {
1371 fclose(fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001372 return -1;
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +05301373 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001374
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301375 len = fread(result, 1, result_len - 1, fp);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001376 fclose(fp);
1377
1378 if (len == 0) {
1379 free(result);
1380 return -1;
1381 }
Pradeep Reddy POTTETIf58a1fe2016-10-13 17:22:03 +05301382 result[len] = '\0';
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001383
1384 pos = strstr(result, "table ");
1385 if (pos == NULL) {
1386 free(result);
1387 return -1;
1388 }
1389
1390 pos += strlen("table ");
1391 tableid = atoi(pos);
1392 if (tableid != 0) {
1393 if (system("ip -6 rule del prio 22000") != 0) {
1394 /* ignore any error */
1395 }
1396 snprintf(cmd, sizeof(cmd),
1397 "ip -6 rule add from all lookup %d prio 22000",
1398 tableid);
1399 if (system(cmd) != 0) {
1400 sigma_dut_print(dut, DUT_MSG_INFO,
1401 "Failed to run %s", cmd);
1402 free(result);
1403 return -1;
1404 }
1405 } else {
1406 sigma_dut_print(dut, DUT_MSG_INFO,
1407 "No Valid Table Id found %s", pos);
1408 free(result);
1409 return -1;
1410 }
1411 free(result);
1412
1413 return 0;
1414}
1415#endif /* ANDROID */
1416
1417
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301418int set_ipv4_addr(struct sigma_dut *dut, const char *ifname,
1419 const char *ip, const char *mask)
1420{
1421 char buf[200];
1422
1423 snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s",
1424 ifname, ip, mask);
1425 return system(buf) == 0;
1426}
1427
1428
1429int set_ipv4_gw(struct sigma_dut *dut, const char *gw)
1430{
1431 char buf[200];
1432
1433 if (!is_ip_addr(gw)) {
1434 sigma_dut_print(dut, DUT_MSG_DEBUG, "Invalid gw addr - %s", gw);
1435 return -1;
1436 }
1437
1438 snprintf(buf, sizeof(buf), "route add default gw %s", gw);
1439 if (!dut->no_ip_addr_set && system(buf) != 0) {
1440 snprintf(buf, sizeof(buf), "ip ro re default via %s",
1441 gw);
1442 if (system(buf) != 0)
1443 return 0;
1444 }
1445
1446 return 1;
1447}
1448
1449
Jouni Malinenf7222712019-06-13 01:50:21 +03001450static enum sigma_cmd_result cmd_sta_set_ip_config(struct sigma_dut *dut,
1451 struct sigma_conn *conn,
1452 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001453{
1454 const char *intf = get_param(cmd, "Interface");
1455 const char *ifname;
1456 char buf[200];
1457 const char *val, *ip, *mask, *gw;
1458 int type = 1;
1459
1460 if (intf == NULL)
1461 return -1;
1462
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001463 if (strcmp(intf, get_main_ifname(dut)) == 0)
1464 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001465 else
1466 ifname = intf;
1467
1468 if (if_nametoindex(ifname) == 0) {
1469 send_resp(dut, conn, SIGMA_ERROR,
1470 "ErrorCode,Unknown interface");
1471 return 0;
1472 }
1473
1474 val = get_param(cmd, "Type");
1475 if (val) {
1476 type = atoi(val);
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301477 if (type < 1 || type > 3) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001478 send_resp(dut, conn, SIGMA_ERROR,
1479 "ErrorCode,Unsupported address type");
1480 return 0;
1481 }
1482 }
1483
1484 dut->last_set_ip_config_ipv6 = 0;
1485
1486 val = get_param(cmd, "dhcp");
1487 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "true") == 0)) {
1488 static_ip_file(0, NULL, NULL, NULL);
1489#ifdef __linux__
1490 if (type == 2) {
1491 dut->last_set_ip_config_ipv6 = 1;
1492 sigma_dut_print(dut, DUT_MSG_INFO, "Using IPv6 "
1493 "stateless address autoconfiguration");
1494#ifdef ANDROID
Hu Wang8fd144d2021-12-29 17:07:45 +08001495 snprintf(buf, sizeof(buf),
1496 "sysctl net.ipv6.conf.%s.disable_ipv6=0",
1497 ifname);
1498 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1499 if (system(buf) != 0) {
1500 sigma_dut_print(dut, DUT_MSG_DEBUG,
1501 "Failed to enable IPv6 address");
1502 }
1503
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001504 /*
1505 * This sleep is required as the assignment in case of
1506 * Android is taking time and is done by the kernel.
1507 * The subsequent ping for IPv6 is impacting HS20 test
1508 * case.
1509 */
1510 sleep(2);
1511 add_ipv6_rule(dut, intf);
1512#endif /* ANDROID */
1513 /* Assume this happens by default */
1514 return 1;
1515 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301516 if (type != 3) {
1517 kill_dhcp_client(dut, ifname);
1518 if (start_dhcp_client(dut, ifname) < 0)
1519 return -2;
1520 } else {
1521 sigma_dut_print(dut, DUT_MSG_DEBUG,
1522 "Using FILS HLP DHCPv4 Rapid Commit");
1523 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001524
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001525 return 1;
1526#endif /* __linux__ */
1527 return -2;
1528 }
1529
1530 ip = get_param(cmd, "ip");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301531 if (!ip) {
1532 send_resp(dut, conn, SIGMA_INVALID,
1533 "ErrorCode,Missing IP address");
1534 return 0;
1535 }
1536
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001537 mask = get_param(cmd, "mask");
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301538 if (!mask) {
1539 send_resp(dut, conn, SIGMA_INVALID,
1540 "ErrorCode,Missing subnet mask");
1541 return 0;
1542 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001543
1544 if (type == 2) {
1545 int net = atoi(mask);
1546
1547 if ((net < 0 && net > 64) || !is_ipv6_addr(ip))
1548 return -1;
1549
1550 if (dut->no_ip_addr_set) {
1551 snprintf(buf, sizeof(buf),
1552 "sysctl net.ipv6.conf.%s.disable_ipv6=1",
1553 ifname);
1554 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
1555 if (system(buf) != 0) {
1556 sigma_dut_print(dut, DUT_MSG_DEBUG,
1557 "Failed to disable IPv6 address before association");
1558 }
1559 } else {
Veerendranath Jakkam176181c2020-05-16 00:19:21 +05301560 if (set_ipv6_addr(dut, ip, mask, ifname) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001561 send_resp(dut, conn, SIGMA_ERROR,
1562 "ErrorCode,Failed to set IPv6 address");
1563 return 0;
1564 }
1565 }
1566
1567 dut->last_set_ip_config_ipv6 = 1;
1568 static_ip_file(6, ip, mask, NULL);
1569 return 1;
1570 } else if (type == 1) {
Pradeep Reddy POTTETIb18c5652016-01-18 12:45:37 +05301571 if (!is_ip_addr(ip) || !is_ip_addr(mask))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001572 return -1;
1573 }
1574
1575 kill_dhcp_client(dut, ifname);
1576
1577 if (!dut->no_ip_addr_set) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301578 if (!set_ipv4_addr(dut, ifname, ip, mask)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001579 send_resp(dut, conn, SIGMA_ERROR,
1580 "ErrorCode,Failed to set IP address");
1581 return 0;
1582 }
1583 }
1584
1585 gw = get_param(cmd, "defaultGateway");
1586 if (gw) {
Ankita Bajaj1bde7942018-01-09 19:15:01 +05301587 if (set_ipv4_gw(dut, gw) < 1) {
1588 send_resp(dut, conn, SIGMA_ERROR,
1589 "ErrorCode,Failed to set default gateway");
1590 return 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001591 }
1592 }
1593
1594 val = get_param(cmd, "primary-dns");
1595 if (val) {
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301596#ifdef ANDROID
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001597 /* TODO */
1598 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored primary-dns %s "
1599 "setting", val);
Vinita S. Maloo069e8d42021-04-29 13:15:08 +05301600#else /* ANDROID */
1601 char dns_cmd[200];
1602 int len;
1603
1604 if (system("sed -i '/nameserver/d' /etc/resolv.conf") != 0) {
1605 sigma_dut_print(dut, DUT_MSG_ERROR,
1606 "Failed to clear nameserver entries in /etc/resolv.conf");
1607 return ERROR_SEND_STATUS;
1608 }
1609
1610 len = snprintf(dns_cmd, sizeof(dns_cmd),
1611 "sed -i '1 i nameserver %s' /etc/resolv.conf", val);
1612 if (len < 0 || len >= sizeof(dns_cmd))
1613 return ERROR_SEND_STATUS;
1614
1615 sigma_dut_print(dut, DUT_MSG_DEBUG, "Running %s", dns_cmd);
1616 if (system(dns_cmd) != 0) {
1617 send_resp(dut, conn, SIGMA_ERROR,
1618 "ErrorCode,Failed to set primary-dns");
1619 return STATUS_SENT_ERROR;
1620 }
1621#endif /* ANDROID */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001622 }
1623
1624 val = get_param(cmd, "secondary-dns");
1625 if (val) {
1626 /* TODO */
1627 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored secondary-dns %s "
1628 "setting", val);
1629 }
1630
1631 static_ip_file(4, ip, mask, gw);
1632
1633 return 1;
1634}
1635
1636
Jouni Malinenf7222712019-06-13 01:50:21 +03001637static enum sigma_cmd_result cmd_sta_get_info(struct sigma_dut *dut,
1638 struct sigma_conn *conn,
1639 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001640{
1641 /* const char *intf = get_param(cmd, "Interface"); */
1642 /* TODO: could report more details here */
1643 send_resp(dut, conn, SIGMA_COMPLETE, "vendor,Atheros");
1644 return 0;
1645}
1646
1647
Jouni Malinenf7222712019-06-13 01:50:21 +03001648static enum sigma_cmd_result cmd_sta_get_mac_address(struct sigma_dut *dut,
1649 struct sigma_conn *conn,
1650 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001651{
1652 /* const char *intf = get_param(cmd, "Interface"); */
1653 char addr[20], resp[50];
1654
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05301655 if (dut->dev_role == DEVROLE_STA_CFON)
1656 return sta_cfon_get_mac_address(dut, conn, cmd);
1657
Jouni Malinen9540e012019-11-05 17:08:42 +02001658 start_sta_mode(dut);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001659 if (get_wpa_status(get_station_ifname(dut), "address",
1660 addr, sizeof(addr)) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001661 return -2;
1662
1663 snprintf(resp, sizeof(resp), "mac,%s", addr);
1664 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1665 return 0;
1666}
1667
1668
Jouni Malinenf7222712019-06-13 01:50:21 +03001669static enum sigma_cmd_result cmd_sta_is_connected(struct sigma_dut *dut,
1670 struct sigma_conn *conn,
1671 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001672{
1673 /* const char *intf = get_param(cmd, "Interface"); */
1674 int connected = 0;
1675 char result[32];
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001676 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001677 sizeof(result)) < 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001678 sigma_dut_print(dut, DUT_MSG_INFO,
1679 "Could not get interface %s status",
1680 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001681 return -2;
1682 }
1683
1684 sigma_dut_print(dut, DUT_MSG_DEBUG, "wpa_state=%s", result);
1685 if (strncmp(result, "COMPLETED", 9) == 0)
1686 connected = 1;
1687
1688 if (connected)
1689 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1690 else
1691 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1692
1693 return 0;
1694}
1695
1696
Jouni Malinenf7222712019-06-13 01:50:21 +03001697static enum sigma_cmd_result
1698cmd_sta_verify_ip_connection(struct sigma_dut *dut, struct sigma_conn *conn,
1699 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001700{
1701 /* const char *intf = get_param(cmd, "Interface"); */
1702 const char *dst, *timeout;
1703 int wait_time = 90;
1704 char buf[100];
1705 int res;
1706
1707 dst = get_param(cmd, "destination");
1708 if (dst == NULL || !is_ip_addr(dst))
1709 return -1;
1710
1711 timeout = get_param(cmd, "timeout");
1712 if (timeout) {
1713 wait_time = atoi(timeout);
1714 if (wait_time < 1)
1715 wait_time = 1;
1716 }
1717
1718 /* TODO: force renewal of IP lease if DHCP is enabled */
1719
1720 snprintf(buf, sizeof(buf), "ping %s -c 3 -W %d", dst, wait_time);
1721 res = system(buf);
1722 sigma_dut_print(dut, DUT_MSG_DEBUG, "ping returned: %d", res);
1723 if (res == 0)
1724 send_resp(dut, conn, SIGMA_COMPLETE, "connected,1");
1725 else if (res == 256)
1726 send_resp(dut, conn, SIGMA_COMPLETE, "connected,0");
1727 else
1728 return -2;
1729
1730 return 0;
1731}
1732
1733
Jouni Malinenf7222712019-06-13 01:50:21 +03001734static enum sigma_cmd_result cmd_sta_get_bssid(struct sigma_dut *dut,
1735 struct sigma_conn *conn,
1736 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001737{
1738 /* const char *intf = get_param(cmd, "Interface"); */
1739 char bssid[20], resp[50];
1740
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001741 if (get_wpa_status(get_station_ifname(dut), "bssid",
1742 bssid, sizeof(bssid)) < 0)
Peng Xub8fc5cc2017-05-10 17:27:28 -07001743 strlcpy(bssid, "00:00:00:00:00:00", sizeof(bssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001744
1745 snprintf(resp, sizeof(resp), "bssid,%s", bssid);
1746 send_resp(dut, conn, SIGMA_COMPLETE, resp);
1747 return 0;
1748}
1749
1750
1751#ifdef __SAMSUNG__
1752static int add_use_network(const char *ifname)
1753{
1754 char buf[100];
1755
1756 snprintf(buf, sizeof(buf), "USE_NETWORK ON");
1757 wpa_command(ifname, buf);
1758 return 0;
1759}
1760#endif /* __SAMSUNG__ */
1761
1762
1763static int add_network_common(struct sigma_dut *dut, struct sigma_conn *conn,
1764 const char *ifname, struct sigma_cmd *cmd)
1765{
1766 const char *ssid = get_param(cmd, "ssid");
1767 int id;
1768 const char *val;
1769
1770 if (ssid == NULL)
1771 return -1;
1772
1773 start_sta_mode(dut);
1774
1775#ifdef __SAMSUNG__
1776 add_use_network(ifname);
1777#endif /* __SAMSUNG__ */
1778
1779 id = add_network(ifname);
1780 if (id < 0)
1781 return -2;
1782 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding network %d", id);
1783
1784 if (set_network_quoted(ifname, id, "ssid", ssid) < 0)
1785 return -2;
1786
1787 dut->infra_network_id = id;
1788 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
1789
1790 val = get_param(cmd, "program");
1791 if (!val)
1792 val = get_param(cmd, "prog");
1793 if (val && strcasecmp(val, "hs2") == 0) {
1794 char buf[100];
1795 snprintf(buf, sizeof(buf), "ENABLE_NETWORK %d no-connect", id);
1796 wpa_command(ifname, buf);
1797
1798 val = get_param(cmd, "prefer");
1799 if (val && atoi(val) > 0)
1800 set_network(ifname, id, "priority", "1");
1801 }
1802
1803 return id;
1804}
1805
1806
Jouni Malinenf7222712019-06-13 01:50:21 +03001807static enum sigma_cmd_result cmd_sta_set_encryption(struct sigma_dut *dut,
1808 struct sigma_conn *conn,
1809 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001810{
1811 const char *intf = get_param(cmd, "Interface");
1812 const char *ssid = get_param(cmd, "ssid");
1813 const char *type = get_param(cmd, "encpType");
1814 const char *ifname;
1815 char buf[200];
1816 int id;
1817
1818 if (intf == NULL || ssid == NULL)
1819 return -1;
1820
Jouni Malinen016ae6c2019-11-04 17:00:01 +02001821 if (strcmp(intf, get_main_ifname(dut)) == 0)
1822 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001823 else
1824 ifname = intf;
1825
1826 id = add_network_common(dut, conn, ifname, cmd);
1827 if (id < 0)
1828 return id;
1829
1830 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
1831 return -2;
1832
1833 if (type && strcasecmp(type, "wep") == 0) {
1834 const char *val;
1835 int i;
1836
1837 val = get_param(cmd, "activeKey");
1838 if (val) {
1839 int keyid;
1840 keyid = atoi(val);
1841 if (keyid < 1 || keyid > 4)
1842 return -1;
1843 snprintf(buf, sizeof(buf), "%d", keyid - 1);
1844 if (set_network(ifname, id, "wep_tx_keyidx", buf) < 0)
1845 return -2;
1846 }
1847
1848 for (i = 0; i < 4; i++) {
1849 snprintf(buf, sizeof(buf), "key%d", i + 1);
1850 val = get_param(cmd, buf);
1851 if (val == NULL)
1852 continue;
1853 snprintf(buf, sizeof(buf), "wep_key%d", i);
1854 if (set_network(ifname, id, buf, val) < 0)
1855 return -2;
1856 }
1857 }
1858
1859 return 1;
1860}
1861
1862
Jouni Malinene4fde732019-03-25 22:29:37 +02001863static int set_akm_suites(struct sigma_dut *dut, const char *ifname,
1864 int id, const char *val)
1865{
1866 char key_mgmt[200], *end, *pos;
1867 const char *in_pos = val;
1868
Jouni Malinen8179fee2019-03-28 03:19:47 +02001869 dut->akm_values = 0;
Jouni Malinene4fde732019-03-25 22:29:37 +02001870 pos = key_mgmt;
1871 end = pos + sizeof(key_mgmt);
1872 while (*in_pos) {
1873 int res, akm = atoi(in_pos);
1874 const char *str;
1875
Jouni Malinen8179fee2019-03-28 03:19:47 +02001876 if (akm >= 0 && akm < 32)
1877 dut->akm_values |= 1 << akm;
1878
Jouni Malinene4fde732019-03-25 22:29:37 +02001879 switch (akm) {
1880 case AKM_WPA_EAP:
1881 str = "WPA-EAP";
1882 break;
1883 case AKM_WPA_PSK:
1884 str = "WPA-PSK";
1885 break;
1886 case AKM_FT_EAP:
1887 str = "FT-EAP";
1888 break;
1889 case AKM_FT_PSK:
1890 str = "FT-PSK";
1891 break;
1892 case AKM_EAP_SHA256:
1893 str = "WPA-EAP-SHA256";
1894 break;
1895 case AKM_PSK_SHA256:
1896 str = "WPA-PSK-SHA256";
1897 break;
1898 case AKM_SAE:
1899 str = "SAE";
1900 break;
1901 case AKM_FT_SAE:
1902 str = "FT-SAE";
1903 break;
1904 case AKM_SUITE_B:
1905 str = "WPA-EAP-SUITE-B-192";
1906 break;
1907 case AKM_FT_SUITE_B:
1908 str = "FT-EAP-SHA384";
1909 break;
1910 case AKM_FILS_SHA256:
1911 str = "FILS-SHA256";
1912 break;
1913 case AKM_FILS_SHA384:
1914 str = "FILS-SHA384";
1915 break;
1916 case AKM_FT_FILS_SHA256:
1917 str = "FT-FILS-SHA256";
1918 break;
1919 case AKM_FT_FILS_SHA384:
1920 str = "FT-FILS-SHA384";
1921 break;
1922 default:
1923 sigma_dut_print(dut, DUT_MSG_ERROR,
1924 "Unsupported AKMSuitetype %d", akm);
1925 return -1;
1926 }
1927
1928 res = snprintf(pos, end - pos, "%s%s",
1929 pos == key_mgmt ? "" : " ", str);
1930 if (res < 0 || res >= end - pos)
1931 return -1;
1932 pos += res;
1933
1934 in_pos = strchr(in_pos, ';');
1935 if (!in_pos)
1936 break;
1937 while (*in_pos == ';')
1938 in_pos++;
1939 }
1940 sigma_dut_print(dut, DUT_MSG_DEBUG, "AKMSuiteType %s --> %s",
1941 val, key_mgmt);
1942 return set_network(ifname, id, "key_mgmt", key_mgmt);
1943}
1944
1945
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001946static int set_wpa_common(struct sigma_dut *dut, struct sigma_conn *conn,
1947 const char *ifname, struct sigma_cmd *cmd)
1948{
1949 const char *val;
1950 int id;
Jouni Malinenad395a22017-09-01 21:13:46 +03001951 int cipher_set = 0;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001952 int owe;
Sunil Duttc75a1e62018-01-11 20:47:50 +05301953 int suite_b = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001954
1955 id = add_network_common(dut, conn, ifname, cmd);
1956 if (id < 0)
1957 return id;
1958
Jouni Malinen47dcc952017-10-09 16:43:24 +03001959 val = get_param(cmd, "Type");
1960 owe = val && strcasecmp(val, "OWE") == 0;
1961
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001962 val = get_param(cmd, "keyMgmtType");
Jouni Malinen47dcc952017-10-09 16:43:24 +03001963 if (!val && owe)
1964 val = "OWE";
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001965 if (val == NULL) {
Jouni Malinene4fde732019-03-25 22:29:37 +02001966 /* keyMgmtType is being replaced with AKMSuiteType, so ignore
1967 * this missing parameter and assume proto=WPA2. */
1968 if (set_network(ifname, id, "proto", "WPA2") < 0)
1969 return ERROR_SEND_STATUS;
1970 } else if (strcasecmp(val, "wpa") == 0 ||
1971 strcasecmp(val, "wpa-psk") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001972 if (set_network(ifname, id, "proto", "WPA") < 0)
1973 return -2;
1974 } else if (strcasecmp(val, "wpa2") == 0 ||
1975 strcasecmp(val, "wpa2-psk") == 0 ||
1976 strcasecmp(val, "wpa2-ft") == 0 ||
1977 strcasecmp(val, "wpa2-sha256") == 0) {
1978 if (set_network(ifname, id, "proto", "WPA2") < 0)
1979 return -2;
Pradeep Reddy POTTETI6d04b3b2016-11-15 14:51:26 +05301980 } else if (strcasecmp(val, "wpa2-wpa-psk") == 0 ||
1981 strcasecmp(val, "wpa2-wpa-ent") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001982 if (set_network(ifname, id, "proto", "WPA WPA2") < 0)
1983 return -2;
Jouni Malinenad395a22017-09-01 21:13:46 +03001984 } else if (strcasecmp(val, "SuiteB") == 0) {
Sunil Duttc75a1e62018-01-11 20:47:50 +05301985 suite_b = 1;
Jouni Malinenad395a22017-09-01 21:13:46 +03001986 if (set_network(ifname, id, "proto", "WPA2") < 0)
1987 return -2;
Jouni Malinen47dcc952017-10-09 16:43:24 +03001988 } else if (strcasecmp(val, "OWE") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02001989 } else {
1990 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized keyMgmtType value");
1991 return 0;
1992 }
1993
1994 val = get_param(cmd, "encpType");
Jouni Malinenad395a22017-09-01 21:13:46 +03001995 if (val) {
1996 cipher_set = 1;
1997 if (strcasecmp(val, "tkip") == 0) {
1998 if (set_network(ifname, id, "pairwise", "TKIP") < 0)
1999 return -2;
2000 } else if (strcasecmp(val, "aes-ccmp") == 0) {
2001 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2002 return -2;
2003 } else if (strcasecmp(val, "aes-ccmp-tkip") == 0) {
2004 if (set_network(ifname, id, "pairwise",
2005 "CCMP TKIP") < 0)
2006 return -2;
2007 } else if (strcasecmp(val, "aes-gcmp") == 0) {
2008 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2009 return -2;
2010 if (set_network(ifname, id, "group", "GCMP") < 0)
2011 return -2;
2012 } else {
2013 send_resp(dut, conn, SIGMA_ERROR,
2014 "errorCode,Unrecognized encpType value");
2015 return 0;
2016 }
2017 }
2018
2019 val = get_param(cmd, "PairwiseCipher");
2020 if (val) {
2021 cipher_set = 1;
2022 /* TODO: Support space separated list */
2023 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2024 if (set_network(ifname, id, "pairwise", "GCMP-256") < 0)
2025 return -2;
2026 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2027 if (set_network(ifname, id, "pairwise",
2028 "CCMP-256") < 0)
2029 return -2;
2030 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2031 if (set_network(ifname, id, "pairwise", "GCMP") < 0)
2032 return -2;
2033 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2034 if (set_network(ifname, id, "pairwise", "CCMP") < 0)
2035 return -2;
2036 } else {
2037 send_resp(dut, conn, SIGMA_ERROR,
2038 "errorCode,Unrecognized PairwiseCipher value");
2039 return 0;
2040 }
2041 }
2042
Jouni Malinen47dcc952017-10-09 16:43:24 +03002043 if (!cipher_set && !owe) {
Jouni Malinenad395a22017-09-01 21:13:46 +03002044 send_resp(dut, conn, SIGMA_ERROR,
2045 "errorCode,Missing encpType and PairwiseCipher");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002046 return 0;
2047 }
Jouni Malinenad395a22017-09-01 21:13:46 +03002048
2049 val = get_param(cmd, "GroupCipher");
2050 if (val) {
2051 if (strcasecmp(val, "AES-GCMP-256") == 0) {
2052 if (set_network(ifname, id, "group", "GCMP-256") < 0)
2053 return -2;
2054 } else if (strcasecmp(val, "AES-CCMP-256") == 0) {
2055 if (set_network(ifname, id, "group", "CCMP-256") < 0)
2056 return -2;
2057 } else if (strcasecmp(val, "AES-GCMP-128") == 0) {
2058 if (set_network(ifname, id, "group", "GCMP") < 0)
2059 return -2;
2060 } else if (strcasecmp(val, "AES-CCMP-128") == 0) {
2061 if (set_network(ifname, id, "group", "CCMP") < 0)
2062 return -2;
2063 } else {
2064 send_resp(dut, conn, SIGMA_ERROR,
2065 "errorCode,Unrecognized GroupCipher value");
2066 return 0;
2067 }
2068 }
2069
Jouni Malinen7b239522017-09-14 21:37:18 +03002070 val = get_param(cmd, "GroupMgntCipher");
Jouni Malinenad395a22017-09-01 21:13:46 +03002071 if (val) {
Jouni Malinene8898cb2017-09-26 17:55:26 +03002072 const char *cipher;
2073
2074 if (strcasecmp(val, "BIP-GMAC-256") == 0) {
2075 cipher = "BIP-GMAC-256";
2076 } else if (strcasecmp(val, "BIP-CMAC-256") == 0) {
2077 cipher = "BIP-CMAC-256";
2078 } else if (strcasecmp(val, "BIP-GMAC-128") == 0) {
2079 cipher = "BIP-GMAC-128";
2080 } else if (strcasecmp(val, "BIP-CMAC-128") == 0) {
2081 cipher = "AES-128-CMAC";
2082 } else {
2083 send_resp(dut, conn, SIGMA_INVALID,
2084 "errorCode,Unsupported GroupMgntCipher");
2085 return 0;
2086 }
2087 if (set_network(ifname, id, "group_mgmt", cipher) < 0) {
2088 send_resp(dut, conn, SIGMA_INVALID,
2089 "errorCode,Failed to set GroupMgntCipher");
2090 return 0;
2091 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002092 }
2093
Jouni Malinene4fde732019-03-25 22:29:37 +02002094 val = get_param(cmd, "AKMSuiteType");
2095 if (val && set_akm_suites(dut, ifname, id, val) < 0)
2096 return ERROR_SEND_STATUS;
2097
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002098 dut->sta_pmf = STA_PMF_DISABLED;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302099
2100 if (dut->program == PROGRAM_OCE) {
2101 dut->sta_pmf = STA_PMF_OPTIONAL;
2102 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2103 return -2;
2104 }
2105
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002106 val = get_param(cmd, "PMF");
2107 if (val) {
2108 if (strcasecmp(val, "Required") == 0 ||
2109 strcasecmp(val, "Forced_Required") == 0) {
2110 dut->sta_pmf = STA_PMF_REQUIRED;
2111 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2112 return -2;
2113 } else if (strcasecmp(val, "Optional") == 0) {
2114 dut->sta_pmf = STA_PMF_OPTIONAL;
2115 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2116 return -2;
2117 } else if (strcasecmp(val, "Disabled") == 0 ||
Kiran Kumar Lokere07da3b22018-12-16 22:42:49 -08002118 strcasecmp(val, "Disable") == 0 ||
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002119 strcasecmp(val, "Forced_Disabled") == 0) {
2120 dut->sta_pmf = STA_PMF_DISABLED;
2121 } else {
2122 send_resp(dut, conn, SIGMA_INVALID, "errorCode,Unrecognized PMF value");
2123 return 0;
2124 }
Sunil Duttc75a1e62018-01-11 20:47:50 +05302125 } else if (owe || suite_b) {
Jouni Malinen1287cd72018-01-04 17:08:01 +02002126 dut->sta_pmf = STA_PMF_REQUIRED;
2127 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2128 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002129 }
2130
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002131 val = get_param(cmd, "BeaconProtection");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05302132 if (val)
2133 dut->beacon_prot = atoi(val);
2134 if (dut->beacon_prot && set_network(ifname, id, "beacon_prot", "1") < 0)
Jouni Malinen0165c7f2020-03-26 11:51:58 +02002135 return ERROR_SEND_STATUS;
2136
Veerendranath Jakkam54fd51c2020-12-21 01:36:04 +05302137 if (dut->ocvc && set_network(ifname, id, "ocv", "1") < 0)
2138 return ERROR_SEND_STATUS;
2139
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002140 return id;
2141}
2142
2143
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302144static int wcn_set_ignore_h2e_rsnxe(struct sigma_dut *dut, const char *intf,
2145 uint8_t cfg)
2146{
2147#ifdef NL80211_SUPPORT
2148 return wcn_wifi_test_config_set_u8(
2149 dut, intf,
2150 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_H2E_RSNXE, cfg);
2151#else /* NL80211_SUPPORT */
2152 sigma_dut_print(dut, DUT_MSG_ERROR,
2153 "Ignore SAE H2E requirement mismatch can't be set without NL80211_SUPPORT defined");
2154 return -1;
2155#endif /* NL80211_SUPPORT */
2156}
2157
2158
Jouni Malinenf7222712019-06-13 01:50:21 +03002159static enum sigma_cmd_result cmd_sta_set_psk(struct sigma_dut *dut,
2160 struct sigma_conn *conn,
2161 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002162{
2163 const char *intf = get_param(cmd, "Interface");
Jouni Malinen992a81e2017-08-22 13:57:47 +03002164 const char *type = get_param(cmd, "Type");
Jouni Malinen1287cd72018-01-04 17:08:01 +02002165 const char *pmf = get_param(cmd, "PMF");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002166 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinene4fde732019-03-25 22:29:37 +02002167 const char *akm = get_param(cmd, "AKMSuiteType");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002168 const char *ifname, *val, *alg;
2169 int id;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002170 char buf[50];
Jouni Malinen11e55212019-11-22 21:46:59 +02002171 int sae_pwe = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002172
2173 if (intf == NULL)
2174 return -1;
2175
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002176 if (strcmp(intf, get_main_ifname(dut)) == 0)
2177 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002178 else
2179 ifname = intf;
2180
2181 id = set_wpa_common(dut, conn, ifname, cmd);
2182 if (id < 0)
2183 return id;
2184
2185 val = get_param(cmd, "keyMgmtType");
2186 alg = get_param(cmd, "micAlg");
2187
Jouni Malinen992a81e2017-08-22 13:57:47 +03002188 if (type && strcasecmp(type, "SAE") == 0) {
Jouni Malinene4fde732019-03-25 22:29:37 +02002189 if (!akm && val && strcasecmp(val, "wpa2-ft") == 0) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002190 if (set_network(ifname, id, "key_mgmt", "FT-SAE") < 0)
2191 return -2;
Jouni Malinene4fde732019-03-25 22:29:37 +02002192 } else if (!akm) {
Jouni Malinen992a81e2017-08-22 13:57:47 +03002193 if (set_network(ifname, id, "key_mgmt", "SAE") < 0)
2194 return -2;
2195 }
2196 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2197 sigma_dut_print(dut, DUT_MSG_ERROR,
2198 "Failed to clear sae_groups to default");
2199 return -2;
2200 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002201 if (!pmf) {
2202 dut->sta_pmf = STA_PMF_REQUIRED;
2203 if (set_network(ifname, id, "ieee80211w", "2") < 0)
2204 return -2;
2205 }
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002206 } else if (type && strcasecmp(type, "PSK-SAE") == 0) {
2207 if (val && strcasecmp(val, "wpa2-ft") == 0) {
2208 if (set_network(ifname, id, "key_mgmt",
2209 "FT-SAE FT-PSK") < 0)
2210 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002211 } else if (!akm) {
Jouni Malinen0ab50f42017-08-31 01:34:59 +03002212 if (set_network(ifname, id, "key_mgmt",
2213 "SAE WPA-PSK") < 0)
2214 return -2;
2215 }
2216 if (wpa_command(ifname, "SET sae_groups ") != 0) {
2217 sigma_dut_print(dut, DUT_MSG_ERROR,
2218 "Failed to clear sae_groups to default");
2219 return -2;
2220 }
Jouni Malinen1287cd72018-01-04 17:08:01 +02002221 if (!pmf) {
2222 dut->sta_pmf = STA_PMF_OPTIONAL;
2223 if (set_network(ifname, id, "ieee80211w", "1") < 0)
2224 return -2;
2225 }
Jouni Malinen992a81e2017-08-22 13:57:47 +03002226 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002227 if (set_network(ifname, id, "key_mgmt", "WPA-PSK-SHA256") < 0)
2228 return -2;
2229 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2230 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2231 return -2;
Ashwini Patil6dbf7b02017-03-20 13:42:11 +05302232 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2233 if (set_network(ifname, id, "key_mgmt", "FT-PSK") < 0)
2234 return -2;
Jouni Malinen3b73d872019-06-12 03:13:25 +03002235 } else if (!akm &&
2236 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2237 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002238 if (set_network(ifname, id, "key_mgmt",
2239 "WPA-PSK WPA-PSK-SHA256") < 0)
2240 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002241 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002242 if (set_network(ifname, id, "key_mgmt",
2243 "WPA-PSK WPA-PSK-SHA256") < 0)
2244 return -2;
Jouni Malinen77ff3f02019-03-28 03:45:40 +02002245 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002246 if (set_network(ifname, id, "key_mgmt", "WPA-PSK") < 0)
2247 return -2;
2248 }
2249
2250 val = get_param(cmd, "passPhrase");
2251 if (val == NULL)
2252 return -1;
Jouni Malinen2126f422017-10-11 23:24:33 +03002253 if (type && strcasecmp(type, "SAE") == 0) {
2254 if (set_network_quoted(ifname, id, "sae_password", val) < 0)
2255 return -2;
2256 } else {
2257 if (set_network_quoted(ifname, id, "psk", val) < 0)
2258 return -2;
2259 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002260
Jouni Malinen78d10c42019-03-25 22:34:32 +02002261 val = get_param(cmd, "PasswordId");
2262 if (val && set_network_quoted(ifname, id, "sae_password_id", val) < 0)
2263 return ERROR_SEND_STATUS;
2264
Jouni Malinen992a81e2017-08-22 13:57:47 +03002265 val = get_param(cmd, "ECGroupID");
2266 if (val) {
Jouni Malinenb54f0df2019-12-12 01:57:29 +02002267 snprintf(buf, sizeof(buf), "SET sae_groups %s", val);
Jouni Malinen992a81e2017-08-22 13:57:47 +03002268 if (wpa_command(ifname, buf) != 0) {
2269 sigma_dut_print(dut, DUT_MSG_ERROR,
2270 "Failed to clear sae_groups");
2271 return -2;
2272 }
2273 }
2274
Jouni Malinen68143132017-09-02 02:34:08 +03002275 val = get_param(cmd, "InvalidSAEElement");
2276 if (val) {
2277 free(dut->sae_commit_override);
2278 dut->sae_commit_override = strdup(val);
2279 }
2280
Jouni Malinen4b3769d2019-10-10 16:20:29 +03002281 val = get_param(cmd, "PMKID_Include");
2282 if (val) {
2283 snprintf(buf, sizeof(buf), "SET sae_pmkid_in_assoc %d",
2284 get_enable_disable(val));
2285 wpa_command(intf, buf);
2286 }
2287
Jouni Malineneeb43d32019-12-06 17:40:07 +02002288 val = get_param(cmd, "IgnoreH2E_RSNXE_BSSMemSel");
2289 if (val) {
2290 snprintf(buf, sizeof(buf), "SET ignore_sae_h2e_only %d",
2291 get_enable_disable(val));
2292 wpa_command(intf, buf);
Veerendranath Jakkamca239592021-10-11 20:48:00 +05302293 if (get_driver_type(dut) == DRIVER_WCN)
2294 wcn_set_ignore_h2e_rsnxe(dut, intf,
2295 get_enable_disable(val));
Jouni Malineneeb43d32019-12-06 17:40:07 +02002296 }
2297
Jouni Malinenf2348d22019-12-07 11:52:55 +02002298 val = get_param(cmd, "ECGroupID_RGE");
2299 if (val) {
2300 snprintf(buf, sizeof(buf), "SET extra_sae_rejected_groups %s",
2301 val);
2302 wpa_command(intf, buf);
2303 }
2304
Jouni Malinen99e55022019-12-07 13:59:41 +02002305 val = get_param(cmd, "RSNXE_Content");
2306 if (val) {
2307 const char *param;
2308
2309 if (strncasecmp(val, "AssocReq:", 9) == 0) {
2310 val += 9;
2311 param = "rsnxe_override_assoc";
2312 } else if (strncasecmp(val, "EapolM2:", 8) == 0) {
2313 val += 8;
2314 param = "rsnxe_override_eapol";
2315 } else {
2316 send_resp(dut, conn, SIGMA_ERROR,
2317 "errorCode,Unsupported RSNXE_Content value");
2318 return STATUS_SENT_ERROR;
2319 }
2320 snprintf(buf, sizeof(buf), "SET %s %s", param, val);
2321 wpa_command(intf, buf);
2322 }
2323
Jouni Malinen11e55212019-11-22 21:46:59 +02002324 val = get_param(cmd, "sae_pwe");
2325 if (val) {
2326 if (strcasecmp(val, "h2e") == 0) {
2327 dut->sae_pwe = SAE_PWE_H2E;
Jouni Malinen7244a412019-12-07 11:54:10 +02002328 } else if (strcasecmp(val, "loop") == 0 ||
2329 strcasecmp(val, "looping") == 0) {
Jouni Malinen11e55212019-11-22 21:46:59 +02002330 dut->sae_pwe = SAE_PWE_LOOP;
2331 } else {
2332 send_resp(dut, conn, SIGMA_ERROR,
2333 "errorCode,Unsupported sae_pwe value");
2334 return STATUS_SENT_ERROR;
2335 }
2336 }
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302337
2338 val = get_param(cmd, "Clear_RSNXE");
2339 if (val && strcmp(val, "1") == 0 &&
2340 (wpa_command(intf, "SET rsnxe_override_assoc ") ||
2341 wpa_command(intf, "SET rsnxe_override_eapol "))) {
2342 send_resp(dut, conn, SIGMA_ERROR,
2343 "errorCode,Failed to clear RSNXE");
Jouni Malinenb11498c2020-08-03 11:05:53 +03002344 return STATUS_SENT_ERROR;
Vinita S. Maloo6d7454f2020-04-02 15:03:26 +05302345 }
2346
Jouni Malinenc0078772020-03-04 21:23:16 +02002347 if (dut->sae_pwe == SAE_PWE_LOOP && get_param(cmd, "PasswordId"))
2348 sae_pwe = 3;
2349 else if (dut->sae_pwe == SAE_PWE_LOOP)
Jouni Malinen11e55212019-11-22 21:46:59 +02002350 sae_pwe = 0;
2351 else if (dut->sae_pwe == SAE_PWE_H2E)
2352 sae_pwe = 1;
2353 else if (dut->sae_h2e_default)
2354 sae_pwe = 2;
2355 snprintf(buf, sizeof(buf), "SET sae_pwe %d", sae_pwe);
2356 if (sae_pwe >= 0 && wpa_command(ifname, buf) != 0)
2357 return ERROR_SEND_STATUS;
2358
Veerendranath Jakkam0316be12020-06-23 20:11:41 +05302359 val = get_param(cmd, "sae_pk");
2360 if (val && strcmp(val, "0") == 0 &&
2361 set_network(ifname, id, "sae_pk", "2") < 0)
2362 return ERROR_SEND_STATUS;
2363
Veerendranath Jakkama9177042020-08-10 00:14:03 +05302364 val = get_param(cmd, "sae_pk_only");
2365 if (val && strcmp(val, "1") == 0 &&
2366 set_network(ifname, id, "sae_pk", "1") < 0)
2367 return ERROR_SEND_STATUS;
2368
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02002369 if (dut->program == PROGRAM_60GHZ && network_mode &&
2370 strcasecmp(network_mode, "PBSS") == 0 &&
2371 set_network(ifname, id, "pbss", "1") < 0)
2372 return -2;
2373
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002374 return 1;
2375}
2376
2377
Jouni Malinen8ac93452019-08-14 15:19:13 +03002378static enum sigma_cmd_result set_trust_root_system(struct sigma_dut *dut,
2379 struct sigma_conn *conn,
2380 const char *ifname, int id)
2381{
2382 char buf[200];
2383
2384 snprintf(buf, sizeof(buf), "%s/certs", sigma_cert_path);
2385 if (!file_exists(buf))
2386 strlcpy(buf, "/system/etc/security/cacerts", sizeof(buf));
2387 if (!file_exists(buf))
2388 strlcpy(buf, "/etc/ssl/certs", sizeof(buf));
2389 if (!file_exists(buf)) {
2390 char msg[300];
2391
2392 snprintf(msg, sizeof(msg),
2393 "ErrorCode,trustedRootCA system store (%s) not found",
2394 buf);
2395 send_resp(dut, conn, SIGMA_ERROR, msg);
2396 return STATUS_SENT_ERROR;
2397 }
2398
2399 if (set_network_quoted(ifname, id, "ca_path", buf) < 0)
2400 return ERROR_SEND_STATUS;
2401
2402 return SUCCESS_SEND_STATUS;
2403}
2404
2405
2406static enum sigma_cmd_result set_trust_root(struct sigma_dut *dut,
2407 struct sigma_conn *conn,
2408 const char *ifname, int id,
2409 const char *val)
2410{
2411 char buf[200];
2412#ifdef ANDROID
2413 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2414 int length;
2415#endif /* ANDROID */
2416
2417 if (strcmp(val, "DEFAULT") == 0)
2418 return set_trust_root_system(dut, conn, ifname, id);
2419
2420#ifdef ANDROID
2421 snprintf(buf, sizeof(buf), "CACERT_%s", val);
2422 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2423 if (length > 0) {
2424 sigma_dut_print(dut, DUT_MSG_INFO, "Use Android keystore [%s]",
2425 buf);
2426 snprintf(buf, sizeof(buf), "keystore://CACERT_%s", val);
2427 goto ca_cert_selected;
2428 }
2429#endif /* ANDROID */
2430
2431 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2432#ifdef __linux__
2433 if (!file_exists(buf)) {
2434 char msg[300];
2435
2436 snprintf(msg, sizeof(msg),
2437 "ErrorCode,trustedRootCA file (%s) not found", buf);
2438 send_resp(dut, conn, SIGMA_ERROR, msg);
2439 return STATUS_SENT_ERROR;
2440 }
2441#endif /* __linux__ */
2442#ifdef ANDROID
2443ca_cert_selected:
2444#endif /* ANDROID */
2445 if (set_network_quoted(ifname, id, "ca_cert", buf) < 0)
2446 return ERROR_SEND_STATUS;
2447
2448 return SUCCESS_SEND_STATUS;
2449}
2450
2451
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002452static int set_eap_common(struct sigma_dut *dut, struct sigma_conn *conn,
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302453 const char *ifname, int username_identity,
2454 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002455{
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002456 const char *val, *alg, *akm, *trust_root, *domain, *domain_suffix;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002457 int id;
Jouni Malinen53264f62019-05-03 13:04:40 +03002458 char buf[200], buf2[300];
Jouni Malinen8179fee2019-03-28 03:19:47 +02002459 int erp = 0;
Jouni Malinen8ac93452019-08-14 15:19:13 +03002460 enum sigma_cmd_result res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002461
2462 id = set_wpa_common(dut, conn, ifname, cmd);
2463 if (id < 0)
2464 return id;
2465
2466 val = get_param(cmd, "keyMgmtType");
2467 alg = get_param(cmd, "micAlg");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302468 akm = get_param(cmd, "AKMSuiteType");
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002469 trust_root = get_param(cmd, "trustedRootCA");
2470 domain = get_param(cmd, "Domain");
2471 domain_suffix = get_param(cmd, "DomainSuffix");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002472
Jouni Malinenad395a22017-09-01 21:13:46 +03002473 if (val && strcasecmp(val, "SuiteB") == 0) {
2474 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SUITE-B-192") <
2475 0)
2476 return -2;
2477 } else if (alg && strcasecmp(alg, "SHA-256") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002478 if (set_network(ifname, id, "key_mgmt", "WPA-EAP-SHA256") < 0)
2479 return -2;
2480 } else if (alg && strcasecmp(alg, "SHA-1") == 0) {
2481 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2482 return -2;
2483 } else if (val && strcasecmp(val, "wpa2-ft") == 0) {
2484 if (set_network(ifname, id, "key_mgmt", "FT-EAP") < 0)
2485 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002486 } else if (!akm &&
2487 ((val && strcasecmp(val, "wpa2-sha256") == 0) ||
2488 dut->sta_pmf == STA_PMF_REQUIRED)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002489 if (set_network(ifname, id, "key_mgmt",
2490 "WPA-EAP WPA-EAP-SHA256") < 0)
2491 return -2;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302492 } else if (akm && atoi(akm) == 14) {
2493 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2494 dut->sta_pmf == STA_PMF_REQUIRED) {
2495 if (set_network(ifname, id, "key_mgmt",
2496 "WPA-EAP-SHA256 FILS-SHA256") < 0)
2497 return -2;
2498 } else {
2499 if (set_network(ifname, id, "key_mgmt",
2500 "WPA-EAP FILS-SHA256") < 0)
2501 return -2;
2502 }
2503
Jouni Malinen8179fee2019-03-28 03:19:47 +02002504 erp = 1;
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05302505 } else if (akm && atoi(akm) == 15) {
2506 if (dut->sta_pmf == STA_PMF_OPTIONAL ||
2507 dut->sta_pmf == STA_PMF_REQUIRED) {
2508 if (set_network(ifname, id, "key_mgmt",
2509 "WPA-EAP-SHA256 FILS-SHA384") < 0)
2510 return -2;
2511 } else {
2512 if (set_network(ifname, id, "key_mgmt",
2513 "WPA-EAP FILS-SHA384") < 0)
2514 return -2;
2515 }
2516
Jouni Malinen8179fee2019-03-28 03:19:47 +02002517 erp = 1;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002518 } else if (!akm && dut->sta_pmf == STA_PMF_OPTIONAL) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002519 if (set_network(ifname, id, "key_mgmt",
2520 "WPA-EAP WPA-EAP-SHA256") < 0)
2521 return -2;
Jouni Malinend6a9d692019-03-28 03:01:24 +02002522 } else if (!akm) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002523 if (set_network(ifname, id, "key_mgmt", "WPA-EAP") < 0)
2524 return -2;
2525 }
2526
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002527 if (trust_root) {
2528 if (strcmp(trust_root, "DEFAULT") == 0 && !domain &&
2529 !domain_suffix) {
2530 send_resp(dut, conn, SIGMA_ERROR,
2531 "errorCode,trustRootCA DEFAULT used without specifying Domain or DomainSuffix");
2532 return STATUS_SENT_ERROR;
2533 }
2534 res = set_trust_root(dut, conn, ifname, id, trust_root);
Jouni Malinen8ac93452019-08-14 15:19:13 +03002535 if (res != SUCCESS_SEND_STATUS)
2536 return res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002537 }
2538
Jouni Malinen53264f62019-05-03 13:04:40 +03002539 val = get_param(cmd, "ServerCert");
2540 if (val) {
2541 FILE *f;
2542 char *result = NULL, *pos;
2543
2544 snprintf(buf, sizeof(buf), "%s/%s.sha256", sigma_cert_path,
2545 val);
2546 f = fopen(buf, "r");
2547 if (f) {
2548 result = fgets(buf, sizeof(buf), f);
2549 fclose(f);
2550 }
2551 if (!result) {
2552 snprintf(buf2, sizeof(buf2),
2553 "ErrorCode,ServerCert hash could not be read from %s",
2554 buf);
2555 send_resp(dut, conn, SIGMA_ERROR, buf2);
2556 return STATUS_SENT_ERROR;
2557 }
2558 pos = strchr(buf, '\n');
2559 if (pos)
2560 *pos = '\0';
Jouni Malinen0572a742020-10-08 13:53:25 +03002561 pos = strchr(buf, '\r');
2562 if (pos)
2563 *pos = '\0';
Jouni Malinen53264f62019-05-03 13:04:40 +03002564 snprintf(buf2, sizeof(buf2), "hash://server/sha256/%s", buf);
2565 if (set_network_quoted(ifname, id, "ca_cert", buf2) < 0)
2566 return ERROR_SEND_STATUS;
Jouni Malinen29108dc2019-06-13 23:42:11 +03002567
2568 snprintf(buf, sizeof(buf), "%s/%s.tod", sigma_cert_path, val);
2569 if (file_exists(buf)) {
2570 sigma_dut_print(dut, DUT_MSG_DEBUG,
2571 "TOD policy enabled for the configured ServerCert hash");
2572 dut->sta_tod_policy = 1;
2573 }
Jouni Malinen53264f62019-05-03 13:04:40 +03002574 }
2575
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002576 if (domain &&
2577 set_network_quoted(ifname, id, "domain_match", domain) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002578 return ERROR_SEND_STATUS;
2579
Jouni Malinenb4d56ba2019-08-23 18:17:44 +03002580 if (domain_suffix &&
2581 set_network_quoted(ifname, id, "domain_suffix_match",
2582 domain_suffix) < 0)
Jouni Malinen96f84b02019-05-03 12:32:56 +03002583 return ERROR_SEND_STATUS;
2584
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302585 if (username_identity) {
2586 val = get_param(cmd, "username");
2587 if (val) {
2588 if (set_network_quoted(ifname, id, "identity", val) < 0)
2589 return -2;
2590 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002591
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302592 val = get_param(cmd, "password");
2593 if (val) {
2594 if (set_network_quoted(ifname, id, "password", val) < 0)
2595 return -2;
2596 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002597 }
2598
Jouni Malinen8179fee2019-03-28 03:19:47 +02002599 if (dut->akm_values &
2600 ((1 << AKM_FILS_SHA256) |
2601 (1 << AKM_FILS_SHA384) |
2602 (1 << AKM_FT_FILS_SHA256) |
2603 (1 << AKM_FT_FILS_SHA384)))
2604 erp = 1;
2605 if (erp && set_network(ifname, id, "erp", "1") < 0)
2606 return ERROR_SEND_STATUS;
2607
Jouni Malinen134fe3c2019-06-12 04:16:49 +03002608 dut->sta_associate_wait_connect = 1;
2609
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002610 return id;
2611}
2612
2613
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002614static int set_tls_cipher(const char *ifname, int id, const char *cipher)
2615{
2616 const char *val;
2617
2618 if (!cipher)
2619 return 0;
2620
2621 if (strcasecmp(cipher, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384") == 0)
2622 val = "ECDHE-ECDSA-AES256-GCM-SHA384";
2623 else if (strcasecmp(cipher,
2624 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2625 val = "ECDHE-RSA-AES256-GCM-SHA384";
2626 else if (strcasecmp(cipher, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384") == 0)
2627 val = "DHE-RSA-AES256-GCM-SHA384";
2628 else if (strcasecmp(cipher,
2629 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256") == 0)
2630 val = "ECDHE-ECDSA-AES128-GCM-SHA256";
2631 else
2632 return -1;
2633
2634 /* Need to clear phase1="tls_suiteb=1" to allow cipher enforcement */
2635 set_network_quoted(ifname, id, "phase1", "");
2636
2637 return set_network_quoted(ifname, id, "openssl_ciphers", val);
2638}
2639
2640
Jouni Malinenf7222712019-06-13 01:50:21 +03002641static enum sigma_cmd_result cmd_sta_set_eaptls(struct sigma_dut *dut,
2642 struct sigma_conn *conn,
2643 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002644{
2645 const char *intf = get_param(cmd, "Interface");
2646 const char *ifname, *val;
2647 int id;
2648 char buf[200];
2649#ifdef ANDROID
2650 unsigned char kvalue[KEYSTORE_MESSAGE_SIZE];
2651 int length;
2652 int jb_or_newer = 0;
2653 char prop[PROPERTY_VALUE_MAX];
2654#endif /* ANDROID */
2655
2656 if (intf == NULL)
2657 return -1;
2658
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002659 if (strcmp(intf, get_main_ifname(dut)) == 0)
2660 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002661 else
2662 ifname = intf;
2663
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302664 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002665 if (id < 0)
2666 return id;
2667
2668 if (set_network(ifname, id, "eap", "TLS") < 0)
2669 return -2;
2670
Pradeep Reddy POTTETI9f6c2132016-05-05 16:28:19 +05302671 if (!get_param(cmd, "username") &&
2672 set_network_quoted(ifname, id, "identity",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002673 "wifi-user@wifilabs.local") < 0)
2674 return -2;
2675
2676 val = get_param(cmd, "clientCertificate");
2677 if (val == NULL)
2678 return -1;
2679#ifdef ANDROID
2680 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2681 length = android_keystore_get(ANDROID_KEYSTORE_GET, buf, kvalue);
2682 if (length < 0) {
2683 /*
2684 * JB started reporting keystore type mismatches, so retry with
2685 * the GET_PUBKEY command if the generic GET fails.
2686 */
2687 length = android_keystore_get(ANDROID_KEYSTORE_GET_PUBKEY,
2688 buf, kvalue);
2689 }
2690
2691 if (property_get("ro.build.version.release", prop, NULL) != 0) {
2692 sigma_dut_print(dut, DUT_MSG_DEBUG, "Android release %s", prop);
2693 if (strncmp(prop, "4.0", 3) != 0)
2694 jb_or_newer = 1;
2695 } else
2696 jb_or_newer = 1; /* assume newer */
2697
2698 if (jb_or_newer && length > 0) {
2699 sigma_dut_print(dut, DUT_MSG_INFO,
2700 "Use Android keystore [%s]", buf);
2701 if (set_network(ifname, id, "engine", "1") < 0)
2702 return -2;
2703 if (set_network_quoted(ifname, id, "engine_id", "keystore") < 0)
2704 return -2;
2705 snprintf(buf, sizeof(buf), "USRPKEY_%s", val);
2706 if (set_network_quoted(ifname, id, "key_id", buf) < 0)
2707 return -2;
2708 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2709 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2710 return -2;
2711 return 1;
2712 } else if (length > 0) {
2713 sigma_dut_print(dut, DUT_MSG_INFO,
2714 "Use Android keystore [%s]", buf);
2715 snprintf(buf, sizeof(buf), "keystore://USRPKEY_%s", val);
2716 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2717 return -2;
2718 snprintf(buf, sizeof(buf), "keystore://USRCERT_%s", val);
2719 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2720 return -2;
2721 return 1;
2722 }
2723#endif /* ANDROID */
2724
2725 snprintf(buf, sizeof(buf), "%s/%s", sigma_cert_path, val);
2726#ifdef __linux__
2727 if (!file_exists(buf)) {
2728 char msg[300];
2729 snprintf(msg, sizeof(msg), "ErrorCode,clientCertificate file "
2730 "(%s) not found", buf);
2731 send_resp(dut, conn, SIGMA_ERROR, msg);
2732 return -3;
2733 }
2734#endif /* __linux__ */
2735 if (set_network_quoted(ifname, id, "private_key", buf) < 0)
2736 return -2;
2737 if (set_network_quoted(ifname, id, "client_cert", buf) < 0)
2738 return -2;
2739
2740 if (set_network_quoted(ifname, id, "private_key_passwd", "wifi") < 0)
2741 return -2;
2742
Jouni Malinen5eabb2a2017-10-03 18:17:30 +03002743 val = get_param(cmd, "keyMgmtType");
2744 if (val && strcasecmp(val, "SuiteB") == 0) {
2745 val = get_param(cmd, "CertType");
2746 if (val && strcasecmp(val, "RSA") == 0) {
2747 if (set_network_quoted(ifname, id, "phase1",
2748 "tls_suiteb=1") < 0)
2749 return -2;
2750 } else {
2751 if (set_network_quoted(ifname, id, "openssl_ciphers",
2752 "SUITEB192") < 0)
2753 return -2;
2754 }
2755
2756 val = get_param(cmd, "TLSCipher");
2757 if (set_tls_cipher(ifname, id, val) < 0) {
2758 send_resp(dut, conn, SIGMA_ERROR,
2759 "ErrorCode,Unsupported TLSCipher value");
2760 return -3;
2761 }
2762 }
2763
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002764 return 1;
2765}
2766
2767
Jouni Malinenf7222712019-06-13 01:50:21 +03002768static enum sigma_cmd_result cmd_sta_set_eapttls(struct sigma_dut *dut,
2769 struct sigma_conn *conn,
2770 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002771{
2772 const char *intf = get_param(cmd, "Interface");
2773 const char *ifname;
2774 int id;
2775
2776 if (intf == NULL)
2777 return -1;
2778
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002779 if (strcmp(intf, get_main_ifname(dut)) == 0)
2780 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002781 else
2782 ifname = intf;
2783
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302784 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002785 if (id < 0)
2786 return id;
2787
2788 if (set_network(ifname, id, "eap", "TTLS") < 0) {
2789 send_resp(dut, conn, SIGMA_ERROR,
2790 "errorCode,Failed to set TTLS method");
2791 return 0;
2792 }
2793
2794 if (set_network_quoted(ifname, id, "phase2", "auth=MSCHAPV2") < 0) {
2795 send_resp(dut, conn, SIGMA_ERROR,
2796 "errorCode,Failed to set MSCHAPv2 for TTLS Phase 2");
2797 return 0;
2798 }
2799
2800 return 1;
2801}
2802
2803
Jouni Malinenf7222712019-06-13 01:50:21 +03002804static enum sigma_cmd_result cmd_sta_set_eapsim(struct sigma_dut *dut,
2805 struct sigma_conn *conn,
2806 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002807{
2808 const char *intf = get_param(cmd, "Interface");
2809 const char *ifname;
2810 int id;
2811
2812 if (intf == NULL)
2813 return -1;
2814
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002815 if (strcmp(intf, get_main_ifname(dut)) == 0)
2816 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002817 else
2818 ifname = intf;
2819
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302820 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002821 if (id < 0)
2822 return id;
2823
2824 if (set_network(ifname, id, "eap", "SIM") < 0)
2825 return -2;
2826
2827 return 1;
2828}
2829
2830
Jouni Malinenf7222712019-06-13 01:50:21 +03002831static enum sigma_cmd_result cmd_sta_set_peap(struct sigma_dut *dut,
2832 struct sigma_conn *conn,
2833 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002834{
2835 const char *intf = get_param(cmd, "Interface");
2836 const char *ifname, *val;
2837 int id;
2838 char buf[100];
2839
2840 if (intf == NULL)
2841 return -1;
2842
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002843 if (strcmp(intf, get_main_ifname(dut)) == 0)
2844 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002845 else
2846 ifname = intf;
2847
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302848 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002849 if (id < 0)
2850 return id;
2851
2852 if (set_network(ifname, id, "eap", "PEAP") < 0)
2853 return -2;
2854
2855 val = get_param(cmd, "innerEAP");
2856 if (val) {
2857 if (strcasecmp(val, "MSCHAPv2") == 0) {
2858 if (set_network_quoted(ifname, id, "phase2",
2859 "auth=MSCHAPV2") < 0)
2860 return -2;
2861 } else if (strcasecmp(val, "GTC") == 0) {
2862 if (set_network_quoted(ifname, id, "phase2",
2863 "auth=GTC") < 0)
2864 return -2;
2865 } else
2866 return -1;
2867 }
2868
2869 val = get_param(cmd, "peapVersion");
2870 if (val) {
2871 int ver = atoi(val);
2872 if (ver < 0 || ver > 1)
2873 return -1;
2874 snprintf(buf, sizeof(buf), "peapver=%d", ver);
2875 if (set_network_quoted(ifname, id, "phase1", buf) < 0)
2876 return -2;
2877 }
2878
2879 return 1;
2880}
2881
2882
Jouni Malinenf7222712019-06-13 01:50:21 +03002883static enum sigma_cmd_result cmd_sta_set_eapfast(struct sigma_dut *dut,
2884 struct sigma_conn *conn,
2885 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002886{
2887 const char *intf = get_param(cmd, "Interface");
2888 const char *ifname, *val;
2889 int id;
2890 char buf[100];
2891
2892 if (intf == NULL)
2893 return -1;
2894
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002895 if (strcmp(intf, get_main_ifname(dut)) == 0)
2896 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002897 else
2898 ifname = intf;
2899
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302900 id = set_eap_common(dut, conn, ifname, 1, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002901 if (id < 0)
2902 return id;
2903
2904 if (set_network(ifname, id, "eap", "FAST") < 0)
2905 return -2;
2906
2907 val = get_param(cmd, "innerEAP");
2908 if (val) {
2909 if (strcasecmp(val, "MSCHAPV2") == 0) {
2910 if (set_network_quoted(ifname, id, "phase2",
2911 "auth=MSCHAPV2") < 0)
2912 return -2;
2913 } else if (strcasecmp(val, "GTC") == 0) {
2914 if (set_network_quoted(ifname, id, "phase2",
2915 "auth=GTC") < 0)
2916 return -2;
2917 } else
2918 return -1;
2919 }
2920
2921 val = get_param(cmd, "validateServer");
2922 if (val) {
2923 /* TODO */
2924 sigma_dut_print(dut, DUT_MSG_INFO, "Ignored EAP-FAST "
2925 "validateServer=%s", val);
2926 }
2927
2928 val = get_param(cmd, "pacFile");
2929 if (val) {
2930 snprintf(buf, sizeof(buf), "blob://%s", val);
2931 if (set_network_quoted(ifname, id, "pac_file", buf) < 0)
2932 return -2;
2933 }
2934
2935 if (set_network_quoted(ifname, id, "phase1", "fast_provisioning=2") <
2936 0)
2937 return -2;
2938
2939 return 1;
2940}
2941
2942
Jouni Malinenf7222712019-06-13 01:50:21 +03002943static enum sigma_cmd_result cmd_sta_set_eapaka(struct sigma_dut *dut,
2944 struct sigma_conn *conn,
2945 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002946{
2947 const char *intf = get_param(cmd, "Interface");
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302948 const char *username = get_param(cmd, "Username");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002949 const char *ifname;
2950 int id;
2951
2952 if (intf == NULL)
2953 return -1;
2954
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002955 if (strcmp(intf, get_main_ifname(dut)) == 0)
2956 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002957 else
2958 ifname = intf;
2959
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302960 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002961 if (id < 0)
2962 return id;
2963
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302964 /* RFC 5448: EAP-AKA' MUST use the leading character "6" (ASCII 36
2965 * hexadecimal).
2966 */
2967 if (username && username[0] == '6') {
2968 if (set_network(ifname, id, "eap", "AKA'") < 0)
2969 return -2;
2970 } else if (set_network(ifname, id, "eap", "AKA") < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002971 return -2;
Purushottam Kushwahacdd8cb12019-10-04 11:33:59 +05302972 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002973
2974 return 1;
2975}
2976
2977
Jouni Malinenf7222712019-06-13 01:50:21 +03002978static enum sigma_cmd_result cmd_sta_set_eapakaprime(struct sigma_dut *dut,
2979 struct sigma_conn *conn,
2980 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002981{
2982 const char *intf = get_param(cmd, "Interface");
2983 const char *ifname;
2984 int id;
2985
2986 if (intf == NULL)
2987 return -1;
2988
Jouni Malinen016ae6c2019-11-04 17:00:01 +02002989 if (strcmp(intf, get_main_ifname(dut)) == 0)
2990 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002991 else
2992 ifname = intf;
2993
Bala Krishna Bhamidipati73d7af02016-03-24 12:27:56 +05302994 id = set_eap_common(dut, conn, ifname, !dut->sim_no_username, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02002995 if (id < 0)
2996 return id;
2997
2998 if (set_network(ifname, id, "eap", "AKA'") < 0)
2999 return -2;
3000
3001 return 1;
3002}
3003
3004
3005static int sta_set_open(struct sigma_dut *dut, struct sigma_conn *conn,
3006 struct sigma_cmd *cmd)
3007{
3008 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003009 const char *network_mode = get_param(cmd, "network_mode");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003010 const char *ifname;
3011 int id;
3012
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003013 if (strcmp(intf, get_main_ifname(dut)) == 0)
3014 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003015 else
3016 ifname = intf;
3017
3018 id = add_network_common(dut, conn, ifname, cmd);
3019 if (id < 0)
3020 return id;
3021
3022 if (set_network(ifname, id, "key_mgmt", "NONE") < 0)
3023 return -2;
3024
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02003025 if (dut->program == PROGRAM_60GHZ && network_mode &&
3026 strcasecmp(network_mode, "PBSS") == 0 &&
3027 set_network(ifname, id, "pbss", "1") < 0)
3028 return -2;
3029
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003030 return 1;
3031}
3032
3033
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003034static enum sigma_cmd_result sta_set_owe(struct sigma_dut *dut,
3035 struct sigma_conn *conn,
3036 struct sigma_cmd *cmd)
Jouni Malinen47dcc952017-10-09 16:43:24 +03003037{
3038 const char *intf = get_param(cmd, "Interface");
3039 const char *ifname, *val;
3040 int id;
3041
3042 if (intf == NULL)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003043 return INVALID_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003044
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003045 if (strcmp(intf, get_main_ifname(dut)) == 0)
3046 ifname = get_station_ifname(dut);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003047 else
3048 ifname = intf;
3049
3050 id = set_wpa_common(dut, conn, ifname, cmd);
3051 if (id < 0)
3052 return id;
3053
3054 if (set_network(ifname, id, "key_mgmt", "OWE") < 0)
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003055 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003056
Hu Wangdd5eed22020-07-16 12:18:03 +08003057 if (dut->owe_ptk_workaround &&
3058 set_network(ifname, id, "owe_ptk_workaround", "1") < 0) {
3059 sigma_dut_print(dut, DUT_MSG_ERROR,
3060 "Failed to set owe_ptk_workaround to 1");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003061 return ERROR_SEND_STATUS;
Hu Wangdd5eed22020-07-16 12:18:03 +08003062 }
3063
Jouni Malinen47dcc952017-10-09 16:43:24 +03003064 val = get_param(cmd, "ECGroupID");
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003065 if (val && strcmp(val, "0") == 0) {
3066 if (wpa_command(ifname,
3067 "VENDOR_ELEM_ADD 13 ff23200000783590fb7440e03d5b3b33911f86affdcc6b4411b707846ac4ff08ddc8831ccd") != 0) {
3068 sigma_dut_print(dut, DUT_MSG_ERROR,
3069 "Failed to set OWE DH Param element override");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003070 return ERROR_SEND_STATUS;
Jouni Malinenfac9cad2017-10-10 18:35:55 +03003071 }
Hu Wangdd5eed22020-07-16 12:18:03 +08003072 } else if (val && set_network(ifname, id, "owe_group", val) < 0) {
Jouni Malinen47dcc952017-10-09 16:43:24 +03003073 sigma_dut_print(dut, DUT_MSG_ERROR,
Hu Wang6010ce72020-03-05 19:33:53 +08003074 "Failed to set owe_group");
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003075 return ERROR_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003076 }
3077
Jouni Malinen8e3f8812020-10-05 10:02:03 +03003078 return SUCCESS_SEND_STATUS;
Jouni Malinen47dcc952017-10-09 16:43:24 +03003079}
3080
3081
Jouni Malinenf7222712019-06-13 01:50:21 +03003082static enum sigma_cmd_result cmd_sta_set_security(struct sigma_dut *dut,
3083 struct sigma_conn *conn,
3084 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003085{
3086 const char *type = get_param(cmd, "Type");
3087
3088 if (type == NULL) {
3089 send_resp(dut, conn, SIGMA_ERROR,
3090 "ErrorCode,Missing Type argument");
3091 return 0;
3092 }
3093
3094 if (strcasecmp(type, "OPEN") == 0)
3095 return sta_set_open(dut, conn, cmd);
Jouni Malinen47dcc952017-10-09 16:43:24 +03003096 if (strcasecmp(type, "OWE") == 0)
3097 return sta_set_owe(dut, conn, cmd);
Jouni Malinen992a81e2017-08-22 13:57:47 +03003098 if (strcasecmp(type, "PSK") == 0 ||
Jouni Malinen0ab50f42017-08-31 01:34:59 +03003099 strcasecmp(type, "PSK-SAE") == 0 ||
Jouni Malinen992a81e2017-08-22 13:57:47 +03003100 strcasecmp(type, "SAE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003101 return cmd_sta_set_psk(dut, conn, cmd);
3102 if (strcasecmp(type, "EAPTLS") == 0)
3103 return cmd_sta_set_eaptls(dut, conn, cmd);
3104 if (strcasecmp(type, "EAPTTLS") == 0)
3105 return cmd_sta_set_eapttls(dut, conn, cmd);
3106 if (strcasecmp(type, "EAPPEAP") == 0)
3107 return cmd_sta_set_peap(dut, conn, cmd);
3108 if (strcasecmp(type, "EAPSIM") == 0)
3109 return cmd_sta_set_eapsim(dut, conn, cmd);
3110 if (strcasecmp(type, "EAPFAST") == 0)
3111 return cmd_sta_set_eapfast(dut, conn, cmd);
3112 if (strcasecmp(type, "EAPAKA") == 0)
3113 return cmd_sta_set_eapaka(dut, conn, cmd);
3114 if (strcasecmp(type, "EAPAKAPRIME") == 0)
3115 return cmd_sta_set_eapakaprime(dut, conn, cmd);
Amarnath Hullur Subramanyam81b11cd2018-01-30 19:07:17 -08003116 if (strcasecmp(type, "wep") == 0)
3117 return cmd_sta_set_encryption(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003118
3119 send_resp(dut, conn, SIGMA_ERROR,
3120 "ErrorCode,Unsupported Type value");
3121 return 0;
3122}
3123
3124
3125int ath6kl_client_uapsd(struct sigma_dut *dut, const char *intf, int uapsd)
3126{
3127#ifdef __linux__
3128 /* special handling for ath6kl */
3129 char path[128], fname[128], *pos;
3130 ssize_t res;
3131 FILE *f;
3132
Jouni Malinene39cd562019-05-29 23:39:56 +03003133 res = snprintf(fname, sizeof(fname), "/sys/class/net/%s/phy80211",
3134 intf);
3135 if (res < 0 || res >= sizeof(fname))
3136 return 0;
3137 res = readlink(fname, path, sizeof(path));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003138 if (res < 0)
3139 return 0; /* not ath6kl */
3140
3141 if (res >= (int) sizeof(path))
3142 res = sizeof(path) - 1;
3143 path[res] = '\0';
3144 pos = strrchr(path, '/');
3145 if (pos == NULL)
3146 pos = path;
3147 else
3148 pos++;
Jouni Malinen77dda642020-01-07 11:21:55 +02003149 res = snprintf(fname, sizeof(fname),
3150 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3151 "create_qos", pos);
3152 if (res < 0 || res >= sizeof(fname) || !file_exists(fname))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003153 return 0; /* not ath6kl */
3154
3155 if (uapsd) {
3156 f = fopen(fname, "w");
3157 if (f == NULL)
3158 return -1;
3159
3160 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl create_qos");
3161 fprintf(f, "4 2 2 1 2 9999999 9999999 9999999 7777777 0 4 "
3162 "45000 200 56789000 56789000 5678900 0 0 9999999 "
3163 "20000 0\n");
3164 fclose(f);
3165 } else {
Jouni Malinen77dda642020-01-07 11:21:55 +02003166 res = snprintf(fname, sizeof(fname),
3167 "/sys/kernel/debug/ieee80211/%s/ath6kl/"
3168 "delete_qos", pos);
3169 if (res < 0 || res >= sizeof(fname))
3170 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003171
3172 f = fopen(fname, "w");
3173 if (f == NULL)
3174 return -1;
3175
3176 sigma_dut_print(dut, DUT_MSG_DEBUG, "Use ath6kl delete_qos");
3177 fprintf(f, "2 4\n");
3178 fclose(f);
3179 }
3180#endif /* __linux__ */
3181
3182 return 0;
3183}
3184
3185
Jouni Malinenf7222712019-06-13 01:50:21 +03003186static enum sigma_cmd_result cmd_sta_set_uapsd(struct sigma_dut *dut,
3187 struct sigma_conn *conn,
3188 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003189{
3190 const char *intf = get_param(cmd, "Interface");
3191 /* const char *ssid = get_param(cmd, "ssid"); */
3192 const char *val;
3193 int max_sp_len = 4;
3194 int ac_be = 1, ac_bk = 1, ac_vi = 1, ac_vo = 1;
3195 char buf[100];
3196 int ret1, ret2;
3197
3198 val = get_param(cmd, "maxSPLength");
3199 if (val) {
3200 max_sp_len = atoi(val);
3201 if (max_sp_len != 0 && max_sp_len != 1 && max_sp_len != 2 &&
3202 max_sp_len != 4)
3203 return -1;
3204 }
3205
3206 val = get_param(cmd, "acBE");
3207 if (val)
3208 ac_be = atoi(val);
3209
3210 val = get_param(cmd, "acBK");
3211 if (val)
3212 ac_bk = atoi(val);
3213
3214 val = get_param(cmd, "acVI");
3215 if (val)
3216 ac_vi = atoi(val);
3217
3218 val = get_param(cmd, "acVO");
3219 if (val)
3220 ac_vo = atoi(val);
3221
3222 dut->client_uapsd = ac_be || ac_bk || ac_vi || ac_vo;
3223
3224 snprintf(buf, sizeof(buf), "P2P_SET client_apsd %d,%d,%d,%d;%d",
3225 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3226 ret1 = wpa_command(intf, buf);
3227
3228 snprintf(buf, sizeof(buf), "SET uapsd %d,%d,%d,%d;%d",
3229 ac_be, ac_bk, ac_vi, ac_vo, max_sp_len);
3230 ret2 = wpa_command(intf, buf);
3231
3232 if (ret1 && ret2) {
3233 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to set client mode "
3234 "UAPSD parameters.");
3235 return -2;
3236 }
3237
3238 if (ath6kl_client_uapsd(dut, intf, dut->client_uapsd) < 0) {
3239 send_resp(dut, conn, SIGMA_ERROR,
3240 "ErrorCode,Failed to set ath6kl QoS parameters");
3241 return 0;
3242 }
3243
3244 return 1;
3245}
3246
3247
Jouni Malinenf7222712019-06-13 01:50:21 +03003248static enum sigma_cmd_result cmd_sta_set_wmm(struct sigma_dut *dut,
3249 struct sigma_conn *conn,
3250 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003251{
3252 char buf[1000];
3253 const char *intf = get_param(cmd, "Interface");
3254 const char *grp = get_param(cmd, "Group");
3255 const char *act = get_param(cmd, "Action");
3256 const char *tid = get_param(cmd, "Tid");
3257 const char *dir = get_param(cmd, "Direction");
3258 const char *psb = get_param(cmd, "Psb");
3259 const char *up = get_param(cmd, "Up");
3260 const char *fixed = get_param(cmd, "Fixed");
3261 const char *size = get_param(cmd, "Size");
3262 const char *msize = get_param(cmd, "Maxsize");
3263 const char *minsi = get_param(cmd, "Min_srvc_intrvl");
3264 const char *maxsi = get_param(cmd, "Max_srvc_intrvl");
3265 const char *inact = get_param(cmd, "Inactivity");
3266 const char *sus = get_param(cmd, "Suspension");
3267 const char *mindr = get_param(cmd, "Mindatarate");
3268 const char *meandr = get_param(cmd, "Meandatarate");
3269 const char *peakdr = get_param(cmd, "Peakdatarate");
3270 const char *phyrate = get_param(cmd, "Phyrate");
3271 const char *burstsize = get_param(cmd, "Burstsize");
3272 const char *sba = get_param(cmd, "Sba");
3273 int direction;
3274 int handle;
Peng Xu93319622017-10-04 17:58:16 -07003275 float sba_fv = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003276 int fixed_int;
3277 int psb_ts;
3278
3279 if (intf == NULL || grp == NULL || act == NULL )
3280 return -1;
3281
3282 if (strcasecmp(act, "addts") == 0) {
3283 if (tid == NULL || dir == NULL || psb == NULL ||
3284 up == NULL || fixed == NULL || size == NULL)
3285 return -1;
3286
3287 /*
3288 * Note: Sigma CAPI spec lists uplink, downlink, and bidi as the
3289 * possible values, but WMM-AC and V-E test scripts use "UP,
3290 * "DOWN", and "BIDI".
3291 */
3292 if (strcasecmp(dir, "uplink") == 0 ||
3293 strcasecmp(dir, "up") == 0) {
3294 direction = 0;
3295 } else if (strcasecmp(dir, "downlink") == 0 ||
3296 strcasecmp(dir, "down") == 0) {
3297 direction = 1;
3298 } else if (strcasecmp(dir, "bidi") == 0) {
3299 direction = 2;
3300 } else {
3301 sigma_dut_print(dut, DUT_MSG_ERROR,
3302 "Direction %s not supported", dir);
3303 return -1;
3304 }
3305
3306 if (strcasecmp(psb, "legacy") == 0) {
3307 psb_ts = 0;
3308 } else if (strcasecmp(psb, "uapsd") == 0) {
3309 psb_ts = 1;
3310 } else {
3311 sigma_dut_print(dut, DUT_MSG_ERROR,
3312 "PSB %s not supported", psb);
3313 return -1;
3314 }
3315
3316 if (atoi(tid) < 0 || atoi(tid) > 7) {
3317 sigma_dut_print(dut, DUT_MSG_ERROR,
3318 "TID %s not supported", tid);
3319 return -1;
3320 }
3321
3322 if (strcasecmp(fixed, "true") == 0) {
3323 fixed_int = 1;
3324 } else {
3325 fixed_int = 0;
3326 }
3327
Peng Xu93319622017-10-04 17:58:16 -07003328 if (sba)
3329 sba_fv = atof(sba);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02003330
3331 dut->dialog_token++;
3332 handle = 7000 + dut->dialog_token;
3333
3334 /*
3335 * size: convert to hex
3336 * maxsi: convert to hex
3337 * mindr: convert to hex
3338 * meandr: convert to hex
3339 * peakdr: convert to hex
3340 * burstsize: convert to hex
3341 * phyrate: convert to hex
3342 * sba: convert to hex with modification
3343 * minsi: convert to integer
3344 * sus: convert to integer
3345 * inact: convert to integer
3346 * maxsi: convert to integer
3347 */
3348
3349 /*
3350 * The Nominal MSDU Size field is 2 octets long and contains an
3351 * unsigned integer that specifies the nominal size, in octets,
3352 * of MSDUs belonging to the traffic under this traffic
3353 * specification and is defined in Figure 16. If the Fixed
3354 * subfield is set to 1, then the size of the MSDU is fixed and
3355 * is indicated by the Size Subfield. If the Fixed subfield is
3356 * set to 0, then the size of the MSDU might not be fixed and
3357 * the Size indicates the nominal MSDU size.
3358 *
3359 * The Surplus Bandwidth Allowance Factor field is 2 octets long
3360 * and specifies the excess allocation of time (and bandwidth)
3361 * over and above the stated rates required to transport an MSDU
3362 * belonging to the traffic in this TSPEC. This field is
3363 * represented as an unsigned binary number with an implicit
3364 * binary point after the leftmost 3 bits. For example, an SBA
3365 * of 1.75 is represented as 0x3800. This field is included to
3366 * account for retransmissions. As such, the value of this field
3367 * must be greater than unity.
3368 */
3369
3370 snprintf(buf, sizeof(buf),
3371 "iwpriv %s addTspec %d %s %d %d %s 0x%X"
3372 " 0x%X 0x%X 0x%X"
3373 " 0x%X 0x%X 0x%X"
3374 " 0x%X %d %d %d %d"
3375 " %d %d",
3376 intf, handle, tid, direction, psb_ts, up,
3377 (unsigned int) ((fixed_int << 15) | atoi(size)),
3378 msize ? atoi(msize) : 0,
3379 mindr ? atoi(mindr) : 0,
3380 meandr ? atoi(meandr) : 0,
3381 peakdr ? atoi(peakdr) : 0,
3382 burstsize ? atoi(burstsize) : 0,
3383 phyrate ? atoi(phyrate) : 0,
3384 sba ? ((unsigned int) (((int) sba_fv << 13) |
3385 (int)((sba_fv - (int) sba_fv) *
3386 8192))) : 0,
3387 minsi ? atoi(minsi) : 0,
3388 sus ? atoi(sus) : 0,
3389 0, 0,
3390 inact ? atoi(inact) : 0,
3391 maxsi ? atoi(maxsi) : 0);
3392
3393 if (system(buf) != 0) {
3394 sigma_dut_print(dut, DUT_MSG_ERROR,
3395 "iwpriv addtspec request failed");
3396 send_resp(dut, conn, SIGMA_ERROR,
3397 "errorCode,Failed to execute addTspec command");
3398 return 0;
3399 }
3400
3401 sigma_dut_print(dut, DUT_MSG_INFO,
3402 "iwpriv addtspec request send");
3403
3404 /* Mapping handle to a TID */
3405 dut->tid_to_handle[atoi(tid)] = handle;
3406 } else if (strcasecmp(act, "delts") == 0) {
3407 if (tid == NULL)
3408 return -1;
3409
3410 if (atoi(tid) < 0 || atoi(tid) > 7) {
3411 sigma_dut_print(dut, DUT_MSG_ERROR,
3412 "TID %s not supported", tid);
3413 send_resp(dut, conn, SIGMA_ERROR,
3414 "errorCode,Unsupported TID");
3415 return 0;
3416 }
3417
3418 handle = dut->tid_to_handle[atoi(tid)];
3419
3420 if (handle < 7000 || handle > 7255) {
3421 /* Invalid handle ie no mapping for that TID */
3422 sigma_dut_print(dut, DUT_MSG_ERROR,
3423 "handle-> %d not found", handle);
3424 }
3425
3426 snprintf(buf, sizeof(buf), "iwpriv %s delTspec %d",
3427 intf, handle);
3428
3429 if (system(buf) != 0) {
3430 sigma_dut_print(dut, DUT_MSG_ERROR,
3431 "iwpriv deltspec request failed");
3432 send_resp(dut, conn, SIGMA_ERROR,
3433 "errorCode,Failed to execute delTspec command");
3434 return 0;
3435 }
3436
3437 sigma_dut_print(dut, DUT_MSG_INFO,
3438 "iwpriv deltspec request send");
3439
3440 dut->tid_to_handle[atoi(tid)] = 0;
3441 } else {
3442 sigma_dut_print(dut, DUT_MSG_ERROR,
3443 "Action type %s not supported", act);
3444 send_resp(dut, conn, SIGMA_ERROR,
3445 "errorCode,Unsupported Action");
3446 return 0;
3447 }
3448
3449 return 1;
3450}
3451
3452
vamsi krishna52e16f92017-08-29 12:37:34 +05303453static int find_network(struct sigma_dut *dut, const char *ssid)
3454{
3455 char list[4096];
3456 char *pos;
3457
3458 sigma_dut_print(dut, DUT_MSG_DEBUG,
3459 "Search for profile based on SSID: '%s'", ssid);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02003460 if (wpa_command_resp(get_station_ifname(dut), "LIST_NETWORKS",
vamsi krishna52e16f92017-08-29 12:37:34 +05303461 list, sizeof(list)) < 0)
3462 return -1;
3463 pos = strstr(list, ssid);
3464 if (!pos || pos == list || pos[-1] != '\t' || pos[strlen(ssid)] != '\t')
3465 return -1;
3466
3467 while (pos > list && pos[-1] != '\n')
3468 pos--;
3469 dut->infra_network_id = atoi(pos);
3470 snprintf(dut->infra_ssid, sizeof(dut->infra_ssid), "%s", ssid);
3471 return 0;
3472}
3473
3474
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303475/**
3476 * enum qca_sta_helper_config_params - This helper enum defines the config
3477 * parameters which can be delivered to sta.
3478 */
3479enum qca_sta_helper_config_params {
3480 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE */
3481 STA_SET_RSNIE,
3482
3483 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC */
3484 STA_SET_LDPC,
3485
3486 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC */
3487 STA_SET_TX_STBC,
3488
3489 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC */
3490 STA_SET_RX_STBC,
3491
3492 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION */
3493 STA_SET_TX_MSDU,
3494
3495 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION */
3496 STA_SET_RX_MSDU,
Shivani Baranwal2a572842021-09-16 12:27:15 +05303497
3498 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH */
3499 STA_SET_CHAN_WIDTH,
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303500
3501 /* For the attribute QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS */
3502 STA_SET_FT_DS,
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303503};
3504
3505
3506static int sta_config_params(struct sigma_dut *dut, const char *intf,
3507 enum qca_sta_helper_config_params config_cmd,
3508 int value)
Sunil Dutt44595082018-02-12 19:41:45 +05303509{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303510#ifdef NL80211_SUPPORT
Sunil Dutt44595082018-02-12 19:41:45 +05303511 struct nl_msg *msg;
3512 int ret;
3513 struct nlattr *params;
3514 int ifindex;
3515
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303516 ifindex = if_nametoindex(intf);
3517 if (ifindex == 0) {
3518 sigma_dut_print(dut, DUT_MSG_ERROR,
3519 "%s: Interface %s does not exist",
3520 __func__, intf);
3521 return -1;
3522 }
3523
Sunil Dutt44595082018-02-12 19:41:45 +05303524 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
3525 NL80211_CMD_VENDOR)) ||
3526 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
3527 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
3528 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
3529 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303530 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)))
3531 goto fail;
3532
3533 switch (config_cmd) {
3534 case STA_SET_RSNIE:
3535 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE, value))
3536 goto fail;
3537 break;
3538 case STA_SET_LDPC:
3539 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_LDPC, value))
3540 goto fail;
3541 break;
3542 case STA_SET_TX_STBC:
3543 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TX_STBC, value))
3544 goto fail;
3545 break;
3546 case STA_SET_RX_STBC:
3547 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_RX_STBC, value))
3548 goto fail;
3549 break;
3550 case STA_SET_TX_MSDU:
3551 if (nla_put_u8(msg,
3552 QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MSDU_AGGREGATION,
3553 value))
3554 goto fail;
3555 break;
3556 case STA_SET_RX_MSDU:
3557 if (nla_put_u8(msg,
3558 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MSDU_AGGREGATION,
3559 value))
3560 goto fail;
3561 break;
Shivani Baranwal2a572842021-09-16 12:27:15 +05303562 case STA_SET_CHAN_WIDTH:
3563 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_WIDTH,
3564 value))
3565 goto fail;
3566 break;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05303567 case STA_SET_FT_DS:
3568 if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_FT_OVER_DS,
3569 value))
3570 goto fail;
3571 break;
Sunil Dutt44595082018-02-12 19:41:45 +05303572 }
3573 nla_nest_end(msg, params);
3574
3575 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
3576 if (ret) {
3577 sigma_dut_print(dut, DUT_MSG_ERROR,
3578 "%s: err in send_and_recv_msgs, ret=%d",
3579 __func__, ret);
3580 return ret;
3581 }
3582
3583 return 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303584
3585fail:
3586 sigma_dut_print(dut, DUT_MSG_ERROR,
3587 "%s: err in adding vendor_cmd and vendor_data",
3588 __func__);
3589 nlmsg_free(msg);
Sunil Dutt44595082018-02-12 19:41:45 +05303590#endif /* NL80211_SUPPORT */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05303591 return -1;
3592}
Sunil Dutt44595082018-02-12 19:41:45 +05303593
3594
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303595void free_dscp_policy_table(struct sigma_dut *dut)
3596{
3597 struct dscp_policy_data *dscp_policy;
3598
3599 while (dut->dscp_policy_table) {
3600 dscp_policy = dut->dscp_policy_table;
3601 dut->dscp_policy_table = dscp_policy->next;
3602 free(dscp_policy);
3603 }
3604}
3605
3606
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303607static char * protocol_to_str(int proto)
3608{
3609 switch (proto) {
3610 case 6:
3611 return "tcp";
3612 case 17:
3613 return "udp";
3614 case 50:
3615 return "esp";
3616 default:
3617 return "unknown";
3618 }
3619}
3620
3621
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303622static int delete_nft_table(struct sigma_dut *dut, const char *table,
3623 const char *ip_type)
3624{
3625 int res;
3626 char cmd[200];
3627
3628 res = snprintf(cmd, sizeof(cmd), "nft delete table %s %s_%s", ip_type,
3629 table, ip_type);
3630 if (snprintf_error(sizeof(cmd), res)) {
3631 sigma_dut_print(dut, DUT_MSG_ERROR,
3632 "Failed to create delete table command");
3633 return -1;
3634 }
3635
3636 if (system(cmd) != 0) {
3637 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3638 return -1;
3639 }
3640
3641 return 0;
3642}
3643
3644
3645static int remove_nft_rule(struct sigma_dut *dut, int policy_id,
3646 enum ip_version ip_ver)
3647{
3648 int res;
3649 char table[50];
3650
3651 res = snprintf(table, sizeof(table), "wifi_%s_dscp_policy_%d",
3652 dut->station_ifname, policy_id);
3653 if (snprintf_error(sizeof(table), res)) {
3654 sigma_dut_print(dut, DUT_MSG_INFO,
3655 "Failed to create table name for policy %d",
3656 policy_id);
3657 return -1;
3658 }
3659
3660
3661 if (ip_ver == IPV6)
3662 return delete_nft_table(dut, table, "ip6");
3663 else
3664 return delete_nft_table(dut, table, "ip");
3665}
3666
3667
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303668static int remove_iptable_rule(struct sigma_dut *dut,
3669 struct dscp_policy_data *dscp_policy)
3670{
3671 char ip_cmd[1000];
3672 char *pos;
3673 int ret, len;
3674 enum ip_version ip_ver = dscp_policy->ip_version;
3675
3676 pos = ip_cmd;
3677 len = sizeof(ip_cmd);
3678
3679 ret = snprintf(pos, len,
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05303680 "%s -t mangle -D OUTPUT -o %s",
3681#ifdef ANDROID
3682 ip_ver == IPV6 ? "/system/bin/ip6tables" : "/system/bin/iptables",
3683#else /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303684 ip_ver == IPV6 ? "ip6tables" : "iptables",
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05303685#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303686 dut->station_ifname);
3687 if (snprintf_error(len, ret)) {
3688 sigma_dut_print(dut, DUT_MSG_INFO,
3689 "Failed to create delete iptables command %s",
3690 ip_cmd);
3691 return -1;
3692 }
3693
3694 pos += ret;
3695 len -= ret;
3696
3697 if (strlen(dscp_policy->src_ip)) {
3698 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
3699 if (snprintf_error(len, ret)) {
3700 sigma_dut_print(dut, DUT_MSG_INFO,
3701 "Error in adding src_ip %s in delete command",
3702 dscp_policy->src_ip);
3703 return -1;
3704 }
3705 pos += ret;
3706 len -= ret;
3707 }
3708
3709 if (strlen(dscp_policy->dst_ip)) {
3710 ret = snprintf(pos, len, " -d %s",
3711 dscp_policy->dst_ip);
3712 if (snprintf_error(len, ret)) {
3713 sigma_dut_print(dut, DUT_MSG_INFO,
3714 "Error in adding dst_ip %s in delete cmd",
3715 dscp_policy->dst_ip);
3716 return -1;
3717 }
3718 pos += ret;
3719 len -= ret;
3720 }
3721
3722 if (dscp_policy->src_port || dscp_policy->dst_port ||
3723 (dscp_policy->start_port && dscp_policy->end_port)) {
3724 ret = snprintf(pos, len, " -p %s",
3725 protocol_to_str(dscp_policy->protocol));
3726 if (snprintf_error(len, ret)) {
3727 sigma_dut_print(dut, DUT_MSG_INFO,
3728 "Error in adding protocol %d in delete command",
3729 dscp_policy->protocol);
3730 return -1;
3731 }
3732 pos += ret;
3733 len -= ret;
3734 }
3735
3736 if (dscp_policy->src_port) {
3737 ret = snprintf(pos, len, " --sport %d",
3738 dscp_policy->src_port);
3739 if (snprintf_error(len, ret)) {
3740 sigma_dut_print(dut, DUT_MSG_INFO,
3741 "Error in adding src_port %d in delete command",
3742 dscp_policy->src_port);
3743 return -1;
3744 }
3745 pos += ret;
3746 len -= ret;
3747 }
3748
3749 if (dscp_policy->dst_port) {
3750 ret = snprintf(pos, len, " --dport %d",
3751 dscp_policy->dst_port);
3752 if (snprintf_error(len, ret)) {
3753 sigma_dut_print(dut, DUT_MSG_INFO,
3754 "Error in adding dst_port %d in delete command",
3755 dscp_policy->dst_port);
3756 return -1;
3757 }
3758 pos += ret;
3759 len -= ret;
3760 }
3761
3762 if (dscp_policy->start_port && dscp_policy->end_port) {
3763 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
3764 dscp_policy->start_port,
3765 dscp_policy->end_port);
3766 if (snprintf_error(len, ret)) {
3767 sigma_dut_print(dut, DUT_MSG_INFO,
3768 "Error in adding start:end port %d:%d in delete command",
3769 dscp_policy->start_port,
3770 dscp_policy->end_port);
3771 return -1;
3772 }
3773 pos += ret;
3774 len -= ret;
3775 }
3776
3777 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
3778 dscp_policy->dscp);
3779 if (snprintf_error(len, ret)) {
3780 sigma_dut_print(dut, DUT_MSG_INFO,
3781 "Error in adding dscp %0x in delete command",
3782 dscp_policy->dscp);
3783 return -1;
3784 }
3785 ret = system(ip_cmd);
3786 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
3787 ip_cmd, ret);
3788
3789 return ret;
3790}
3791
3792
3793static int remove_dscp_policy_rule(struct sigma_dut *dut,
3794 struct dscp_policy_data *dscp_policy)
3795{
3796 return dut->dscp_use_iptables ? remove_iptable_rule(dut, dscp_policy) :
3797 remove_nft_rule(dut, dscp_policy->policy_id,
3798 dscp_policy->ip_version);
3799}
3800
3801
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303802static int create_nft_table(struct sigma_dut *dut, int policy_id,
3803 const char *table_name, enum ip_version ip_ver)
3804{
3805 char cmd[200];
3806 int res;
3807
3808 res = snprintf(cmd, sizeof(cmd), "nft add table %s %s",
3809 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3810 if (snprintf_error(sizeof(cmd), res)) {
3811 sigma_dut_print(dut, DUT_MSG_INFO,
3812 "Failed to add rule to create table for policy id %d",
3813 policy_id);
3814 return -1;
3815 }
3816
3817 if (system(cmd) != 0) {
3818 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3819 return -1;
3820 }
3821
3822 res = snprintf(cmd, sizeof(cmd),
3823 "nft add chain %s %s OUTPUT { type filter hook output priority 0 \\; }",
3824 ip_ver == IPV6 ? "ip6" : "ip", table_name);
3825 if (snprintf_error(sizeof(cmd), res)) {
3826 sigma_dut_print(dut, DUT_MSG_INFO,
3827 "Failed to add rule to create chain for table = %s",
3828 table_name);
3829 return -1;
3830 }
3831
3832 if (system(cmd) != 0) {
3833 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run %s", cmd);
3834 return -1;
3835 }
3836
3837 return 0;
3838}
3839
3840
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303841static int remove_dscp_policy(struct sigma_dut *dut, u8 policy_id)
3842{
3843 struct dscp_policy_data *dscp_policy = dut->dscp_policy_table;
3844 struct dscp_policy_data *prev = NULL;
3845
3846 while (dscp_policy) {
3847 if (dscp_policy->policy_id == policy_id)
3848 break;
3849
3850 prev = dscp_policy;
3851 dscp_policy = dscp_policy->next;
3852 }
3853
3854 /*
3855 * Consider remove request for a policy id which does not exist as
3856 * success.
3857 */
3858 if (!dscp_policy)
3859 return 0;
3860
3861 if (strlen(dscp_policy->domain_name) == 0 &&
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303862 remove_dscp_policy_rule(dut, dscp_policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05303863 return -1;
3864
3865 if (prev)
3866 prev->next = dscp_policy->next;
3867 else
3868 dut->dscp_policy_table = dscp_policy->next;
3869
3870 free(dscp_policy);
3871 return 0;
3872}
3873
3874
3875static int add_nft_rule(struct sigma_dut *dut,
3876 struct dscp_policy_data *dscp_policy)
3877{
3878 char nft_cmd[1000], ip[4], table_name[100];
3879 char *pos;
3880 int ret, len, policy_id = dscp_policy->policy_id;
3881 enum ip_version ip_ver = dscp_policy->ip_version;
3882
3883 if (ip_ver == IPV6)
3884 strlcpy(ip, "ip6", sizeof(ip));
3885 else
3886 strlcpy(ip, "ip", sizeof(ip));
3887
3888 ret = snprintf(table_name, sizeof(table_name),
3889 "wifi_%s_dscp_policy_%d_%s",
3890 dut->station_ifname, policy_id, ip);
3891 if (snprintf_error(sizeof(table_name), ret))
3892 return -1;
3893
3894 if (create_nft_table(dut, policy_id, table_name, ip_ver)) {
3895 sigma_dut_print(dut, DUT_MSG_INFO,
3896 "Failed to create nft table");
3897 return -1;
3898 }
3899
3900 pos = nft_cmd;
3901 len = sizeof(nft_cmd);
3902
3903 ret = snprintf(pos, len,
3904 "nft add rule %s %s OUTPUT oifname \"%s\"",
3905 ip, table_name, dut->station_ifname);
3906 if (snprintf_error(len, ret)) {
3907 sigma_dut_print(dut, DUT_MSG_INFO,
3908 "Failed to create nft cmd %s", nft_cmd);
3909 return -1;
3910 }
3911
3912 pos += ret;
3913 len -= ret;
3914
3915 if (strlen(dscp_policy->src_ip)) {
3916 ret = snprintf(pos, len, " %s saddr %s", ip,
3917 dscp_policy->src_ip);
3918 if (snprintf_error(len, ret))
3919 return -1;
3920
3921 pos += ret;
3922 len -= ret;
3923 }
3924
3925 if (strlen(dscp_policy->dst_ip)) {
3926 ret = snprintf(pos, len, " %s daddr %s", ip,
3927 dscp_policy->dst_ip);
3928 if (snprintf_error(len, ret))
3929 return -1;
3930
3931 pos += ret;
3932 len -= ret;
3933 }
3934
3935 if (dscp_policy->src_port) {
3936 ret = snprintf(pos, len, " %s sport %d",
3937 protocol_to_str(dscp_policy->protocol),
3938 dscp_policy->src_port);
3939 if (snprintf_error(len, ret))
3940 return -1;
3941
3942 pos += ret;
3943 len -= ret;
3944 }
3945
3946 if (dscp_policy->dst_port) {
3947 ret = snprintf(pos, len, " %s dport %d",
3948 protocol_to_str(dscp_policy->protocol),
3949 dscp_policy->dst_port);
3950 if (snprintf_error(len, ret))
3951 return -1;
3952
3953 pos += ret;
3954 len -= ret;
3955 }
3956
3957 if (dscp_policy->start_port && dscp_policy->end_port) {
3958 ret = snprintf(pos, len, " %s dport %d-%d",
3959 protocol_to_str(dscp_policy->protocol),
3960 dscp_policy->start_port,
3961 dscp_policy->end_port);
3962 if (snprintf_error(len, ret))
3963 return -1;
3964
3965 pos += ret;
3966 len -= ret;
3967 }
3968
3969 ret = snprintf(pos, len, " counter %s dscp set 0x%0x", ip,
3970 dscp_policy->dscp);
3971 if (snprintf_error(len, ret))
3972 return -1;
3973
3974 ret = system(nft_cmd);
3975 sigma_dut_print(dut, DUT_MSG_INFO, "nft rule: %s err: %d",
3976 nft_cmd, ret);
3977
3978 return ret;
3979}
3980
3981
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05303982static int add_iptable_rule(struct sigma_dut *dut,
3983 struct dscp_policy_data *dscp_policy)
3984{
3985 char ip_cmd[1000];
3986 char *pos;
3987 int ret, len;
3988 enum ip_version ip_ver = dscp_policy->ip_version;
3989 struct dscp_policy_data *active_policy = dut->dscp_policy_table;
3990 int ipv4_rule_num = 1, ipv6_rule_num = 1;
3991
3992 pos = ip_cmd;
3993 len = sizeof(ip_cmd);
3994
3995 /*
3996 * DSCP target in the mangle table doesn't stop processing of rules
3997 * so to make sure the most granular rule is applied last, add the new
3998 * rules in granularity increasing order.
3999 */
4000 while (active_policy) {
4001 /*
4002 * Domain name rules are managed in sigma_dut thus don't count
4003 * them while counting the number of active rules.
4004 */
4005 if (strlen(active_policy->domain_name)) {
4006 active_policy = active_policy->next;
4007 continue;
4008 }
4009
4010 if (active_policy->granularity_score >
4011 dscp_policy->granularity_score)
4012 break;
4013
4014 if (active_policy->ip_version == IPV6)
4015 ipv6_rule_num++;
4016 else
4017 ipv4_rule_num++;
4018
4019 active_policy = active_policy->next;
4020 }
4021
4022 ret = snprintf(pos, len,
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304023 "%s -t mangle -I OUTPUT %d -o %s",
4024#ifdef ANDROID
4025 ip_ver == IPV6 ? "/system/bin/ip6tables" : "/system/bin/iptables",
4026#else /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304027 ip_ver == IPV6 ? "ip6tables" : "iptables",
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304028#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304029 ip_ver == IPV6 ? ipv6_rule_num : ipv4_rule_num,
4030 dut->station_ifname);
4031 if (snprintf_error(len, ret)) {
4032 sigma_dut_print(dut, DUT_MSG_INFO,
4033 "Failed to create iptables command %s", ip_cmd);
4034 return -1;
4035 }
4036
4037 pos += ret;
4038 len -= ret;
4039
4040 if (strlen(dscp_policy->src_ip)) {
4041 ret = snprintf(pos, len, " -s %s", dscp_policy->src_ip);
4042 if (snprintf_error(len, ret)) {
4043 sigma_dut_print(dut, DUT_MSG_INFO,
4044 "Error in adding src_ip %s",
4045 dscp_policy->src_ip);
4046 return -1;
4047 }
4048 pos += ret;
4049 len -= ret;
4050 }
4051
4052 if (strlen(dscp_policy->dst_ip)) {
4053 ret = snprintf(pos, len, " -d %s", dscp_policy->dst_ip);
4054 if (snprintf_error(len, ret)) {
4055 sigma_dut_print(dut, DUT_MSG_INFO,
4056 "Error in adding dst_ip %s",
4057 dscp_policy->dst_ip);
4058 return -1;
4059 }
4060 pos += ret;
4061 len -= ret;
4062 }
4063
4064 if (dscp_policy->src_port || dscp_policy->dst_port ||
4065 (dscp_policy->start_port && dscp_policy->end_port)) {
4066 ret = snprintf(pos, len, " -p %s",
4067 protocol_to_str(dscp_policy->protocol));
4068 if (snprintf_error(len, ret)) {
4069 sigma_dut_print(dut, DUT_MSG_INFO,
4070 "Error in adding protocol %d in add command",
4071 dscp_policy->protocol);
4072 return -1;
4073 }
4074 pos += ret;
4075 len -= ret;
4076 }
4077
4078 if (dscp_policy->src_port) {
4079 ret = snprintf(pos, len, " --sport %d", dscp_policy->src_port);
4080 if (snprintf_error(len, ret)) {
4081 sigma_dut_print(dut, DUT_MSG_INFO,
4082 "Error in adding src_port %d",
4083 dscp_policy->src_port);
4084 return -1;
4085 }
4086 pos += ret;
4087 len -= ret;
4088 }
4089
4090 if (dscp_policy->dst_port) {
4091 ret = snprintf(pos, len, " --dport %d", dscp_policy->dst_port);
4092 if (snprintf_error(len, ret)) {
4093 sigma_dut_print(dut, DUT_MSG_INFO,
4094 "Error in adding dst_port %d",
4095 dscp_policy->dst_port);
4096 return -1;
4097 }
4098 pos += ret;
4099 len -= ret;
4100 }
4101
4102 if (dscp_policy->start_port && dscp_policy->end_port) {
4103 ret = snprintf(pos, len, " --match multiport --dports %d:%d",
4104 dscp_policy->start_port, dscp_policy->end_port);
4105 if (snprintf_error(len, ret)) {
4106 sigma_dut_print(dut, DUT_MSG_INFO,
4107 "Error in adding start:end port %d:%d",
4108 dscp_policy->start_port,
4109 dscp_policy->end_port);
4110 return -1;
4111 }
4112 pos += ret;
4113 len -= ret;
4114 }
4115
4116 ret = snprintf(pos, len, " -j DSCP --set-dscp 0x%0x",
4117 dscp_policy->dscp);
4118 if (snprintf_error(len, ret)) {
4119 sigma_dut_print(dut, DUT_MSG_INFO,
4120 "Error in adding dscp %0x", dscp_policy->dscp);
4121 return -1;
4122 }
4123 ret = system(ip_cmd);
4124 sigma_dut_print(dut, DUT_MSG_DEBUG, "iptables rule: %s err: %d",
4125 ip_cmd, ret);
4126
4127 return ret;
4128}
4129
4130
4131static int add_dscp_policy_rule(struct sigma_dut *dut,
4132 struct dscp_policy_data *dscp_policy)
4133{
4134 return dut->dscp_use_iptables ? add_iptable_rule(dut, dscp_policy) :
4135 add_nft_rule(dut, dscp_policy);
4136}
4137
4138
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304139static void clear_all_dscp_policies(struct sigma_dut *dut)
4140{
4141 free_dscp_policy_table(dut);
4142
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304143 if (dut->dscp_use_iptables) {
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304144#ifdef ANDROID
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304145 if (system("/system/bin/iptables -t mangle -F && /system/bin/iptables -t mangle -X") != 0 ||
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304146 system("/system/bin/ip6tables -t mangle -F && /system/bin/ip6tables -t mangle -X") != 0)
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304147 sigma_dut_print(dut, DUT_MSG_ERROR,
4148 "iptables: Failed to flush DSCP policy");
Shivani Baranwalbf2b5212021-12-08 16:38:23 +05304149#else /* ANDROID */
4150 if (system("iptables -t mangle -F && iptables -t mangle -X") != 0 ||
4151 system("ip6tables -t mangle -F && ip6tables -t mangle -X") != 0)
4152 sigma_dut_print(dut, DUT_MSG_ERROR,
4153 "iptables: Failed to flush DSCP policy");
4154#endif /* ANDROID */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304155 } else {
4156 if (system("nft flush ruleset") != 0)
4157 sigma_dut_print(dut, DUT_MSG_ERROR,
4158 "nftables: Failed to flush DSCP policy");
4159 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304160}
4161
4162
4163static int send_dscp_response(struct sigma_dut *dut,
4164 struct dscp_policy_status *status_list,
4165 int num_status)
4166{
4167 int rem_len, ret;
4168 char buf[200] = "", *pos, cmd[256];
4169
4170 pos = buf;
4171 rem_len = sizeof(buf);
4172
4173 ret = snprintf(pos, rem_len, " solicited");
4174 if (snprintf_error(rem_len, ret)) {
4175 sigma_dut_print(dut, DUT_MSG_ERROR,
4176 "Failed to write DSCP policy response command");
4177 return -1;
4178 }
4179 pos += ret;
4180 rem_len -= ret;
4181
4182 for (int i = 0; i < num_status; i++) {
4183 ret = snprintf(pos, rem_len, " policy_id=%d status=%d",
4184 status_list[i].id, status_list[i].status);
4185 if (snprintf_error(rem_len, ret)) {
4186 sigma_dut_print(dut, DUT_MSG_ERROR,
4187 "Failed to wite DSCP policy response");
4188 return -1;
4189 }
4190
4191 pos += ret;
4192 rem_len -= ret;
4193 }
4194
4195 ret = snprintf(cmd, sizeof(cmd), "DSCP_RESP%s", buf);
4196 if (snprintf_error(sizeof(cmd), ret)) {
4197 sigma_dut_print(dut, DUT_MSG_ERROR,
4198 "Failed to create DSCP Policy Response frame");
4199 return -1;
4200 }
4201
4202 if (wpa_command(dut->station_ifname, cmd) != 0) {
4203 sigma_dut_print(dut, DUT_MSG_ERROR,
4204 "Failed to send DSCP Policy Response frame");
4205 return -1;
4206 }
4207
4208 sigma_dut_print(dut, DUT_MSG_DEBUG,
4209 "DSCP Policy Response frame sent: %s", cmd);
4210 return 0;
4211}
4212
4213
4214#ifdef ANDROID
4215static void thread_cancel_handler(int sig)
4216{
4217 if (sig == SIGUSR1)
4218 pthread_exit(0);
4219}
4220#endif /* ANDROID */
4221
4222
4223static void * mon_dscp_policies(void *ptr)
4224{
4225 struct sigma_dut *dut = ptr;
4226 int ret, policy_id;
4227 struct wpa_ctrl *ctrl;
4228 char buf[4096], *pos, *end;
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304229 struct dscp_policy_data *policy = NULL, *current_policy, *prev_policy;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304230 struct dscp_policy_status status_list[10];
4231 int num_status = 0;
4232 const char *events[] = {
4233 "CTRL-EVENT-DISCONNECTED",
4234 "CTRL-EVENT-DSCP-POLICY",
4235 NULL
4236 };
4237#ifdef ANDROID
4238 struct sigaction actions;
4239#endif /* ANDROID */
4240
4241 ctrl = open_wpa_mon(get_station_ifname(dut));
4242 if (!ctrl) {
4243 sigma_dut_print(dut, DUT_MSG_ERROR,
4244 "Failed to open wpa_supplicant monitor connection");
4245 return NULL;
4246 }
4247
4248#ifdef ANDROID
4249 memset(&actions, 0, sizeof(actions));
4250 sigemptyset(&actions.sa_mask);
4251 actions.sa_flags = 0;
4252 actions.sa_handler = thread_cancel_handler;
4253 if (sigaction(SIGUSR1, &actions, NULL) == -1) {
4254 sigma_dut_print(dut, DUT_MSG_ERROR,
4255 "Failed to register exit handler for %s",
4256 __func__);
4257 wpa_ctrl_detach(ctrl);
4258 wpa_ctrl_close(ctrl);
4259 return NULL;
4260 }
4261#endif /* ANDROID */
4262
4263 while (1) {
4264 ret = get_wpa_cli_events_timeout(dut, ctrl, events,
4265 buf, sizeof(buf), 0);
4266
4267 if (ret || strlen(buf) == 0) {
4268 sigma_dut_print(dut, DUT_MSG_INFO,
4269 "Did not receive any event");
4270 continue;
4271 }
4272
4273 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4274 clear_all_dscp_policies(dut);
4275 break;
4276 }
4277
4278 if (strstr(buf, "request_start")) {
4279 num_status = 0;
4280 if (strstr(buf, "clear_all"))
4281 clear_all_dscp_policies(dut);
4282 continue;
4283 }
4284
4285 if (strstr(buf, "request_end")) {
4286 send_dscp_response(dut, status_list, num_status);
4287 continue;
4288 }
4289
4290 if (!strstr(buf, "add") && !strstr(buf, "remove") &&
4291 !strstr(buf, "reject")) {
4292 sigma_dut_print(dut, DUT_MSG_DEBUG, "Ignore event: %s",
4293 buf);
4294 continue;
4295 }
4296
4297 pos = strstr(buf, "policy_id=");
4298 if (!pos) {
4299 sigma_dut_print(dut, DUT_MSG_INFO,
4300 "Policy id not present");
4301 continue;
4302 }
4303 policy_id = atoi(pos + 10);
4304
4305 if (num_status >= ARRAY_SIZE(status_list)) {
4306 sigma_dut_print(dut, DUT_MSG_INFO,
4307 "Max policies allowed per DSCP request reached. Drop policy id %d request",
4308 policy_id);
4309 continue;
4310 }
4311 status_list[num_status].id = policy_id;
4312
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05304313 if (dut->reject_dscp_policies) {
4314 status_list[num_status].status =
4315 dut->dscp_reject_resp_code;
4316 num_status++;
4317 continue;
4318 }
4319
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304320 if (strstr(buf, "reject"))
4321 goto reject;
4322
4323 /*
4324 * In case of "add" also if policy with same policy id exist it
4325 * shall be removed. So always call remove_dscp_policy().
4326 */
4327 if (remove_dscp_policy(dut, policy_id))
4328 goto reject;
4329
4330 if (strstr(buf, "remove"))
4331 goto success;
4332
4333 policy = malloc(sizeof(*policy));
4334 if (!policy)
4335 goto reject;
4336
4337 memset(policy, 0, sizeof(*policy));
4338
4339 policy->policy_id = policy_id;
4340
4341 pos = strstr(buf, "dscp=");
4342 if (!pos) {
4343 sigma_dut_print(dut, DUT_MSG_ERROR,
4344 "DSCP info not present");
4345 goto reject;
4346 }
4347 policy->dscp = atoi(pos + 5);
4348
4349 pos = strstr(buf, "ip_version=");
4350 if (!pos) {
4351 sigma_dut_print(dut, DUT_MSG_ERROR,
4352 "IP version info not present");
4353 goto reject;
4354 }
4355 policy->ip_version = atoi(pos + 11);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304356 if (policy->ip_version)
4357 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304358
4359 pos = strstr(buf, "domain_name=");
4360 if (pos) {
4361 pos += 12;
4362 end = strchr(pos, ' ');
4363 if (!end)
4364 end = pos + strlen(pos);
4365
4366 if (end - pos >= (int) sizeof(policy->domain_name))
4367 goto reject;
4368
4369 memcpy(policy->domain_name, pos, end - pos);
4370 policy->domain_name[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304371 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304372 }
4373
4374 pos = strstr(buf, "start_port=");
4375 if (pos) {
4376 pos += 11;
4377 policy->start_port = atoi(pos);
4378 }
4379
4380 pos = strstr(buf, "end_port=");
4381 if (pos) {
4382 pos += 9;
4383 policy->end_port = atoi(pos);
4384 }
4385
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304386 if (policy->start_port && policy->end_port)
4387 policy->granularity_score++;
4388
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304389 pos = strstr(buf, "src_ip=");
4390 if (pos) {
4391 pos += 7;
4392 end = strchr(pos, ' ');
4393 if (!end)
4394 end = pos + strlen(pos);
4395
4396 if (end - pos >= (int) sizeof(policy->src_ip))
4397 goto reject;
4398
4399 memcpy(policy->src_ip, pos, end - pos);
4400 policy->src_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304401 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304402 }
4403
4404 pos = strstr(buf, "dst_ip=");
4405 if (pos) {
4406 pos += 7;
4407 end = strchr(pos, ' ');
4408 if (!end)
4409 end = pos + strlen(pos);
4410
4411 if (end - pos >= (int) sizeof(policy->dst_ip))
4412 goto reject;
4413
4414 memcpy(policy->dst_ip, pos, end - pos);
4415 policy->dst_ip[end - pos] = '\0';
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304416 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304417 }
4418
4419 pos = strstr(buf, "src_port=");
4420 if (pos) {
4421 pos += 9;
4422 policy->src_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304423 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304424 }
4425
4426 pos = strstr(buf, "dst_port=");
4427 if (pos) {
4428 pos += 9;
4429 policy->dst_port = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304430 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304431 }
4432
4433 pos = strstr(buf, "protocol=");
4434 if (pos) {
4435 pos += 9;
4436 policy->protocol = atoi(pos);
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304437 policy->granularity_score++;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304438 }
4439
4440 /*
4441 * Skip adding nft rules for doman name policies.
4442 * Domain name rules are applied in sigma_dut itself.
4443 */
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304444 if (!strlen(policy->domain_name) &&
4445 add_dscp_policy_rule(dut, policy))
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304446 goto reject;
4447
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304448 /*
4449 * Add the new policy in policy table in granularity increasing
4450 * order.
4451 */
4452 current_policy = dut->dscp_policy_table;
4453 prev_policy = NULL;
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304454
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304455 while (current_policy) {
4456 if (current_policy->granularity_score >
4457 policy->granularity_score)
4458 break;
4459
4460 prev_policy = current_policy;
4461 current_policy = current_policy->next;
4462 }
4463
4464 if (prev_policy)
4465 prev_policy->next = policy;
4466 else
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304467 dut->dscp_policy_table = policy;
4468
Shivani Baranwal9cfc8d72021-11-22 11:53:19 +05304469 policy->next = current_policy;
4470
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304471success:
4472 status_list[num_status].status = DSCP_POLICY_SUCCESS;
4473 num_status++;
4474 policy = NULL;
4475 continue;
4476reject:
4477 status_list[num_status].status = DSCP_POLICY_REJECT;
4478 num_status++;
4479 free(policy);
4480 policy = NULL;
4481 }
4482
4483 free_dscp_policy_table(dut);
4484 wpa_ctrl_detach(ctrl);
4485 wpa_ctrl_close(ctrl);
4486
4487 pthread_exit(0);
4488 return NULL;
4489}
4490
4491
4492static void start_dscp_policy_mon_thread(struct sigma_dut *dut)
4493{
4494 /* Create event thread */
4495 pthread_create(&dut->dscp_policy_mon_thread, NULL, &mon_dscp_policies,
4496 (void *) dut);
4497}
4498
4499
4500void stop_dscp_policy_mon_thread(struct sigma_dut *dut)
4501{
4502 if (dut->dscp_policy_mon_thread) {
4503#ifdef ANDROID
4504 /* pthread_cancel not supported in Android */
4505 pthread_kill(dut->dscp_policy_mon_thread, SIGUSR1);
4506#else /* ANDROID */
4507 pthread_cancel(dut->dscp_policy_mon_thread);
4508#endif /* ANDROID */
4509 dut->dscp_policy_mon_thread = 0;
4510 }
4511}
4512
4513
Jouni Malinenf7222712019-06-13 01:50:21 +03004514static enum sigma_cmd_result cmd_sta_associate(struct sigma_dut *dut,
4515 struct sigma_conn *conn,
4516 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004517{
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304518#ifdef NL80211_SUPPORT
4519 const char *intf = get_param(cmd, "Interface");
4520#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004521 const char *ssid = get_param(cmd, "ssid");
4522 const char *wps_param = get_param(cmd, "WPS");
4523 const char *bssid = get_param(cmd, "bssid");
Jouni Malinen46a19b62017-06-23 14:31:27 +03004524 const char *chan = get_param(cmd, "channel");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004525 const char *network_mode = get_param(cmd, "network_mode");
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304526 const char *ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004527 int wps = 0;
Jouni Malinen3c367e82017-06-23 17:01:47 +03004528 char buf[1000], extra[50];
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004529 int e;
4530 enum sigma_cmd_result ret = SUCCESS_SEND_STATUS;
4531 struct wpa_ctrl *ctrl = NULL;
4532 int num_network_not_found = 0;
4533 int num_disconnected = 0;
4534 int tod = -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004535
4536 if (ssid == NULL)
4537 return -1;
4538
Jouni Malinen37d5c692019-08-19 16:56:55 +03004539 dut->server_cert_tod = 0;
4540
Jouni Malinen3c367e82017-06-23 17:01:47 +03004541 if (dut->rsne_override) {
Sunil Dutt44595082018-02-12 19:41:45 +05304542#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004543 if (get_driver_type(dut) == DRIVER_WCN) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05304544 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Sunil Dutt44595082018-02-12 19:41:45 +05304545 dut->config_rsnie = 1;
4546 }
4547#endif /* NL80211_SUPPORT */
Jouni Malinen3c367e82017-06-23 17:01:47 +03004548 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
4549 dut->rsne_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004550 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen3c367e82017-06-23 17:01:47 +03004551 send_resp(dut, conn, SIGMA_ERROR,
4552 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
4553 return 0;
4554 }
4555 }
4556
Jouni Malinen68143132017-09-02 02:34:08 +03004557 if (dut->sae_commit_override) {
4558 snprintf(buf, sizeof(buf), "SET sae_commit_override %s",
4559 dut->sae_commit_override);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004560 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinen68143132017-09-02 02:34:08 +03004561 send_resp(dut, conn, SIGMA_ERROR,
4562 "ErrorCode,Failed to set SAE commit override");
4563 return 0;
4564 }
4565 }
Ankita Bajaj1bde7942018-01-09 19:15:01 +05304566#ifdef ANDROID
4567 if (dut->fils_hlp)
4568 process_fils_hlp(dut);
4569#endif /* ANDROID */
Jouni Malinen68143132017-09-02 02:34:08 +03004570
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004571 if (wps_param &&
4572 (strcmp(wps_param, "1") == 0 || strcasecmp(wps_param, "On") == 0))
4573 wps = 1;
4574
4575 if (wps) {
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004576 if (dut->program == PROGRAM_60GHZ && network_mode &&
4577 strcasecmp(network_mode, "PBSS") == 0 &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004578 set_network(get_station_ifname(dut), dut->infra_network_id,
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02004579 "pbss", "1") < 0)
4580 return -2;
4581
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004582 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
4583 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,WPS "
4584 "parameters not yet set");
4585 return 0;
4586 }
4587 if (dut->wps_method == WFA_CS_WPS_PBC) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004588 if (wpa_command(get_station_ifname(dut), "WPS_PBC") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004589 return -2;
4590 } else {
4591 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
4592 dut->wps_pin);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004593 if (wpa_command(get_station_ifname(dut), buf) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004594 return -2;
4595 }
4596 } else {
vamsi krishna52e16f92017-08-29 12:37:34 +05304597 if (strcmp(ssid, dut->infra_ssid) == 0) {
4598 sigma_dut_print(dut, DUT_MSG_DEBUG,
4599 "sta_associate for the most recently added network");
4600 } else if (find_network(dut, ssid) < 0) {
4601 sigma_dut_print(dut, DUT_MSG_DEBUG,
4602 "sta_associate for a previously stored network profile");
4603 send_resp(dut, conn, SIGMA_ERROR,
4604 "ErrorCode,Profile not found");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004605 return 0;
4606 }
4607
4608 if (bssid &&
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004609 set_network(get_station_ifname(dut), dut->infra_network_id,
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004610 "bssid", bssid) < 0) {
4611 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4612 "Invalid bssid argument");
4613 return 0;
4614 }
4615
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304616 if ((dut->program == PROGRAM_WPA3 &&
4617 dut->sta_associate_wait_connect) ||
4618 dut->program == PROGRAM_QM) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004619 ctrl = open_wpa_mon(get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004620 if (!ctrl)
4621 return ERROR_SEND_STATUS;
4622 }
4623
Jouni Malinen46a19b62017-06-23 14:31:27 +03004624 extra[0] = '\0';
4625 if (chan)
4626 snprintf(extra, sizeof(extra), " freq=%u",
Alexei Avshalom Lazar093569f2018-11-13 14:08:17 +02004627 channel_to_freq(dut, atoi(chan)));
Jouni Malinen46a19b62017-06-23 14:31:27 +03004628 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d%s",
4629 dut->infra_network_id, extra);
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004630 if (wpa_command(get_station_ifname(dut), buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004631 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to select "
4632 "network id %d on %s",
4633 dut->infra_network_id,
Jouni Malinen016ae6c2019-11-04 17:00:01 +02004634 get_station_ifname(dut));
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004635 ret = ERROR_SEND_STATUS;
4636 goto done;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004637 }
4638 }
4639
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004640 if (!ctrl)
4641 return SUCCESS_SEND_STATUS;
4642
4643 /* Wait for connection result to be able to store server certificate
4644 * hash for trust root override testing
4645 * (dev_exec_action,ServerCertTrust). */
4646
4647 for (e = 0; e < 20; e++) {
4648 const char *events[] = {
4649 "CTRL-EVENT-EAP-PEER-CERT",
4650 "CTRL-EVENT-EAP-TLS-CERT-ERROR",
4651 "CTRL-EVENT-DISCONNECTED",
4652 "CTRL-EVENT-CONNECTED",
4653 "CTRL-EVENT-NETWORK-NOT-FOUND",
4654 NULL
4655 };
4656 char buf[1024];
4657 int res;
4658
4659 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
4660 if (res < 0) {
Jouni Malinenf1f16642019-11-15 21:19:04 +02004661 send_resp(dut, conn, SIGMA_COMPLETE,
4662 "Result,Association did not complete");
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004663 ret = STATUS_SENT_ERROR;
4664 break;
4665 }
4666 sigma_dut_print(dut, DUT_MSG_DEBUG, "Connection event: %s",
4667 buf);
4668
4669 if (strstr(buf, "CTRL-EVENT-EAP-PEER-CERT") &&
4670 strstr(buf, " depth=0")) {
4671 char *pos = strstr(buf, " hash=");
4672
4673 if (pos) {
4674 char *end;
4675
Jouni Malinen34b19cb2019-08-16 16:37:17 +03004676 if (strstr(buf, " tod=1"))
4677 tod = 1;
4678 else if (strstr(buf, " tod=2"))
4679 tod = 2;
4680 else
4681 tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004682 sigma_dut_print(dut, DUT_MSG_DEBUG,
4683 "Server certificate TOD policy: %d",
4684 tod);
Jouni Malinen37d5c692019-08-19 16:56:55 +03004685 dut->server_cert_tod = tod;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004686
4687 pos += 6;
4688 end = strchr(pos, ' ');
4689 if (end)
4690 *end = '\0';
4691 strlcpy(dut->server_cert_hash, pos,
4692 sizeof(dut->server_cert_hash));
4693 sigma_dut_print(dut, DUT_MSG_DEBUG,
4694 "Server certificate hash: %s",
4695 dut->server_cert_hash);
4696 }
4697 }
4698
4699 if (strstr(buf, "CTRL-EVENT-EAP-TLS-CERT-ERROR")) {
4700 send_resp(dut, conn, SIGMA_COMPLETE,
4701 "Result,TLS server certificate validation failed");
4702 ret = STATUS_SENT_ERROR;
4703 break;
4704 }
4705
4706 if (strstr(buf, "CTRL-EVENT-NETWORK-NOT-FOUND")) {
4707 num_network_not_found++;
4708
4709 if (num_network_not_found > 2) {
4710 send_resp(dut, conn, SIGMA_COMPLETE,
4711 "Result,Network not found");
4712 ret = STATUS_SENT_ERROR;
4713 break;
4714 }
4715 }
4716
4717 if (strstr(buf, "CTRL-EVENT-DISCONNECTED")) {
4718 num_disconnected++;
4719
4720 if (num_disconnected > 2) {
4721 send_resp(dut, conn, SIGMA_COMPLETE,
4722 "Result,Connection failed");
4723 ret = STATUS_SENT_ERROR;
4724 break;
4725 }
4726 }
4727
4728 if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
4729 if (tod >= 0) {
4730 sigma_dut_print(dut, DUT_MSG_DEBUG,
4731 "Network profile TOD policy update: %d -> %d",
4732 dut->sta_tod_policy, tod);
4733 dut->sta_tod_policy = tod;
4734 }
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304735 if (dut->program == PROGRAM_QM) {
4736 unsigned char iface_mac_addr[ETH_ALEN];
4737 char ipv6[100];
4738
4739 if (get_hwaddr(ifname, iface_mac_addr) < 0) {
4740 sigma_dut_print(dut, DUT_MSG_ERROR,
4741 "%s: get_hwaddr %s failed",
4742 __func__, ifname);
4743 ret = ERROR_SEND_STATUS;
4744 break;
4745 }
4746
4747 convert_mac_addr_to_ipv6_lladdr(iface_mac_addr,
4748 ipv6,
4749 sizeof(ipv6));
4750
4751 if (set_ipv6_addr(dut, ipv6, "64", ifname) !=
4752 0) {
4753 ret = ERROR_SEND_STATUS;
4754 break;
4755 }
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05304756 start_dscp_policy_mon_thread(dut);
Veerendranath Jakkama082e342020-05-16 00:19:21 +05304757 }
Jouni Malinen134fe3c2019-06-12 04:16:49 +03004758 break;
4759 }
4760 }
4761done:
4762 if (ctrl) {
4763 wpa_ctrl_detach(ctrl);
4764 wpa_ctrl_close(ctrl);
4765 }
4766 return ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02004767}
4768
4769
4770static int run_hs20_osu(struct sigma_dut *dut, const char *params)
4771{
4772 char buf[500], cmd[200];
4773 int res;
4774
4775 /* Use hs20-osu-client file at the current dir, if found; otherwise use
4776 * default path */
4777 res = snprintf(cmd, sizeof(cmd),
4778 "%s -w \"%s\" -r hs20-osu-client.res %s%s -dddKt -f Logs/hs20-osu-client.txt",
4779 file_exists("./hs20-osu-client") ?
4780 "./hs20-osu-client" : "hs20-osu-client",
4781 sigma_wpas_ctrl,
4782 dut->summary_log ? "-s " : "",
4783 dut->summary_log ? dut->summary_log : "");
4784 if (res < 0 || res >= (int) sizeof(cmd))
4785 return -1;
4786
4787 res = snprintf(buf, sizeof(buf), "%s %s", cmd, params);
4788 if (res < 0 || res >= (int) sizeof(buf))
4789 return -1;
4790 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
4791
4792 if (system(buf) != 0) {
4793 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s", buf);
4794 return -1;
4795 }
4796 sigma_dut_print(dut, DUT_MSG_DEBUG,
4797 "Completed hs20-osu-client operation");
4798
4799 return 0;
4800}
4801
4802
4803static int download_ppsmo(struct sigma_dut *dut,
4804 struct sigma_conn *conn,
4805 const char *intf,
4806 struct sigma_cmd *cmd)
4807{
4808 const char *name, *path, *val;
4809 char url[500], buf[600], fbuf[100];
4810 char *fqdn = NULL;
4811
4812 name = get_param(cmd, "FileName");
4813 path = get_param(cmd, "FilePath");
4814 if (name == NULL || path == NULL)
4815 return -1;
4816
4817 if (strcasecmp(path, "VendorSpecific") == 0) {
4818 snprintf(url, sizeof(url), "PPS/%s", name);
4819 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured PPS MO "
4820 "from the device (%s)", url);
4821 if (!file_exists(url)) {
4822 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
4823 "PPS MO file does not exist");
4824 return 0;
4825 }
4826 snprintf(buf, sizeof(buf), "cp %s pps-tnds.xml", url);
4827 if (system(buf) != 0) {
4828 send_resp(dut, conn, SIGMA_ERROR,
4829 "errorCode,Failed to copy PPS MO");
4830 return 0;
4831 }
4832 } else if (strncasecmp(path, "http:", 5) != 0 &&
4833 strncasecmp(path, "https:", 6) != 0) {
4834 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
4835 "Unsupported FilePath value");
4836 return 0;
4837 } else {
4838 snprintf(url, sizeof(url), "%s/%s", path, name);
4839 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading PPS MO from %s",
4840 url);
4841 snprintf(buf, sizeof(buf), "wget -T 10 -t 3 -O pps-tnds.xml '%s'", url);
4842 remove("pps-tnds.xml");
4843 if (system(buf) != 0) {
4844 send_resp(dut, conn, SIGMA_ERROR,
4845 "errorCode,Failed to download PPS MO");
4846 return 0;
4847 }
4848 }
4849
4850 if (run_hs20_osu(dut, "from_tnds pps-tnds.xml pps.xml") < 0) {
4851 send_resp(dut, conn, SIGMA_ERROR,
4852 "errorCode,Failed to parse downloaded PPSMO");
4853 return 0;
4854 }
4855 unlink("pps-tnds.xml");
4856
4857 val = get_param(cmd, "managementTreeURI");
4858 if (val) {
4859 const char *pos, *end;
4860 sigma_dut_print(dut, DUT_MSG_DEBUG, "managementTreeURI: %s",
4861 val);
4862 if (strncmp(val, "./Wi-Fi/", 8) != 0) {
4863 send_resp(dut, conn, SIGMA_ERROR,
4864 "errorCode,Invalid managementTreeURI prefix");
4865 return 0;
4866 }
4867 pos = val + 8;
4868 end = strchr(pos, '/');
4869 if (end == NULL ||
4870 strcmp(end, "/PerProviderSubscription") != 0) {
4871 send_resp(dut, conn, SIGMA_ERROR,
4872 "errorCode,Invalid managementTreeURI postfix");
4873 return 0;
4874 }
4875 if (end - pos >= (int) sizeof(fbuf)) {
4876 send_resp(dut, conn, SIGMA_ERROR,
4877 "errorCode,Too long FQDN in managementTreeURI");
4878 return 0;
4879 }
4880 memcpy(fbuf, pos, end - pos);
4881 fbuf[end - pos] = '\0';
4882 fqdn = fbuf;
4883 sigma_dut_print(dut, DUT_MSG_INFO,
4884 "FQDN from managementTreeURI: %s", fqdn);
4885 } else if (run_hs20_osu(dut, "get_fqdn pps.xml") == 0) {
4886 FILE *f = fopen("pps-fqdn", "r");
4887 if (f) {
4888 if (fgets(fbuf, sizeof(fbuf), f)) {
4889 fbuf[sizeof(fbuf) - 1] = '\0';
4890 fqdn = fbuf;
4891 sigma_dut_print(dut, DUT_MSG_DEBUG,
4892 "Use FQDN %s", fqdn);
4893 }
4894 fclose(f);
4895 }
4896 }
4897
4898 if (fqdn == NULL) {
4899 send_resp(dut, conn, SIGMA_ERROR,
4900 "errorCode,No FQDN specified");
4901 return 0;
4902 }
4903
4904 mkdir("SP", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4905 snprintf(buf, sizeof(buf), "SP/%s", fqdn);
4906 mkdir(buf, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
4907
4908 snprintf(buf, sizeof(buf), "SP/%s/pps.xml", fqdn);
4909 if (rename("pps.xml", buf) < 0) {
4910 send_resp(dut, conn, SIGMA_ERROR,
4911 "errorCode,Could not move PPS MO");
4912 return 0;
4913 }
4914
4915 if (strcasecmp(path, "VendorSpecific") == 0) {
4916 snprintf(buf, sizeof(buf), "cp Certs/ca.pem SP/%s/ca.pem",
4917 fqdn);
4918 if (system(buf)) {
4919 send_resp(dut, conn, SIGMA_ERROR,
4920 "errorCode,Failed to copy OSU CA cert");
4921 return 0;
4922 }
4923
4924 snprintf(buf, sizeof(buf),
4925 "cp Certs/aaa-ca.pem SP/%s/aaa-ca.pem",
4926 fqdn);
4927 if (system(buf)) {
4928 send_resp(dut, conn, SIGMA_ERROR,
4929 "errorCode,Failed to copy AAA CA cert");
4930 return 0;
4931 }
4932 } else {
4933 snprintf(buf, sizeof(buf),
4934 "dl_osu_ca SP/%s/pps.xml SP/%s/ca.pem",
4935 fqdn, fqdn);
4936 if (run_hs20_osu(dut, buf) < 0) {
4937 send_resp(dut, conn, SIGMA_ERROR,
4938 "errorCode,Failed to download OSU CA cert");
4939 return 0;
4940 }
4941
4942 snprintf(buf, sizeof(buf),
4943 "dl_aaa_ca SP/%s/pps.xml SP/%s/aaa-ca.pem",
4944 fqdn, fqdn);
4945 if (run_hs20_osu(dut, buf) < 0) {
4946 sigma_dut_print(dut, DUT_MSG_INFO,
4947 "Failed to download AAA CA cert");
4948 }
4949 }
4950
4951 if (file_exists("next-client-cert.pem")) {
4952 snprintf(buf, sizeof(buf), "SP/%s/client-cert.pem", fqdn);
4953 if (rename("next-client-cert.pem", buf) < 0) {
4954 send_resp(dut, conn, SIGMA_ERROR,
4955 "errorCode,Could not move client certificate");
4956 return 0;
4957 }
4958 }
4959
4960 if (file_exists("next-client-key.pem")) {
4961 snprintf(buf, sizeof(buf), "SP/%s/client-key.pem", fqdn);
4962 if (rename("next-client-key.pem", buf) < 0) {
4963 send_resp(dut, conn, SIGMA_ERROR,
4964 "errorCode,Could not move client key");
4965 return 0;
4966 }
4967 }
4968
4969 snprintf(buf, sizeof(buf), "set_pps SP/%s/pps.xml", fqdn);
4970 if (run_hs20_osu(dut, buf) < 0) {
4971 send_resp(dut, conn, SIGMA_ERROR,
4972 "errorCode,Failed to configure credential from "
4973 "PPSMO");
4974 return 0;
4975 }
4976
4977 return 1;
4978}
4979
4980
4981static int download_cert(struct sigma_dut *dut,
4982 struct sigma_conn *conn,
4983 const char *intf,
4984 struct sigma_cmd *cmd)
4985{
4986 const char *name, *path;
4987 char url[500], buf[600];
4988
4989 name = get_param(cmd, "FileName");
4990 path = get_param(cmd, "FilePath");
4991 if (name == NULL || path == NULL)
4992 return -1;
4993
4994 if (strcasecmp(path, "VendorSpecific") == 0) {
4995 snprintf(url, sizeof(url), "Certs/%s-cert.pem", name);
4996 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
4997 "certificate from the device (%s)", url);
4998 if (!file_exists(url)) {
4999 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
5000 "certificate file does not exist");
5001 return 0;
5002 }
5003 snprintf(buf, sizeof(buf), "cp %s next-client-cert.pem", url);
5004 if (system(buf) != 0) {
5005 send_resp(dut, conn, SIGMA_ERROR,
5006 "errorCode,Failed to copy client "
5007 "certificate");
5008 return 0;
5009 }
5010
5011 snprintf(url, sizeof(url), "Certs/%s-key.pem", name);
5012 sigma_dut_print(dut, DUT_MSG_INFO, "Use pre-configured client "
5013 "private key from the device (%s)", url);
5014 if (!file_exists(url)) {
5015 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Requested "
5016 "private key file does not exist");
5017 return 0;
5018 }
5019 snprintf(buf, sizeof(buf), "cp %s next-client-key.pem", url);
5020 if (system(buf) != 0) {
5021 send_resp(dut, conn, SIGMA_ERROR,
5022 "errorCode,Failed to copy client key");
5023 return 0;
5024 }
5025 } else if (strncasecmp(path, "http:", 5) != 0 &&
5026 strncasecmp(path, "https:", 6) != 0) {
5027 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,"
5028 "Unsupported FilePath value");
5029 return 0;
5030 } else {
5031 snprintf(url, sizeof(url), "%s/%s.pem", path, name);
5032 sigma_dut_print(dut, DUT_MSG_INFO, "Downloading client "
5033 "certificate/key from %s", url);
5034 snprintf(buf, sizeof(buf),
5035 "wget -T 10 -t 3 -O next-client-cert.pem '%s'", url);
5036 if (system(buf) != 0) {
5037 send_resp(dut, conn, SIGMA_ERROR,
5038 "errorCode,Failed to download client "
5039 "certificate");
5040 return 0;
5041 }
5042
5043 if (system("cp next-client-cert.pem next-client-key.pem") != 0)
5044 {
5045 send_resp(dut, conn, SIGMA_ERROR,
5046 "errorCode,Failed to copy client key");
5047 return 0;
5048 }
5049 }
5050
5051 return 1;
5052}
5053
5054
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005055static int cmd_sta_preset_testparameters_60ghz(struct sigma_dut *dut,
5056 struct sigma_conn *conn,
5057 struct sigma_cmd *cmd)
5058{
5059 const char *val;
5060 const char *intf = get_param(cmd, "interface");
5061
5062 if (!intf)
5063 return -1;
5064
5065 val = get_param(cmd, "WscIEFragment");
5066 if (val && strcasecmp(val, "enable") == 0) {
5067 sigma_dut_print(dut, DUT_MSG_DEBUG,
5068 "Enable WSC IE fragmentation");
5069
5070 dut->wsc_fragment = 1;
5071 /* set long attributes to force fragmentation */
5072 if (wpa_command(intf, "SET device_name "
5073 WPS_LONG_DEVICE_NAME) < 0)
5074 return -2;
5075 if (wpa_command(intf, "SET manufacturer "
5076 WPS_LONG_MANUFACTURER) < 0)
5077 return -2;
5078 if (wpa_command(intf, "SET model_name "
5079 WPS_LONG_MODEL_NAME) < 0)
5080 return -2;
5081 if (wpa_command(intf, "SET model_number "
5082 WPS_LONG_MODEL_NUMBER) < 0)
5083 return -2;
5084 if (wpa_command(intf, "SET serial_number "
5085 WPS_LONG_SERIAL_NUMBER) < 0)
5086 return -2;
5087 }
5088
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02005089 val = get_param(cmd, "RSN_IE");
5090 if (val) {
5091 if (strcasecmp(val, "disable") == 0)
5092 dut->force_rsn_ie = FORCE_RSN_IE_REMOVE;
5093 else if (strcasecmp(val, "enable") == 0)
5094 dut->force_rsn_ie = FORCE_RSN_IE_ADD;
5095 }
5096
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02005097 val = get_param(cmd, "WpsVersion");
5098 if (val)
5099 dut->wps_forced_version = get_wps_forced_version(dut, val);
5100
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02005101 val = get_param(cmd, "WscEAPFragment");
5102 if (val && strcasecmp(val, "enable") == 0)
5103 dut->eap_fragment = 1;
5104
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005105 return 1;
5106}
5107
5108
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005109static int cmd_sta_preset_testparameters_hs2_r2(struct sigma_dut *dut,
5110 struct sigma_conn *conn,
5111 const char *intf,
5112 struct sigma_cmd *cmd)
5113{
5114 const char *val;
5115
5116 val = get_param(cmd, "FileType");
5117 if (val && strcasecmp(val, "PPSMO") == 0)
5118 return download_ppsmo(dut, conn, intf, cmd);
5119 if (val && strcasecmp(val, "CERT") == 0)
5120 return download_cert(dut, conn, intf, cmd);
5121 if (val) {
5122 send_resp(dut, conn, SIGMA_ERROR,
5123 "ErrorCode,Unsupported FileType");
5124 return 0;
5125 }
5126
5127 return 1;
5128}
5129
5130
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305131static int cmd_sta_preset_testparameters_oce(struct sigma_dut *dut,
5132 struct sigma_conn *conn,
5133 const char *intf,
5134 struct sigma_cmd *cmd)
5135{
5136 const char *val;
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305137 char buf[1000];
5138 char text[20];
5139 unsigned char addr[ETH_ALEN];
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305140
5141 val = get_param(cmd, "OCESupport");
5142 if (val && strcasecmp(val, "Disable") == 0) {
5143 if (wpa_command(intf, "SET oce 0") < 0) {
5144 send_resp(dut, conn, SIGMA_ERROR,
5145 "ErrorCode,Failed to disable OCE");
5146 return 0;
5147 }
5148 } else if (val && strcasecmp(val, "Enable") == 0) {
5149 if (wpa_command(intf, "SET oce 1") < 0) {
5150 send_resp(dut, conn, SIGMA_ERROR,
5151 "ErrorCode,Failed to enable OCE");
5152 return 0;
5153 }
5154 }
5155
vamsi krishnaa2799492017-12-05 14:28:01 +05305156 val = get_param(cmd, "FILScap");
5157 if (val && (atoi(val) == 1)) {
5158 if (wpa_command(intf, "SET disable_fils 0") < 0) {
5159 send_resp(dut, conn, SIGMA_ERROR,
5160 "ErrorCode,Failed to enable FILS");
5161 return 0;
5162 }
5163 } else if (val && (atoi(val) == 0)) {
5164 if (wpa_command(intf, "SET disable_fils 1") < 0) {
5165 send_resp(dut, conn, SIGMA_ERROR,
5166 "ErrorCode,Failed to disable FILS");
5167 return 0;
5168 }
5169 }
5170
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305171 val = get_param(cmd, "FILSHLP");
5172 if (val && strcasecmp(val, "Enable") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02005173 if (get_wpa_status(get_station_ifname(dut), "address", text,
Ankita Bajaj1bde7942018-01-09 19:15:01 +05305174 sizeof(text)) < 0)
5175 return -2;
5176 hwaddr_aton(text, addr);
5177 snprintf(buf, sizeof(buf),
5178 "FILS_HLP_REQ_ADD ff:ff:ff:ff:ff:ff "
5179 "080045100140000040004011399e00000000ffffffff00440043"
5180 "012cb30001010600fd4f46410000000000000000000000000000"
5181 "000000000000"
5182 "%02x%02x%02x%02x%02x%02x"
5183 "0000000000000000000000000000000000000000000000000000"
5184 "0000000000000000000000000000000000000000000000000000"
5185 "0000000000000000000000000000000000000000000000000000"
5186 "0000000000000000000000000000000000000000000000000000"
5187 "0000000000000000000000000000000000000000000000000000"
5188 "0000000000000000000000000000000000000000000000000000"
5189 "0000000000000000000000000000000000000000000000000000"
5190 "0000000000000000000000000000000000000000638253633501"
5191 "013d0701000af549d29b390205dc3c12616e64726f69642d6468"
5192 "63702d382e302e30370a0103060f1a1c333a3b2b5000ff00",
5193 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
5194 if (wpa_command(intf, buf)) {
5195 send_resp(dut, conn, SIGMA_ERROR,
5196 "ErrorCode,Failed to add HLP");
5197 return 0;
5198 }
5199 dut->fils_hlp = 1;
5200 }
5201
Ankita Bajaja2cb5672017-10-25 16:08:28 +05305202 return 1;
5203}
5204
5205
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005206static void ath_sta_set_noack(struct sigma_dut *dut, const char *intf,
5207 const char *val)
5208{
5209 int counter = 0;
5210 char token[50];
5211 char *result;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305212 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005213
Peng Xub8fc5cc2017-05-10 17:27:28 -07005214 strlcpy(token, val, sizeof(token));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005215 token[sizeof(token) - 1] = '\0';
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305216 result = strtok_r(token, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005217 while (result) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005218 if (strcmp(result, "disable") == 0)
5219 run_iwpriv(dut, intf, "noackpolicy %d 1 0", counter);
5220 else
5221 run_iwpriv(dut, intf, "noackpolicy %d 1 1", counter);
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05305222 result = strtok_r(NULL, ":", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005223 counter++;
5224 }
5225}
5226
5227
5228static void ath_sta_set_rts(struct sigma_dut *dut, const char *intf,
5229 const char *val)
5230{
5231 char buf[100];
5232
5233 snprintf(buf, sizeof(buf), "iwconfig %s rts %s", intf, val);
5234 if (system(buf) != 0) {
5235 sigma_dut_print(dut, DUT_MSG_ERROR, "iwconfig RTS failed");
5236 }
5237}
5238
5239
5240static void ath_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5241 const char *val)
5242{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005243 if (strcasecmp(val, "off") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005244 run_iwpriv(dut, intf, "wmm 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005245 }
5246}
5247
5248
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005249static int wcn_sta_set_wmm(struct sigma_dut *dut, const char *intf,
5250 const char *val)
5251{
5252#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005253 int wmmenable = 1;
5254
5255 if (val &&
5256 (strcasecmp(val, "off") == 0 || strcmp(val, "0") == 0))
5257 wmmenable = 0;
5258
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305259 return wcn_wifi_test_config_set_u8(
5260 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE,
5261 wmmenable);
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08005262#else /* NL80211_SUPPORT */
5263 sigma_dut_print(dut, DUT_MSG_ERROR,
5264 "WMM cannot be changed without NL80211_SUPPORT defined");
5265 return -1;
5266#endif /* NL80211_SUPPORT */
5267}
5268
5269
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005270static void ath_sta_set_sgi(struct sigma_dut *dut, const char *intf,
5271 const char *val)
5272{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005273 int sgi20;
5274
5275 sgi20 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
5276
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005277 run_iwpriv(dut, intf, "shortgi %d", sgi20);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005278}
5279
5280
5281static void ath_sta_set_11nrates(struct sigma_dut *dut, const char *intf,
5282 const char *val)
5283{
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305284 int rate_code, v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005285
5286 /* Disable Tx Beam forming when using a fixed rate */
5287 ath_disable_txbf(dut, intf);
5288
Pradeep Reddy POTTETI67376b72016-10-25 20:08:17 +05305289 v = atoi(val);
5290 if (v < 0 || v > 32) {
5291 sigma_dut_print(dut, DUT_MSG_ERROR,
5292 "Invalid Fixed MCS rate: %d", v);
5293 return;
5294 }
5295 rate_code = 0x80 + v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005296
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005297 run_iwpriv(dut, intf, "set11NRates 0x%x", rate_code);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005298
5299 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005300 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005301}
5302
5303
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08005304static void iwpriv_sta_set_amsdu(struct sigma_dut *dut, const char *intf,
5305 const char *val)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005306{
5307 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305308 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005309
5310 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)
5311 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 2", intf);
5312 else
5313 snprintf(buf, sizeof(buf), "iwpriv %s amsdu 1", intf);
5314
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305315 ret = system(buf);
5316#ifdef NL80211_SUPPORT
5317 if (ret) {
5318 int value = (strcasecmp(val, "Enable") == 0) ? 2 : 1;
5319
5320 ret = sta_config_params(dut, intf, STA_SET_TX_MSDU, value);
5321 ret |= sta_config_params(dut, intf, STA_SET_RX_MSDU, value);
5322 }
5323#endif /* NL80211_SUPPORT */
5324 if (ret)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005325 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv amsdu failed");
5326}
5327
5328
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005329static int iwpriv_sta_set_ampdu(struct sigma_dut *dut, const char *intf,
5330 int ampdu)
5331{
5332 char buf[60];
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005333 int maxaggregation = 63;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005334
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08005335 if (ampdu)
5336 ampdu = maxaggregation;
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07005337 snprintf(buf, sizeof(buf), "iwpriv %s ampdu %d", intf, ampdu);
5338 if (system(buf) != 0) {
5339 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv ampdu failed");
5340 return -1;
5341 }
5342
5343 return 0;
5344}
5345
5346
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005347static void ath_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5348 const char *val)
5349{
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005350 run_iwpriv(dut, intf, "tx_stbc %s", val);
5351 run_iwpriv(dut, intf, "rx_stbc %s", val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005352}
5353
5354
5355static int wcn_sta_set_cts_width(struct sigma_dut *dut, const char *intf,
5356 const char *val)
5357{
5358 char buf[60];
5359
Peng Xucc317ed2017-05-18 16:44:37 -07005360 if (strcmp(val, "160") == 0) {
5361 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 5", intf);
5362 } else if (strcmp(val, "80") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005363 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
5364 } else if (strcmp(val, "40") == 0) {
5365 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 2", intf);
5366 } else if (strcmp(val, "20") == 0) {
5367 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 1", intf);
5368 } else if (strcasecmp(val, "Auto") == 0) {
5369 buf[0] = '\0';
5370 } else {
5371 sigma_dut_print(dut, DUT_MSG_ERROR,
5372 "WIDTH/CTS_WIDTH value not supported");
5373 return -1;
5374 }
5375
5376 if (buf[0] != '\0' && system(buf) != 0) {
5377 sigma_dut_print(dut, DUT_MSG_ERROR,
5378 "Failed to set WIDTH/CTS_WIDTH");
5379 return -1;
5380 }
5381
5382 return 0;
5383}
5384
5385
5386int ath_set_width(struct sigma_dut *dut, struct sigma_conn *conn,
5387 const char *intf, const char *val)
5388{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005389 if (strcasecmp(val, "Auto") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005390 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005391 dut->chwidth = 0;
5392 } else if (strcasecmp(val, "20") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005393 run_iwpriv(dut, intf, "chwidth 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005394 dut->chwidth = 0;
5395 } else if (strcasecmp(val, "40") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005396 run_iwpriv(dut, intf, "chwidth 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005397 dut->chwidth = 1;
5398 } else if (strcasecmp(val, "80") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005399 run_iwpriv(dut, intf, "chwidth 2");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005400 dut->chwidth = 2;
5401 } else if (strcasecmp(val, "160") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07005402 run_iwpriv(dut, intf, "chwidth 3");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005403 dut->chwidth = 3;
5404 } else {
5405 send_resp(dut, conn, SIGMA_ERROR,
5406 "ErrorCode,WIDTH not supported");
5407 return -1;
5408 }
5409
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005410 return 0;
5411}
5412
5413
5414static int wcn_sta_set_sp_stream(struct sigma_dut *dut, const char *intf,
5415 const char *val)
5416{
5417 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -07005418 int sta_nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005419
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005420 if (strcmp(val, "1SS") == 0 || strcmp(val, "1") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005421 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005422 sta_nss = 1;
Amarnath Hullur Subramanyamd5374fa2018-02-25 19:00:24 -08005423 } else if (strcmp(val, "2SS") == 0 || strcmp(val, "2") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005424 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
Arif Hussainac6c5112018-05-25 17:34:00 -07005425 sta_nss = 2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005426 } else {
5427 sigma_dut_print(dut, DUT_MSG_ERROR,
5428 "SP_STREAM value not supported");
5429 return -1;
5430 }
5431
5432 if (system(buf) != 0) {
5433 sigma_dut_print(dut, DUT_MSG_ERROR,
5434 "Failed to set SP_STREAM");
5435 return -1;
5436 }
5437
Arif Hussainac6c5112018-05-25 17:34:00 -07005438 dut->sta_nss = sta_nss;
5439
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005440 return 0;
5441}
5442
5443
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305444static void wcn_sta_set_stbc(struct sigma_dut *dut, const char *intf,
5445 const char *val)
5446{
5447 char buf[60];
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305448 int ret;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305449
5450 snprintf(buf, sizeof(buf), "iwpriv %s tx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305451 ret = system(buf);
5452#ifdef NL80211_SUPPORT
5453 if (ret)
5454 ret = sta_config_params(dut, intf, STA_SET_TX_STBC,
5455 strcmp(val, "0") == 0 ? 0 : 1);
5456#endif /* NL80211_SUPPORT */
5457 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305458 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv tx_stbc failed");
5459
5460 snprintf(buf, sizeof(buf), "iwpriv %s rx_stbc %s", intf, val);
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05305461 ret = system(buf);
5462#ifdef NL80211_SUPPORT
5463 if (ret)
5464 ret = sta_config_params(dut, intf, STA_SET_RX_STBC,
5465 strcmp(val, "0") == 0 ? 0 : 1);
5466#endif /* NL80211_SUPPORT */
5467 if (ret)
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05305468 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv rx_stbc failed");
5469}
5470
5471
Ashwini Patil68d02cd2017-01-10 15:39:16 +05305472static int mbo_set_cellular_data_capa(struct sigma_dut *dut,
5473 struct sigma_conn *conn,
5474 const char *intf, int capa)
5475{
5476 char buf[32];
5477
5478 if (capa > 0 && capa < 4) {
5479 snprintf(buf, sizeof(buf), "SET mbo_cell_capa %d", capa);
5480 if (wpa_command(intf, buf) < 0) {
5481 send_resp(dut, conn, SIGMA_ERROR,
5482 "ErrorCode, Failed to set cellular data capability");
5483 return 0;
5484 }
5485 return 1;
5486 }
5487
5488 sigma_dut_print(dut, DUT_MSG_ERROR,
5489 "Invalid Cellular data capability: %d", capa);
5490 send_resp(dut, conn, SIGMA_INVALID,
5491 "ErrorCode,Invalid cellular data capability");
5492 return 0;
5493}
5494
5495
Ashwini Patil9183fdb2017-04-13 16:58:25 +05305496static int mbo_set_roaming(struct sigma_dut *dut, struct sigma_conn *conn,
5497 const char *intf, const char *val)
5498{
5499 if (strcasecmp(val, "Disable") == 0) {
5500 if (wpa_command(intf, "SET roaming 0") < 0) {
5501 send_resp(dut, conn, SIGMA_ERROR,
5502 "ErrorCode,Failed to disable roaming");
5503 return 0;
5504 }
5505 return 1;
5506 }
5507
5508 if (strcasecmp(val, "Enable") == 0) {
5509 if (wpa_command(intf, "SET roaming 1") < 0) {
5510 send_resp(dut, conn, SIGMA_ERROR,
5511 "ErrorCode,Failed to enable roaming");
5512 return 0;
5513 }
5514 return 1;
5515 }
5516
5517 sigma_dut_print(dut, DUT_MSG_ERROR,
5518 "Invalid value provided for roaming: %s", val);
5519 send_resp(dut, conn, SIGMA_INVALID,
5520 "ErrorCode,Unknown value provided for Roaming");
5521 return 0;
5522}
5523
5524
Ashwini Patila75de5a2017-04-13 16:35:05 +05305525static int mbo_set_assoc_disallow(struct sigma_dut *dut,
5526 struct sigma_conn *conn,
5527 const char *intf, const char *val)
5528{
5529 if (strcasecmp(val, "Disable") == 0) {
5530 if (wpa_command(intf, "SET ignore_assoc_disallow 1") < 0) {
5531 send_resp(dut, conn, SIGMA_ERROR,
5532 "ErrorCode,Failed to disable Assoc_disallow");
5533 return 0;
5534 }
5535 return 1;
5536 }
5537
5538 if (strcasecmp(val, "Enable") == 0) {
5539 if (wpa_command(intf, "SET ignore_assoc_disallow 0") < 0) {
5540 send_resp(dut, conn, SIGMA_ERROR,
5541 "ErrorCode,Failed to enable Assoc_disallow");
5542 return 0;
5543 }
5544 return 1;
5545 }
5546
5547 sigma_dut_print(dut, DUT_MSG_ERROR,
5548 "Invalid value provided for Assoc_disallow: %s", val);
5549 send_resp(dut, conn, SIGMA_INVALID,
5550 "ErrorCode,Unknown value provided for Assoc_disallow");
5551 return 0;
5552}
5553
5554
Ashwini Patilc63161e2017-04-13 16:30:23 +05305555static int mbo_set_bss_trans_req(struct sigma_dut *dut, struct sigma_conn *conn,
5556 const char *intf, const char *val)
5557{
5558 if (strcasecmp(val, "Reject") == 0) {
5559 if (wpa_command(intf, "SET reject_btm_req_reason 1") < 0) {
5560 send_resp(dut, conn, SIGMA_ERROR,
5561 "ErrorCode,Failed to Reject BTM Request");
5562 return 0;
5563 }
5564 return 1;
5565 }
5566
5567 if (strcasecmp(val, "Accept") == 0) {
5568 if (wpa_command(intf, "SET reject_btm_req_reason 0") < 0) {
5569 send_resp(dut, conn, SIGMA_ERROR,
5570 "ErrorCode,Failed to Accept BTM Request");
5571 return 0;
5572 }
5573 return 1;
5574 }
5575
5576 sigma_dut_print(dut, DUT_MSG_ERROR,
5577 "Invalid value provided for BSS_Transition: %s", val);
5578 send_resp(dut, conn, SIGMA_INVALID,
5579 "ErrorCode,Unknown value provided for BSS_Transition");
5580 return 0;
5581}
5582
5583
Ashwini Patil00402582017-04-13 12:29:39 +05305584static int mbo_set_non_pref_ch_list(struct sigma_dut *dut,
5585 struct sigma_conn *conn,
5586 const char *intf,
5587 struct sigma_cmd *cmd)
5588{
5589 const char *ch, *pref, *op_class, *reason;
5590 char buf[120];
5591 int len, ret;
5592
5593 pref = get_param(cmd, "Ch_Pref");
5594 if (!pref)
5595 return 1;
5596
5597 if (strcasecmp(pref, "clear") == 0) {
5598 free(dut->non_pref_ch_list);
5599 dut->non_pref_ch_list = NULL;
5600 } else {
5601 op_class = get_param(cmd, "Ch_Op_Class");
5602 if (!op_class) {
5603 send_resp(dut, conn, SIGMA_INVALID,
5604 "ErrorCode,Ch_Op_Class not provided");
5605 return 0;
5606 }
5607
5608 ch = get_param(cmd, "Ch_Pref_Num");
5609 if (!ch) {
5610 send_resp(dut, conn, SIGMA_INVALID,
5611 "ErrorCode,Ch_Pref_Num not provided");
5612 return 0;
5613 }
5614
5615 reason = get_param(cmd, "Ch_Reason_Code");
5616 if (!reason) {
5617 send_resp(dut, conn, SIGMA_INVALID,
5618 "ErrorCode,Ch_Reason_Code not provided");
5619 return 0;
5620 }
5621
5622 if (!dut->non_pref_ch_list) {
5623 dut->non_pref_ch_list =
5624 calloc(1, NON_PREF_CH_LIST_SIZE);
5625 if (!dut->non_pref_ch_list) {
5626 send_resp(dut, conn, SIGMA_ERROR,
5627 "ErrorCode,Failed to allocate memory for non_pref_ch_list");
5628 return 0;
5629 }
5630 }
5631 len = strlen(dut->non_pref_ch_list);
5632 ret = snprintf(dut->non_pref_ch_list + len,
5633 NON_PREF_CH_LIST_SIZE - len,
5634 " %s:%s:%s:%s", op_class, ch, pref, reason);
5635 if (ret > 0 && ret < NON_PREF_CH_LIST_SIZE - len) {
5636 sigma_dut_print(dut, DUT_MSG_DEBUG, "non_pref_list: %s",
5637 dut->non_pref_ch_list);
5638 } else {
5639 sigma_dut_print(dut, DUT_MSG_ERROR,
5640 "snprintf failed for non_pref_list, ret = %d",
5641 ret);
5642 send_resp(dut, conn, SIGMA_ERROR,
5643 "ErrorCode,snprintf failed");
5644 free(dut->non_pref_ch_list);
5645 dut->non_pref_ch_list = NULL;
5646 return 0;
5647 }
5648 }
5649
5650 ret = snprintf(buf, sizeof(buf), "SET non_pref_chan%s",
5651 dut->non_pref_ch_list ? dut->non_pref_ch_list : " ");
5652 if (ret < 0 || ret >= (int) sizeof(buf)) {
5653 sigma_dut_print(dut, DUT_MSG_DEBUG,
5654 "snprintf failed for set non_pref_chan, ret: %d",
5655 ret);
5656 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,snprint failed");
5657 return 0;
5658 }
5659
5660 if (wpa_command(intf, buf) < 0) {
5661 send_resp(dut, conn, SIGMA_ERROR,
5662 "ErrorCode,Failed to set non-preferred channel list");
5663 return 0;
5664 }
5665
5666 return 1;
5667}
5668
5669
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005670#ifdef NL80211_SUPPORT
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005671
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005672static int sta_set_he_htc_supp(struct sigma_dut *dut, const char *intf,
5673 uint8_t cfg)
5674{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305675 return wcn_wifi_test_config_set_u8(
5676 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP,
5677 cfg);
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08005678}
5679
5680
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005681static int sta_set_he_fragmentation(struct sigma_dut *dut, const char *intf,
5682 enum he_fragmentation_val frag)
5683{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305684 return wcn_wifi_test_config_set_u8(
5685 dut, intf,
5686 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION, frag);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005687}
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005688
5689
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08005690int wcn_set_he_ltf(struct sigma_dut *dut, const char *intf,
5691 enum qca_wlan_he_ltf_cfg ltf)
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005692{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05305693 return wcn_wifi_test_config_set_u8(
5694 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF, ltf);
Subhani Shaik8e7a3052018-04-24 14:03:00 -07005695}
5696
5697
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08005698static int nlvendor_sta_set_noack(struct sigma_dut *dut, const char *intf,
5699 int noack, enum qca_wlan_ac_type ac)
5700{
5701 struct nl_msg *msg;
5702 int ret = 0;
5703 struct nlattr *params;
5704 int ifindex;
5705
5706 ifindex = if_nametoindex(intf);
5707 if (ifindex == 0) {
5708 sigma_dut_print(dut, DUT_MSG_ERROR,
5709 "%s: Index for interface %s failed",
5710 __func__, intf);
5711 return -1;
5712 }
5713
5714 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5715 NL80211_CMD_VENDOR)) ||
5716 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
5717 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5718 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5719 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
5720 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
5721 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK,
5722 noack) ||
5723 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC,
5724 ac)) {
5725 sigma_dut_print(dut, DUT_MSG_ERROR,
5726 "%s: err in adding vendor_cmd and vendor_data",
5727 __func__);
5728 nlmsg_free(msg);
5729 return -1;
5730 }
5731 nla_nest_end(msg, params);
5732
5733 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5734 if (ret) {
5735 sigma_dut_print(dut, DUT_MSG_ERROR,
5736 "%s: err in send_and_recv_msgs, ret=%d",
5737 __func__, ret);
5738 }
5739 return ret;
5740}
5741
5742
5743static void wcn_sta_set_noack(struct sigma_dut *dut, const char *intf,
5744 const char *val)
5745{
5746 int noack, ret;
5747 char token[100];
5748 char *result;
5749 char *saveptr;
5750 enum qca_wlan_ac_type ac = QCA_WLAN_AC_BE;
5751
5752 strlcpy(token, val, sizeof(token));
5753 token[sizeof(token) - 1] = '\0';
5754 result = strtok_r(token, ":", &saveptr);
5755 while (result) {
5756 noack = strcasecmp(result, "Disable") != 0;
5757 ret = nlvendor_sta_set_noack(dut, intf, noack, ac);
5758 if (ret) {
5759 sigma_dut_print(dut, DUT_MSG_ERROR,
5760 "nlvendor_sta_set_noack failed for ac:%d, ret:%d",
5761 ac, ret);
5762 }
5763 result = strtok_r(NULL, ":", &saveptr);
5764 ac++;
5765 }
5766}
5767
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305768
5769static int nlvendor_sta_set_phymode(struct sigma_dut *dut, const char *intf,
5770 enum qca_wlan_vendor_phy_mode val)
5771{
5772 struct nl_msg *msg;
5773 struct nlattr *params;
5774 int ifindex, ret;
5775
5776 ifindex = if_nametoindex(intf);
5777 if (ifindex == 0) {
5778 sigma_dut_print(dut, DUT_MSG_ERROR,
5779 "%s: Index for interface %s not found",
5780 __func__, intf);
5781 return -1;
5782 }
5783
5784 msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
5785 NL80211_CMD_VENDOR);
5786 if (!msg) {
5787 sigma_dut_print(dut, DUT_MSG_ERROR,
5788 "%s: err in adding vendor_cmd", __func__);
5789 return -1;
5790 }
5791
5792 if (nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
5793 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
5794 QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION)) {
5795 sigma_dut_print(dut, DUT_MSG_ERROR,
5796 "%s: err in adding vendor_attr", __func__);
5797 nlmsg_free(msg);
5798 return -1;
5799 }
5800
5801 params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
5802 if (!params || nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_PHY_MODE,
5803 val)) {
5804 sigma_dut_print(dut, DUT_MSG_ERROR,
5805 "%s: err in adding vendor_data", __func__);
5806 nlmsg_free(msg);
5807 return -1;
5808 }
5809
5810 nla_nest_end(msg, params);
5811 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
5812 if (ret) {
5813 sigma_dut_print(dut, DUT_MSG_ERROR,
5814 "%s: err in send_and_recv_msgs, ret=%d (%s)",
5815 __func__, ret, strerror(-ret));
5816 return ret;
5817 }
5818
5819 return 0;
5820}
5821
5822
5823static enum qca_wlan_vendor_phy_mode get_qca_vendor_phymode(const char *val)
5824{
5825 if (strcmp(val, "11a") == 0) {
5826 /* IEEE80211_MODE_11A */
5827 return QCA_WLAN_VENDOR_PHY_MODE_11A;
5828 }
5829
5830 if (strcmp(val, "11g") == 0) {
5831 /* IEEE80211_MODE_11G */
5832 return QCA_WLAN_VENDOR_PHY_MODE_11G;
5833 }
5834
5835 if (strcmp(val, "11b") == 0) {
5836 /* IEEE80211_MODE_11B */
5837 return QCA_WLAN_VENDOR_PHY_MODE_11B;
5838 }
5839
5840 if (strcmp(val, "11n") == 0 ||
5841 strcmp(val, "11nl") == 0 ||
5842 strcmp(val, "11nl(nabg)") == 0) {
5843 /* IEEE80211_MODE_11AGN */
5844 return QCA_WLAN_VENDOR_PHY_MODE_11AGN;
5845 }
5846
5847 if (strcmp(val, "11ng") == 0) {
5848 /* IEEE80211_MODE_11NG_HT40 */
5849 return QCA_WLAN_VENDOR_PHY_MODE_11NG_HT40;
5850 }
5851
5852 if (strcmp(val, "AC") == 0 ||
5853 strcasecmp(val, "11AC") == 0) {
5854 /* IEEE80211_MODE_11AC_VHT80 */
5855 return QCA_WLAN_VENDOR_PHY_MODE_11AC_VHT80;
5856 }
5857
5858 if (strcmp(val, "11na") == 0 ||
5859 strcasecmp(val, "11an") == 0) {
5860 /* IEEE80211_MODE_11NA_HT40 */
5861 return QCA_WLAN_VENDOR_PHY_MODE_11NA_HT40;
5862 }
5863
5864 if (strcmp(val, "11ax") == 0 ||
5865 strcmp(val, "auto") == 0) {
5866 /* IEEE80211_MODE_AUTO */
5867 return QCA_WLAN_VENDOR_PHY_MODE_AUTO;
5868 }
5869
5870 return -1;
5871}
5872
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08005873#endif /* NL80211_SUPPORT */
5874
5875
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305876static int get_phymode(const char *val)
5877{
5878 if (strcmp(val, "11a") == 0)
5879 return 1; /* IEEE80211_MODE_11A */
5880 if (strcmp(val, "11g") == 0)
5881 return 3; /* IEEE80211_MODE_11G */
5882 if (strcmp(val, "11b") == 0)
5883 return 2; /* IEEE80211_MODE_11B */
5884 if (strcmp(val, "11n") == 0 ||
5885 strcmp(val, "11nl") == 0 ||
5886 strcmp(val, "11nl(nabg)") == 0)
5887 return 22; /* IEEE80211_MODE_11AGN */
5888 if (strcmp(val, "11ng") == 0)
5889 return 13; /* IEEE80211_MODE_11NG_HT40 */
5890 if (strcmp(val, "AC") == 0 ||
5891 strcasecmp(val, "11AC") == 0)
5892 return 19; /* IEEE80211_MODE_11AC_VHT80 */
5893 if (strcmp(val, "11na") == 0 ||
5894 strcasecmp(val, "11an") == 0)
5895 return 14; /* IEEE80211_MODE_11NA_HT40 */
5896 if (strcmp(val, "11ax") == 0 ||
5897 strcmp(val, "auto") == 0)
5898 return 0; /* IEEE80211_MODE_AUTO */
5899 return -1;
5900}
5901
5902
5903static void sta_set_phymode(struct sigma_dut *dut, const char *intf,
5904 const char *val)
5905{
5906 char buf[100];
5907 int len, phymode;
Vinita S. Maloo7462e812020-05-22 15:16:04 +05305908#ifdef NL80211_SUPPORT
5909 enum qca_wlan_vendor_phy_mode qca_phymode;
5910
5911 qca_phymode = get_qca_vendor_phymode(val);
5912 if (qca_phymode == -1) {
5913 sigma_dut_print(dut, DUT_MSG_DEBUG,
5914 "Ignoring mode change for mode: %s",
5915 val);
5916 return;
5917 }
5918
5919 if (nlvendor_sta_set_phymode(dut, intf, qca_phymode) == 0)
5920 return;
5921#endif /* NL80211_SUPPORT */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05305922
5923 phymode = get_phymode(val);
5924 if (phymode == -1) {
5925 sigma_dut_print(dut, DUT_MSG_DEBUG,
5926 "Ignoring mode change for mode: %s",
5927 val);
5928 return;
5929 }
5930
5931 len = snprintf(buf, sizeof(buf), "iwpriv %s setphymode %d", intf,
5932 phymode);
5933 if (len < 0 || len >= sizeof(buf)) {
5934 sigma_dut_print(dut, DUT_MSG_ERROR,
5935 "Failed to set phymode");
5936 return;
5937 }
5938
5939 if (system(buf) != 0)
5940 sigma_dut_print(dut, DUT_MSG_ERROR,
5941 "iwpriv setting of phymode failed");
5942}
5943
5944
Jouni Malinenf7222712019-06-13 01:50:21 +03005945static enum sigma_cmd_result
5946cmd_sta_preset_testparameters(struct sigma_dut *dut, struct sigma_conn *conn,
5947 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005948{
5949 const char *intf = get_param(cmd, "Interface");
5950 const char *val;
5951
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005952 val = get_param(cmd, "FT_DS");
5953 if (val) {
5954 if (strcasecmp(val, "Enable") == 0) {
5955 dut->sta_ft_ds = 1;
5956 } else if (strcasecmp(val, "Disable") == 0) {
5957 dut->sta_ft_ds = 0;
5958 } else {
5959 send_resp(dut, conn, SIGMA_ERROR,
5960 "errorCode,Unsupported value for FT_DS");
5961 return STATUS_SENT_ERROR;
5962 }
Shivani Baranwal7aa48602021-09-29 10:53:38 +05305963 if (get_driver_type(dut) == DRIVER_WCN &&
5964 sta_config_params(dut, intf, STA_SET_FT_DS,
5965 dut->sta_ft_ds) != 0) {
5966 send_resp(dut, conn, SIGMA_ERROR,
5967 "errorCode,Failed to enable/disable FT_DS");
5968 return STATUS_SENT_ERROR;
5969 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03005970 }
5971
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005972 val = get_param(cmd, "Program");
Jouni Malinen1f6ae642018-06-07 23:56:13 +03005973 if (val && (strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02005974 strcasecmp(val, "HS2-R3") == 0 ||
5975 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005976 return cmd_sta_preset_testparameters_hs2_r2(dut, conn, intf,
5977 cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02005978
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005979 if (val && strcasecmp(val, "LOC") == 0)
5980 return loc_cmd_sta_preset_testparameters(dut, conn, cmd);
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02005981 if (val && strcasecmp(val, "60GHZ") == 0) {
5982 val = get_param(cmd, "WPS");
5983 if (val && strcasecmp(val, "disable") == 0) {
5984 dut->wps_disable = 1;
5985 sigma_dut_print(dut, DUT_MSG_INFO, "WPS disabled");
5986 } else {
5987 /* wps_disable can have other value from the previous
5988 * test, so make sure it has the correct value.
5989 */
5990 dut->wps_disable = 0;
5991 }
5992
5993 val = get_param(cmd, "P2P");
5994 if (val && strcasecmp(val, "disable") == 0)
5995 sigma_dut_print(dut, DUT_MSG_INFO, "P2P disabled");
5996 }
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07005997
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02005998 if (dut->program == PROGRAM_WPS && dut->band == WPS_BAND_60G)
5999 return cmd_sta_preset_testparameters_60ghz(dut, conn, cmd);
6000
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006001#ifdef ANDROID_NAN
6002 if (val && strcasecmp(val, "NAN") == 0)
6003 return nan_cmd_sta_preset_testparameters(dut, conn, cmd);
6004#endif /* ANDROID_NAN */
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07006005#ifdef MIRACAST
6006 if (val && (strcasecmp(val, "WFD") == 0 ||
6007 strcasecmp(val, "DisplayR2") == 0))
6008 return miracast_preset_testparameters(dut, conn, cmd);
6009#endif /* MIRACAST */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006010
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07006011 if (val &&
6012 (strcasecmp(val, "MBO") == 0 || strcasecmp(val, "HE") == 0)) {
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306013 val = get_param(cmd, "Cellular_Data_Cap");
6014 if (val &&
6015 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
6016 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +05306017
6018 val = get_param(cmd, "Ch_Pref");
6019 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
6020 return 0;
6021
Ashwini Patilc63161e2017-04-13 16:30:23 +05306022 val = get_param(cmd, "BSS_Transition");
6023 if (val && mbo_set_bss_trans_req(dut, conn, intf, val) == 0)
6024 return 0;
6025
Ashwini Patila75de5a2017-04-13 16:35:05 +05306026 val = get_param(cmd, "Assoc_Disallow");
6027 if (val && mbo_set_assoc_disallow(dut, conn, intf, val) == 0)
6028 return 0;
6029
Ashwini Patil9183fdb2017-04-13 16:58:25 +05306030 val = get_param(cmd, "Roaming");
6031 if (val && mbo_set_roaming(dut, conn, intf, val) == 0)
6032 return 0;
6033
Ashwini Patil68d02cd2017-01-10 15:39:16 +05306034 return 1;
6035 }
6036
Ankita Bajaja2cb5672017-10-25 16:08:28 +05306037 if (val && strcasecmp(val, "OCE") == 0)
6038 return cmd_sta_preset_testparameters_oce(dut, conn, intf, cmd);
6039
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006040#if 0
6041 val = get_param(cmd, "Supplicant");
6042 if (val && strcasecmp(val, "Default") != 0) {
6043 send_resp(dut, conn, SIGMA_ERROR,
6044 "ErrorCode,Only default(Vendor) supplicant "
6045 "supported");
6046 return 0;
6047 }
6048#endif
6049
6050 val = get_param(cmd, "RTS");
6051 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006052 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006053 case DRIVER_ATHEROS:
6054 ath_sta_set_rts(dut, intf, val);
6055 break;
6056 default:
6057#if 0
6058 send_resp(dut, conn, SIGMA_ERROR,
6059 "ErrorCode,Setting RTS not supported");
6060 return 0;
6061#else
6062 sigma_dut_print(dut, DUT_MSG_DEBUG,
6063 "Setting RTS not supported");
6064 break;
6065#endif
6066 }
6067 }
6068
6069#if 0
6070 val = get_param(cmd, "FRGMNT");
6071 if (val) {
6072 /* TODO */
6073 send_resp(dut, conn, SIGMA_ERROR,
6074 "ErrorCode,Setting FRGMNT not supported");
6075 return 0;
6076 }
6077#endif
6078
6079#if 0
6080 val = get_param(cmd, "Preamble");
6081 if (val) {
6082 /* TODO: Long/Short */
6083 send_resp(dut, conn, SIGMA_ERROR,
6084 "ErrorCode,Setting Preamble not supported");
6085 return 0;
6086 }
6087#endif
6088
6089 val = get_param(cmd, "Mode");
6090 if (val) {
6091 if (strcmp(val, "11b") == 0 ||
6092 strcmp(val, "11g") == 0 ||
6093 strcmp(val, "11a") == 0 ||
6094 strcmp(val, "11n") == 0 ||
6095 strcmp(val, "11ng") == 0 ||
6096 strcmp(val, "11nl") == 0 ||
6097 strcmp(val, "11nl(nabg)") == 0 ||
6098 strcmp(val, "AC") == 0 ||
6099 strcmp(val, "11AC") == 0 ||
6100 strcmp(val, "11ac") == 0 ||
6101 strcmp(val, "11na") == 0 ||
Amarnath Hullur Subramanyamb0db2712018-01-30 19:40:35 -08006102 strcmp(val, "11an") == 0 ||
6103 strcmp(val, "11ax") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006104 /* STA supports all modes by default */
6105 } else {
6106 send_resp(dut, conn, SIGMA_ERROR,
6107 "ErrorCode,Setting Mode not supported");
6108 return 0;
6109 }
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006110
6111 /* Change the mode only in case of testbed for HE program
6112 * and for 11a and 11g modes only. */
6113 if (dut->program == PROGRAM_HE &&
6114 dut->device_type == STA_testbed) {
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05306115 sta_set_phymode(dut, intf, val);
Amarnath Hullur Subramanyam97d0e532018-01-31 02:53:02 -08006116 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006117 }
6118
6119 val = get_param(cmd, "wmm");
6120 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006121 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006122 case DRIVER_ATHEROS:
6123 ath_sta_set_wmm(dut, intf, val);
6124 break;
Amarnath Hullur Subramanyam75214d22018-02-04 19:17:11 -08006125 case DRIVER_WCN:
6126 wcn_sta_set_wmm(dut, intf, val);
6127 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006128 default:
6129 sigma_dut_print(dut, DUT_MSG_DEBUG,
6130 "Setting wmm not supported");
6131 break;
6132 }
6133 }
6134
6135 val = get_param(cmd, "Powersave");
6136 if (val) {
6137 if (strcmp(val, "0") == 0 || strcasecmp(val, "off") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006138 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306139 if (set_power_save_wcn(dut, intf, 2) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006140 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006141 }
6142
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006143 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006144 "P2P_SET ps 0") < 0)
6145 return -2;
6146 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006147 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6148 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006149 } else if (strcmp(val, "1") == 0 ||
6150 strcasecmp(val, "PSPoll") == 0 ||
6151 strcasecmp(val, "on") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006152 if (get_driver_type(dut) == DRIVER_WCN) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +05306153 if (set_power_save_wcn(dut, intf, 1) < 0)
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006154 return 0;
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08006155 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006156 /* Disable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006157 wpa_command(get_station_ifname(dut), "P2P_SET ps 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006158 /* Enable PS-Poll test mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006159 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006160 "P2P_SET ps 97") < 0 ||
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006161 wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006162 "P2P_SET ps 99") < 0)
6163 return -2;
6164 } else if (strcmp(val, "2") == 0 ||
6165 strcasecmp(val, "Fast") == 0) {
6166 /* TODO */
6167 send_resp(dut, conn, SIGMA_ERROR,
6168 "ErrorCode,Powersave=Fast not supported");
6169 return 0;
6170 } else if (strcmp(val, "3") == 0 ||
6171 strcasecmp(val, "PSNonPoll") == 0) {
6172 /* Make sure test modes are disabled */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006173 wpa_command(get_station_ifname(dut), "P2P_SET ps 98");
6174 wpa_command(get_station_ifname(dut), "P2P_SET ps 96");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006175
6176 /* Enable default power save mode */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006177 if (wpa_command(get_station_ifname(dut),
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006178 "P2P_SET ps 1") < 0)
6179 return -2;
6180 } else
6181 return -1;
6182 }
6183
6184 val = get_param(cmd, "NoAck");
6185 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006186 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006187 case DRIVER_ATHEROS:
6188 ath_sta_set_noack(dut, intf, val);
6189 break;
Amarnath Hullur Subramanyamae8a2d92018-03-01 06:32:21 -08006190#ifdef NL80211_SUPPORT
6191 case DRIVER_WCN:
6192 wcn_sta_set_noack(dut, intf, val);
6193 break;
6194#endif /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006195 default:
6196 send_resp(dut, conn, SIGMA_ERROR,
6197 "ErrorCode,Setting NoAck not supported");
6198 return 0;
6199 }
6200 }
6201
6202 val = get_param(cmd, "IgnoreChswitchProhibit");
6203 if (val) {
6204 /* TODO: Enabled/disabled */
6205 if (strcasecmp(val, "Enabled") == 0) {
6206 send_resp(dut, conn, SIGMA_ERROR,
6207 "ErrorCode,Enabling IgnoreChswitchProhibit "
6208 "not supported");
6209 return 0;
6210 }
6211 }
6212
6213 val = get_param(cmd, "TDLS");
6214 if (val) {
6215 if (strcasecmp(val, "Disabled") == 0) {
6216 if (wpa_command(intf, "SET tdls_disabled 1")) {
6217 send_resp(dut, conn, SIGMA_ERROR,
6218 "ErrorCode,Failed to disable TDLS");
6219 return 0;
6220 }
6221 } else if (strcasecmp(val, "Enabled") == 0) {
6222 if (wpa_command(intf, "SET tdls_disabled 0")) {
6223 send_resp(dut, conn, SIGMA_ERROR,
6224 "ErrorCode,Failed to enable TDLS");
6225 return 0;
6226 }
6227 } else {
6228 send_resp(dut, conn, SIGMA_ERROR,
6229 "ErrorCode,Unsupported TDLS value");
6230 return 0;
6231 }
6232 }
6233
6234 val = get_param(cmd, "TDLSmode");
6235 if (val) {
6236 if (strcasecmp(val, "Default") == 0) {
6237 wpa_command(intf, "SET tdls_testing 0");
6238 } else if (strcasecmp(val, "APProhibit") == 0) {
6239 if (wpa_command(intf, "SET tdls_testing 0x400")) {
6240 send_resp(dut, conn, SIGMA_ERROR,
6241 "ErrorCode,Failed to enable ignore "
6242 "APProhibit TDLS mode");
6243 return 0;
6244 }
6245 } else if (strcasecmp(val, "HiLoMac") == 0) {
6246 /* STA should respond with TDLS setup req for a TDLS
6247 * setup req */
6248 if (wpa_command(intf, "SET tdls_testing 0x80")) {
6249 send_resp(dut, conn, SIGMA_ERROR,
6250 "ErrorCode,Failed to enable HiLoMac "
6251 "TDLS mode");
6252 return 0;
6253 }
6254 } else if (strcasecmp(val, "WeakSecurity") == 0) {
6255 /*
6256 * Since all security modes are enabled by default when
6257 * Sigma control is used, there is no need to do
6258 * anything here.
6259 */
6260 } else if (strcasecmp(val, "ExistLink") == 0) {
6261 /*
6262 * Since we allow new TDLS Setup Request even if there
6263 * is an existing link, nothing needs to be done for
6264 * this.
6265 */
6266 } else {
6267 /* TODO:
6268 * ExistLink: STA should send TDLS setup req even if
6269 * direct link already exists
6270 */
6271 send_resp(dut, conn, SIGMA_ERROR,
6272 "ErrorCode,Unsupported TDLSmode value");
6273 return 0;
6274 }
6275 }
6276
6277 val = get_param(cmd, "FakePubKey");
6278 if (val && atoi(val) && wpa_command(intf, "SET wps_corrupt_pkhash 1")) {
6279 send_resp(dut, conn, SIGMA_ERROR,
6280 "ErrorCode,Failed to enable FakePubKey");
6281 return 0;
6282 }
6283
Amarnath Hullur Subramanyamae1042b2018-02-22 21:52:52 -08006284#ifdef NL80211_SUPPORT
6285 val = get_param(cmd, "FrgmntSupport");
6286 if (val) {
6287 if (strcasecmp(val, "Enable") == 0) {
6288 if (sta_set_he_fragmentation(dut, intf,
6289 HE_FRAG_LEVEL1)) {
6290 send_resp(dut, conn, SIGMA_ERROR,
6291 "ErrorCode,Failed to enable HE Fragmentation");
6292 return 0;
6293 }
6294 } else if (strcasecmp(val, "Disable") == 0) {
6295 if (sta_set_he_fragmentation(dut, intf,
6296 HE_FRAG_DISABLE)) {
6297 send_resp(dut, conn, SIGMA_ERROR,
6298 "ErrorCode,Failed to disable HE Fragmentation");
6299 return 0;
6300 }
6301 }
6302 }
6303#endif /* NL80211_SUPPORT */
6304
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306305 val = get_param(cmd, "IncludeMSCSDescriptor");
6306 if (val && strcasecmp(val, "1") == 0) {
6307 char buf[128];
6308 int len;
6309
6310 len = snprintf(buf, sizeof(buf),
Veerendranath Jakkam62cde372020-08-19 18:03:06 +05306311 "MSCS add up_bitmap=F0 up_limit=7 stream_timeout=60000 frame_classifier=045F%032x",
Vinita S. Maloo8a4779c2020-06-22 19:32:37 +05306312 0);
6313
6314 if (len < 0 || len >= sizeof(buf)) {
6315 sigma_dut_print(dut, DUT_MSG_ERROR,
6316 "Failed to build MSCS Descriptor IE");
6317 return ERROR_SEND_STATUS;
6318 }
6319
6320 if (wpa_command(intf, buf) != 0) {
6321 send_resp(dut, conn, SIGMA_ERROR,
6322 "ErrorCode,Failed to include MSCS descriptor");
6323 return STATUS_SENT_ERROR;
6324 }
6325 }
6326
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306327 val = get_param(cmd, "SCSSupport");
6328 if (val) {
6329 char buf[30];
6330 int disable_scs, len;
6331
6332 if (strcasecmp(val, "Enable") == 0) {
6333 disable_scs = 0;
6334 } else if (strcasecmp(val, "Disable") == 0) {
6335 disable_scs = 1;
6336 } else {
6337 sigma_dut_print(dut, DUT_MSG_ERROR,
6338 "Invalid SCSsupport parameter");
6339 return INVALID_SEND_STATUS;
6340 }
6341
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306342 if (disable_scs || dut->prev_disable_scs_support) {
6343 len = snprintf(buf, sizeof(buf),
6344 "SET disable_scs_support %d",
6345 disable_scs);
6346 if (len < 0 || len >= sizeof(buf) ||
6347 wpa_command(intf, buf) != 0) {
6348 send_resp(dut, conn, SIGMA_ERROR,
6349 "ErrorCode,Failed to update SCS support");
6350 return STATUS_SENT_ERROR;
6351 }
6352 dut->prev_disable_scs_support = disable_scs;
Vinita S. Maloo2287f142021-02-01 16:17:09 +05306353 }
6354 }
6355
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306356 val = get_param(cmd, "MSCSSupport");
6357 if (val) {
6358 char buf[30];
6359 int disable_mscs, len;
6360
6361 if (strcasecmp(val, "Enable") == 0) {
6362 disable_mscs = 0;
6363 } else if (strcasecmp(val, "Disable") == 0) {
6364 disable_mscs = 1;
6365 } else {
6366 sigma_dut_print(dut, DUT_MSG_ERROR,
6367 "Invalid MSCSsupport parameter");
6368 return INVALID_SEND_STATUS;
6369 }
6370
Shivani Baranwalebde8f62021-10-19 12:26:02 +05306371 if (disable_mscs || dut->prev_disable_mscs_support) {
6372 len = snprintf(buf, sizeof(buf),
6373 "SET disable_mscs_support %d",
6374 disable_mscs);
6375 if (len < 0 || len >= sizeof(buf) ||
6376 wpa_command(intf, buf) != 0) {
6377 send_resp(dut, conn, SIGMA_ERROR,
6378 "ErrorCode,Failed to update MSCS support");
6379 return STATUS_SENT_ERROR;
6380 }
6381 dut->prev_disable_mscs_support = disable_mscs;
Vinita S. Maloo83dee552021-04-12 16:47:47 +05306382 }
6383 }
6384
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05306385 val = get_param(cmd, "DSCPPolicyCapability");
6386 if (val) {
6387 char buf[35];
6388 int len;
6389
6390 if (strcasecmp(val, "Enable") == 0) {
6391 len = snprintf(buf, sizeof(buf),
6392 "SET enable_dscp_policy_capa 1");
6393 } else if (strcasecmp(val, "Disable") == 0) {
6394 len = snprintf(buf, sizeof(buf),
6395 "SET enable_dscp_policy_capa 0");
6396 } else {
6397 sigma_dut_print(dut, DUT_MSG_ERROR,
6398 "Invalid DSCP policy parameter");
6399 return INVALID_SEND_STATUS;
6400 }
6401
6402 if (len < 0 || len >= sizeof(buf) ||
6403 wpa_command(intf, buf) != 0) {
6404 send_resp(dut, conn, SIGMA_ERROR,
6405 "ErrorCode,Failed to update DSCP policy capability");
6406 return STATUS_SENT_ERROR;
6407 }
6408 }
6409
6410 val = get_param(cmd, "DSCPPolicyRespParams");
6411 if (val) {
6412 if (strcasecmp(val, "RejectAll") == 0) {
6413 dut->reject_dscp_policies = 1;
6414 dut->dscp_reject_resp_code = DSCP_POLICY_REJECT;
6415 } else if (strcasecmp(val, "AcceptAll") == 0) {
6416 dut->reject_dscp_policies = 0;
6417 }
6418 }
6419
6420 val = get_param(cmd, "DSCPPolicyResp_StatusCode");
6421 if (val)
6422 dut->dscp_reject_resp_code = atoi(val);
6423
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006424 return 1;
6425}
6426
6427
6428static const char * ath_get_radio_name(const char *radio_name)
6429{
6430 if (radio_name == NULL)
6431 return "wifi0";
6432 if (strcmp(radio_name, "wifi1") == 0)
6433 return "wifi1";
6434 if (strcmp(radio_name, "wifi2") == 0)
6435 return "wifi2";
6436 return "wifi0";
6437}
6438
6439
6440static void ath_sta_set_txsp_stream(struct sigma_dut *dut, const char *intf,
6441 const char *val)
6442{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006443 unsigned int vht_mcsmap = 0;
6444 int txchainmask = 0;
6445 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6446
6447 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6448 if (dut->testbed_flag_txsp == 1) {
6449 vht_mcsmap = 0xfffc;
6450 dut->testbed_flag_txsp = 0;
6451 } else {
6452 vht_mcsmap = 0xfffe;
6453 }
6454 txchainmask = 1;
6455 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6456 if (dut->testbed_flag_txsp == 1) {
6457 vht_mcsmap = 0xfff0;
6458 dut->testbed_flag_txsp = 0;
6459 } else {
6460 vht_mcsmap = 0xfffa;
6461 }
6462 txchainmask = 3;
6463 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6464 if (dut->testbed_flag_txsp == 1) {
6465 vht_mcsmap = 0xffc0;
6466 dut->testbed_flag_txsp = 0;
6467 } else {
6468 vht_mcsmap = 0xffea;
6469 }
6470 txchainmask = 7;
6471 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6472 if (dut->testbed_flag_txsp == 1) {
6473 vht_mcsmap = 0xff00;
6474 dut->testbed_flag_txsp = 0;
6475 } else {
6476 vht_mcsmap = 0xffaa;
6477 }
6478 txchainmask = 15;
6479 } else {
6480 if (dut->testbed_flag_txsp == 1) {
6481 vht_mcsmap = 0xffc0;
6482 dut->testbed_flag_txsp = 0;
6483 } else {
6484 vht_mcsmap = 0xffea;
6485 }
6486 }
6487
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006488 if (txchainmask)
6489 run_iwpriv(dut, basedev, "txchainmask %d", txchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006490
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006491 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006492}
6493
6494
6495static void ath_sta_set_rxsp_stream(struct sigma_dut *dut, const char *intf,
6496 const char *val)
6497{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006498 unsigned int vht_mcsmap = 0;
6499 int rxchainmask = 0;
6500 const char *basedev = ath_get_radio_name(sigma_radio_ifname[0]);
6501
6502 if (strcasecmp(val, "1") == 0 || strcasecmp(val, "1SS") == 0) {
6503 if (dut->testbed_flag_rxsp == 1) {
6504 vht_mcsmap = 0xfffc;
6505 dut->testbed_flag_rxsp = 0;
6506 } else {
6507 vht_mcsmap = 0xfffe;
6508 }
6509 rxchainmask = 1;
6510 } else if (strcasecmp(val, "2") == 0 || strcasecmp(val, "2SS") == 0) {
6511 if (dut->testbed_flag_rxsp == 1) {
6512 vht_mcsmap = 0xfff0;
6513 dut->testbed_flag_rxsp = 0;
6514 } else {
6515 vht_mcsmap = 0xfffa;
6516 }
6517 rxchainmask = 3;
6518 } else if (strcasecmp(val, "3") == 0 || strcasecmp(val, "3SS") == 0) {
6519 if (dut->testbed_flag_rxsp == 1) {
6520 vht_mcsmap = 0xffc0;
6521 dut->testbed_flag_rxsp = 0;
6522 } else {
6523 vht_mcsmap = 0xffea;
6524 }
6525 rxchainmask = 7;
6526 } else if (strcasecmp(val, "4") == 0 || strcasecmp(val, "4SS") == 0) {
6527 if (dut->testbed_flag_rxsp == 1) {
6528 vht_mcsmap = 0xff00;
6529 dut->testbed_flag_rxsp = 0;
6530 } else {
6531 vht_mcsmap = 0xffaa;
6532 }
6533 rxchainmask = 15;
6534 } else {
6535 if (dut->testbed_flag_rxsp == 1) {
6536 vht_mcsmap = 0xffc0;
6537 dut->testbed_flag_rxsp = 0;
6538 } else {
6539 vht_mcsmap = 0xffea;
6540 }
6541 }
6542
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006543 if (rxchainmask)
6544 run_iwpriv(dut, basedev, "rxchainmask %d", rxchainmask);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006545
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07006546 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006547}
6548
6549
6550void ath_set_zero_crc(struct sigma_dut *dut, const char *val)
6551{
6552 if (strcasecmp(val, "enable") == 0) {
6553 if (system("athdiag --set --address=0x2a204 --and=0xbfffffff")
6554 != 0) {
6555 sigma_dut_print(dut, DUT_MSG_ERROR,
6556 "Disable BB_VHTSIGB_CRC_CALC failed");
6557 }
6558
6559 if (system("athdiag --set --address=0x2a204 --or=0x80000000")
6560 != 0) {
6561 sigma_dut_print(dut, DUT_MSG_ERROR,
6562 "Enable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6563 }
6564 } else {
6565 if (system("athdiag --set --address=0x2a204 --and=0x7fffffff")
6566 != 0) {
6567 sigma_dut_print(dut, DUT_MSG_ERROR,
6568 "Disable FORCE_VHT_SIGB_CRC_VALUE_ZERO failed");
6569 }
6570
6571 if (system("athdiag --set --address=0x2a204 --or=0x40000000")
6572 != 0) {
6573 sigma_dut_print(dut, DUT_MSG_ERROR,
6574 "Enable BB_VHTSIGB_CRC_CALC failed");
6575 }
6576 }
6577}
6578
6579
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006580static int wcn_sta_set_width(struct sigma_dut *dut, const char *intf,
6581 const char *val)
6582{
6583 char buf[60];
6584
Shivani Baranwal2a572842021-09-16 12:27:15 +05306585#ifdef NL80211_SUPPORT
6586 enum nl80211_chan_width qca_channel_width;
6587
6588 if (strcmp(val, "20") == 0) {
6589 qca_channel_width = NL80211_CHAN_WIDTH_20;
6590 dut->chwidth = 0;
6591 } else if (strcmp(val, "40") == 0) {
6592 qca_channel_width = NL80211_CHAN_WIDTH_40;
6593 dut->chwidth = 1;
6594 } else if (strcmp(val, "80") == 0) {
6595 qca_channel_width = NL80211_CHAN_WIDTH_80;
6596 dut->chwidth = 2;
6597 } else if (strcmp(val, "160") == 0) {
6598 qca_channel_width = NL80211_CHAN_WIDTH_160;
6599 dut->chwidth = 3;
6600 } else if (strcasecmp(val, "Auto") == 0) {
6601 return 0;
6602 } else {
6603 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6604 val);
6605 return -1;
6606 }
6607 if (sta_config_params(dut, intf, STA_SET_CHAN_WIDTH,
6608 qca_channel_width) == 0)
6609 return 0;
6610#endif /* NL80211_SUPPORT */
6611
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006612 if (strcmp(val, "20") == 0) {
6613 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 0", intf);
6614 dut->chwidth = 0;
6615 } else if (strcmp(val, "40") == 0) {
6616 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 1", intf);
6617 dut->chwidth = 1;
6618 } else if (strcmp(val, "80") == 0) {
6619 snprintf(buf, sizeof(buf), "iwpriv %s chwidth 2", intf);
6620 dut->chwidth = 2;
Sunil Duttb1cccac2018-05-22 21:03:12 +05306621 } else if (strcasecmp(val, "Auto") == 0) {
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006622 buf[0] = '\0';
6623 } else {
6624 sigma_dut_print(dut, DUT_MSG_ERROR, "WIDTH %s not supported",
6625 val);
6626 return -1;
6627 }
6628
6629 if (buf[0] != '\0' && system(buf) != 0) {
6630 sigma_dut_print(dut, DUT_MSG_ERROR, "iwpriv chwidth failed");
6631 return -1;
6632 }
6633
6634 return 0;
6635}
6636
6637
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006638static int nlvendor_sta_set_addba_reject(struct sigma_dut *dut,
6639 const char *intf, int addbareject)
6640{
6641#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306642 return wcn_wifi_test_config_set_u8(
6643 dut, intf,
6644 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ,
6645 !addbareject);
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006646#else /* NL80211_SUPPORT */
6647 sigma_dut_print(dut, DUT_MSG_ERROR,
6648 "ADDBA_REJECT cannot be set without NL80211_SUPPORT defined");
6649 return -1;
6650#endif /* NL80211_SUPPORT */
6651}
6652
6653
6654static int sta_set_addba_reject(struct sigma_dut *dut, const char *intf,
6655 int addbareject)
6656{
6657 int ret;
6658
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006659 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006660 case DRIVER_WCN:
6661 ret = nlvendor_sta_set_addba_reject(dut, intf, addbareject);
6662 if (ret) {
6663 sigma_dut_print(dut, DUT_MSG_ERROR,
6664 "nlvendor_sta_set_addba_reject failed, ret:%d",
6665 ret);
6666 return ret;
6667 }
6668 break;
6669 default:
6670 sigma_dut_print(dut, DUT_MSG_ERROR,
6671 "errorCode,Unsupported ADDBA_REJECT with the current driver");
6672 ret = -1;
6673 break;
6674 }
6675
6676 return ret;
6677}
6678
6679
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006680static int nlvendor_config_send_addba(struct sigma_dut *dut, const char *intf,
6681 int enable)
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006682{
6683#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05306684 return wcn_wifi_test_config_set_u8(
6685 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ,
6686 enable);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006687#else /* NL80211_SUPPORT */
6688 sigma_dut_print(dut, DUT_MSG_ERROR,
6689 "Disable addba not possible without NL80211_SUPPORT defined");
6690 return -1;
6691#endif /* NL80211_SUPPORT */
6692}
6693
6694
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306695#ifdef NL80211_SUPPORT
6696static int nl80211_sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6697{
6698 struct nl_msg *msg;
6699 int ret = 0;
6700 int ifindex;
6701
6702 ifindex = if_nametoindex(intf);
6703 if (ifindex == 0) {
6704 sigma_dut_print(dut, DUT_MSG_ERROR,
6705 "%s: Index for interface %s failed",
6706 __func__, intf);
6707 return -1;
6708 }
6709
6710 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
6711 NL80211_CMD_SET_WIPHY)) ||
6712 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, val)) {
6713 sigma_dut_print(dut, DUT_MSG_ERROR,
6714 "%s: err in adding RTS threshold",
6715 __func__);
6716 nlmsg_free(msg);
6717 return -1;
6718 }
6719
6720 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
6721 if (ret) {
6722 sigma_dut_print(dut, DUT_MSG_ERROR,
6723 "%s: err in send_and_recv_msgs, ret=%d",
6724 __func__, ret);
6725 }
6726 return ret;
6727}
6728#endif /* NL80211_SUPPORT */
6729
6730
6731static int sta_set_rts(struct sigma_dut *dut, const char *intf, int val)
6732{
6733 char buf[100];
6734
6735#ifdef NL80211_SUPPORT
6736 if (nl80211_sta_set_rts(dut, intf, val) == 0)
6737 return 0;
6738 sigma_dut_print(dut, DUT_MSG_DEBUG,
6739 "Fall back to using iwconfig for setting RTS threshold");
6740#endif /* NL80211_SUPPORT */
6741
6742 snprintf(buf, sizeof(buf), "iwconfig %s rts %d", intf, val);
6743 if (system(buf) != 0) {
6744 sigma_dut_print(dut, DUT_MSG_ERROR,
6745 "Failed to set RTS threshold %d", val);
6746 return -1;
6747 }
6748 return 0;
6749}
6750
6751
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006752static enum sigma_cmd_result
6753cmd_sta_set_wireless_common(const char *intf, struct sigma_dut *dut,
6754 struct sigma_conn *conn, struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006755{
6756 const char *val;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006757 int ampdu = -1, addbareject = -1;
Jouni Malinen3aa72862019-05-29 23:14:51 +03006758 char buf[128];
6759 int res;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006760
6761 val = get_param(cmd, "40_INTOLERANT");
6762 if (val) {
6763 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6764 /* TODO: iwpriv ht40intol through wpa_supplicant */
6765 send_resp(dut, conn, SIGMA_ERROR,
6766 "ErrorCode,40_INTOLERANT not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006767 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006768 }
6769 }
6770
6771 val = get_param(cmd, "ADDBA_REJECT");
6772 if (val) {
6773 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6774 /* reject any ADDBA with status "decline" */
6775 ampdu = 0;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006776 addbareject = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006777 } else {
6778 /* accept ADDBA */
6779 ampdu = 1;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006780 addbareject = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006781 }
6782 }
6783
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006784 if (addbareject >= 0 &&
6785 sta_set_addba_reject(dut, intf, addbareject) < 0) {
6786 send_resp(dut, conn, SIGMA_ERROR,
6787 "ErrorCode,set addba_reject failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006788 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyamd8a9db92018-02-02 18:53:14 -08006789 }
6790
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006791 val = get_param(cmd, "AMPDU");
6792 if (val) {
6793 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
6794 /* enable AMPDU Aggregation */
6795 if (ampdu == 0) {
6796 send_resp(dut, conn, SIGMA_ERROR,
6797 "ErrorCode,Mismatch in "
6798 "addba_reject/ampdu - "
6799 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006800 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006801 }
6802 ampdu = 1;
6803 } else {
6804 /* disable AMPDU Aggregation */
6805 if (ampdu == 1) {
6806 send_resp(dut, conn, SIGMA_ERROR,
6807 "ErrorCode,Mismatch in "
6808 "addba_reject/ampdu - "
6809 "not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006810 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006811 }
6812 ampdu = 0;
6813 }
6814 }
6815
6816 if (ampdu >= 0) {
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006817 int ret;
6818
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006819 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s A-MPDU aggregation",
6820 ampdu ? "Enabling" : "Disabling");
6821 snprintf(buf, sizeof(buf), "SET ampdu %d", ampdu);
Deepak Dhamdhere80356cb2016-03-28 16:48:32 -07006822 if (wpa_command(intf, buf) < 0 &&
6823 iwpriv_sta_set_ampdu(dut, intf, ampdu) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006824 send_resp(dut, conn, SIGMA_ERROR,
6825 "ErrorCode,set aggr failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006826 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006827 }
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006828
6829 if (ampdu == 0) {
6830 /* Disable sending of addba using nl vendor command */
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08006831 ret = nlvendor_config_send_addba(dut, intf, 0);
Amarnath Hullur Subramanyam9745b3c2018-02-04 21:27:57 -08006832 if (ret) {
6833 sigma_dut_print(dut, DUT_MSG_ERROR,
6834 "Failed to disable addba, ret:%d",
6835 ret);
6836 }
6837 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006838 }
6839
6840 val = get_param(cmd, "AMSDU");
6841 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006842 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006843 case DRIVER_ATHEROS:
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08006844 case DRIVER_WCN:
6845 iwpriv_sta_set_amsdu(dut, intf, val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006846 break;
6847 default:
6848 if (strcmp(val, "1") == 0 ||
6849 strcasecmp(val, "Enable") == 0) {
6850 /* Enable AMSDU Aggregation */
6851 send_resp(dut, conn, SIGMA_ERROR,
6852 "ErrorCode,AMSDU aggregation not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006853 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006854 }
6855 break;
6856 }
6857 }
6858
6859 val = get_param(cmd, "STBC_RX");
6860 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006861 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006862 case DRIVER_ATHEROS:
6863 ath_sta_set_stbc(dut, intf, val);
6864 break;
Pradeep Reddy POTTETI4a1f6b32016-11-23 13:15:21 +05306865 case DRIVER_WCN:
6866 wcn_sta_set_stbc(dut, intf, val);
6867 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006868 default:
6869 send_resp(dut, conn, SIGMA_ERROR,
6870 "ErrorCode,STBC_RX not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006871 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006872 }
6873 }
6874
6875 val = get_param(cmd, "WIDTH");
6876 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006877 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006878 case DRIVER_WCN:
Amarnath Hullur Subramanyamebfe6b62018-01-31 03:04:17 -08006879 if (wcn_sta_set_width(dut, intf, val) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006880 send_resp(dut, conn, SIGMA_ERROR,
6881 "ErrorCode,Failed to set WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006882 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006883 }
6884 break;
6885 case DRIVER_ATHEROS:
6886 if (ath_set_width(dut, conn, intf, val) < 0)
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006887 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006888 break;
6889 default:
6890 sigma_dut_print(dut, DUT_MSG_ERROR,
6891 "Setting WIDTH not supported");
6892 break;
6893 }
6894 }
6895
6896 val = get_param(cmd, "SMPS");
6897 if (val) {
6898 /* TODO: Dynamic/0, Static/1, No Limit/2 */
6899 send_resp(dut, conn, SIGMA_ERROR,
6900 "ErrorCode,SMPS not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006901 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006902 }
6903
6904 val = get_param(cmd, "TXSP_STREAM");
6905 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006906 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006907 case DRIVER_WCN:
6908 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6909 send_resp(dut, conn, SIGMA_ERROR,
6910 "ErrorCode,Failed to set TXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006911 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006912 }
6913 break;
6914 case DRIVER_ATHEROS:
6915 ath_sta_set_txsp_stream(dut, intf, val);
6916 break;
6917 default:
6918 sigma_dut_print(dut, DUT_MSG_ERROR,
6919 "Setting TXSP_STREAM not supported");
6920 break;
6921 }
6922 }
6923
6924 val = get_param(cmd, "RXSP_STREAM");
6925 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006926 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006927 case DRIVER_WCN:
6928 if (wcn_sta_set_sp_stream(dut, intf, val) < 0) {
6929 send_resp(dut, conn, SIGMA_ERROR,
6930 "ErrorCode,Failed to set RXSP_STREAM");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006931 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006932 }
6933 break;
6934 case DRIVER_ATHEROS:
6935 ath_sta_set_rxsp_stream(dut, intf, val);
6936 break;
6937 default:
6938 sigma_dut_print(dut, DUT_MSG_ERROR,
6939 "Setting RXSP_STREAM not supported");
6940 break;
6941 }
6942 }
6943
6944 val = get_param(cmd, "DYN_BW_SGNL");
6945 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02006946 switch (get_driver_type(dut)) {
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006947 case DRIVER_WCN:
Peng Xuc59afd32016-11-21 15:01:11 -08006948 if (strcasecmp(val, "enable") == 0) {
6949 snprintf(buf, sizeof(buf),
6950 "iwpriv %s cwmenable 1", intf);
6951 if (system(buf) != 0) {
6952 sigma_dut_print(dut, DUT_MSG_ERROR,
6953 "iwpriv cwmenable 1 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006954 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006955 }
6956 } else if (strcasecmp(val, "disable") == 0) {
6957 snprintf(buf, sizeof(buf),
6958 "iwpriv %s cwmenable 0", intf);
6959 if (system(buf) != 0) {
6960 sigma_dut_print(dut, DUT_MSG_ERROR,
6961 "iwpriv cwmenable 0 failed");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006962 return ERROR_SEND_STATUS;
Peng Xuc59afd32016-11-21 15:01:11 -08006963 }
6964 } else {
6965 sigma_dut_print(dut, DUT_MSG_ERROR,
6966 "Unsupported DYN_BW_SGL");
6967 }
6968
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006969 snprintf(buf, sizeof(buf), "iwpriv %s cts_cbw 3", intf);
6970 if (system(buf) != 0) {
6971 sigma_dut_print(dut, DUT_MSG_ERROR,
6972 "Failed to set cts_cbw in DYN_BW_SGNL");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03006973 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006974 }
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006975 break;
6976 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07006977 novap_reset(dut, intf, 1);
Priyadharshini Gowthaman818afef2015-11-09 13:28:15 -08006978 ath_config_dyn_bw_sig(dut, intf, val);
6979 break;
6980 default:
6981 sigma_dut_print(dut, DUT_MSG_ERROR,
6982 "Failed to set DYN_BW_SGNL");
6983 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006984 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006985 }
6986
6987 val = get_param(cmd, "RTS_FORCE");
6988 if (val) {
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07006989 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02006990 if (strcasecmp(val, "Enable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05306991 if (sta_set_rts(dut, intf, 64) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02006992 sigma_dut_print(dut, DUT_MSG_ERROR,
6993 "Failed to set RTS_FORCE 64");
6994 }
Jouni Malinen3aa72862019-05-29 23:14:51 +03006995 res = snprintf(buf, sizeof(buf),
6996 "wifitool %s beeliner_fw_test 100 1",
6997 intf);
6998 if (res < 0 || res >= sizeof(buf) || system(buf) != 0) {
priyadharshini gowthaman270870e2015-12-09 10:10:23 -08006999 sigma_dut_print(dut, DUT_MSG_ERROR,
7000 "wifitool beeliner_fw_test 100 1 failed");
7001 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007002 } else if (strcasecmp(val, "Disable") == 0) {
Veerendranath Jakkamadcd6202019-04-17 12:32:21 +05307003 if (sta_set_rts(dut, intf, 2347) != 0) {
Priyadharshini Gowthamanabdb2122015-11-17 11:52:19 +02007004 sigma_dut_print(dut, DUT_MSG_ERROR,
7005 "Failed to set RTS_FORCE 2347");
7006 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007007 } else {
7008 send_resp(dut, conn, SIGMA_ERROR,
7009 "ErrorCode,RTS_FORCE value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007010 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007011 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007012 }
7013
7014 val = get_param(cmd, "CTS_WIDTH");
7015 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007016 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007017 case DRIVER_WCN:
7018 if (wcn_sta_set_cts_width(dut, intf, val) < 0) {
7019 send_resp(dut, conn, SIGMA_ERROR,
7020 "ErrorCode,Failed to set CTS_WIDTH");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007021 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007022 }
7023 break;
7024 case DRIVER_ATHEROS:
7025 ath_set_cts_width(dut, intf, val);
7026 break;
7027 default:
7028 sigma_dut_print(dut, DUT_MSG_ERROR,
7029 "Setting CTS_WIDTH not supported");
7030 break;
7031 }
7032 }
7033
7034 val = get_param(cmd, "BW_SGNL");
7035 if (val) {
7036 if (strcasecmp(val, "Enable") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07007037 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007038 } else if (strcasecmp(val, "Disable") == 0) {
7039 /* TODO: Disable */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007040 } else {
7041 send_resp(dut, conn, SIGMA_ERROR,
7042 "ErrorCode,BW_SGNL value not supported");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007043 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007044 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007045 }
7046
7047 val = get_param(cmd, "Band");
7048 if (val) {
7049 if (strcmp(val, "2.4") == 0 || strcmp(val, "5") == 0) {
7050 /* STA supports all bands by default */
7051 } else {
7052 send_resp(dut, conn, SIGMA_ERROR,
7053 "ErrorCode,Unsupported Band");
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007054 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007055 }
7056 }
7057
7058 val = get_param(cmd, "zero_crc");
7059 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007060 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007061 case DRIVER_ATHEROS:
7062 ath_set_zero_crc(dut, val);
7063 break;
7064 default:
7065 break;
7066 }
7067 }
7068
Jouni Malinen3d96a1e2021-06-09 16:45:06 +03007069 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007070}
7071
7072
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007073static int sta_set_force_mcs(struct sigma_dut *dut, int force, int mcs)
7074{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007075 switch (get_driver_type(dut)) {
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007076#ifdef __linux__
7077 case DRIVER_WIL6210:
7078 return wil6210_set_force_mcs(dut, force, mcs);
7079#endif /* __linux__ */
7080 default:
7081 sigma_dut_print(dut, DUT_MSG_ERROR,
7082 "Unsupported sta_set_force_mcs with the current driver");
7083 return -1;
7084 }
7085}
7086
7087
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007088static int sta_60g_force_rsn_ie(struct sigma_dut *dut, int state)
7089{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007090 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02007091#ifdef __linux__
7092 case DRIVER_WIL6210:
7093 return wil6210_force_rsn_ie(dut, state);
7094#endif /* __linux__ */
7095 default:
7096 sigma_dut_print(dut, DUT_MSG_ERROR,
7097 "Unsupported sta_60g_force_rsn_ie with the current driver");
7098 return -1;
7099 }
7100}
7101
7102
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007103static int sta_set_60g_common(struct sigma_dut *dut, struct sigma_conn *conn,
7104 struct sigma_cmd *cmd)
7105{
7106 const char *val;
7107 char buf[100];
7108
7109 val = get_param(cmd, "MSDUSize");
7110 if (val) {
7111 int mtu;
7112
7113 dut->amsdu_size = atoi(val);
7114 if (dut->amsdu_size > IEEE80211_MAX_DATA_LEN_DMG ||
7115 dut->amsdu_size < IEEE80211_SNAP_LEN_DMG) {
7116 sigma_dut_print(dut, DUT_MSG_ERROR,
7117 "MSDUSize %d is above max %d or below min %d",
7118 dut->amsdu_size,
7119 IEEE80211_MAX_DATA_LEN_DMG,
7120 IEEE80211_SNAP_LEN_DMG);
7121 dut->amsdu_size = 0;
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007122 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007123 }
7124
7125 mtu = dut->amsdu_size - IEEE80211_SNAP_LEN_DMG;
7126 sigma_dut_print(dut, DUT_MSG_DEBUG,
7127 "Setting amsdu_size to %d", mtu);
7128 snprintf(buf, sizeof(buf), "ifconfig %s mtu %d",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007129 get_station_ifname(dut), mtu);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007130
7131 if (system(buf) != 0) {
7132 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
7133 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007134 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007135 }
7136 }
7137
7138 val = get_param(cmd, "BAckRcvBuf");
7139 if (val) {
7140 dut->back_rcv_buf = atoi(val);
7141 if (dut->back_rcv_buf == 0) {
7142 sigma_dut_print(dut, DUT_MSG_ERROR,
7143 "Failed to convert %s or value is 0",
7144 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007145 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007146 }
7147
7148 sigma_dut_print(dut, DUT_MSG_DEBUG,
7149 "Setting BAckRcvBuf to %s", val);
7150 }
7151
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007152 val = get_param(cmd, "MCS_FixedRate");
7153 if (val) {
7154 if (sta_set_force_mcs(dut, 1, atoi(val))) {
7155 sigma_dut_print(dut, DUT_MSG_ERROR,
7156 "Failed to force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007157 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02007158 }
7159 }
7160
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007161 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007162}
7163
7164
7165static int sta_pcp_start(struct sigma_dut *dut, struct sigma_conn *conn,
7166 struct sigma_cmd *cmd)
7167{
7168 int net_id;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007169 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007170 const char *val;
7171 char buf[100];
7172
7173 dut->mode = SIGMA_MODE_STATION;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007174 ifname = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007175 if (wpa_command(ifname, "PING") != 0) {
7176 sigma_dut_print(dut, DUT_MSG_ERROR, "Supplicant not running");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007177 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007178 }
7179
7180 wpa_command(ifname, "FLUSH");
7181 net_id = add_network_common(dut, conn, ifname, cmd);
7182 if (net_id < 0) {
7183 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add network");
7184 return net_id;
7185 }
7186
7187 /* TODO: mode=2 for the AP; in the future, replace for mode PCP */
7188 if (set_network(ifname, net_id, "mode", "2") < 0) {
7189 sigma_dut_print(dut, DUT_MSG_ERROR,
7190 "Failed to set supplicant network mode");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007191 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007192 }
7193
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +02007194 if (set_network(ifname, net_id, "pbss", "1") < 0)
7195 return -2;
7196
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007197 sigma_dut_print(dut, DUT_MSG_DEBUG,
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007198 "Supplicant set network with mode 2. network_id %d",
7199 net_id);
7200
7201 if (set_network(ifname, net_id, "wps_disabled", "0") < 0) {
7202 sigma_dut_print(dut, DUT_MSG_INFO,
7203 "Failed to set supplicant to WPS ENABLE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007204 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarfd9f1352018-11-13 14:07:58 +02007205 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007206
7207 val = get_param(cmd, "Security");
7208 if (val && strcasecmp(val, "OPEN") == 0) {
7209 dut->ap_key_mgmt = AP_OPEN;
7210 if (set_network(ifname, net_id, "key_mgmt", "NONE") < 0) {
7211 sigma_dut_print(dut, DUT_MSG_ERROR,
7212 "Failed to set supplicant to %s security",
7213 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007214 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007215 }
7216 } else if (val && strcasecmp(val, "WPA2-PSK") == 0) {
7217 dut->ap_key_mgmt = AP_WPA2_PSK;
7218 if (set_network(ifname, net_id, "key_mgmt", "WPA-PSK") < 0) {
7219 sigma_dut_print(dut, DUT_MSG_ERROR,
7220 "Failed to set supplicant to %s security",
7221 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007222 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007223 }
7224
7225 if (set_network(ifname, net_id, "proto", "RSN") < 0) {
7226 sigma_dut_print(dut, DUT_MSG_ERROR,
7227 "Failed to set supplicant to proto RSN");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007228 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007229 }
7230 } else if (val) {
7231 sigma_dut_print(dut, DUT_MSG_ERROR,
7232 "Requested Security %s is not supported on 60GHz",
7233 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007234 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007235 }
7236
7237 val = get_param(cmd, "Encrypt");
7238 if (val && strcasecmp(val, "AES-GCMP") == 0) {
7239 if (set_network(ifname, net_id, "pairwise", "GCMP") < 0) {
7240 sigma_dut_print(dut, DUT_MSG_ERROR,
7241 "Failed to set supplicant to pairwise GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007242 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007243 }
7244 if (set_network(ifname, net_id, "group", "GCMP") < 0) {
7245 sigma_dut_print(dut, DUT_MSG_ERROR,
7246 "Failed to set supplicant to group GCMP");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007247 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007248 }
7249 } else if (val) {
7250 sigma_dut_print(dut, DUT_MSG_ERROR,
7251 "Requested Encrypt %s is not supported on 60 GHz",
7252 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007253 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007254 }
7255
7256 val = get_param(cmd, "PSK");
7257 if (val && set_network_quoted(ifname, net_id, "psk", val) < 0) {
7258 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set psk %s",
7259 val);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007260 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007261 }
7262
7263 /* Convert 60G channel to freq */
7264 switch (dut->ap_channel) {
7265 case 1:
7266 val = "58320";
7267 break;
7268 case 2:
7269 val = "60480";
7270 break;
7271 case 3:
7272 val = "62640";
7273 break;
7274 default:
7275 sigma_dut_print(dut, DUT_MSG_ERROR,
7276 "Failed to configure channel %d. Not supported",
7277 dut->ap_channel);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007278 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007279 }
7280
7281 if (set_network(ifname, net_id, "frequency", val) < 0) {
7282 sigma_dut_print(dut, DUT_MSG_ERROR,
7283 "Failed to set supplicant network frequency");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007284 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007285 }
7286
Alexei Avshalom Lazar2eccf4d2019-01-31 10:03:59 +02007287 if (dut->eap_fragment) {
7288 sigma_dut_print(dut, DUT_MSG_DEBUG,
7289 "Set EAP fragment size to 128 bytes.");
7290 if (set_network(ifname, net_id, "fragment_size", "128") < 0)
7291 return ERROR_SEND_STATUS;
7292 }
7293
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007294 sigma_dut_print(dut, DUT_MSG_DEBUG,
7295 "Supplicant set network with frequency");
7296
7297 snprintf(buf, sizeof(buf), "SELECT_NETWORK %d", net_id);
7298 if (wpa_command(ifname, buf) < 0) {
7299 sigma_dut_print(dut, DUT_MSG_INFO,
7300 "Failed to select network id %d on %s",
7301 net_id, ifname);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007302 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007303 }
7304
7305 sigma_dut_print(dut, DUT_MSG_DEBUG, "Selected network");
7306
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007307 return SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007308}
7309
7310
Lior David67543f52017-01-03 19:04:22 +02007311static int wil6210_set_abft_len(struct sigma_dut *dut, int abft_len)
7312{
7313 char buf[128], fname[128];
7314 FILE *f;
Jouni Malinen3aa72862019-05-29 23:14:51 +03007315 int res;
Lior David67543f52017-01-03 19:04:22 +02007316
7317 if (wil6210_get_debugfs_dir(dut, buf, sizeof(buf))) {
7318 sigma_dut_print(dut, DUT_MSG_ERROR,
7319 "failed to get wil6210 debugfs dir");
7320 return -1;
7321 }
7322
Jouni Malinen3aa72862019-05-29 23:14:51 +03007323 res = snprintf(fname, sizeof(fname), "%s/abft_len", buf);
7324 if (res < 0 || res >= sizeof(fname))
7325 return -1;
Lior David67543f52017-01-03 19:04:22 +02007326 f = fopen(fname, "w");
7327 if (!f) {
7328 sigma_dut_print(dut, DUT_MSG_ERROR,
7329 "failed to open: %s", fname);
7330 return -1;
7331 }
7332
7333 fprintf(f, "%d\n", abft_len);
7334 fclose(f);
7335
7336 return 0;
7337}
7338
7339
Alexei Avshalom Lazar49498b82019-01-31 15:16:32 +02007340int sta_set_60g_abft_len(struct sigma_dut *dut, struct sigma_conn *conn,
7341 int abft_len)
Lior David67543f52017-01-03 19:04:22 +02007342{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007343 switch (get_driver_type(dut)) {
Lior David67543f52017-01-03 19:04:22 +02007344 case DRIVER_WIL6210:
7345 return wil6210_set_abft_len(dut, abft_len);
7346 default:
7347 sigma_dut_print(dut, DUT_MSG_ERROR,
7348 "set abft_len not supported");
7349 return -1;
7350 }
7351}
7352
7353
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007354static int sta_set_60g_pcp(struct sigma_dut *dut, struct sigma_conn *conn,
7355 struct sigma_cmd *cmd)
7356{
7357 const char *val;
Lior David67543f52017-01-03 19:04:22 +02007358 unsigned int abft_len = 1; /* default is one slot */
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007359
7360 if (dut->dev_role != DEVROLE_PCP) {
7361 send_resp(dut, conn, SIGMA_INVALID,
7362 "ErrorCode,Invalid DevRole");
7363 return 0;
7364 }
7365
7366 val = get_param(cmd, "SSID");
7367 if (val) {
7368 if (strlen(val) > sizeof(dut->ap_ssid) - 1) {
7369 send_resp(dut, conn, SIGMA_INVALID,
7370 "ErrorCode,Invalid SSID");
7371 return -1;
7372 }
7373
Peng Xub8fc5cc2017-05-10 17:27:28 -07007374 strlcpy(dut->ap_ssid, val, sizeof(dut->ap_ssid));
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007375 }
7376
7377 val = get_param(cmd, "CHANNEL");
7378 if (val) {
7379 const char *pos;
7380
7381 dut->ap_channel = atoi(val);
7382 pos = strchr(val, ';');
7383 if (pos) {
7384 pos++;
7385 dut->ap_channel_1 = atoi(pos);
7386 }
7387 }
7388
7389 switch (dut->ap_channel) {
7390 case 1:
7391 case 2:
7392 case 3:
7393 break;
7394 default:
7395 sigma_dut_print(dut, DUT_MSG_ERROR,
7396 "Channel %d is not supported", dut->ap_channel);
7397 send_resp(dut, conn, SIGMA_ERROR,
7398 "Requested channel is not supported");
7399 return -1;
7400 }
7401
7402 val = get_param(cmd, "BCNINT");
7403 if (val)
7404 dut->ap_bcnint = atoi(val);
7405
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007406 val = get_param(cmd, "AllocType");
7407 if (val) {
7408 send_resp(dut, conn, SIGMA_ERROR,
7409 "ErrorCode,AllocType is not supported yet");
7410 return -1;
7411 }
7412
7413 val = get_param(cmd, "PercentBI");
7414 if (val) {
7415 send_resp(dut, conn, SIGMA_ERROR,
7416 "ErrorCode,PercentBI is not supported yet");
7417 return -1;
7418 }
7419
7420 val = get_param(cmd, "CBAPOnly");
7421 if (val) {
7422 send_resp(dut, conn, SIGMA_ERROR,
7423 "ErrorCode,CBAPOnly is not supported yet");
7424 return -1;
7425 }
7426
7427 val = get_param(cmd, "AMPDU");
7428 if (val) {
7429 if (strcasecmp(val, "Enable") == 0)
7430 dut->ap_ampdu = 1;
7431 else if (strcasecmp(val, "Disable") == 0)
7432 dut->ap_ampdu = 2;
7433 else {
7434 send_resp(dut, conn, SIGMA_ERROR,
7435 "ErrorCode,AMPDU value is not Enable nor Disabled");
7436 return -1;
7437 }
7438 }
7439
7440 val = get_param(cmd, "AMSDU");
7441 if (val) {
7442 if (strcasecmp(val, "Enable") == 0)
7443 dut->ap_amsdu = 1;
7444 else if (strcasecmp(val, "Disable") == 0)
7445 dut->ap_amsdu = 2;
7446 }
7447
7448 val = get_param(cmd, "NumMSDU");
7449 if (val) {
7450 send_resp(dut, conn, SIGMA_ERROR,
7451 "ErrorCode, NumMSDU is not supported yet");
7452 return -1;
7453 }
7454
7455 val = get_param(cmd, "ABFTLRang");
7456 if (val) {
7457 sigma_dut_print(dut, DUT_MSG_DEBUG,
Lior David67543f52017-01-03 19:04:22 +02007458 "ABFTLRang parameter %s", val);
7459 if (strcmp(val, "Gt1") == 0)
7460 abft_len = 2; /* 2 slots in this case */
7461 }
7462
7463 if (sta_set_60g_abft_len(dut, conn, abft_len)) {
7464 send_resp(dut, conn, SIGMA_ERROR,
7465 "ErrorCode, Can't set ABFT length");
7466 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007467 }
7468
7469 if (sta_pcp_start(dut, conn, cmd) < 0) {
7470 send_resp(dut, conn, SIGMA_ERROR,
7471 "ErrorCode, Can't start PCP role");
7472 return -1;
7473 }
7474
7475 return sta_set_60g_common(dut, conn, cmd);
7476}
7477
7478
7479static int sta_set_60g_sta(struct sigma_dut *dut, struct sigma_conn *conn,
7480 struct sigma_cmd *cmd)
7481{
7482 const char *val = get_param(cmd, "DiscoveryMode");
7483
7484 if (dut->dev_role != DEVROLE_STA) {
7485 send_resp(dut, conn, SIGMA_INVALID,
7486 "ErrorCode,Invalid DevRole");
7487 return 0;
7488 }
7489
7490 if (val) {
7491 sigma_dut_print(dut, DUT_MSG_DEBUG, "Discovery: %s", val);
7492 /* Ignore Discovery mode till Driver expose API. */
7493#if 0
7494 if (strcasecmp(val, "1") == 0) {
7495 send_resp(dut, conn, SIGMA_INVALID,
7496 "ErrorCode,DiscoveryMode 1 not supported");
7497 return 0;
7498 }
7499
7500 if (strcasecmp(val, "0") == 0) {
7501 /* OK */
7502 } else {
7503 send_resp(dut, conn, SIGMA_INVALID,
7504 "ErrorCode,DiscoveryMode not supported");
7505 return 0;
7506 }
7507#endif
7508 }
7509
7510 if (start_sta_mode(dut) != 0)
Jouni Malinen0e29cf22019-02-19 01:13:21 +02007511 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007512 return sta_set_60g_common(dut, conn, cmd);
7513}
7514
7515
Jouni Malinenf7222712019-06-13 01:50:21 +03007516static enum sigma_cmd_result cmd_sta_disconnect(struct sigma_dut *dut,
7517 struct sigma_conn *conn,
7518 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007519{
7520 const char *intf = get_param(cmd, "Interface");
Jouni Malinened77e672018-01-10 16:45:13 +02007521 const char *val = get_param(cmd, "maintain_profile");
vamsi krishnad605c422017-09-20 14:56:31 +05307522
Jouni Malinened77e672018-01-10 16:45:13 +02007523 if (dut->program == PROGRAM_OCE ||
Amarnath Hullur Subramanyamebeda9e2018-01-31 03:21:48 -08007524 dut->program == PROGRAM_HE ||
Jouni Malinened77e672018-01-10 16:45:13 +02007525 (val && atoi(val) == 1)) {
vamsi krishnad605c422017-09-20 14:56:31 +05307526 wpa_command(intf, "DISCONNECT");
7527 return 1;
7528 }
7529
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007530 disconnect_station(dut);
7531 /* Try to ignore old scan results to avoid HS 2.0R2 test case failures
7532 * due to cached results. */
7533 wpa_command(intf, "SET ignore_old_scan_res 1");
7534 wpa_command(intf, "BSS_FLUSH");
7535 return 1;
7536}
7537
7538
Jouni Malinenf7222712019-06-13 01:50:21 +03007539static enum sigma_cmd_result cmd_sta_reassoc(struct sigma_dut *dut,
7540 struct sigma_conn *conn,
7541 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007542{
7543 const char *intf = get_param(cmd, "Interface");
7544 const char *bssid = get_param(cmd, "bssid");
7545 const char *val = get_param(cmd, "CHANNEL");
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007546 const char *freq_val = get_param(cmd, "ChnlFreq");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007547 struct wpa_ctrl *ctrl;
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307548 char buf[1000];
Sunil Duttd30ce092018-01-11 23:56:29 +05307549 char result[32];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007550 int res;
7551 int chan = 0;
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007552 int freq = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007553 enum sigma_cmd_result status = STATUS_SENT;
Sunil Duttd30ce092018-01-11 23:56:29 +05307554 int fastreassoc = 1;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007555 int ft_ds = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007556
7557 if (bssid == NULL) {
7558 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing bssid "
7559 "argument");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007560 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007561 }
7562
7563 if (val)
7564 chan = atoi(val);
7565
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007566 if (freq_val)
7567 freq = atoi(freq_val);
7568
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007569 if (wifi_chip_type != DRIVER_WCN && wifi_chip_type != DRIVER_AR6003) {
7570 /* The current network may be from sta_associate or
7571 * sta_hs2_associate
7572 */
7573 if (set_network(intf, dut->infra_network_id, "bssid", bssid) <
7574 0 ||
7575 set_network(intf, 0, "bssid", bssid) < 0)
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007576 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007577 }
7578
7579 ctrl = open_wpa_mon(intf);
7580 if (ctrl == NULL) {
7581 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
7582 "wpa_supplicant monitor connection");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007583 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007584 }
7585
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007586 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Sunil Duttd30ce092018-01-11 23:56:29 +05307587 sizeof(result)) < 0 ||
7588 strncmp(result, "COMPLETED", 9) != 0) {
7589 sigma_dut_print(dut, DUT_MSG_DEBUG,
7590 "sta_reassoc: Not connected");
7591 fastreassoc = 0;
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007592 } else if (dut->sta_ft_ds) {
7593 sigma_dut_print(dut, DUT_MSG_DEBUG,
7594 "sta_reassoc: Use FT-over-DS");
7595 ft_ds = 1;
Sunil Duttd30ce092018-01-11 23:56:29 +05307596 }
7597
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307598 if (dut->rsne_override) {
7599#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007600 if (get_driver_type(dut) == DRIVER_WCN &&
7601 dut->config_rsnie == 0) {
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05307602 sta_config_params(dut, intf, STA_SET_RSNIE, 1);
Srinivas Dasari0ebedb12018-02-14 17:03:51 +05307603 dut->config_rsnie = 1;
7604 }
7605#endif /* NL80211_SUPPORT */
7606 snprintf(buf, sizeof(buf), "TEST_ASSOC_IE %s",
7607 dut->rsne_override);
7608 if (wpa_command(intf, buf) < 0) {
7609 send_resp(dut, conn, SIGMA_ERROR,
7610 "ErrorCode,Failed to set DEV_CONFIGURE_IE RSNE override");
7611 return 0;
7612 }
7613 }
7614
Shivani Baranwal7aa48602021-09-29 10:53:38 +05307615 if (ft_ds && get_driver_type(dut) != DRIVER_WCN) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007616 if (chan || freq) {
7617 if (!freq)
7618 freq = channel_to_freq(dut, chan);
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007619 if (!freq) {
7620 sigma_dut_print(dut, DUT_MSG_ERROR,
7621 "Invalid channel number provided: %d",
7622 chan);
7623 send_resp(dut, conn, SIGMA_INVALID,
7624 "ErrorCode,Invalid channel number");
7625 goto close_mon_conn;
7626 }
7627 res = snprintf(buf, sizeof(buf),
7628 "SCAN TYPE=ONLY freq=%d", freq);
7629 } else {
7630 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7631 }
7632 if (res < 0 || res >= (int) sizeof(buf)) {
7633 send_resp(dut, conn, SIGMA_ERROR,
7634 "ErrorCode,snprintf failed");
7635 goto close_mon_conn;
7636 }
7637 if (wpa_command(intf, buf) < 0) {
7638 sigma_dut_print(dut, DUT_MSG_INFO,
7639 "Failed to start scan");
7640 send_resp(dut, conn, SIGMA_ERROR,
7641 "ErrorCode,scan failed");
7642 goto close_mon_conn;
7643 }
7644
7645 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7646 buf, sizeof(buf));
7647 if (res < 0) {
7648 sigma_dut_print(dut, DUT_MSG_INFO,
7649 "Scan did not complete");
7650 send_resp(dut, conn, SIGMA_ERROR,
7651 "ErrorCode,scan did not complete");
7652 goto close_mon_conn;
7653 }
7654
7655 res = snprintf(buf, sizeof(buf), "FT_DS %s", bssid);
7656 if (res > 0 && res < (int) sizeof(buf))
7657 res = wpa_command(intf, buf);
7658
7659 if (res < 0 || res >= (int) sizeof(buf)) {
7660 send_resp(dut, conn, SIGMA_ERROR,
7661 "errorCode,FT_DS command failed");
7662 status = STATUS_SENT_ERROR;
7663 goto close_mon_conn;
7664 }
7665 } else if (wifi_chip_type == DRIVER_WCN && fastreassoc) {
Kiran Kumar Lokere94a86b52020-06-03 23:25:19 -07007666 if (chan || freq) {
7667 if (!freq)
7668 freq = channel_to_freq(dut, chan);
Ashwini Patil4c8158f2017-05-25 12:49:21 +05307669 if (!freq) {
7670 sigma_dut_print(dut, DUT_MSG_ERROR,
7671 "Invalid channel number provided: %d",
7672 chan);
7673 send_resp(dut, conn, SIGMA_INVALID,
7674 "ErrorCode,Invalid channel number");
7675 goto close_mon_conn;
7676 }
7677 res = snprintf(buf, sizeof(buf),
7678 "SCAN TYPE=ONLY freq=%d", freq);
7679 } else {
7680 res = snprintf(buf, sizeof(buf), "SCAN TYPE=ONLY");
7681 }
7682 if (res < 0 || res >= (int) sizeof(buf)) {
7683 send_resp(dut, conn, SIGMA_ERROR,
7684 "ErrorCode,snprintf failed");
7685 goto close_mon_conn;
7686 }
7687 if (wpa_command(intf, buf) < 0) {
7688 sigma_dut_print(dut, DUT_MSG_INFO,
7689 "Failed to start scan");
7690 send_resp(dut, conn, SIGMA_ERROR,
7691 "ErrorCode,scan failed");
7692 goto close_mon_conn;
7693 }
7694
7695 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
7696 buf, sizeof(buf));
7697 if (res < 0) {
7698 sigma_dut_print(dut, DUT_MSG_INFO,
7699 "Scan did not complete");
7700 send_resp(dut, conn, SIGMA_ERROR,
7701 "ErrorCode,scan did not complete");
7702 goto close_mon_conn;
7703 }
7704
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007705 if (set_network(intf, dut->infra_network_id, "bssid", "any")
7706 < 0) {
7707 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
7708 "bssid to any during FASTREASSOC");
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007709 status = ERROR_SEND_STATUS;
Ashwini Patil467efef2017-05-25 12:18:27 +05307710 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007711 }
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307712 res = snprintf(buf, sizeof(buf), "FASTREASSOC %s %d",
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007713 bssid, chan);
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307714 if (res < 0 || res >= (int) sizeof(buf) ||
7715 wcn_driver_cmd(intf, buf) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007716 send_resp(dut, conn, SIGMA_ERROR,
Vinita Maloo54b78cf2020-03-30 12:18:19 +05307717 "errorCode,Failed to run FASTREASSOC");
Ashwini Patil467efef2017-05-25 12:18:27 +05307718 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007719 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007720 sigma_dut_print(dut, DUT_MSG_INFO,
7721 "sta_reassoc: Run %s successful", buf);
7722 } else if (wpa_command(intf, "REASSOCIATE")) {
7723 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
7724 "request reassociation");
Ashwini Patil467efef2017-05-25 12:18:27 +05307725 goto close_mon_conn;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007726 }
7727
7728 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
7729 buf, sizeof(buf));
Ashwini Patil467efef2017-05-25 12:18:27 +05307730 if (res < 0) {
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007731 send_resp(dut, conn, SIGMA_ERROR,
7732 "errorCode,Connection did not complete");
7733 status = STATUS_SENT_ERROR;
Ashwini Patil467efef2017-05-25 12:18:27 +05307734 goto close_mon_conn;
7735 }
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03007736 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007737
Ashwini Patil467efef2017-05-25 12:18:27 +05307738close_mon_conn:
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007739 wpa_ctrl_detach(ctrl);
7740 wpa_ctrl_close(ctrl);
Ashwini Patil467efef2017-05-25 12:18:27 +05307741 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007742}
7743
7744
7745static void hs2_clear_credentials(const char *intf)
7746{
7747 wpa_command(intf, "REMOVE_CRED all");
7748}
7749
7750
Lior Davidcc88b562017-01-03 18:52:09 +02007751#ifdef __linux__
7752static int wil6210_get_aid(struct sigma_dut *dut, const char *bssid,
7753 unsigned int *aid)
7754{
Lior David0fe101e2017-03-09 16:09:50 +02007755 const char *pattern = "AID[ \t]+([0-9]+)";
Lior Davidcc88b562017-01-03 18:52:09 +02007756
Lior David0fe101e2017-03-09 16:09:50 +02007757 return wil6210_get_sta_info_field(dut, bssid, pattern, aid);
Lior Davidcc88b562017-01-03 18:52:09 +02007758}
7759#endif /* __linux__ */
7760
7761
7762static int sta_get_aid_60g(struct sigma_dut *dut, const char *bssid,
7763 unsigned int *aid)
7764{
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007765 switch (get_driver_type(dut)) {
Lior Davidcc88b562017-01-03 18:52:09 +02007766#ifdef __linux__
7767 case DRIVER_WIL6210:
7768 return wil6210_get_aid(dut, bssid, aid);
7769#endif /* __linux__ */
7770 default:
7771 sigma_dut_print(dut, DUT_MSG_ERROR, "get AID not supported");
7772 return -1;
7773 }
7774}
7775
7776
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007777static int sta_get_parameter_60g(struct sigma_dut *dut, struct sigma_conn *conn,
7778 struct sigma_cmd *cmd)
7779{
7780 char buf[MAX_CMD_LEN];
7781 char bss_list[MAX_CMD_LEN];
7782 const char *parameter = get_param(cmd, "Parameter");
7783
7784 if (parameter == NULL)
7785 return -1;
7786
Lior Davidcc88b562017-01-03 18:52:09 +02007787 if (strcasecmp(parameter, "AID") == 0) {
7788 unsigned int aid = 0;
7789 char bssid[20];
7790
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007791 if (get_wpa_status(get_station_ifname(dut), "bssid",
Lior Davidcc88b562017-01-03 18:52:09 +02007792 bssid, sizeof(bssid)) < 0) {
7793 sigma_dut_print(dut, DUT_MSG_ERROR,
7794 "could not get bssid");
7795 return -2;
7796 }
7797
7798 if (sta_get_aid_60g(dut, bssid, &aid))
7799 return -2;
7800
7801 snprintf(buf, sizeof(buf), "aid,%d", aid);
7802 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
7803 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7804 return 0;
7805 }
7806
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007807 if (strcasecmp(parameter, "DiscoveredDevList") == 0) {
7808 char *bss_line;
7809 char *bss_id = NULL;
7810 const char *ifname = get_param(cmd, "Interface");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307811 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007812
7813 if (ifname == NULL) {
7814 sigma_dut_print(dut, DUT_MSG_INFO,
7815 "For get DiscoveredDevList need Interface name.");
7816 return -1;
7817 }
7818
7819 /*
7820 * Use "BSS RANGE=ALL MASK=0x2" which provides a list
7821 * of BSSIDs in "bssid=<BSSID>\n"
7822 */
7823 if (wpa_command_resp(ifname, "BSS RANGE=ALL MASK=0x2",
7824 bss_list,
7825 sizeof(bss_list)) < 0) {
7826 sigma_dut_print(dut, DUT_MSG_ERROR,
7827 "Failed to get bss list");
7828 return -1;
7829 }
7830
7831 sigma_dut_print(dut, DUT_MSG_DEBUG,
7832 "bss list for ifname:%s is:%s",
7833 ifname, bss_list);
7834
7835 snprintf(buf, sizeof(buf), "DeviceList");
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307836 bss_line = strtok_r(bss_list, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007837 while (bss_line) {
7838 if (sscanf(bss_line, "bssid=%ms", &bss_id) > 0 &&
7839 bss_id) {
7840 int len;
7841
7842 len = snprintf(buf + strlen(buf),
7843 sizeof(buf) - strlen(buf),
7844 ",%s", bss_id);
7845 free(bss_id);
7846 bss_id = NULL;
7847 if (len < 0) {
7848 sigma_dut_print(dut,
7849 DUT_MSG_ERROR,
7850 "Failed to read BSSID");
7851 send_resp(dut, conn, SIGMA_ERROR,
7852 "ErrorCode,Failed to read BSS ID");
7853 return 0;
7854 }
7855
7856 if ((size_t) len >= sizeof(buf) - strlen(buf)) {
7857 sigma_dut_print(dut,
7858 DUT_MSG_ERROR,
7859 "Response buf too small for list");
7860 send_resp(dut, conn,
7861 SIGMA_ERROR,
7862 "ErrorCode,Response buf too small for list");
7863 return 0;
7864 }
7865 }
7866
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +05307867 bss_line = strtok_r(NULL, "\n", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02007868 }
7869
7870 sigma_dut_print(dut, DUT_MSG_INFO, "DiscoveredDevList is %s",
7871 buf);
7872 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7873 return 0;
7874 }
7875
7876 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7877 return 0;
7878}
7879
7880
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007881static int sta_get_parameter_he(struct sigma_dut *dut, struct sigma_conn *conn,
7882 struct sigma_cmd *cmd)
7883{
7884 char buf[MAX_CMD_LEN];
7885 const char *parameter = get_param(cmd, "Parameter");
7886
7887 if (!parameter)
7888 return -1;
7889
7890 if (strcasecmp(parameter, "RSSI") == 0) {
7891 char rssi[10];
7892
Jouni Malinen016ae6c2019-11-04 17:00:01 +02007893 if (get_wpa_signal_poll(dut, get_station_ifname(dut), "RSSI",
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07007894 rssi, sizeof(rssi)) < 0) {
7895 sigma_dut_print(dut, DUT_MSG_ERROR,
7896 "Could not get RSSI");
7897 return -2;
7898 }
7899
7900 snprintf(buf, sizeof(buf), "rssi,%s", rssi);
7901 sigma_dut_print(dut, DUT_MSG_INFO, "RSSI %s", buf);
7902 send_resp(dut, conn, SIGMA_COMPLETE, buf);
7903 return 0;
7904 }
7905
7906 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
7907 return 0;
7908}
7909
7910
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05307911#ifdef NL80211_SUPPORT
7912
7913struct station_info {
7914 uint64_t filled;
7915 uint32_t beacon_mic_error_count;
7916 uint32_t beacon_replay_count;
7917};
7918
7919
7920static int qca_get_sta_info_handler(struct nl_msg *msg, void *arg)
7921{
7922 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7923 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7924 struct station_info *data = arg;
7925 struct nlattr *info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1];
7926 static struct nla_policy info_policy[
7927 QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX + 1] = {
7928 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT] = {
7929 .type = NLA_U32
7930 },
7931 [QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT] = {
7932 .type = NLA_U32
7933 },
7934 };
7935
7936 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7937 genlmsg_attrlen(gnlh, 0), NULL);
7938
7939 if (!tb[NL80211_ATTR_VENDOR_DATA])
7940 return NL_SKIP;
7941
7942 if (nla_parse_nested(info, QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_MAX,
7943 tb[NL80211_ATTR_VENDOR_DATA], info_policy)) {
7944 return NL_SKIP;
7945 }
7946
7947 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]) {
7948 data->filled |=
7949 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT);
7950 data->beacon_mic_error_count =
7951 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT]);
7952 }
7953
7954 if (info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]) {
7955 data->filled |=
7956 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT);
7957 data->beacon_replay_count =
7958 nla_get_u32(info[QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT]);
7959 }
7960
7961 return NL_SKIP;
7962}
7963
7964
7965static int qca_nl80211_get_sta_info(struct sigma_dut *dut, const char *intf,
7966 struct station_info *sta_data)
7967{
7968 struct nl_msg *msg;
7969 int ifindex, ret;
7970
7971 ifindex = if_nametoindex(intf);
7972 if (ifindex == 0) {
7973 sigma_dut_print(dut, DUT_MSG_ERROR,
7974 "%s: Index for interface %s not found",
7975 __func__, intf);
7976 return -1;
7977 }
7978
7979 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
7980 NL80211_CMD_VENDOR)) ||
7981 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
7982 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
7983 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
7984 QCA_NL80211_VENDOR_SUBCMD_GET_STA_INFO)) {
7985 sigma_dut_print(dut, DUT_MSG_ERROR,
7986 "%s: err in adding vendor_cmd", __func__);
7987 nlmsg_free(msg);
7988 return -1;
7989 }
7990
7991 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg,
7992 qca_get_sta_info_handler, sta_data);
7993 if (ret) {
7994 sigma_dut_print(dut, DUT_MSG_ERROR,
7995 "%s: err in send_and_recv_msgs, ret=%d",
7996 __func__, ret);
7997 }
7998 return ret;
7999}
8000#endif /* NL80211_SUPPORT */
8001
8002
8003static int get_bip_mic_error_count(struct sigma_dut *dut,
8004 const char *ifname,
8005 unsigned int *count)
8006{
8007#ifdef NL80211_SUPPORT
8008 struct station_info sta_data;
8009#endif /* NL80211_SUPPORT */
8010
8011 if (get_driver_type(dut) != DRIVER_WCN) {
8012 sigma_dut_print(dut, DUT_MSG_ERROR,
8013 "BIP MIC error count not supported");
8014 return -1;
8015 }
8016
8017#ifdef NL80211_SUPPORT
8018 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8019 !(sta_data.filled &
8020 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_MIC_ERROR_COUNT))) {
8021 sigma_dut_print(dut, DUT_MSG_ERROR,
8022 "BIP MIC error count fetching failed");
8023 return -1;
8024 }
8025
8026 *count = sta_data.beacon_mic_error_count;
8027 return 0;
8028#else /* NL80211_SUPPORT */
8029 sigma_dut_print(dut, DUT_MSG_ERROR,
8030 "BIP MIC error count cannot be fetched without NL80211_SUPPORT defined");
8031 return -1;
8032#endif /* NL80211_SUPPORT */
8033}
8034
8035
8036static int get_cmac_replay_count(struct sigma_dut *dut, const char *ifname,
8037 unsigned int *count)
8038{
8039#ifdef NL80211_SUPPORT
8040 struct station_info sta_data;
8041#endif /* NL80211_SUPPORT */
8042
8043 if (get_driver_type(dut) != DRIVER_WCN) {
8044 sigma_dut_print(dut, DUT_MSG_ERROR,
8045 "CMAC reply count not supported");
8046 return -1;
8047 }
8048
8049#ifdef NL80211_SUPPORT
8050 if (qca_nl80211_get_sta_info(dut, ifname, &sta_data) != 0 ||
8051 !(sta_data.filled &
8052 BIT_ULL(QCA_WLAN_VENDOR_ATTR_GET_STA_INFO_BEACON_REPLAY_COUNT))) {
8053 sigma_dut_print(dut, DUT_MSG_ERROR,
8054 "CMAC replay count fetching failed");
8055 return -1;
8056 }
8057
8058 *count = sta_data.beacon_replay_count;
8059 return 0;
8060#else /* NL80211_SUPPORT */
8061 sigma_dut_print(dut, DUT_MSG_ERROR,
8062 "CMAC replay count cannot be fetched without NL80211_SUPPORT defined");
8063 return -1;
8064#endif /* NL80211_SUPPORT */
8065}
8066
8067
8068static enum sigma_cmd_result sta_get_parameter_wpa3(struct sigma_dut *dut,
8069 struct sigma_conn *conn,
8070 struct sigma_cmd *cmd)
8071{
8072 char buf[MAX_CMD_LEN];
8073 const char *ifname = get_param(cmd, "interface");
8074 const char *parameter = get_param(cmd, "Parameter");
8075 unsigned int val;
8076
8077 if (!ifname || !parameter)
8078 return INVALID_SEND_STATUS;
8079
8080 if (strcasecmp(parameter, "BIPMICErrors") == 0) {
8081 if (get_bip_mic_error_count(dut, ifname, &val)) {
8082 send_resp(dut, conn, SIGMA_ERROR,
8083 "ErrorCode,Failed to get BIPMICErrors");
8084 return STATUS_SENT_ERROR;
8085 }
8086 snprintf(buf, sizeof(buf), "BIPMICErrors,%d", val);
8087 sigma_dut_print(dut, DUT_MSG_INFO, "BIPMICErrors %s", buf);
8088 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8089 return STATUS_SENT;
8090 }
8091
8092 if (strcasecmp(parameter, "CMACReplays") == 0) {
8093 if (get_cmac_replay_count(dut, ifname, &val)) {
8094 send_resp(dut, conn, SIGMA_ERROR,
8095 "ErrorCode,Failed to get CMACReplays");
8096 return STATUS_SENT_ERROR;
8097 }
8098 snprintf(buf, sizeof(buf), "CMACReplays,%d", val);
8099 sigma_dut_print(dut, DUT_MSG_INFO, "CMACReplays %s", buf);
8100 send_resp(dut, conn, SIGMA_COMPLETE, buf);
8101 return STATUS_SENT;
8102 }
8103
8104 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8105 return STATUS_SENT_ERROR;
8106}
8107
8108
Jouni Malinenca0abd32020-02-09 20:18:10 +02008109static enum sigma_cmd_result sta_get_pmk(struct sigma_dut *dut,
8110 struct sigma_conn *conn,
8111 struct sigma_cmd *cmd)
8112{
8113 const char *intf = get_param(cmd, "Interface");
8114 char buf[4096], bssid[20], resp[200], *pos, *tmp;
8115
8116 snprintf(buf, sizeof(buf), "PMKSA_GET %d", dut->infra_network_id);
8117 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
8118 strncmp(buf, "UNKNOWN COMMAND", 15) == 0) {
8119 send_resp(dut, conn, SIGMA_ERROR,
8120 "ErrorCode,PMKSA_GET not supported");
8121 return STATUS_SENT_ERROR;
8122 }
8123
8124 if (strncmp(buf, "FAIL", 4) == 0 ||
8125 get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
8126 send_resp(dut, conn, SIGMA_ERROR,
8127 "ErrorCode,Could not find current network");
8128 return STATUS_SENT_ERROR;
8129 }
8130
8131 pos = buf;
8132 while (pos) {
8133 if (strncmp(pos, bssid, 17) == 0) {
8134 pos = strchr(pos, ' ');
8135 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308136 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008137 pos++;
8138 pos = strchr(pos, ' ');
8139 if (!pos)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308140 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008141 pos++;
8142 tmp = strchr(pos, ' ');
8143 if (!tmp)
Mohammad Asaad Akram956bfc32020-04-08 16:26:18 +05308144 break;
Jouni Malinenca0abd32020-02-09 20:18:10 +02008145 *tmp = '\0';
8146 break;
8147 }
Jouni Malinenca0abd32020-02-09 20:18:10 +02008148 pos = strchr(pos, '\n');
8149 if (pos)
8150 pos++;
8151 }
8152
8153 if (!pos) {
8154 send_resp(dut, conn, SIGMA_ERROR,
8155 "ErrorCode,PMK not available");
8156 return STATUS_SENT_ERROR;
8157 }
8158
8159 snprintf(resp, sizeof(resp), "PMK,%s", pos);
8160 send_resp(dut, conn, SIGMA_COMPLETE, resp);
8161 return STATUS_SENT;
8162}
8163
8164
Jouni Malinenf7222712019-06-13 01:50:21 +03008165static enum sigma_cmd_result cmd_sta_get_parameter(struct sigma_dut *dut,
8166 struct sigma_conn *conn,
8167 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008168{
8169 const char *program = get_param(cmd, "Program");
Jouni Malinenca0abd32020-02-09 20:18:10 +02008170 const char *parameter = get_param(cmd, "Parameter");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008171
Jouni Malinenca0abd32020-02-09 20:18:10 +02008172 if (!parameter)
8173 return INVALID_SEND_STATUS;
8174
8175 if (strcasecmp(parameter, "PMK") == 0)
8176 return sta_get_pmk(dut, conn, cmd);
8177
8178 if (!program)
8179 return INVALID_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008180
8181 if (strcasecmp(program, "P2PNFC") == 0)
8182 return p2p_cmd_sta_get_parameter(dut, conn, cmd);
8183
8184 if (strcasecmp(program, "60ghz") == 0)
8185 return sta_get_parameter_60g(dut, conn, cmd);
8186
Kiran Kumar Lokerec86d8022018-10-11 13:57:12 -07008187 if (strcasecmp(program, "he") == 0)
8188 return sta_get_parameter_he(dut, conn, cmd);
8189
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008190#ifdef ANDROID_NAN
8191 if (strcasecmp(program, "NAN") == 0)
Amarnath Hullur Subramanyam1854ec62016-08-11 19:29:35 -07008192 return nan_cmd_sta_get_parameter(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008193#endif /* ANDROID_NAN */
8194
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008195#ifdef MIRACAST
8196 if (strcasecmp(program, "WFD") == 0 ||
8197 strcasecmp(program, "DisplayR2") == 0)
8198 return miracast_cmd_sta_get_parameter(dut, conn, cmd);
8199#endif /* MIRACAST */
Veerendranath Jakkamd0ad6ef2020-05-21 17:09:26 +05308200 if (strcasecmp(program, "WPA3") == 0)
8201 return sta_get_parameter_wpa3(dut, conn, cmd);
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07008202
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008203 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
8204 return 0;
8205}
8206
8207
8208static void sta_reset_default_ath(struct sigma_dut *dut, const char *intf,
8209 const char *type)
8210{
8211 char buf[100];
8212
8213 if (dut->program == PROGRAM_VHT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008214 run_iwpriv(dut, intf, "chwidth 2");
8215 run_iwpriv(dut, intf, "mode 11ACVHT80");
8216 run_iwpriv(dut, intf, "vhtmcs -1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008217 }
8218
8219 if (dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008220 run_iwpriv(dut, intf, "chwidth 0");
8221 run_iwpriv(dut, intf, "mode 11naht40");
8222 run_iwpriv(dut, intf, "set11NRates 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008223 }
8224
8225 if (dut->program == PROGRAM_VHT || dut->program == PROGRAM_HT) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008226 run_iwpriv(dut, intf, "powersave 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008227
8228 /* Reset CTS width */
8229 snprintf(buf, sizeof(buf), "wifitool %s beeliner_fw_test 54 0",
8230 intf);
8231 if (system(buf) != 0) {
8232 sigma_dut_print(dut, DUT_MSG_ERROR,
8233 "wifitool %s beeliner_fw_test 54 0 failed",
8234 intf);
8235 }
8236
8237 /* Enable Dynamic Bandwidth signalling by default */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008238 run_iwpriv(dut, intf, "cwmenable 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008239
8240 snprintf(buf, sizeof(buf), "iwconfig %s rts 2347", intf);
8241 if (system(buf) != 0) {
8242 sigma_dut_print(dut, DUT_MSG_ERROR,
8243 "iwpriv rts failed");
8244 }
8245 }
8246
8247 if (type && strcasecmp(type, "Testbed") == 0) {
8248 dut->testbed_flag_txsp = 1;
8249 dut->testbed_flag_rxsp = 1;
8250 /* STA has to set spatial stream to 2 per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008251 run_iwpriv(dut, intf, "vht_mcsmap 0xfff0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008252
8253 /* Disable LDPC per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008254 run_iwpriv(dut, intf, "ldpc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008255
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008256 run_iwpriv(dut, intf, "amsdu 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008257
8258 /* TODO: Disable STBC 2x1 transmit and receive */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008259 run_iwpriv(dut, intf, "tx_stbc 0");
8260 run_iwpriv(dut, intf, "rx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008261
8262 /* STA has to disable Short GI per Appendix H */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008263 run_iwpriv(dut, intf, "shortgi 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008264 }
8265
8266 if (type && strcasecmp(type, "DUT") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008267 run_iwpriv(dut, intf, "nss 3");
Arif Hussainac6c5112018-05-25 17:34:00 -07008268 dut->sta_nss = 3;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008269
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -07008270 run_iwpriv(dut, intf, "shortgi 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02008271 }
8272}
8273
8274
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008275#ifdef NL80211_SUPPORT
8276static int sta_set_he_mcs(struct sigma_dut *dut, const char *intf,
8277 enum he_mcs_config mcs)
8278{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308279 return wcn_wifi_test_config_set_u8(
8280 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS, mcs);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008281}
8282#endif /* NL80211_SUPPORT */
8283
8284
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008285static int sta_set_action_tx_in_he_tb_ppdu(struct sigma_dut *dut,
8286 const char *intf, int enable)
8287{
8288#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308289 return wcn_wifi_test_config_set_u8(
8290 dut, intf,
8291 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU,
8292 enable);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008293#else /* NL80211_SUPPORT */
8294 sigma_dut_print(dut, DUT_MSG_ERROR,
8295 "HE action Tx TB PPDU cannot be set without NL80211_SUPPORT defined");
8296 return -1;
8297#endif /* NL80211_SUPPORT */
8298}
8299
8300
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008301static int sta_set_heconfig_and_wep_tkip(struct sigma_dut *dut,
8302 const char *intf, int enable)
8303{
8304#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308305 return wcn_wifi_test_config_set_u8(
8306 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE,
8307 enable);
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08008308#else /* NL80211_SUPPORT */
8309 sigma_dut_print(dut, DUT_MSG_ERROR,
8310 "HE config enablement cannot be changed without NL80211_SUPPORT defined");
8311 return -1;
8312#endif /* NL80211_SUPPORT */
8313}
8314
8315
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008316#ifdef NL80211_SUPPORT
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008317
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008318static int sta_set_he_testbed_def(struct sigma_dut *dut,
8319 const char *intf, int cfg)
8320{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308321 return wcn_wifi_test_config_set_u8(
8322 dut, intf,
8323 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS,
8324 cfg);
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008325}
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008326
8327
8328static int sta_set_2g_vht_supp(struct sigma_dut *dut, const char *intf, int cfg)
8329{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308330 return wcn_wifi_test_config_set_u8(
8331 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT,
8332 cfg);
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08008333}
8334
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008335#endif /* NL80211_SUPPORT */
8336
8337
Qiwei Caib6806972020-01-15 13:52:11 +08008338int sta_set_addba_buf_size(struct sigma_dut *dut,
8339 const char *intf, int bufsize)
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008340{
8341#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308342 return wcn_wifi_test_config_set_u16(
8343 dut, intf,
8344 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE, bufsize);
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008345#else /* NL80211_SUPPORT */
8346 sigma_dut_print(dut, DUT_MSG_ERROR,
8347 "AddBA bufsize cannot be changed without NL80211_SUPPORT defined");
8348 return -1;
8349#endif /* NL80211_SUPPORT */
8350}
8351
8352
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008353static int sta_set_scan_unicast_probe(struct sigma_dut *dut,
8354 const char *intf, int val)
8355{
8356#ifdef NL80211_SUPPORT
8357 return wcn_wifi_test_config_set_u8(
8358 dut, intf,
8359 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_USE_BSSID_IN_PROBE_REQ_RA,
8360 val);
8361#else /* NL80211_SUPPORT */
8362 sigma_dut_print(dut, DUT_MSG_ERROR,
8363 "Unicast RA in Probe Request frame cannot be set without NL80211_SUPPORT defined");
8364 return -1;
8365#endif /* NL80211_SUPPORT */
8366}
8367
8368
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -07008369static int sta_set_rx_ctrl_multi_bss(struct sigma_dut *dut, const char *intf,
8370 int enable)
8371{
8372#ifdef NL80211_SUPPORT
8373 return wcn_wifi_test_config_set_u8(
8374 dut, intf,
8375 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_RX_CTRL_FRAME_TO_MBSS,
8376 enable);
8377#else /* NL80211_SUPPORT */
8378 sigma_dut_print(dut, DUT_MSG_ERROR,
8379 "Rx ctrl frame to Multi-BSS cannot be changed without NL80211_SUPPORT defined");
8380 return -1;
8381#endif /* NL80211_SUPPORT */
8382}
8383
8384
8385static int sta_set_bcast_twt_support(struct sigma_dut *dut, const char *intf,
8386 int enable)
8387{
8388#ifdef NL80211_SUPPORT
8389 return wcn_wifi_test_config_set_u8(
8390 dut, intf,
8391 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BCAST_TWT_SUPPORT,
8392 enable);
8393#else /* NL80211_SUPPORT */
8394 sigma_dut_print(dut, DUT_MSG_ERROR,
8395 "BCAST TWT cannot be changed without NL80211_SUPPORT defined");
8396 return -1;
8397#endif /* NL80211_SUPPORT */
8398}
8399
8400
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008401static int sta_set_tx_beamformee(struct sigma_dut *dut, const char *intf,
8402 int enable)
8403{
8404#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308405 return wcn_wifi_test_config_set_u8(
8406 dut, intf,
8407 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE,
8408 enable);
Arif Hussain8d5b27b2018-05-14 14:31:03 -07008409#else /* NL80211_SUPPORT */
8410 sigma_dut_print(dut, DUT_MSG_ERROR,
8411 "tx beamformee cannot be changed without NL80211_SUPPORT defined");
8412 return -1;
8413#endif /* NL80211_SUPPORT */
8414}
8415
8416
Arif Hussain9765f7d2018-07-03 08:28:26 -07008417static int sta_set_beamformee_sts(struct sigma_dut *dut, const char *intf,
8418 int val)
8419{
8420#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308421 return wcn_wifi_test_config_set_u8(
8422 dut, intf,
8423 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS,
8424 val);
Arif Hussain9765f7d2018-07-03 08:28:26 -07008425#else /* NL80211_SUPPORT */
8426 sigma_dut_print(dut, DUT_MSG_ERROR,
8427 "beamformee sts cannot be changed without NL80211_SUPPORT defined");
8428 return -1;
8429#endif /* NL80211_SUPPORT */
8430}
8431
8432
Arif Hussain68d23f52018-07-11 13:39:08 -07008433#ifdef NL80211_SUPPORT
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008434static int sta_set_mac_padding_duration(struct sigma_dut *dut, const char *intf,
8435 enum qca_wlan_he_mac_padding_dur val)
8436{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308437 return wcn_wifi_test_config_set_u8(
8438 dut, intf,
8439 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR, val);
Arif Hussain68d23f52018-07-11 13:39:08 -07008440}
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008441#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -07008442
8443
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008444static int sta_set_tx_su_ppdu_cfg(struct sigma_dut *dut, const char *intf,
8445 int val)
8446{
8447#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308448 return wcn_wifi_test_config_set_u8(
8449 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU,
8450 val);
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008451#else /* NL80211_SUPPORT */
8452 sigma_dut_print(dut, DUT_MSG_ERROR,
8453 "Tx SU PPDU cannot be set without NL80211_SUPPORT defined");
8454 return -1;
8455#endif /* NL80211_SUPPORT */
8456}
8457
8458
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008459static int sta_set_mgmt_data_tx_disable_cfg(struct sigma_dut *dut,
8460 const char *intf, int val)
8461{
8462#ifdef NL80211_SUPPORT
8463 return wcn_wifi_test_config_set_u8(
8464 dut, intf,
8465 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISABLE_DATA_MGMT_RSP_TX,
8466 val);
8467#else /* NL80211_SUPPORT */
8468 sigma_dut_print(dut, DUT_MSG_ERROR,
8469 "Tx disable config cannot be set without NL80211_SUPPORT defined");
8470 return -1;
8471#endif /* NL80211_SUPPORT */
8472}
8473
8474
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -07008475static int sta_set_keep_alive_data_cfg(struct sigma_dut *dut, const char *intf,
8476 int val)
8477{
8478#ifdef NL80211_SUPPORT
8479 return wcn_wifi_test_config_set_u8(
8480 dut, intf,
8481 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_KEEP_ALIVE_FRAME_TYPE,
8482 val);
8483#else /* NL80211_SUPPORT */
8484 sigma_dut_print(dut, DUT_MSG_ERROR,
8485 "Keep alive data type cannot be set without NL80211_SUPPORT defined");
8486 return -1;
8487#endif /* NL80211_SUPPORT */
8488}
8489
8490
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008491#ifdef NL80211_SUPPORT
8492static int sta_set_he_om_ctrl_reset(struct sigma_dut *dut, const char *intf)
8493{
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308494 return wcn_wifi_test_config_set_flag(
8495 dut, intf,
8496 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG);
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008497}
8498#endif /* NL80211_SUPPORT */
8499
8500
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008501static int sta_set_mu_edca_override(struct sigma_dut *dut, const char *intf,
8502 int val)
8503{
8504#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308505 return wcn_wifi_test_config_set_u8(
8506 dut, intf,
8507 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA, val);
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008508#else /* NL80211_SUPPORT */
8509 sigma_dut_print(dut, DUT_MSG_ERROR,
8510 "MU EDCA override cannot be changed without NL80211_SUPPORT defined");
8511 return -1;
8512#endif /* NL80211_SUPPORT */
8513}
8514
8515
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008516static int sta_set_er_su_ppdu_type_tx(struct sigma_dut *dut, const char *intf,
8517 int val)
8518{
8519#ifdef NL80211_SUPPORT
8520 return wcn_wifi_test_config_set_u8(
8521 dut, intf,
8522 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ER_SU_PPDU_TYPE, val);
8523#else /* NL80211_SUPPORT */
8524 sigma_dut_print(dut, DUT_MSG_ERROR,
8525 "ER-SU PPDU type cannot be set without NL80211_SUPPORT defined");
8526 return -1;
8527#endif /* NL80211_SUPPORT */
8528}
8529
8530
8531static int sta_set_ru_242_tone_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_RU_242_TONE_TX, val);
8538#else /* NL80211_SUPPORT */
8539 sigma_dut_print(dut, DUT_MSG_ERROR,
8540 "RU 242 tone cannot be set without NL80211_SUPPORT defined");
8541 return -1;
8542#endif /* NL80211_SUPPORT */
8543}
8544
8545
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008546static int sta_set_om_ctrl_supp(struct sigma_dut *dut, const char *intf,
8547 int val)
8548{
8549#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308550 return wcn_wifi_test_config_set_u8(
8551 dut, intf,
8552 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP, val);
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008553#else /* NL80211_SUPPORT */
8554 sigma_dut_print(dut, DUT_MSG_ERROR,
8555 "HE OM ctrl cannot be changed without NL80211_SUPPORT defined");
8556 return -1;
8557#endif /* NL80211_SUPPORT */
8558}
8559
8560
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008561#ifdef NL80211_SUPPORT
8562
8563struct features_info {
8564 unsigned char flags[8];
8565 size_t flags_len;
8566};
8567
8568static int features_info_handler(struct nl_msg *msg, void *arg)
8569{
8570 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8571 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8572 struct features_info *info = arg;
8573 struct nlattr *nl_vend, *attr;
8574
8575 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8576 genlmsg_attrlen(gnlh, 0), NULL);
8577
8578 nl_vend = tb[NL80211_ATTR_VENDOR_DATA];
8579 if (nl_vend) {
8580 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_MAX + 1];
8581
8582 nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_MAX,
8583 nla_data(nl_vend), nla_len(nl_vend), NULL);
8584
8585 attr = tb_vendor[QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS];
8586 if (attr) {
8587 int len = nla_len(attr);
8588
Vamsi Krishna79a91132021-08-16 21:40:22 +05308589 if (info && len <= sizeof(info->flags)) {
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008590 memcpy(info->flags, nla_data(attr), len);
8591 info->flags_len = len;
8592 }
8593 }
8594 }
8595
8596 return NL_SKIP;
8597}
8598
8599
8600static int check_feature(enum qca_wlan_vendor_features feature,
8601 struct features_info *info)
8602{
8603 size_t idx = feature / 8;
8604
Vamsi Krishna79a91132021-08-16 21:40:22 +05308605 if (!info)
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008606 return 0;
8607
8608 return (idx < info->flags_len) &&
8609 (info->flags[idx] & BIT(feature % 8));
8610}
8611
8612#endif /* NL80211_SUPPORT */
8613
8614
8615static void sta_get_twt_feature_async_supp(struct sigma_dut *dut,
8616 const char *intf)
8617{
8618#ifdef NL80211_SUPPORT
8619 struct nl_msg *msg;
8620 struct features_info info = { 0 };
8621 int ifindex, ret;
8622
8623 ifindex = if_nametoindex(intf);
8624 if (ifindex == 0) {
8625 sigma_dut_print(dut, DUT_MSG_ERROR,
8626 "%s: Index for interface %s failed",
8627 __func__, intf);
8628 return;
8629 }
8630
8631 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8632 NL80211_CMD_VENDOR)) ||
8633 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
8634 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
8635 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
8636 QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES)) {
8637 sigma_dut_print(dut, DUT_MSG_ERROR,
8638 "%s: err in adding vendor_cmd and vendor_data",
8639 __func__);
8640 nlmsg_free(msg);
8641 return;
8642 }
8643
8644 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, features_info_handler,
8645 &info);
8646 if (ret) {
8647 sigma_dut_print(dut, DUT_MSG_ERROR,
8648 "%s: err in send_and_recv_msgs, ret=%d",
8649 __func__, ret);
8650 return;
8651 }
8652
8653 if (check_feature(QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT, &info))
8654 dut->sta_async_twt_supp = 1;
8655 else
8656 dut->sta_async_twt_supp = 0;
8657
8658 sigma_dut_print(dut, DUT_MSG_DEBUG,
8659 "%s: sta_async_twt_supp %d",
8660 __func__, dut->sta_async_twt_supp);
8661#else /* NL80211_SUPPORT */
8662 sigma_dut_print(dut, DUT_MSG_INFO,
8663 "TWT async supp get cannot be done without NL80211_SUPPORT defined");
8664 dut->sta_async_twt_supp = 0;
8665#endif /* NL80211_SUPPORT */
8666}
8667
8668
Arif Hussain480d5f42019-03-12 14:40:42 -07008669static int sta_set_twt_req_support(struct sigma_dut *dut, const char *intf,
8670 int val)
8671{
8672#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +05308673 return wcn_wifi_test_config_set_u8(
8674 dut, intf,
8675 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT, val);
Arif Hussain480d5f42019-03-12 14:40:42 -07008676#else /* NL80211_SUPPORT */
8677 sigma_dut_print(dut, DUT_MSG_ERROR,
8678 "TWT Request cannot be changed without NL80211_SUPPORT defined");
8679 return -1;
8680#endif /* NL80211_SUPPORT */
8681}
8682
8683
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -07008684static int sta_set_bss_max_idle_period(struct sigma_dut *dut, const char *intf,
8685 int val)
8686{
8687#ifdef NL80211_SUPPORT
8688 return wcn_wifi_test_config_set_u16(
8689 dut, intf,
8690 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD, val);
8691#else /* NL80211_SUPPORT */
8692 sigma_dut_print(dut, DUT_MSG_ERROR,
8693 "BSS max idle period cannot be set without NL80211_SUPPORT defined");
8694 return -1;
8695#endif /* NL80211_SUPPORT */
8696}
8697
8698
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -07008699static int sta_set_bss_max_idle_support(struct sigma_dut *dut, const char *intf,
8700 int val)
8701{
8702#ifdef NL80211_SUPPORT
8703 return wcn_wifi_test_config_set_u8(
8704 dut, intf,
8705 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BSS_MAX_IDLE_PERIOD_ENABLE,
8706 val);
8707#else /* NL80211_SUPPORT */
8708 sigma_dut_print(dut, DUT_MSG_ERROR,
8709 "BSS max idle support cannot be set without NL80211_SUPPORT defined");
8710 return -1;
8711#endif /* NL80211_SUPPORT */
8712}
8713
8714
Srinivas Girigowda0525e292020-11-12 13:28:21 -08008715static int sta_set_fullbw_ulmumimo(struct sigma_dut *dut, const char *intf,
8716 int val)
8717{
8718#ifdef NL80211_SUPPORT
8719 return wcn_wifi_test_config_set_u8(
8720 dut, intf,
8721 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FULL_BW_UL_MU_MIMO, val);
8722#else /* NL80211_SUPPORT */
8723 sigma_dut_print(dut, DUT_MSG_ERROR,
8724 "Full BW UL MU MIMO cannot be changed without NL80211_SUPPORT defined");
8725 return -1;
8726#endif /* NL80211_SUPPORT */
8727}
8728
8729
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07008730static int sta_set_punctured_preamble_rx(struct sigma_dut *dut,
8731 const char *intf, 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_PUNCTURED_PREAMBLE_RX,
8737 val);
8738#else /* NL80211_SUPPORT */
8739 sigma_dut_print(dut, DUT_MSG_ERROR,
8740 "Punctured preamble Rx cannot be set without NL80211_SUPPORT defined");
8741 return -1;
8742#endif /* NL80211_SUPPORT */
8743}
8744
8745
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -08008746int wcn_set_he_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8747{
8748 #ifdef NL80211_SUPPORT
8749 struct nlattr *attr;
8750 struct nlattr *attr1;
8751 int ifindex, ret;
8752 struct nl_msg *msg;
8753
8754 ifindex = if_nametoindex(intf);
8755 if (ifindex == 0) {
8756 sigma_dut_print(dut, DUT_MSG_ERROR,
8757 "%s: Index for interface %s failed",
8758 __func__, intf);
8759 return -1;
8760 }
8761
8762 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8763 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8764 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8765 sigma_dut_print(dut, DUT_MSG_ERROR,
8766 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8767 __func__);
8768 nlmsg_free(msg);
8769 return -1;
8770 }
8771
8772 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting HE GI %d",
8773 __func__, gi_val);
8774
8775 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8776 if (!attr1) {
8777 sigma_dut_print(dut, DUT_MSG_ERROR,
8778 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8779 __func__);
8780 nlmsg_free(msg);
8781 return -1;
8782 }
8783 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8784 nla_nest_end(msg, attr1);
8785
8786 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8787 if (!attr1) {
8788 sigma_dut_print(dut, DUT_MSG_ERROR,
8789 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8790 __func__);
8791 nlmsg_free(msg);
8792 return -1;
8793 }
8794 nla_put_u8(msg, NL80211_TXRATE_HE_GI, gi_val);
8795 nla_nest_end(msg, attr1);
8796
8797 nla_nest_end(msg, attr);
8798 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8799 if (ret) {
8800 sigma_dut_print(dut, DUT_MSG_ERROR,
8801 "%s: send_and_recv_msgs failed, ret=%d",
8802 __func__, ret);
8803 }
8804 return ret;
8805#else /* NL80211_SUPPORT */
8806 return -1;
8807#endif /* NL80211_SUPPORT */
8808}
8809
8810
8811static int sta_set_vht_gi(struct sigma_dut *dut, const char *intf, u8 gi_val)
8812{
8813 #ifdef NL80211_SUPPORT
8814 struct nlattr *attr;
8815 struct nlattr *attr1;
8816 int ifindex, ret;
8817 struct nl_msg *msg;
8818
8819 ifindex = if_nametoindex(intf);
8820 if (ifindex == 0) {
8821 sigma_dut_print(dut, DUT_MSG_ERROR,
8822 "%s: Index for interface %s failed",
8823 __func__, intf);
8824 return -1;
8825 }
8826
8827 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
8828 NL80211_CMD_SET_TX_BITRATE_MASK)) ||
8829 !(attr = nla_nest_start(msg, NL80211_ATTR_TX_RATES))) {
8830 sigma_dut_print(dut, DUT_MSG_ERROR,
8831 "%s: NL80211_CMD_SET_TX_BITRATE_MASK msg failed",
8832 __func__);
8833 nlmsg_free(msg);
8834 return -1;
8835 }
8836
8837 sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Setting VHT GI %d",
8838 __func__, gi_val);
8839
8840 attr1 = nla_nest_start(msg, NL80211_BAND_2GHZ);
8841 if (!attr1) {
8842 sigma_dut_print(dut, DUT_MSG_ERROR,
8843 "%s: Netlink nest start failed for NL80211_BAND_2GHZ",
8844 __func__);
8845 nlmsg_free(msg);
8846 return -1;
8847 }
8848 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8849 nla_nest_end(msg, attr1);
8850
8851 attr1 = nla_nest_start(msg, NL80211_BAND_5GHZ);
8852 if (!attr1) {
8853 sigma_dut_print(dut, DUT_MSG_ERROR,
8854 "%s: Netlink nest start failed for NL80211_BAND_5GHZ",
8855 __func__);
8856 nlmsg_free(msg);
8857 return -1;
8858 }
8859 nla_put_u8(msg, NL80211_TXRATE_GI, gi_val);
8860 nla_nest_end(msg, attr1);
8861 nla_nest_end(msg, attr);
8862
8863 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
8864 if (ret) {
8865 sigma_dut_print(dut, DUT_MSG_ERROR,
8866 "%s: send_and_recv_msgs failed, ret=%d",
8867 __func__, ret);
8868 }
8869 return ret;
8870#else /* NL80211_SUPPORT */
8871 return -1;
8872#endif /* NL80211_SUPPORT */
8873}
8874
8875
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008876static void sta_reset_default_wcn(struct sigma_dut *dut, const char *intf,
8877 const char *type)
8878{
8879 char buf[60];
8880
8881 if (dut->program == PROGRAM_HE) {
8882 /* resetting phymode to auto in case of HE program */
Vinita S. Maloo13a5cf72020-05-22 14:45:06 +05308883 sta_set_phymode(dut, intf, "auto");
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008884
Amarnath Hullur Subramanyam9cecb502018-04-25 13:26:30 -07008885 /* reset the rate to Auto rate */
8886 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0xff",
8887 intf);
8888 if (system(buf) != 0) {
8889 sigma_dut_print(dut, DUT_MSG_ERROR,
8890 "iwpriv %s set_11ax_rate 0xff failed",
8891 intf);
8892 }
8893
Kiran Kumar Lokere86cfe3a2018-06-01 11:55:15 -07008894 /* reset the LDPC setting */
8895 snprintf(buf, sizeof(buf), "iwpriv %s ldpc 1", intf);
8896 if (system(buf) != 0) {
8897 sigma_dut_print(dut, DUT_MSG_ERROR,
8898 "iwpriv %s ldpc 1 failed", intf);
8899 }
8900
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008901 /* reset the power save setting */
Vinita S. Malooa8b62722020-04-23 01:45:41 +05308902 set_power_save_wcn(dut, intf, 2);
Kiran Kumar Lokered6149ff2018-12-05 20:20:41 -08008903
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08008904 /* remove all network profiles */
8905 remove_wpa_networks(intf);
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08008906
Amarnath Hullur Subramanyam13215de2018-02-27 14:12:55 -08008907 /* Configure ADDBA Req/Rsp buffer size to be 64 */
8908 sta_set_addba_buf_size(dut, intf, 64);
8909
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07008910 if (dut->sta_async_twt_supp == -1)
8911 sta_get_twt_feature_async_supp(dut, intf);
8912
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -07008913 sta_set_scan_unicast_probe(dut, intf, 0);
8914
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008915#ifdef NL80211_SUPPORT
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008916 /* Reset the device HE capabilities to its default supported
8917 * configuration. */
8918 sta_set_he_testbed_def(dut, intf, 0);
8919
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008920 /* Disable noackpolicy for all AC */
8921 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
8922 sigma_dut_print(dut, DUT_MSG_ERROR,
8923 "Disable of noackpolicy for all AC failed");
8924 }
8925#endif /* NL80211_SUPPORT */
8926
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08008927 /* Enable WMM by default */
8928 if (wcn_sta_set_wmm(dut, intf, "on")) {
8929 sigma_dut_print(dut, DUT_MSG_ERROR,
8930 "Enable of WMM in sta_reset_default_wcn failed");
8931 }
8932
8933 /* Disable ADDBA_REJECT by default */
8934 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
8935 sigma_dut_print(dut, DUT_MSG_ERROR,
8936 "Disable of addba_reject in sta_reset_default_wcn failed");
8937 }
8938
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08008939 /* Enable sending of ADDBA by default */
8940 if (nlvendor_config_send_addba(dut, intf, 1)) {
8941 sigma_dut_print(dut, DUT_MSG_ERROR,
8942 "Enable sending of ADDBA in sta_reset_default_wcn failed");
8943 }
8944
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08008945 /* Enable AMPDU by default */
8946 iwpriv_sta_set_ampdu(dut, intf, 1);
8947
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008948#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08008949 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008950 sigma_dut_print(dut, DUT_MSG_ERROR,
8951 "Set LTF config to default in sta_reset_default_wcn failed");
8952 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07008953
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08008954 /* set the beamformee NSTS(maximum number of
8955 * space-time streams) to default DUT config
8956 */
8957 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07008958 sigma_dut_print(dut, DUT_MSG_ERROR,
8959 "Failed to set BeamformeeSTS");
8960 }
Arif Hussain68d23f52018-07-11 13:39:08 -07008961
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008962 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, 0)) {
8963 sigma_dut_print(dut, DUT_MSG_ERROR,
8964 "Failed to reset mgmt/data Tx disable config");
8965 }
8966
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008967 if (sta_set_mac_padding_duration(
8968 dut, intf,
8969 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008970 sigma_dut_print(dut, DUT_MSG_ERROR,
8971 "Failed to set MAC padding duration");
8972 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008973
8974 if (sta_set_mu_edca_override(dut, intf, 0)) {
8975 sigma_dut_print(dut, DUT_MSG_ERROR,
8976 "ErrorCode,Failed to set MU EDCA override disable");
8977 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008978
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008979 if (sta_set_ru_242_tone_tx(dut, intf, 0)) {
8980 sigma_dut_print(dut, DUT_MSG_ERROR,
8981 "Failed to set RU 242 tone Tx");
8982 }
8983
8984 if (sta_set_er_su_ppdu_type_tx(dut, intf, 0)) {
8985 sigma_dut_print(dut, DUT_MSG_ERROR,
8986 "Failed to set ER-SU PPDU type Tx");
8987 }
8988
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008989 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
8990 sigma_dut_print(dut, DUT_MSG_ERROR,
8991 "Failed to set OM ctrl supp");
8992 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008993
8994 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
8995 sigma_dut_print(dut, DUT_MSG_ERROR,
8996 "Failed to set Tx SU PPDU enable");
8997 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07008998
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07008999 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
9000 sigma_dut_print(dut, DUT_MSG_ERROR,
9001 "failed to send TB PPDU Tx cfg");
9002 }
9003
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009004 if (sta_set_he_om_ctrl_reset(dut, intf)) {
9005 sigma_dut_print(dut, DUT_MSG_ERROR,
9006 "Failed to set OM ctrl reset");
9007 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009008
9009 /* +HTC-HE support default on */
9010 if (sta_set_he_htc_supp(dut, intf, 1)) {
9011 sigma_dut_print(dut, DUT_MSG_ERROR,
9012 "Setting of +HTC-HE support failed");
9013 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009014#endif /* NL80211_SUPPORT */
9015
Arif Hussain8d5b27b2018-05-14 14:31:03 -07009016 if (sta_set_tx_beamformee(dut, intf, 1)) {
9017 sigma_dut_print(dut, DUT_MSG_ERROR,
9018 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
9019 }
9020
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009021 wpa_command(intf, "SET oce 1");
9022
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009023 /* Set nss to 1 and MCS 0-7 in case of testbed */
9024 if (type && strcasecmp(type, "Testbed") == 0) {
9025#ifdef NL80211_SUPPORT
9026 int ret;
9027#endif /* NL80211_SUPPORT */
9028
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009029 wpa_command(intf, "SET oce 0");
9030
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009031 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
9032 if (system(buf) != 0) {
9033 sigma_dut_print(dut, DUT_MSG_ERROR,
9034 "iwpriv %s nss failed", intf);
9035 }
9036
9037#ifdef NL80211_SUPPORT
9038 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
9039 if (ret) {
9040 sigma_dut_print(dut, DUT_MSG_ERROR,
9041 "Setting of MCS failed, ret:%d",
9042 ret);
9043 }
9044#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08009045
9046 /* Disable STBC as default */
9047 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08009048
9049 /* Disable AMSDU as default */
9050 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009051
9052#ifdef NL80211_SUPPORT
9053 /* HE fragmentation default off */
9054 if (sta_set_he_fragmentation(dut, intf,
9055 HE_FRAG_DISABLE)) {
9056 sigma_dut_print(dut, DUT_MSG_ERROR,
9057 "Setting of HE fragmentation failed");
9058 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009059
9060 /* set the beamformee NSTS(maximum number of
9061 * space-time streams) to default testbed config
9062 */
9063 if (sta_set_beamformee_sts(dut, intf, 3)) {
9064 sigma_dut_print(dut, DUT_MSG_ERROR,
9065 "Failed to set BeamformeeSTS");
9066 }
9067
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07009068 if (sta_set_punctured_preamble_rx(dut, intf, 0)) {
9069 sigma_dut_print(dut, DUT_MSG_ERROR,
9070 "Failed to reset PreamblePunctRx support");
9071 }
9072
Kiran Kumar Lokere727687f2021-06-24 00:35:49 -07009073 if (sta_set_bss_max_idle_period(dut, intf, 0)) {
9074 sigma_dut_print(dut, DUT_MSG_ERROR,
9075 "Failed to reset BSS max idle period");
9076 }
9077
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009078 /* +HTC-HE support default off */
9079 if (sta_set_he_htc_supp(dut, intf, 0)) {
9080 sigma_dut_print(dut, DUT_MSG_ERROR,
9081 "Setting of +HTC-HE support failed");
9082 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08009083
9084 /* Set device HE capabilities to testbed default
9085 * configuration. */
9086 if (sta_set_he_testbed_def(dut, intf, 1)) {
9087 sigma_dut_print(dut, DUT_MSG_DEBUG,
9088 "Failed to set HE defaults");
9089 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08009090
9091 /* Disable VHT support in 2.4 GHz for testbed */
9092 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009093#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08009094
9095 /* Enable WEP/TKIP with HE capability in testbed */
9096 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
9097 sigma_dut_print(dut, DUT_MSG_ERROR,
9098 "Enabling HE config with WEP/TKIP failed");
9099 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009100 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009101
9102 /* Defaults in case of DUT */
9103 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07009104 /* Enable STBC by default */
9105 wcn_sta_set_stbc(dut, intf, "1");
9106
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009107 /* set nss to 2 */
9108 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
9109 if (system(buf) != 0) {
9110 sigma_dut_print(dut, DUT_MSG_ERROR,
9111 "iwpriv %s nss 2 failed", intf);
9112 }
Arif Hussainac6c5112018-05-25 17:34:00 -07009113 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009114
9115#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07009116 /* Set HE_MCS to 0-11 */
9117 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009118 sigma_dut_print(dut, DUT_MSG_ERROR,
9119 "Setting of MCS failed");
9120 }
9121#endif /* NL80211_SUPPORT */
9122
9123 /* Disable WEP/TKIP with HE capability in DUT */
9124 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
9125 sigma_dut_print(dut, DUT_MSG_ERROR,
9126 "Enabling HE config with WEP/TKIP failed");
9127 }
9128 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009129 }
9130}
9131
9132
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309133static int sta_set_client_privacy(struct sigma_dut *dut,
9134 struct sigma_conn *conn, const char *intf,
9135 int enable)
9136{
9137 if (enable &&
9138 (wpa_command(intf, "SET mac_addr 1") < 0 ||
9139 wpa_command(intf, "SET rand_addr_lifetime 1") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309140 (wpa_command(intf, "MAC_RAND_SCAN enable=1 all") < 0 &&
9141 wpa_command(intf, "SET preassoc_mac_addr 1") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309142 wpa_command(intf, "SET gas_rand_mac_addr 1") < 0 ||
9143 wpa_command(intf, "SET gas_rand_addr_lifetime 1") < 0))
9144 return -1;
9145
9146 if (!enable &&
9147 (wpa_command(intf, "SET mac_addr 0") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309148 (wpa_command(intf, "MAC_RAND_SCAN enable=0 all") < 0 &&
9149 wpa_command(intf, "SET preassoc_mac_addr 0") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309150 wpa_command(intf, "SET gas_rand_mac_addr 0") < 0))
9151 return -1;
9152
9153 dut->client_privacy = enable;
9154 return 0;
9155}
9156
9157
Jouni Malinenf7222712019-06-13 01:50:21 +03009158static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
9159 struct sigma_conn *conn,
9160 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009161{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009162 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009163 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009164 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009165 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309166 const char *dev_role = get_param(cmd, "DevRole");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309167 char resp[20];
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309168 char buf[100];
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309169 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009170
Jouni Malinenb21f0542019-11-04 17:53:38 +02009171 if (dut->station_ifname_2g &&
9172 strcmp(dut->station_ifname_2g, intf) == 0)
9173 dut->use_5g = 0;
9174 else if (dut->station_ifname_5g &&
9175 strcmp(dut->station_ifname_5g, intf) == 0)
9176 dut->use_5g = 1;
9177
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009178 if (!program)
9179 program = get_param(cmd, "prog");
9180 dut->program = sigma_program_to_enum(program);
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05309181
9182 if (dut->program == PROGRAM_WFD && dut->user_config_timeout)
9183 dut->default_timeout = dut->user_config_timeout;
9184
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009185 dut->device_type = STA_unknown;
9186 type = get_param(cmd, "type");
9187 if (type && strcasecmp(type, "Testbed") == 0)
9188 dut->device_type = STA_testbed;
9189 if (type && strcasecmp(type, "DUT") == 0)
9190 dut->device_type = STA_dut;
9191
9192 if (dut->program == PROGRAM_TDLS) {
9193 /* Clear TDLS testing mode */
9194 wpa_command(intf, "SET tdls_disabled 0");
9195 wpa_command(intf, "SET tdls_testing 0");
9196 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009197 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05309198 /* Enable the WCN driver in TDLS Explicit trigger mode
9199 */
9200 wpa_command(intf, "SET tdls_external_control 0");
9201 wpa_command(intf, "SET tdls_trigger_control 0");
9202 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009203 }
9204
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009205#ifdef MIRACAST
9206 if (dut->program == PROGRAM_WFD ||
9207 dut->program == PROGRAM_DISPLAYR2)
9208 miracast_sta_reset_default(dut, conn, cmd);
9209#endif /* MIRACAST */
9210
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009211 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009212 case DRIVER_ATHEROS:
9213 sta_reset_default_ath(dut, intf, type);
9214 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009215 case DRIVER_WCN:
9216 sta_reset_default_wcn(dut, intf, type);
9217 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009218 default:
9219 break;
9220 }
9221
9222#ifdef ANDROID_NAN
9223 if (dut->program == PROGRAM_NAN)
9224 nan_cmd_sta_reset_default(dut, conn, cmd);
9225#endif /* ANDROID_NAN */
9226
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05309227 if (dut->program == PROGRAM_LOC &&
9228 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
9229 return ERROR_SEND_STATUS;
9230
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009231 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
9232 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009233 unlink("SP/wi-fi.org/pps.xml");
9234 if (system("rm -r SP/*") != 0) {
9235 }
9236 unlink("next-client-cert.pem");
9237 unlink("next-client-key.pem");
9238 }
9239
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009240 /* For WPS program of the 60 GHz band the band type needs to be saved */
9241 if (dut->program == PROGRAM_WPS) {
9242 if (band && strcasecmp(band, "60GHz") == 0) {
9243 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009244 /* For 60 GHz enable WPS for WPS TCs */
9245 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009246 } else {
9247 dut->band = WPS_BAND_NON_60G;
9248 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009249 } else if (dut->program == PROGRAM_60GHZ) {
9250 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
9251 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009252 }
9253
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02009254 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009255 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009256 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009257
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009258 sigma_dut_print(dut, DUT_MSG_INFO,
9259 "WPS 60 GHz program, wps_disable = %d",
9260 dut->wps_disable);
9261
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009262 if (!dev_role) {
9263 send_resp(dut, conn, SIGMA_ERROR,
9264 "errorCode,Missing DevRole argument");
9265 return 0;
9266 }
9267
9268 if (strcasecmp(dev_role, "STA") == 0)
9269 dut->dev_role = DEVROLE_STA;
9270 else if (strcasecmp(dev_role, "PCP") == 0)
9271 dut->dev_role = DEVROLE_PCP;
9272 else {
9273 send_resp(dut, conn, SIGMA_ERROR,
9274 "errorCode,Unknown DevRole");
9275 return 0;
9276 }
9277
9278 if (dut->device_type == STA_unknown) {
9279 sigma_dut_print(dut, DUT_MSG_ERROR,
9280 "Device type is not STA testbed or DUT");
9281 send_resp(dut, conn, SIGMA_ERROR,
9282 "errorCode,Unknown device type");
9283 return 0;
9284 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009285
9286 sigma_dut_print(dut, DUT_MSG_DEBUG,
9287 "Setting msdu_size to MAX: 7912");
9288 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009289 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009290
9291 if (system(buf) != 0) {
9292 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9293 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009294 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009295 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009296
9297 if (sta_set_force_mcs(dut, 0, 1)) {
9298 sigma_dut_print(dut, DUT_MSG_ERROR,
9299 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009300 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009301 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009302 }
9303
9304 wpa_command(intf, "WPS_ER_STOP");
9305 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05309306 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009307 wpa_command(intf, "SET radio_disabled 0");
9308
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02009309 dut->wps_forced_version = 0;
9310
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009311 if (dut->wsc_fragment) {
9312 dut->wsc_fragment = 0;
9313 wpa_command(intf, "SET device_name Test client");
9314 wpa_command(intf, "SET manufacturer ");
9315 wpa_command(intf, "SET model_name ");
9316 wpa_command(intf, "SET model_number ");
9317 wpa_command(intf, "SET serial_number ");
9318 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02009319 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
9320 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
9321 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
9322 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009323
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009324 if (dut->tmp_mac_addr && dut->set_macaddr) {
9325 dut->tmp_mac_addr = 0;
9326 if (system(dut->set_macaddr) != 0) {
9327 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
9328 "temporary MAC address");
9329 }
9330 }
9331
9332 set_ps(intf, dut, 0);
9333
Jouni Malinenba630452018-06-22 11:49:59 +03009334 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009335 dut->program == PROGRAM_HS2_R3 || dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009336 wpa_command(intf, "SET interworking 1");
9337 wpa_command(intf, "SET hs20 1");
9338 }
9339
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009340 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03009341 dut->program == PROGRAM_HS2_R3 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009342 dut->program == PROGRAM_HS2_R4 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009343 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009344 wpa_command(intf, "SET pmf 1");
9345 } else {
9346 wpa_command(intf, "SET pmf 0");
9347 }
9348
9349 hs2_clear_credentials(intf);
9350 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
9351 wpa_command(intf, "SET access_network_type 15");
9352
9353 static_ip_file(0, NULL, NULL, NULL);
9354 kill_dhcp_client(dut, intf);
9355 clear_ip_addr(dut, intf);
9356
9357 dut->er_oper_performed = 0;
9358 dut->er_oper_bssid[0] = '\0';
9359
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009360 if (dut->program == PROGRAM_LOC) {
9361 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009362 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009363 }
9364
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07009365 if (dut->program == PROGRAM_MBO || dut->program == PROGRAM_HE) {
Ashwini Patil00402582017-04-13 12:29:39 +05309366 free(dut->non_pref_ch_list);
9367 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309368 free(dut->btm_query_cand_list);
9369 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05309370 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05309371 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05309372 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05309373 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05309374 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05309375 }
9376
Jouni Malinen3c367e82017-06-23 17:01:47 +03009377 free(dut->rsne_override);
9378 dut->rsne_override = NULL;
9379
Jouni Malinen68143132017-09-02 02:34:08 +03009380 free(dut->sae_commit_override);
9381 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03009382 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02009383 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03009384
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009385 dut->sta_associate_wait_connect = 0;
9386 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03009387 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009388 dut->sta_tod_policy = 0;
9389
Jouni Malinend86e5822017-08-29 03:55:32 +03009390 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02009391 free(dut->dpp_peer_uri);
9392 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02009393 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02009394 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03009395 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinend86e5822017-08-29 03:55:32 +03009396
Jouni Malinenfac9cad2017-10-10 18:35:55 +03009397 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
9398
vamsi krishnaa2799492017-12-05 14:28:01 +05309399 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309400 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05309401 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05309402 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
9403 dut->fils_hlp = 0;
9404#ifdef ANDROID
9405 hlp_thread_cleanup(dut);
9406#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05309407 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309408
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309409 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309410 wpa_command(intf, "SET interworking 1");
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309411 wpa_command(intf, "SET enable_dscp_policy_capa 1");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05309412 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309413 dut->reject_dscp_policies = 0;
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +05309414 dut->num_dscp_status = 0;
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309415 snprintf(buf, sizeof(buf),
9416 "ip -6 route replace fe80::/64 dev %s table local",
9417 intf);
9418 if (system(buf) != 0)
9419 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
9420 buf);
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05309421
9422 stop_dscp_policy_mon_thread(dut);
9423 clear_all_dscp_policies(dut);
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309424 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309425
Jouni Malinen8179fee2019-03-28 03:19:47 +02009426 dut->akm_values = 0;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05309427
9428#ifdef NL80211_SUPPORT
9429 if (get_driver_type(dut) == DRIVER_WCN)
9430 sta_config_params(dut, intf, STA_SET_FT_DS, 0);
9431#endif /* NL80211_SUPPORT */
9432
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03009433 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02009434
Sunil Dutt076081f2018-02-05 19:45:50 +05309435#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009436 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05309437 dut->config_rsnie == 1) {
9438 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309439 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05309440 }
9441#endif /* NL80211_SUPPORT */
9442
Sunil Duttfebf8a82018-02-09 18:50:13 +05309443 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
9444 dut->dev_role = DEVROLE_STA_CFON;
9445 return sta_cfon_reset_default(dut, conn, cmd);
9446 }
9447
Jouni Malinen439352d2018-09-13 03:42:23 +03009448 wpa_command(intf, "SET setband AUTO");
9449
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309450 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
9451 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
9452
9453 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
9454 sizeof(resp));
9455 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
9456
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309457 if (sta_set_client_privacy(dut, conn, intf,
9458 dut->program == PROGRAM_WPA3 &&
9459 dut->device_type == STA_dut &&
9460 dut->client_privacy_default)) {
9461 sigma_dut_print(dut, DUT_MSG_ERROR,
9462 "Failed to set client privacy functionality");
9463 /* sta_reset_default command is not really supposed to fail,
9464 * so allow this to continue. */
9465 }
9466
Veerendranath Jakkamca239592021-10-11 20:48:00 +05309467 if (get_driver_type(dut) == DRIVER_WCN)
9468 wcn_set_ignore_h2e_rsnxe(dut, intf, 0);
9469
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05309470 dut->saquery_oci_freq = 0;
Shivani Baranwalebde8f62021-10-19 12:26:02 +05309471 dut->prev_disable_scs_support = 0;
9472 dut->prev_disable_mscs_support = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309473
Sunil Duttfebf8a82018-02-09 18:50:13 +05309474 if (dut->program != PROGRAM_VHT)
9475 return cmd_sta_p2p_reset(dut, conn, cmd);
9476
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08009477 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009478}
9479
9480
Jouni Malinenf7222712019-06-13 01:50:21 +03009481static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
9482 struct sigma_conn *conn,
9483 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009484{
9485 const char *program = get_param(cmd, "Program");
9486
9487 if (program == NULL)
9488 return -1;
9489#ifdef ANDROID_NAN
9490 if (strcasecmp(program, "NAN") == 0)
9491 return nan_cmd_sta_get_events(dut, conn, cmd);
9492#endif /* ANDROID_NAN */
9493 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9494 return 0;
9495}
9496
9497
Jouni Malinen82905202018-04-29 17:20:10 +03009498static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
9499 struct sigma_cmd *cmd)
9500{
9501 const char *url = get_param(cmd, "url");
9502 const char *method = get_param(cmd, "method");
9503 pid_t pid;
9504 int status;
9505
9506 if (!url || !method)
9507 return -1;
9508
9509 /* TODO: Add support for method,post */
9510 if (strcasecmp(method, "get") != 0) {
9511 send_resp(dut, conn, SIGMA_ERROR,
9512 "ErrorCode,Unsupported method");
9513 return 0;
9514 }
9515
9516 pid = fork();
9517 if (pid < 0) {
9518 perror("fork");
9519 return -1;
9520 }
9521
9522 if (pid == 0) {
9523 char * argv[5] = { "wget", "-O", "/dev/null",
9524 (char *) url, NULL };
9525
9526 execv("/usr/bin/wget", argv);
9527 perror("execv");
9528 exit(0);
9529 return -1;
9530 }
9531
9532 if (waitpid(pid, &status, 0) < 0) {
9533 perror("waitpid");
9534 return -1;
9535 }
9536
9537 if (WIFEXITED(status)) {
9538 const char *errmsg;
9539
9540 if (WEXITSTATUS(status) == 0)
9541 return 1;
9542 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
9543 WEXITSTATUS(status));
9544 switch (WEXITSTATUS(status)) {
9545 case 4:
9546 errmsg = "errmsg,Network failure";
9547 break;
9548 case 8:
9549 errmsg = "errmsg,Server issued an error response";
9550 break;
9551 default:
9552 errmsg = "errmsg,Unknown failure from wget";
9553 break;
9554 }
9555 send_resp(dut, conn, SIGMA_ERROR, errmsg);
9556 return 0;
9557 }
9558
9559 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
9560 return 0;
9561}
9562
9563
Jouni Malinenf7222712019-06-13 01:50:21 +03009564static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
9565 struct sigma_conn *conn,
9566 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009567{
9568 const char *program = get_param(cmd, "Prog");
9569
Jouni Malinen82905202018-04-29 17:20:10 +03009570 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009571 return -1;
9572#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03009573 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009574 return nan_cmd_sta_exec_action(dut, conn, cmd);
9575#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03009576
9577 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009578 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03009579
9580 if (get_param(cmd, "url"))
9581 return sta_exec_action_url(dut, conn, cmd);
9582
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009583 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9584 return 0;
9585}
9586
9587
Jouni Malinenf7222712019-06-13 01:50:21 +03009588static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
9589 struct sigma_conn *conn,
9590 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009591{
9592 const char *intf = get_param(cmd, "Interface");
9593 const char *val, *mcs32, *rate;
9594
9595 val = get_param(cmd, "GREENFIELD");
9596 if (val) {
9597 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
9598 /* Enable GD */
9599 send_resp(dut, conn, SIGMA_ERROR,
9600 "ErrorCode,GF not supported");
9601 return 0;
9602 }
9603 }
9604
9605 val = get_param(cmd, "SGI20");
9606 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009607 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009608 case DRIVER_ATHEROS:
9609 ath_sta_set_sgi(dut, intf, val);
9610 break;
9611 default:
9612 send_resp(dut, conn, SIGMA_ERROR,
9613 "ErrorCode,SGI20 not supported");
9614 return 0;
9615 }
9616 }
9617
9618 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
9619 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
9620 if (mcs32 && rate) {
9621 /* TODO */
9622 send_resp(dut, conn, SIGMA_ERROR,
9623 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
9624 return 0;
9625 } else if (mcs32 && !rate) {
9626 /* TODO */
9627 send_resp(dut, conn, SIGMA_ERROR,
9628 "ErrorCode,MCS32 not supported");
9629 return 0;
9630 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009631 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009632 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07009633 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009634 ath_sta_set_11nrates(dut, intf, rate);
9635 break;
9636 default:
9637 send_resp(dut, conn, SIGMA_ERROR,
9638 "ErrorCode,MCS32_FIXEDRATE not supported");
9639 return 0;
9640 }
9641 }
9642
9643 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9644}
9645
9646
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009647static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
9648 int mcs_config)
9649{
9650#ifdef NL80211_SUPPORT
9651 int ret;
9652
9653 switch (mcs_config) {
9654 case HE_80_MCS0_7:
9655 case HE_80_MCS0_9:
9656 case HE_80_MCS0_11:
9657 ret = sta_set_he_mcs(dut, intf, mcs_config);
9658 if (ret) {
9659 sigma_dut_print(dut, DUT_MSG_ERROR,
9660 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
9661 mcs_config, ret);
9662 }
9663 break;
9664 default:
9665 sigma_dut_print(dut, DUT_MSG_ERROR,
9666 "cmd_set_max_he_mcs: Invalid mcs %d",
9667 mcs_config);
9668 break;
9669 }
9670#else /* NL80211_SUPPORT */
9671 sigma_dut_print(dut, DUT_MSG_ERROR,
9672 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
9673#endif /* NL80211_SUPPORT */
9674}
9675
9676
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009677struct wait_event {
9678 struct sigma_dut *dut;
9679 int cmd;
9680 unsigned int twt_op;
9681};
9682
9683#ifdef NL80211_SUPPORT
9684
9685static int twt_event_handler(struct nl_msg *msg, void *arg)
9686{
9687 struct wait_event *wait = arg;
9688 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9689 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9690 uint32_t subcmd;
9691 uint8_t *data = NULL;
9692 size_t len = 0;
9693 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
9694 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
9695 int cmd_id;
9696 unsigned char val;
9697
9698 if (!wait)
9699 return NL_SKIP;
9700
9701 if (gnlh->cmd != NL80211_CMD_VENDOR) {
9702 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9703 "%s: NL cmd is not vendor %d", __func__,
9704 gnlh->cmd);
9705 return NL_SKIP;
9706 }
9707
9708 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9709 genlmsg_attrlen(gnlh, 0), NULL);
9710
9711 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
9712 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9713 "%s: vendor ID not found", __func__);
9714 return NL_SKIP;
9715 }
9716 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
9717
9718 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
9719 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9720 "%s: Not a TWT_cmd %d", __func__, subcmd);
9721 return NL_SKIP;
9722 }
9723 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9724 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
9725 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
9726 } else {
9727 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9728 "%s: vendor data not present", __func__);
9729 return NL_SKIP;
9730 }
9731 if (!data || !len) {
9732 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9733 "Invalid vendor data or len");
9734 return NL_SKIP;
9735 }
9736 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
9737 "event data len %ld", len);
9738 hex_dump(wait->dut, data, len);
9739 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
9740 (struct nlattr *) data, len, NULL)) {
9741 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9742 "vendor data parse error");
9743 return NL_SKIP;
9744 }
9745
9746 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
9747 if (val != wait->twt_op) {
9748 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9749 "Invalid TWT operation, expected %d, rcvd %d",
9750 wait->twt_op, val);
9751 return NL_SKIP;
9752 }
9753 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
9754 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
9755 NULL)) {
9756 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9757 "nla_parse failed for TWT event");
9758 return NL_SKIP;
9759 }
9760
9761 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
9762 if (!twt_status[cmd_id]) {
9763 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9764 "%s TWT resp status missing", __func__);
9765 wait->cmd = -1;
9766 } else {
9767 val = nla_get_u8(twt_status[cmd_id]);
9768 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
9769 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9770 "%s TWT resp status %d", __func__, val);
9771 wait->cmd = -1;
9772 } else {
9773 wait->cmd = 1;
9774 }
9775 }
9776
9777 return NL_SKIP;
9778}
9779
9780
9781static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
9782 unsigned int timeout)
9783{
9784 fd_set read_fd_set;
9785 int retval;
9786 int sock_fd;
9787 struct timeval time_out;
9788
9789 time_out.tv_sec = timeout;
9790 time_out.tv_usec = 0;
9791
9792 FD_ZERO(&read_fd_set);
9793
9794 if (!sock)
9795 return -1;
9796
9797 sock_fd = nl_socket_get_fd(sock);
9798 FD_SET(sock_fd, &read_fd_set);
9799
9800 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
9801
9802 if (retval == 0)
9803 sigma_dut_print(dut, DUT_MSG_ERROR,
9804 "%s: TWT event response timedout", __func__);
9805
9806 if (retval < 0)
9807 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
9808 __func__, retval);
9809
9810 return retval;
9811}
9812
9813
9814#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
9815
9816static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
9817{
9818 struct nl_cb *cb;
9819 int err_code = 0, select_retval = 0;
9820 struct wait_event wait_info;
9821
9822 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
9823 if (!cb) {
9824 sigma_dut_print(dut, DUT_MSG_ERROR,
9825 "event callback not found");
9826 return ERROR_SEND_STATUS;
9827 }
9828
9829 wait_info.cmd = 0;
9830 wait_info.dut = dut;
9831 wait_info.twt_op = twt_op;
9832
9833 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
9834
9835 while (!wait_info.cmd) {
9836 select_retval = wait_on_nl_socket(
9837 dut->nl_ctx->event_sock, dut,
9838 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
9839
9840 if (select_retval > 0) {
9841 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
9842 if (err_code < 0) {
9843 sigma_dut_print(dut, DUT_MSG_ERROR,
9844 "%s: nl rcv failed, err_code %d",
9845 __func__, err_code);
9846 break;
9847 }
9848 } else {
9849 sigma_dut_print(dut, DUT_MSG_ERROR,
9850 "%s: wait on socket failed %d",
9851 __func__, select_retval);
9852 err_code = 1;
9853 break;
9854 }
9855
9856 }
9857 nl_cb_put(cb);
9858
9859 if (wait_info.cmd < 0)
9860 err_code = 1;
9861
9862 sigma_dut_print(dut, DUT_MSG_DEBUG,
9863 "%s: rcvd cmd %d, err_code %d, s_ret %d",
9864 __func__, wait_info.cmd, err_code, select_retval);
9865
9866 return err_code;
9867}
9868
9869#endif /* NL80211_SUPPORT */
9870
9871
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009872static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
9873 struct sigma_cmd *cmd)
9874{
9875#ifdef NL80211_SUPPORT
9876 struct nlattr *attr, *attr1;
9877 struct nl_msg *msg;
9878 int ifindex, ret;
9879 const char *intf = get_param(cmd, "Interface");
9880
9881 ifindex = if_nametoindex(intf);
9882 if (ifindex == 0) {
9883 sigma_dut_print(dut, DUT_MSG_ERROR,
9884 "%s: Index for interface %s failed",
9885 __func__, intf);
9886 return ERROR_SEND_STATUS;
9887 }
9888
9889 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9890 NL80211_CMD_VENDOR)) ||
9891 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9892 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9893 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9894 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9895 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9896 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9897 QCA_WLAN_TWT_SUSPEND) ||
9898 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07009899 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009900 sigma_dut_print(dut, DUT_MSG_ERROR,
9901 "%s: err in adding vendor_cmd and vendor_data",
9902 __func__);
9903 nlmsg_free(msg);
9904 return ERROR_SEND_STATUS;
9905 }
9906 nla_nest_end(msg, attr1);
9907 nla_nest_end(msg, attr);
9908
9909 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9910 if (ret) {
9911 sigma_dut_print(dut, DUT_MSG_ERROR,
9912 "%s: err in send_and_recv_msgs, ret=%d",
9913 __func__, ret);
9914 }
9915
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009916 if (!dut->sta_async_twt_supp)
9917 return ret;
9918
9919 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009920#else /* NL80211_SUPPORT */
9921 sigma_dut_print(dut, DUT_MSG_ERROR,
9922 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9923 return ERROR_SEND_STATUS;
9924#endif /* NL80211_SUPPORT */
9925}
9926
9927
9928static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
9929 struct sigma_cmd *cmd,
9930 unsigned int suspend_duration)
9931{
9932#ifdef NL80211_SUPPORT
9933 struct nlattr *attr, *attr1;
9934 struct nl_msg *msg;
9935 int ifindex, ret;
9936 const char *intf = get_param(cmd, "Interface");
9937 int next_twt_size = 1;
9938
9939 ifindex = if_nametoindex(intf);
9940 if (ifindex == 0) {
9941 sigma_dut_print(dut, DUT_MSG_ERROR,
9942 "%s: Index for interface %s failed",
9943 __func__, intf);
9944 return ERROR_SEND_STATUS;
9945 }
9946
9947 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9948 NL80211_CMD_VENDOR)) ||
9949 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9950 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9951 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9952 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9953 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9954 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9955 QCA_WLAN_TWT_NUDGE) ||
9956 !(attr1 = nla_nest_start(msg,
9957 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
9958 (suspend_duration &&
9959 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
9960 suspend_duration)) ||
9961 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009962 next_twt_size) ||
9963 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009964 sigma_dut_print(dut, DUT_MSG_ERROR,
9965 "%s: err in adding vendor_cmd and vendor_data",
9966 __func__);
9967 nlmsg_free(msg);
9968 return ERROR_SEND_STATUS;
9969 }
9970 nla_nest_end(msg, attr1);
9971 nla_nest_end(msg, attr);
9972
9973 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9974 if (ret) {
9975 sigma_dut_print(dut, DUT_MSG_ERROR,
9976 "%s: err in send_and_recv_msgs, ret=%d",
9977 __func__, ret);
9978 }
9979
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009980 if (!dut->sta_async_twt_supp)
9981 return ret;
9982
9983 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009984#else /* NL80211_SUPPORT */
9985 sigma_dut_print(dut, DUT_MSG_ERROR,
9986 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9987 return ERROR_SEND_STATUS;
9988#endif /* NL80211_SUPPORT */
9989}
9990
9991
9992static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
9993 struct sigma_conn *conn,
9994 struct sigma_cmd *cmd)
9995{
9996 const char *val;
9997
9998 val = get_param(cmd, "TWT_SuspendDuration");
9999 if (val) {
10000 unsigned int suspend_duration;
10001
10002 suspend_duration = atoi(val);
10003 suspend_duration = suspend_duration * 1000 * 1000;
10004 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
10005 }
10006
10007 return sta_twt_send_suspend(dut, conn, cmd);
10008}
10009
10010
10011static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
10012 struct sigma_cmd *cmd)
10013{
10014#ifdef NL80211_SUPPORT
10015 struct nlattr *attr, *attr1;
10016 struct nl_msg *msg;
10017 int ifindex, ret;
10018 const char *intf = get_param(cmd, "Interface");
10019 int next2_twt_size = 1;
10020 unsigned int resume_duration = 0;
10021 const char *val;
10022
10023 ifindex = if_nametoindex(intf);
10024 if (ifindex == 0) {
10025 sigma_dut_print(dut, DUT_MSG_ERROR,
10026 "%s: Index for interface %s failed",
10027 __func__, intf);
10028 return ERROR_SEND_STATUS;
10029 }
10030
10031 val = get_param(cmd, "TWT_ResumeDuration");
10032 if (val) {
10033 resume_duration = atoi(val);
10034 resume_duration = resume_duration * 1000 * 1000;
10035 }
10036
10037 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10038 NL80211_CMD_VENDOR)) ||
10039 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10040 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10041 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10042 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10043 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10044 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10045 QCA_WLAN_TWT_RESUME) ||
10046 !(attr1 = nla_nest_start(msg,
10047 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10048 (resume_duration &&
10049 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
10050 resume_duration)) ||
10051 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
10052 next2_twt_size)) {
10053 sigma_dut_print(dut, DUT_MSG_ERROR,
10054 "%s: err in adding vendor_cmd and vendor_data",
10055 __func__);
10056 nlmsg_free(msg);
10057 return ERROR_SEND_STATUS;
10058 }
10059 nla_nest_end(msg, attr1);
10060 nla_nest_end(msg, attr);
10061
10062 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10063 if (ret) {
10064 sigma_dut_print(dut, DUT_MSG_ERROR,
10065 "%s: err in send_and_recv_msgs, ret=%d",
10066 __func__, ret);
10067 }
10068
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010069 if (!dut->sta_async_twt_supp)
10070 return ret;
10071
10072 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010073#else /* NL80211_SUPPORT */
10074 sigma_dut_print(dut, DUT_MSG_ERROR,
10075 "TWT resume cannot be done without NL80211_SUPPORT defined");
10076 return ERROR_SEND_STATUS;
10077#endif /* NL80211_SUPPORT */
10078}
10079
10080
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010081#define TWT_REQUEST_CMD 0
10082#define TWT_SUGGEST_CMD 1
10083#define TWT_DEMAND_CMD 2
10084
Arif Hussain480d5f42019-03-12 14:40:42 -070010085static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
10086 struct sigma_cmd *cmd)
10087{
10088#ifdef NL80211_SUPPORT
10089 struct nlattr *params;
10090 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010091 struct nl_msg *msg;
10092 int ifindex, ret;
10093 const char *val;
10094 const char *intf = get_param(cmd, "Interface");
10095 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
10096 wake_interval_mantissa = 512;
10097 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010098 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010099 int bcast_twt = 0;
10100 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -070010101
10102 ifindex = if_nametoindex(intf);
10103 if (ifindex == 0) {
10104 sigma_dut_print(dut, DUT_MSG_ERROR,
10105 "%s: Index for interface %s failed",
10106 __func__, intf);
10107 return -1;
10108 }
10109
10110 val = get_param(cmd, "FlowType");
10111 if (val) {
10112 flow_type = atoi(val);
10113 if (flow_type != 0 && flow_type != 1) {
10114 sigma_dut_print(dut, DUT_MSG_ERROR,
10115 "TWT: Invalid FlowType %d", flow_type);
10116 return -1;
10117 }
10118 }
10119
10120 val = get_param(cmd, "TWT_Trigger");
10121 if (val) {
10122 twt_trigger = atoi(val);
10123 if (twt_trigger != 0 && twt_trigger != 1) {
10124 sigma_dut_print(dut, DUT_MSG_ERROR,
10125 "TWT: Invalid TWT_Trigger %d",
10126 twt_trigger);
10127 return -1;
10128 }
10129 }
10130
10131 val = get_param(cmd, "Protection");
10132 if (val) {
10133 protection = atoi(val);
10134 if (protection != 0 && protection != 1) {
10135 sigma_dut_print(dut, DUT_MSG_ERROR,
10136 "TWT: Invalid Protection %d",
10137 protection);
10138 return -1;
10139 }
10140 }
10141
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010142 val = get_param(cmd, "SetupCommand");
10143 if (val) {
10144 cmd_type = atoi(val);
10145 if (cmd_type == TWT_REQUEST_CMD)
10146 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
10147 else if (cmd_type == TWT_SUGGEST_CMD)
10148 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
10149 else if (cmd_type == TWT_DEMAND_CMD)
10150 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
10151 else
10152 sigma_dut_print(dut, DUT_MSG_ERROR,
10153 "Default suggest is used for cmd %d",
10154 cmd_type);
10155 }
10156
Arif Hussain480d5f42019-03-12 14:40:42 -070010157 val = get_param(cmd, "TargetWakeTime");
10158 if (val)
10159 target_wake_time = atoi(val);
10160
10161 val = get_param(cmd, "WakeIntervalMantissa");
10162 if (val)
10163 wake_interval_mantissa = atoi(val);
10164
10165 val = get_param(cmd, "WakeIntervalExp");
10166 if (val)
10167 wake_interval_exp = atoi(val);
10168
10169 val = get_param(cmd, "NominalMinWakeDur");
10170 if (val)
10171 nominal_min_wake_dur = atoi(val);
10172
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010173 val = get_param(cmd, "BTWT_ID");
10174 if (val) {
10175 bcast_twt_id = atoi(val);
10176 bcast_twt = 1;
10177 }
10178
10179 val = get_param(cmd, "BTWT_Persistence");
10180 if (val) {
10181 bcast_twt_persis = atoi(val);
10182 bcast_twt = 1;
10183 }
10184
10185 val = get_param(cmd, "BTWT_Recommendation");
10186 if (val) {
10187 bcast_twt_recommdn = atoi(val);
10188 bcast_twt = 1;
10189 }
10190
10191 if (bcast_twt)
10192 sigma_dut_print(dut, DUT_MSG_DEBUG,
10193 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
10194 bcast_twt_id, bcast_twt_recommdn,
10195 bcast_twt_persis);
10196
Arif Hussain480d5f42019-03-12 14:40:42 -070010197 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10198 NL80211_CMD_VENDOR)) ||
10199 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10200 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10201 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010202 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010203 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010204 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10205 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010206 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010207 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010208 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
10209 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010210 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010211 (twt_trigger &&
10212 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010213 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
10214 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010215 (protection &&
10216 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010217 (bcast_twt &&
10218 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10219 (bcast_twt &&
10220 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10221 bcast_twt_id)) ||
10222 (bcast_twt &&
10223 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
10224 bcast_twt_persis)) ||
10225 (bcast_twt &&
10226 nla_put_u8(msg,
10227 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
10228 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010229 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
10230 target_wake_time) ||
10231 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
10232 nominal_min_wake_dur) ||
10233 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
10234 wake_interval_mantissa)) {
10235 sigma_dut_print(dut, DUT_MSG_ERROR,
10236 "%s: err in adding vendor_cmd and vendor_data",
10237 __func__);
10238 nlmsg_free(msg);
10239 return -1;
10240 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010241 nla_nest_end(msg, params);
10242 nla_nest_end(msg, attr);
10243
10244 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10245 if (ret) {
10246 sigma_dut_print(dut, DUT_MSG_ERROR,
10247 "%s: err in send_and_recv_msgs, ret=%d",
10248 __func__, ret);
10249 }
10250
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010251 if (!dut->sta_async_twt_supp)
10252 return ret;
10253
10254 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -070010255#else /* NL80211_SUPPORT */
10256 sigma_dut_print(dut, DUT_MSG_ERROR,
10257 "TWT request cannot be done without NL80211_SUPPORT defined");
10258 return -1;
10259#endif /* NL80211_SUPPORT */
10260}
10261
10262
10263static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
10264 struct sigma_cmd *cmd)
10265{
10266 #ifdef NL80211_SUPPORT
10267 struct nlattr *params;
10268 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010269 int ifindex, ret;
10270 struct nl_msg *msg;
10271 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010272 int bcast_twt = 0;
10273 int bcast_twt_id = 0;
10274 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -070010275
10276 ifindex = if_nametoindex(intf);
10277 if (ifindex == 0) {
10278 sigma_dut_print(dut, DUT_MSG_ERROR,
10279 "%s: Index for interface %s failed",
10280 __func__, intf);
10281 return -1;
10282 }
10283
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010284 val = get_param(cmd, "BTWT_ID");
10285 if (val) {
10286 bcast_twt_id = atoi(val);
10287 bcast_twt = 1;
10288 }
10289
Arif Hussain480d5f42019-03-12 14:40:42 -070010290 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10291 NL80211_CMD_VENDOR)) ||
10292 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10293 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10294 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010295 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010296 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010297 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10298 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010299 !(params = nla_nest_start(
10300 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010301 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010302 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
10303 (bcast_twt &&
10304 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10305 (bcast_twt &&
10306 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10307 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -070010308 sigma_dut_print(dut, DUT_MSG_ERROR,
10309 "%s: err in adding vendor_cmd and vendor_data",
10310 __func__);
10311 nlmsg_free(msg);
10312 return -1;
10313 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010314 nla_nest_end(msg, params);
10315 nla_nest_end(msg, attr);
10316
10317 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10318 if (ret) {
10319 sigma_dut_print(dut, DUT_MSG_ERROR,
10320 "%s: err in send_and_recv_msgs, ret=%d",
10321 __func__, ret);
10322 }
10323
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010324 if (!dut->sta_async_twt_supp)
10325 return ret;
10326
10327 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -070010328#else /* NL80211_SUPPORT */
10329 sigma_dut_print(dut, DUT_MSG_ERROR,
10330 "TWT teardown cannot be done without NL80211_SUPPORT defined");
10331 return -1;
10332#endif /* NL80211_SUPPORT */
10333}
10334
10335
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080010336static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
10337 struct sigma_cmd *cmd)
10338{
10339#ifdef NL80211_SUPPORT
10340 struct nlattr *params;
10341 struct nlattr *attr;
10342 struct nlattr *attr1;
10343 struct nl_msg *msg;
10344 int ifindex, ret;
10345 const char *val;
10346 const char *intf = get_param(cmd, "Interface");
10347 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
10348 ulmu_data_dis = 0;
10349
10350 ifindex = if_nametoindex(intf);
10351 if (ifindex == 0) {
10352 sigma_dut_print(dut, DUT_MSG_ERROR,
10353 "%s: Index for interface %s failed",
10354 __func__, intf);
10355 return -1;
10356 }
10357 val = get_param(cmd, "OMCtrl_RxNSS");
10358 if (val)
10359 rx_nss = atoi(val);
10360
10361 val = get_param(cmd, "OMCtrl_ChnlWidth");
10362 if (val)
10363 ch_bw = atoi(val);
10364
10365 val = get_param(cmd, "OMCtrl_ULMUDisable");
10366 if (val)
10367 ulmu_dis = atoi(val);
10368
10369 val = get_param(cmd, "OMCtrl_TxNSTS");
10370 if (val)
10371 tx_nsts = atoi(val);
10372
10373 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
10374 if (val)
10375 ulmu_data_dis = atoi(val);
10376
10377 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10378 NL80211_CMD_VENDOR)) ||
10379 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10380 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10381 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10382 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10383 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10384 !(params = nla_nest_start(
10385 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
10386 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10387 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
10388 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
10389 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
10390 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
10391 ulmu_data_dis) ||
10392 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
10393 ulmu_dis)) {
10394 sigma_dut_print(dut, DUT_MSG_ERROR,
10395 "%s: err in adding vendor_cmd and vendor_data",
10396 __func__);
10397 nlmsg_free(msg);
10398 return -1;
10399 }
10400 nla_nest_end(msg, attr1);
10401 nla_nest_end(msg, params);
10402 nla_nest_end(msg, attr);
10403
10404 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10405 if (ret) {
10406 sigma_dut_print(dut, DUT_MSG_ERROR,
10407 "%s: err in send_and_recv_msgs, ret=%d",
10408 __func__, ret);
10409 }
10410
10411 return ret;
10412#else /* NL80211_SUPPORT */
10413 sigma_dut_print(dut, DUT_MSG_ERROR,
10414 "OMI TX cannot be processed without NL80211_SUPPORT defined");
10415 return -1;
10416#endif /* NL80211_SUPPORT */
10417}
10418
10419
Jouni Malinen224e3902021-06-09 16:41:27 +030010420static enum sigma_cmd_result
10421cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10422 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010423{
10424 const char *intf = get_param(cmd, "Interface");
10425 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -070010426 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010427 int tkip = -1;
10428 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010429 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010430
Arif Hussaina37e9552018-06-20 17:05:59 -070010431 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010432 val = get_param(cmd, "SGI80");
10433 if (val) {
10434 int sgi80;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010435 enum nl80211_txrate_gi gi_val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010436
10437 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010438 if (sgi80)
10439 gi_val = NL80211_TXRATE_FORCE_LGI;
10440 else
10441 gi_val = NL80211_TXRATE_FORCE_SGI;
10442 if (sta_set_vht_gi(dut, intf, (u8) gi_val)) {
10443 sigma_dut_print(dut, DUT_MSG_INFO,
10444 "sta_set_vht_gi failed, using iwpriv");
10445 run_iwpriv(dut, intf, "shortgi %d", sgi80);
10446 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010447 }
10448
10449 val = get_param(cmd, "TxBF");
10450 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010451 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010452 case DRIVER_WCN:
10453 if (sta_set_tx_beamformee(dut, intf, 1)) {
10454 send_resp(dut, conn, SIGMA_ERROR,
10455 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010456 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010457 }
10458 break;
10459 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010460 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010461 send_resp(dut, conn, SIGMA_ERROR,
10462 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010463 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010464 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010465 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010466 send_resp(dut, conn, SIGMA_ERROR,
10467 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010468 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010469 }
10470 break;
10471 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010472 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010473 "Unsupported driver type");
10474 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010475 }
10476 }
10477
10478 val = get_param(cmd, "MU_TxBF");
10479 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010480 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010481 case DRIVER_ATHEROS:
10482 ath_sta_set_txsp_stream(dut, intf, "1SS");
10483 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010484 run_iwpriv(dut, intf, "vhtmubfee 1");
10485 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +053010486 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010487 case DRIVER_WCN:
10488 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
10489 send_resp(dut, conn, SIGMA_ERROR,
10490 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +030010491 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010492 }
Sunil Duttae9e5d12018-06-29 11:50:47 +053010493 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010494 default:
10495 sigma_dut_print(dut, DUT_MSG_ERROR,
10496 "Setting SP_STREAM not supported");
10497 break;
10498 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010499 }
10500
10501 val = get_param(cmd, "LDPC");
10502 if (val) {
10503 int ldpc;
10504
10505 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010506 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
10507 if (iwpriv_status)
10508 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010509 }
10510
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010511 val = get_param(cmd, "BCC");
10512 if (val) {
10513 int bcc;
10514
10515 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10516 /* use LDPC iwpriv itself to set bcc coding, bcc coding
10517 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010518 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
10519 if (iwpriv_status)
10520 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010521 }
10522
Arif Hussain7b47d2d2018-05-09 10:44:02 -070010523 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
10524 if (val && dut->sta_nss == 1)
10525 cmd_set_max_he_mcs(dut, intf, atoi(val));
10526
10527 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
10528 if (val && dut->sta_nss == 2)
10529 cmd_set_max_he_mcs(dut, intf, atoi(val));
10530
Arif Hussainac6c5112018-05-25 17:34:00 -070010531 val = get_param(cmd, "MCS_FixedRate");
10532 if (val) {
10533#ifdef NL80211_SUPPORT
10534 int mcs, ratecode = 0;
10535 enum he_mcs_config mcs_config;
10536 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +030010537 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -070010538
10539 ratecode = (0x07 & dut->sta_nss) << 5;
10540 mcs = atoi(val);
10541 /* Add the MCS to the ratecode */
10542 if (mcs >= 0 && mcs <= 11) {
10543 ratecode += mcs;
10544 if (dut->device_type == STA_testbed &&
10545 mcs > 7 && mcs <= 11) {
10546 if (mcs <= 9)
10547 mcs_config = HE_80_MCS0_9;
10548 else
10549 mcs_config = HE_80_MCS0_11;
10550 ret = sta_set_he_mcs(dut, intf, mcs_config);
10551 if (ret) {
10552 sigma_dut_print(dut, DUT_MSG_ERROR,
10553 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10554 mcs, mcs_config, ret);
10555 }
10556 }
10557 snprintf(buf, sizeof(buf),
10558 "iwpriv %s set_11ax_rate 0x%03x",
10559 intf, ratecode);
10560 if (system(buf) != 0) {
10561 sigma_dut_print(dut, DUT_MSG_ERROR,
10562 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
10563 ratecode);
10564 }
10565 } else {
10566 sigma_dut_print(dut, DUT_MSG_ERROR,
10567 "MCS_FixedRate: HE MCS %d not supported",
10568 mcs);
10569 }
10570#else /* NL80211_SUPPORT */
10571 sigma_dut_print(dut, DUT_MSG_ERROR,
10572 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
10573#endif /* NL80211_SUPPORT */
10574 }
10575
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010576 val = get_param(cmd, "opt_md_notif_ie");
10577 if (val) {
10578 char *result = NULL;
10579 char delim[] = ";";
10580 char token[30];
10581 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010582 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010583
Peng Xub8fc5cc2017-05-10 17:27:28 -070010584 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010585 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010586
10587 /* Extract the NSS information */
10588 if (result) {
10589 value = atoi(result);
10590 switch (value) {
10591 case 1:
10592 config_val = 1;
10593 break;
10594 case 2:
10595 config_val = 3;
10596 break;
10597 case 3:
10598 config_val = 7;
10599 break;
10600 case 4:
10601 config_val = 15;
10602 break;
10603 default:
10604 config_val = 3;
10605 break;
10606 }
10607
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010608 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
10609 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010610
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010611 }
10612
10613 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010614 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010615 if (result) {
10616 value = atoi(result);
10617 switch (value) {
10618 case 20:
10619 config_val = 0;
10620 break;
10621 case 40:
10622 config_val = 1;
10623 break;
10624 case 80:
10625 config_val = 2;
10626 break;
10627 case 160:
10628 config_val = 3;
10629 break;
10630 default:
10631 config_val = 2;
10632 break;
10633 }
10634
10635 dut->chwidth = config_val;
10636
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010637 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010638 }
10639
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010640 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010641 }
10642
10643 val = get_param(cmd, "nss_mcs_cap");
10644 if (val) {
10645 int nss, mcs;
10646 char token[20];
10647 char *result = NULL;
10648 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010649 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010650
Peng Xub8fc5cc2017-05-10 17:27:28 -070010651 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010652 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010653 if (!result) {
10654 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010655 "NSS not specified");
10656 send_resp(dut, conn, SIGMA_ERROR,
10657 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010658 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010659 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010660 nss = atoi(result);
10661
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010662 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -070010663 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010664
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010665 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010666 if (result == NULL) {
10667 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010668 "MCS not specified");
10669 send_resp(dut, conn, SIGMA_ERROR,
10670 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010671 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010672 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010673 result = strtok_r(result, "-", &saveptr);
10674 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010675 if (!result) {
10676 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010677 "MCS not specified");
10678 send_resp(dut, conn, SIGMA_ERROR,
10679 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010680 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010681 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010682 mcs = atoi(result);
10683
Arif Hussaina37e9552018-06-20 17:05:59 -070010684 if (program && strcasecmp(program, "HE") == 0) {
10685#ifdef NL80211_SUPPORT
10686 enum he_mcs_config mcs_config;
10687 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010688
Arif Hussaina37e9552018-06-20 17:05:59 -070010689 if (mcs >= 0 && mcs <= 7) {
10690 mcs_config = HE_80_MCS0_7;
10691 } else if (mcs > 7 && mcs <= 9) {
10692 mcs_config = HE_80_MCS0_9;
10693 } else if (mcs > 9 && mcs <= 11) {
10694 mcs_config = HE_80_MCS0_11;
10695 } else {
10696 sigma_dut_print(dut, DUT_MSG_ERROR,
10697 "nss_mcs_cap: HE: Invalid mcs: %d",
10698 mcs);
10699 send_resp(dut, conn, SIGMA_ERROR,
10700 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010701 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010702 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010703
10704 ret = sta_set_he_mcs(dut, intf, mcs_config);
10705 if (ret) {
10706 sigma_dut_print(dut, DUT_MSG_ERROR,
10707 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
10708 mcs_config, ret);
10709 send_resp(dut, conn, SIGMA_ERROR,
10710 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010711 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010712 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010713#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010714 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010715 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
10716#endif /* NL80211_SUPPORT */
10717 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010718 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -070010719
10720 switch (nss) {
10721 case 1:
10722 switch (mcs) {
10723 case 7:
10724 vht_mcsmap = 0xfffc;
10725 break;
10726 case 8:
10727 vht_mcsmap = 0xfffd;
10728 break;
10729 case 9:
10730 vht_mcsmap = 0xfffe;
10731 break;
10732 default:
10733 vht_mcsmap = 0xfffe;
10734 break;
10735 }
10736 break;
10737 case 2:
10738 switch (mcs) {
10739 case 7:
10740 vht_mcsmap = 0xfff0;
10741 break;
10742 case 8:
10743 vht_mcsmap = 0xfff5;
10744 break;
10745 case 9:
10746 vht_mcsmap = 0xfffa;
10747 break;
10748 default:
10749 vht_mcsmap = 0xfffa;
10750 break;
10751 }
10752 break;
10753 case 3:
10754 switch (mcs) {
10755 case 7:
10756 vht_mcsmap = 0xffc0;
10757 break;
10758 case 8:
10759 vht_mcsmap = 0xffd5;
10760 break;
10761 case 9:
10762 vht_mcsmap = 0xffea;
10763 break;
10764 default:
10765 vht_mcsmap = 0xffea;
10766 break;
10767 }
10768 break;
10769 default:
10770 vht_mcsmap = 0xffea;
10771 break;
10772 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010773 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010774 }
10775 }
10776
10777 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
10778
10779 val = get_param(cmd, "Vht_tkip");
10780 if (val)
10781 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10782
10783 val = get_param(cmd, "Vht_wep");
10784 if (val)
10785 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10786
10787 if (tkip != -1 || wep != -1) {
10788 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010789 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010790 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010791 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010792 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +030010793 send_resp(dut, conn, SIGMA_ERROR,
10794 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
10795 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010796 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010797 }
10798
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -070010799 val = get_param(cmd, "TWTSchedSTASupport");
10800 if (val) {
10801 int set_val;
10802
10803 switch (get_driver_type(dut)) {
10804 case DRIVER_WCN:
10805 if (strcasecmp(val, "Enable") == 0) {
10806 set_val = 1;
10807 } else if (strcasecmp(val, "Disable") == 0) {
10808 set_val = 0;
10809 } else {
10810 send_resp(dut, conn, SIGMA_ERROR,
10811 "ErrorCode,Invalid TWTSchedSTASupport");
10812 return STATUS_SENT_ERROR;
10813 }
10814
10815 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
10816 send_resp(dut, conn, SIGMA_ERROR,
10817 "ErrorCode,Failed to set TWTSchedSTASupport");
10818 return STATUS_SENT_ERROR;
10819 }
10820 break;
10821 default:
10822 sigma_dut_print(dut, DUT_MSG_ERROR,
10823 "Setting TWTSchedSTASupport not supported");
10824 break;
10825 }
10826 }
10827
10828 val = get_param(cmd, "MBSSID_RxCtrl");
10829 if (val) {
10830 int set_val;
10831
10832 switch (get_driver_type(dut)) {
10833 case DRIVER_WCN:
10834 if (strcasecmp(val, "Enable") == 0) {
10835 set_val = 1;
10836 } else if (strcasecmp(val, "Disable") == 0) {
10837 set_val = 0;
10838 } else {
10839 send_resp(dut, conn, SIGMA_ERROR,
10840 "ErrorCode,Invalid MBSSID_RxCtrl");
10841 return STATUS_SENT_ERROR;
10842 }
10843
10844 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
10845 send_resp(dut, conn, SIGMA_ERROR,
10846 "ErrorCode,Failed to set MBSSID_RxCtrl");
10847 return STATUS_SENT_ERROR;
10848 }
10849 break;
10850 default:
10851 sigma_dut_print(dut, DUT_MSG_ERROR,
10852 "Setting MBSSID_RxCtrl not supported");
10853 break;
10854 }
10855 }
10856
Arif Hussain55f00da2018-07-03 08:28:26 -070010857 val = get_param(cmd, "txBandwidth");
10858 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010859 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -070010860 case DRIVER_WCN:
10861 if (wcn_sta_set_width(dut, intf, val) < 0) {
10862 send_resp(dut, conn, SIGMA_ERROR,
10863 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010864 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010865 }
10866 break;
10867 case DRIVER_ATHEROS:
10868 if (ath_set_width(dut, conn, intf, val) < 0) {
10869 send_resp(dut, conn, SIGMA_ERROR,
10870 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010871 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010872 }
10873 break;
10874 default:
10875 sigma_dut_print(dut, DUT_MSG_ERROR,
10876 "Setting txBandwidth not supported");
10877 break;
10878 }
10879 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010880
Arif Hussain9765f7d2018-07-03 08:28:26 -070010881 val = get_param(cmd, "BeamformeeSTS");
10882 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010883 if (sta_set_tx_beamformee(dut, intf, 1)) {
10884 send_resp(dut, conn, SIGMA_ERROR,
10885 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010886 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010887 }
10888
Arif Hussain9765f7d2018-07-03 08:28:26 -070010889 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
10890 send_resp(dut, conn, SIGMA_ERROR,
10891 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010892 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -070010893 }
10894 }
10895
Arif Hussain68d23f52018-07-11 13:39:08 -070010896 val = get_param(cmd, "Trig_MAC_Padding_Dur");
10897 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010898#ifdef NL80211_SUPPORT
10899 enum qca_wlan_he_mac_padding_dur set_val;
10900
10901 switch (atoi(val)) {
10902 case 16:
10903 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
10904 break;
10905 case 8:
10906 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
10907 break;
10908 default:
10909 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
10910 break;
10911 }
10912 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -070010913 send_resp(dut, conn, SIGMA_ERROR,
10914 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +030010915 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -070010916 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010917#else /* NL80211_SUPPORT */
10918 sigma_dut_print(dut, DUT_MSG_ERROR,
10919 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
10920#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -070010921 }
10922
Arif Hussain480d5f42019-03-12 14:40:42 -070010923 val = get_param(cmd, "TWT_ReqSupport");
10924 if (val) {
10925 int set_val;
10926
10927 if (strcasecmp(val, "Enable") == 0) {
10928 set_val = 1;
10929 } else if (strcasecmp(val, "Disable") == 0) {
10930 set_val = 0;
10931 } else {
10932 send_resp(dut, conn, SIGMA_ERROR,
10933 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010934 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010935 }
10936
10937 if (sta_set_twt_req_support(dut, intf, set_val)) {
10938 sigma_dut_print(dut, DUT_MSG_ERROR,
10939 "Failed to set TWT req support %d",
10940 set_val);
10941 send_resp(dut, conn, SIGMA_ERROR,
10942 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010943 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010944 }
10945 }
10946
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -070010947 val = get_param(cmd, "PreamblePunctRx");
10948 if (val && get_driver_type(dut) == DRIVER_WCN) {
10949 int set_val;
10950
10951 if (strcasecmp(val, "Enable") == 0) {
10952 set_val = 1;
10953 } else if (strcasecmp(val, "Disable") == 0) {
10954 set_val = 0;
10955 } else {
10956 send_resp(dut, conn, SIGMA_ERROR,
10957 "ErrorCode,Invalid PreamblePunctRx");
10958 return STATUS_SENT_ERROR;
10959 }
10960
10961 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
10962 sigma_dut_print(dut, DUT_MSG_ERROR,
10963 "Failed to set PreamblePunctRx support %d",
10964 set_val);
10965 send_resp(dut, conn, SIGMA_ERROR,
10966 "ErrorCode,Failed to set PreamblePunctRx");
10967 return STATUS_SENT_ERROR;
10968 }
10969 }
10970
Srinivas Girigowda0525e292020-11-12 13:28:21 -080010971 val = get_param(cmd, "FullBW_ULMUMIMO");
10972 if (val) {
10973 int set_val;
10974
10975 if (strcasecmp(val, "Enable") == 0) {
10976 set_val = 1;
10977 } else if (strcasecmp(val, "Disable") == 0) {
10978 set_val = 0;
10979 } else {
10980 send_resp(dut, conn, SIGMA_ERROR,
10981 "ErrorCode,Invalid FullBW_ULMUMIMO");
10982 return STATUS_SENT_ERROR;
10983 }
10984
10985 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
10986 sigma_dut_print(dut, DUT_MSG_ERROR,
10987 "Failed to set FullBW_ULMUMIMO %d",
10988 set_val);
10989 send_resp(dut, conn, SIGMA_ERROR,
10990 "ErrorCode,Failed to set FullBW_ULMUMIMO");
10991 return STATUS_SENT_ERROR;
10992 }
10993 }
10994
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010995 val = get_param(cmd, "TWTInfoFrameTx");
10996 if (val) {
10997 if (strcasecmp(val, "Enable") == 0) {
10998 /* No-op */
10999 } else if (strcasecmp(val, "Disable") == 0) {
11000 /* No-op */
11001 } else {
11002 send_resp(dut, conn, SIGMA_ERROR,
11003 "ErrorCode,Invalid TWTInfoFrameTx");
11004 return STATUS_SENT_ERROR;
11005 }
11006 }
11007
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011008 val = get_param(cmd, "MU_EDCA");
11009 if (val && (strcasecmp(val, "Override") == 0)) {
11010 if (sta_set_mu_edca_override(dut, intf, 1)) {
11011 send_resp(dut, conn, SIGMA_ERROR,
11012 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +030011013 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011014 }
11015 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011016
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070011017 val = get_param(cmd, "PPDUTxType");
11018 if (val && strcasecmp(val, "ER-SU") == 0) {
11019 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
11020 send_resp(dut, conn, SIGMA_ERROR,
11021 "ErrorCode,Failed to set ER-SU PPDU type Tx");
11022 return STATUS_SENT_ERROR;
11023 }
11024 }
11025
11026 val = get_param(cmd, "RUAllocTone");
11027 if (val && strcasecmp(val, "242") == 0) {
11028 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
11029 send_resp(dut, conn, SIGMA_ERROR,
11030 "ErrorCode,Failed to set RU 242 tone Tx");
11031 return STATUS_SENT_ERROR;
11032 }
11033 }
11034
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011035 val = get_param(cmd, "OMControl");
11036 if (val) {
11037 int set_val = 1;
11038
11039 if (strcasecmp(val, "Enable") == 0)
11040 set_val = 1;
11041 else if (strcasecmp(val, "Disable") == 0)
11042 set_val = 0;
11043
11044 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
11045 send_resp(dut, conn, SIGMA_ERROR,
11046 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +030011047 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011048 }
11049 }
11050
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -070011051 val = get_param(cmd, "BSSMaxIdlePeriod");
11052 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
11053 send_resp(dut, conn, SIGMA_ERROR,
11054 "ErrorCode,Failed to set BSS max idle period");
11055 return STATUS_SENT_ERROR;
11056 }
11057
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -070011058 val = get_param(cmd, "BSS_max_idle");
11059 if (val) {
11060 int set_val = 0;
11061
11062 if (strcasecmp(val, "Enable") == 0)
11063 set_val = 1;
11064 else if (strcasecmp(val, "Disable") == 0)
11065 set_val = 0;
11066 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
11067 send_resp(dut, conn, SIGMA_ERROR,
11068 "ErrorCode,Failed to set BSS max idle support");
11069 return STATUS_SENT_ERROR;
11070 }
11071 }
11072
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011073 val = get_param(cmd, "ADDBAResp_BufSize");
11074 if (val) {
11075 int buf_size;
11076
11077 if (strcasecmp(val, "gt64") == 0)
11078 buf_size = 256;
11079 else
11080 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011081 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011082 sta_set_addba_buf_size(dut, intf, buf_size)) {
11083 send_resp(dut, conn, SIGMA_ERROR,
11084 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011085 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011086 }
11087 }
11088
11089 val = get_param(cmd, "ADDBAReq_BufSize");
11090 if (val) {
11091 int buf_size;
11092
11093 if (strcasecmp(val, "gt64") == 0)
11094 buf_size = 256;
11095 else
11096 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011097 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011098 sta_set_addba_buf_size(dut, intf, buf_size)) {
11099 send_resp(dut, conn, SIGMA_ERROR,
11100 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011101 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011102 }
11103 }
11104
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011105 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11106}
11107
11108
11109static int sta_set_wireless_60g(struct sigma_dut *dut,
11110 struct sigma_conn *conn,
11111 struct sigma_cmd *cmd)
11112{
11113 const char *dev_role = get_param(cmd, "DevRole");
11114
11115 if (!dev_role) {
11116 send_resp(dut, conn, SIGMA_INVALID,
11117 "ErrorCode,DevRole not specified");
11118 return 0;
11119 }
11120
11121 if (strcasecmp(dev_role, "PCP") == 0)
11122 return sta_set_60g_pcp(dut, conn, cmd);
11123 if (strcasecmp(dev_role, "STA") == 0)
11124 return sta_set_60g_sta(dut, conn, cmd);
11125 send_resp(dut, conn, SIGMA_INVALID,
11126 "ErrorCode,DevRole not supported");
11127 return 0;
11128}
11129
11130
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011131static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
11132 struct sigma_cmd *cmd)
11133{
11134 int status;
11135 const char *intf = get_param(cmd, "Interface");
11136 const char *val = get_param(cmd, "DevRole");
11137
11138 if (val && strcasecmp(val, "STA-CFON") == 0) {
11139 status = sta_cfon_set_wireless(dut, conn, cmd);
11140 if (status)
11141 return status;
11142 }
11143 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11144}
11145
11146
Jouni Malinen67433fc2020-06-26 22:50:33 +030011147static enum sigma_cmd_result
11148sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
11149 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011150{
11151 const char *intf = get_param(cmd, "Interface");
11152 const char *val;
11153
11154 val = get_param(cmd, "ocvc");
11155 if (val)
11156 dut->ocvc = atoi(val);
11157
Jouni Malinen67433fc2020-06-26 22:50:33 +030011158 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +053011159 if (val && dut->client_privacy != atoi(val) &&
11160 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
11161 send_resp(dut, conn, SIGMA_ERROR,
11162 "errorCode,Failed to configure random MAC address use");
11163 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +030011164 }
11165
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011166 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11167}
11168
11169
Jouni Malinenf7222712019-06-13 01:50:21 +030011170static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
11171 struct sigma_conn *conn,
11172 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011173{
11174 const char *val;
11175
11176 val = get_param(cmd, "Program");
11177 if (val) {
11178 if (strcasecmp(val, "11n") == 0)
11179 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080011180 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011181 return cmd_sta_set_wireless_vht(dut, conn, cmd);
11182 if (strcasecmp(val, "60ghz") == 0)
11183 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011184 if (strcasecmp(val, "OCE") == 0)
11185 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020011186 /* sta_set_wireless in WPS program is only used for 60G */
11187 if (is_60g_sigma_dut(dut))
11188 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011189 if (strcasecmp(val, "WPA3") == 0)
11190 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011191 send_resp(dut, conn, SIGMA_ERROR,
11192 "ErrorCode,Program value not supported");
11193 } else {
11194 send_resp(dut, conn, SIGMA_ERROR,
11195 "ErrorCode,Program argument not available");
11196 }
11197
11198 return 0;
11199}
11200
11201
11202static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
11203 int tid)
11204{
11205 char buf[100];
11206 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
11207
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053011208 if (tid < 0 ||
11209 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
11210 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
11211 return;
11212 }
11213
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011214 /*
11215 * Two ways to ensure that addba request with a
11216 * non zero TID could be sent out. EV 117296
11217 */
11218 snprintf(buf, sizeof(buf),
11219 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
11220 tid);
11221 if (system(buf) != 0) {
11222 sigma_dut_print(dut, DUT_MSG_ERROR,
11223 "Ping did not send out");
11224 }
11225
11226 snprintf(buf, sizeof(buf),
11227 "iwconfig %s | grep Access | awk '{print $6}' > %s",
11228 intf, VI_QOS_TMP_FILE);
11229 if (system(buf) != 0)
11230 return;
11231
11232 snprintf(buf, sizeof(buf),
11233 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
11234 intf, VI_QOS_TMP_FILE);
11235 if (system(buf) != 0)
11236 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
11237
11238 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
11239 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
11240 if (system(buf) != 0) {
11241 sigma_dut_print(dut, DUT_MSG_ERROR,
11242 "VI_QOS_TEMP_FILE generation error failed");
11243 }
11244 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11245 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11246 if (system(buf) != 0) {
11247 sigma_dut_print(dut, DUT_MSG_ERROR,
11248 "VI_QOS_FILE generation failed");
11249 }
11250
11251 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11252 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11253 if (system(buf) != 0) {
11254 sigma_dut_print(dut, DUT_MSG_ERROR,
11255 "VI_QOS_FILE generation failed");
11256 }
11257
11258 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
11259 if (system(buf) != 0) {
11260 }
11261}
11262
11263
11264static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11265 struct sigma_cmd *cmd)
11266{
11267 const char *intf = get_param(cmd, "Interface");
11268 const char *val;
11269 int tid = 0;
11270 char buf[100];
11271
11272 val = get_param(cmd, "TID");
11273 if (val) {
11274 tid = atoi(val);
11275 if (tid)
11276 ath_sta_inject_frame(dut, intf, tid);
11277 }
11278
11279 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011280 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011281
11282 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
11283 if (system(buf) != 0) {
11284 sigma_dut_print(dut, DUT_MSG_ERROR,
11285 "wifitool senddelba failed");
11286 }
11287
11288 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
11289 if (system(buf) != 0) {
11290 sigma_dut_print(dut, DUT_MSG_ERROR,
11291 "wifitool sendaddba failed");
11292 }
11293
11294 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11295
11296 return 1;
11297}
11298
11299
Lior David9981b512017-01-20 13:16:40 +020011300#ifdef __linux__
11301
11302static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
11303 int agg_size)
11304{
11305 char dir[128], buf[128];
11306 FILE *f;
11307 regex_t re;
11308 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030011309 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020011310
11311 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
11312 sigma_dut_print(dut, DUT_MSG_ERROR,
11313 "failed to get wil6210 debugfs dir");
11314 return -1;
11315 }
11316
Jouni Malinen3aa72862019-05-29 23:14:51 +030011317 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
11318 if (res < 0 || res >= sizeof(buf))
11319 return -1;
Lior David9981b512017-01-20 13:16:40 +020011320 f = fopen(buf, "r");
11321 if (!f) {
11322 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011323 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030011324 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
11325 if (res < 0 || res >= sizeof(buf))
11326 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011327 f = fopen(buf, "r");
11328 if (!f) {
11329 sigma_dut_print(dut, DUT_MSG_ERROR,
11330 "failed to open: %s", buf);
11331 return -1;
11332 }
Lior David9981b512017-01-20 13:16:40 +020011333 }
11334
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011335 /* can be either VRING tx... or RING... */
11336 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020011337 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
11338 goto out;
11339 }
11340
11341 /* find TX VRING for the mac address */
11342 found = 0;
11343 while (fgets(buf, sizeof(buf), f)) {
11344 if (strcasestr(buf, dest_mac)) {
11345 found = 1;
11346 break;
11347 }
11348 }
11349
11350 if (!found) {
11351 sigma_dut_print(dut, DUT_MSG_ERROR,
11352 "no TX VRING for %s", dest_mac);
11353 goto out;
11354 }
11355
11356 /* extract VRING ID, "VRING tx_<id> = {" */
11357 if (!fgets(buf, sizeof(buf), f)) {
11358 sigma_dut_print(dut, DUT_MSG_ERROR,
11359 "no VRING start line for %s", dest_mac);
11360 goto out;
11361 }
11362
11363 rc = regexec(&re, buf, 2, m, 0);
11364 regfree(&re);
11365 if (rc || m[1].rm_so < 0) {
11366 sigma_dut_print(dut, DUT_MSG_ERROR,
11367 "no VRING TX ID for %s", dest_mac);
11368 goto out;
11369 }
11370 buf[m[1].rm_eo] = 0;
11371 vring_id = atoi(&buf[m[1].rm_so]);
11372
11373 /* send the addba command */
11374 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011375 res = snprintf(buf, sizeof(buf), "%s/back", dir);
11376 if (res < 0 || res >= sizeof(buf))
11377 return -1;
Lior David9981b512017-01-20 13:16:40 +020011378 f = fopen(buf, "w");
11379 if (!f) {
11380 sigma_dut_print(dut, DUT_MSG_ERROR,
11381 "failed to open: %s", buf);
11382 return -1;
11383 }
11384
11385 fprintf(f, "add %d %d\n", vring_id, agg_size);
11386
11387 ret = 0;
11388
11389out:
11390 fclose(f);
11391
11392 return ret;
11393}
11394
11395
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011396int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11397 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011398{
11399 const char *val;
11400 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011401
11402 val = get_param(cmd, "TID");
11403 if (val) {
11404 tid = atoi(val);
11405 if (tid != 0) {
11406 sigma_dut_print(dut, DUT_MSG_ERROR,
11407 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
11408 tid);
11409 }
11410 }
11411
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011412 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011413 if (!val) {
11414 sigma_dut_print(dut, DUT_MSG_ERROR,
11415 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011416 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011417 }
11418
Lior David9981b512017-01-20 13:16:40 +020011419 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011420 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011421
11422 return 1;
11423}
11424
Lior David9981b512017-01-20 13:16:40 +020011425#endif /* __linux__ */
11426
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011427
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011428static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11429 struct sigma_cmd *cmd)
11430{
11431#ifdef NL80211_SUPPORT
11432 const char *intf = get_param(cmd, "Interface");
11433 const char *val;
11434 int tid = -1;
11435 int bufsize = 64;
11436 struct nl_msg *msg;
11437 int ret = 0;
11438 struct nlattr *params;
11439 int ifindex;
11440
11441 val = get_param(cmd, "TID");
11442 if (val)
11443 tid = atoi(val);
11444
11445 if (tid == -1) {
11446 send_resp(dut, conn, SIGMA_ERROR,
11447 "ErrorCode,sta_send_addba tid invalid");
11448 return 0;
11449 }
11450
11451 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11452
11453 ifindex = if_nametoindex(intf);
11454 if (ifindex == 0) {
11455 sigma_dut_print(dut, DUT_MSG_ERROR,
11456 "%s: Index for interface %s failed",
11457 __func__, intf);
11458 send_resp(dut, conn, SIGMA_ERROR,
11459 "ErrorCode,sta_send_addba interface invalid");
11460 return 0;
11461 }
11462
11463 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11464 NL80211_CMD_VENDOR)) ||
11465 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
11466 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
11467 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
11468 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
11469 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
11470 nla_put_u8(msg,
11471 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
11472 QCA_WLAN_ADD_BA) ||
11473 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
11474 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070011475 nla_put_u16(msg,
11476 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
11477 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011478 sigma_dut_print(dut, DUT_MSG_ERROR,
11479 "%s: err in adding vendor_cmd and vendor_data",
11480 __func__);
11481 nlmsg_free(msg);
11482 send_resp(dut, conn, SIGMA_ERROR,
11483 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
11484 return 0;
11485 }
11486 nla_nest_end(msg, params);
11487
11488 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11489 if (ret) {
11490 sigma_dut_print(dut, DUT_MSG_ERROR,
11491 "%s: err in send_and_recv_msgs, ret=%d",
11492 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053011493 if (ret == -EOPNOTSUPP)
11494 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011495 send_resp(dut, conn, SIGMA_ERROR,
11496 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
11497 return 0;
11498 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011499#else /* NL80211_SUPPORT */
11500 sigma_dut_print(dut, DUT_MSG_ERROR,
11501 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011502#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053011503
11504 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011505}
11506
11507
Jouni Malinenf7222712019-06-13 01:50:21 +030011508static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
11509 struct sigma_conn *conn,
11510 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011511{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011512 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011513 case DRIVER_ATHEROS:
11514 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011515 case DRIVER_WCN:
11516 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020011517#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011518 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011519 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020011520#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011521 default:
11522 /*
11523 * There is no driver specific implementation for other drivers.
11524 * Ignore the command and report COMPLETE since the following
11525 * throughput test operation will end up sending ADDBA anyway.
11526 */
11527 return 1;
11528 }
11529}
11530
11531
11532int inject_eth_frame(int s, const void *data, size_t len,
11533 unsigned short ethtype, char *dst, char *src)
11534{
11535 struct iovec iov[4] = {
11536 {
11537 .iov_base = dst,
11538 .iov_len = ETH_ALEN,
11539 },
11540 {
11541 .iov_base = src,
11542 .iov_len = ETH_ALEN,
11543 },
11544 {
11545 .iov_base = &ethtype,
11546 .iov_len = sizeof(unsigned short),
11547 },
11548 {
11549 .iov_base = (void *) data,
11550 .iov_len = len,
11551 }
11552 };
11553 struct msghdr msg = {
11554 .msg_name = NULL,
11555 .msg_namelen = 0,
11556 .msg_iov = iov,
11557 .msg_iovlen = 4,
11558 .msg_control = NULL,
11559 .msg_controllen = 0,
11560 .msg_flags = 0,
11561 };
11562
11563 return sendmsg(s, &msg, 0);
11564}
11565
11566#if defined(__linux__) || defined(__QNXNTO__)
11567
11568int inject_frame(int s, const void *data, size_t len, int encrypt)
11569{
11570#define IEEE80211_RADIOTAP_F_WEP 0x04
11571#define IEEE80211_RADIOTAP_F_FRAG 0x08
11572 unsigned char rtap_hdr[] = {
11573 0x00, 0x00, /* radiotap version */
11574 0x0e, 0x00, /* radiotap length */
11575 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
11576 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
11577 0x00, /* padding */
11578 0x00, 0x00, /* RX and TX flags to indicate that */
11579 0x00, 0x00, /* this is the injected frame directly */
11580 };
11581 struct iovec iov[2] = {
11582 {
11583 .iov_base = &rtap_hdr,
11584 .iov_len = sizeof(rtap_hdr),
11585 },
11586 {
11587 .iov_base = (void *) data,
11588 .iov_len = len,
11589 }
11590 };
11591 struct msghdr msg = {
11592 .msg_name = NULL,
11593 .msg_namelen = 0,
11594 .msg_iov = iov,
11595 .msg_iovlen = 2,
11596 .msg_control = NULL,
11597 .msg_controllen = 0,
11598 .msg_flags = 0,
11599 };
11600
11601 if (encrypt)
11602 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
11603
11604 return sendmsg(s, &msg, 0);
11605}
11606
11607
11608int open_monitor(const char *ifname)
11609{
11610#ifdef __QNXNTO__
11611 struct sockaddr_dl ll;
11612 int s;
11613
11614 memset(&ll, 0, sizeof(ll));
11615 ll.sdl_family = AF_LINK;
11616 ll.sdl_index = if_nametoindex(ifname);
11617 if (ll.sdl_index == 0) {
11618 perror("if_nametoindex");
11619 return -1;
11620 }
11621 s = socket(PF_INET, SOCK_RAW, 0);
11622#else /* __QNXNTO__ */
11623 struct sockaddr_ll ll;
11624 int s;
11625
11626 memset(&ll, 0, sizeof(ll));
11627 ll.sll_family = AF_PACKET;
11628 ll.sll_ifindex = if_nametoindex(ifname);
11629 if (ll.sll_ifindex == 0) {
11630 perror("if_nametoindex");
11631 return -1;
11632 }
11633 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
11634#endif /* __QNXNTO__ */
11635 if (s < 0) {
11636 perror("socket[PF_PACKET,SOCK_RAW]");
11637 return -1;
11638 }
11639
11640 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
11641 perror("monitor socket bind");
11642 close(s);
11643 return -1;
11644 }
11645
11646 return s;
11647}
11648
11649
11650static int hex2num(char c)
11651{
11652 if (c >= '0' && c <= '9')
11653 return c - '0';
11654 if (c >= 'a' && c <= 'f')
11655 return c - 'a' + 10;
11656 if (c >= 'A' && c <= 'F')
11657 return c - 'A' + 10;
11658 return -1;
11659}
11660
11661
11662int hwaddr_aton(const char *txt, unsigned char *addr)
11663{
11664 int i;
11665
11666 for (i = 0; i < 6; i++) {
11667 int a, b;
11668
11669 a = hex2num(*txt++);
11670 if (a < 0)
11671 return -1;
11672 b = hex2num(*txt++);
11673 if (b < 0)
11674 return -1;
11675 *addr++ = (a << 4) | b;
11676 if (i < 5 && *txt++ != ':')
11677 return -1;
11678 }
11679
11680 return 0;
11681}
11682
11683#endif /* defined(__linux__) || defined(__QNXNTO__) */
11684
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011685
11686#ifdef NL80211_SUPPORT
11687static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
11688 const u8 *data, size_t data_len, int freq)
11689{
11690 struct nl_msg *msg;
11691 int ret = 0;
11692 int ifindex;
11693
11694 ifindex = if_nametoindex(intf);
11695 if (ifindex == 0) {
11696 sigma_dut_print(dut, DUT_MSG_ERROR,
11697 "%s: Index for interface %s failed",
11698 __func__, intf);
11699 return -1;
11700 }
11701
11702 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11703 NL80211_CMD_FRAME)) ||
11704 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11705 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
11706 sigma_dut_print(dut, DUT_MSG_ERROR,
11707 "%s: Error in adding NL80211_CMD_FRAME",
11708 __func__);
11709 nlmsg_free(msg);
11710 return -1;
11711 }
11712
11713 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11714 if (ret) {
11715 sigma_dut_print(dut, DUT_MSG_ERROR,
11716 "nl80211: Frame command failed: ret=%d (%s) req=%u",
11717 ret, strerror(-ret), freq);
11718 return -1;
11719 }
11720
11721 return 0;
11722}
11723#endif /* NL80211_SUPPORT */
11724
11725
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011726enum send_frame_type {
11727 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
11728};
11729enum send_frame_protection {
11730 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
11731};
11732
11733
11734static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011735 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011736 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011737 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011738{
11739#ifdef __linux__
11740 unsigned char buf[1000], *pos;
11741 int s, res;
11742 char bssid[20], addr[20];
11743 char result[32], ssid[100];
11744 size_t ssid_len;
11745
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011746 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011747 sizeof(result)) < 0 ||
11748 strncmp(result, "COMPLETED", 9) != 0) {
11749 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
11750 return 0;
11751 }
11752
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011753 if (get_wpa_status(get_station_ifname(dut), "bssid",
11754 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011755 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11756 "current BSSID");
11757 return 0;
11758 }
11759
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011760 if (get_wpa_status(get_station_ifname(dut), "address",
11761 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011762 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11763 "own MAC address");
11764 return 0;
11765 }
11766
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011767 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011768 < 0) {
11769 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11770 "current SSID");
11771 return 0;
11772 }
11773 ssid_len = strlen(ssid);
11774
11775 pos = buf;
11776
11777 /* Frame Control */
11778 switch (frame) {
11779 case DISASSOC:
11780 *pos++ = 0xa0;
11781 break;
11782 case DEAUTH:
11783 *pos++ = 0xc0;
11784 break;
11785 case SAQUERY:
11786 *pos++ = 0xd0;
11787 break;
11788 case AUTH:
11789 *pos++ = 0xb0;
11790 break;
11791 case ASSOCREQ:
11792 *pos++ = 0x00;
11793 break;
11794 case REASSOCREQ:
11795 *pos++ = 0x20;
11796 break;
11797 case DLS_REQ:
11798 *pos++ = 0xd0;
11799 break;
11800 }
11801
11802 if (protected == INCORRECT_KEY)
11803 *pos++ = 0x40; /* Set Protected field to 1 */
11804 else
11805 *pos++ = 0x00;
11806
11807 /* Duration */
11808 *pos++ = 0x00;
11809 *pos++ = 0x00;
11810
11811 /* addr1 = DA (current AP) */
11812 hwaddr_aton(bssid, pos);
11813 pos += 6;
11814 /* addr2 = SA (own address) */
11815 hwaddr_aton(addr, pos);
11816 pos += 6;
11817 /* addr3 = BSSID (current AP) */
11818 hwaddr_aton(bssid, pos);
11819 pos += 6;
11820
11821 /* Seq# (to be filled by driver/mac80211) */
11822 *pos++ = 0x00;
11823 *pos++ = 0x00;
11824
11825 if (protected == INCORRECT_KEY) {
11826 /* CCMP parameters */
11827 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
11828 pos += 8;
11829 }
11830
11831 if (protected == INCORRECT_KEY) {
11832 switch (frame) {
11833 case DEAUTH:
11834 /* Reason code (encrypted) */
11835 memcpy(pos, "\xa7\x39", 2);
11836 pos += 2;
11837 break;
11838 case DISASSOC:
11839 /* Reason code (encrypted) */
11840 memcpy(pos, "\xa7\x39", 2);
11841 pos += 2;
11842 break;
11843 case SAQUERY:
11844 /* Category|Action|TransID (encrypted) */
11845 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
11846 pos += 4;
11847 break;
11848 default:
11849 return -1;
11850 }
11851
11852 /* CCMP MIC */
11853 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
11854 pos += 8;
11855 } else {
11856 switch (frame) {
11857 case DEAUTH:
11858 /* reason code = 8 */
11859 *pos++ = 0x08;
11860 *pos++ = 0x00;
11861 break;
11862 case DISASSOC:
11863 /* reason code = 8 */
11864 *pos++ = 0x08;
11865 *pos++ = 0x00;
11866 break;
11867 case SAQUERY:
11868 /* Category - SA Query */
11869 *pos++ = 0x08;
11870 /* SA query Action - Request */
11871 *pos++ = 0x00;
11872 /* Transaction ID */
11873 *pos++ = 0x12;
11874 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011875 if (dut->saquery_oci_freq) {
11876 /* OCI IE - Extended ID */
11877 *pos++ = 0xFF;
11878 *pos++ = 0x04;
11879 *pos++ = 0x36;
11880 /* Operating Class */
11881 *pos++ = 0x74;
11882 /* Primary Channel */
11883 *pos++ = freq_to_channel(dut->saquery_oci_freq);
11884 /* Frequency Segment 1 Channel Number */
11885 *pos++ = 0x00;
11886 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011887 break;
11888 case AUTH:
11889 /* Auth Alg (Open) */
11890 *pos++ = 0x00;
11891 *pos++ = 0x00;
11892 /* Seq# */
11893 *pos++ = 0x01;
11894 *pos++ = 0x00;
11895 /* Status code */
11896 *pos++ = 0x00;
11897 *pos++ = 0x00;
11898 break;
11899 case ASSOCREQ:
11900 /* Capability Information */
11901 *pos++ = 0x31;
11902 *pos++ = 0x04;
11903 /* Listen Interval */
11904 *pos++ = 0x0a;
11905 *pos++ = 0x00;
11906 /* SSID */
11907 *pos++ = 0x00;
11908 *pos++ = ssid_len;
11909 memcpy(pos, ssid, ssid_len);
11910 pos += ssid_len;
11911 /* Supported Rates */
11912 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11913 10);
11914 pos += 10;
11915 /* Extended Supported Rates */
11916 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11917 pos += 6;
11918 /* RSN */
11919 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
11920 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
11921 "\x00\x00\x00\x00\x0f\xac\x06", 28);
11922 pos += 28;
11923 break;
11924 case REASSOCREQ:
11925 /* Capability Information */
11926 *pos++ = 0x31;
11927 *pos++ = 0x04;
11928 /* Listen Interval */
11929 *pos++ = 0x0a;
11930 *pos++ = 0x00;
11931 /* Current AP */
11932 hwaddr_aton(bssid, pos);
11933 pos += 6;
11934 /* SSID */
11935 *pos++ = 0x00;
11936 *pos++ = ssid_len;
11937 memcpy(pos, ssid, ssid_len);
11938 pos += ssid_len;
11939 /* Supported Rates */
11940 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11941 10);
11942 pos += 10;
11943 /* Extended Supported Rates */
11944 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11945 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011946 /* RSNE - Group and Pairwise ciphers */
11947 memcpy(pos,
11948 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
11949 14);
11950 pos += 14;
11951 /* RSNE - AKM Suite count */
11952 *pos++ = 0x01;
11953 *pos++ = 0x00;
11954 /* RSNE - AKM Suites */
11955 if (dut->program == PROGRAM_WPA3)
11956 memcpy(pos, "\x00\x0f\xac\x08", 4);
11957 else
11958 memcpy(pos, "\x00\x0f\xac\x02", 4);
11959 pos += 4;
11960 /* RSNE - Capabilities */
11961 *pos++ = 0xc0;
11962 if (dut->ocvc)
11963 *pos++ = 0x40;
11964 else
11965 *pos++ = 0x00;
11966 /* RSNE - PMKID list and Group Management Ciphers */
11967 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
11968 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011969 break;
11970 case DLS_REQ:
11971 /* Category - DLS */
11972 *pos++ = 0x02;
11973 /* DLS Action - Request */
11974 *pos++ = 0x00;
11975 /* Destination MACAddress */
11976 if (dest)
11977 hwaddr_aton(dest, pos);
11978 else
11979 memset(pos, 0, 6);
11980 pos += 6;
11981 /* Source MACAddress */
11982 hwaddr_aton(addr, pos);
11983 pos += 6;
11984 /* Capability Information */
11985 *pos++ = 0x10; /* Privacy */
11986 *pos++ = 0x06; /* QoS */
11987 /* DLS Timeout Value */
11988 *pos++ = 0x00;
11989 *pos++ = 0x01;
11990 /* Supported rates */
11991 *pos++ = 0x01;
11992 *pos++ = 0x08;
11993 *pos++ = 0x0c; /* 6 Mbps */
11994 *pos++ = 0x12; /* 9 Mbps */
11995 *pos++ = 0x18; /* 12 Mbps */
11996 *pos++ = 0x24; /* 18 Mbps */
11997 *pos++ = 0x30; /* 24 Mbps */
11998 *pos++ = 0x48; /* 36 Mbps */
11999 *pos++ = 0x60; /* 48 Mbps */
12000 *pos++ = 0x6c; /* 54 Mbps */
12001 /* TODO: Extended Supported Rates */
12002 /* TODO: HT Capabilities */
12003 break;
12004 }
12005 }
12006
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012007 if (use_monitor) {
12008 s = open_monitor("sigmadut");
12009 if (s < 0) {
12010 send_resp(dut, conn, SIGMA_ERROR,
12011 "errorCode,Failed to open monitor socket");
12012 return 0;
12013 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012014
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012015 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
12016 if (res < 0) {
12017 send_resp(dut, conn, SIGMA_ERROR,
12018 "errorCode,Failed to inject frame");
12019 close(s);
12020 return 0;
12021 }
12022 if (res < pos - buf) {
12023 send_resp(dut, conn, SIGMA_ERROR,
12024 "errorCode,Only partial frame sent");
12025 close(s);
12026 return 0;
12027 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012028
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012029 close(s);
12030 } else {
12031#ifdef NL80211_SUPPORT
12032 int freq;
12033 char freq_str[10];
12034
12035 if (get_wpa_status(get_station_ifname(dut), "freq",
12036 freq_str, sizeof(freq_str)) < 0) {
12037 send_resp(dut, conn, SIGMA_ERROR,
12038 "errorCode,Could not get current operating frequency");
12039 return 0;
12040 }
12041 freq = atoi(freq_str);
12042
12043 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
12044 send_resp(dut, conn, SIGMA_ERROR,
12045 "errorCode,Failed to inject frame");
12046 return 0;
12047 }
12048#else /* NL80211_SUPPORT */
12049 send_resp(dut, conn, SIGMA_ERROR,
12050 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
12051 return 0;
12052#endif /* NL80211_SUPPORT */
12053 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012054
12055 return 1;
12056#else /* __linux__ */
12057 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
12058 "yet supported");
12059 return 0;
12060#endif /* __linux__ */
12061}
12062
12063
12064static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
12065 struct sigma_conn *conn,
12066 struct sigma_cmd *cmd)
12067{
12068 const char *intf = get_param(cmd, "Interface");
12069 const char *sta, *val;
12070 unsigned char addr[ETH_ALEN];
12071 char buf[100];
12072
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012073 if (!intf)
12074 return -1;
12075
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012076 sta = get_param(cmd, "peer");
12077 if (sta == NULL)
12078 sta = get_param(cmd, "station");
12079 if (sta == NULL) {
12080 send_resp(dut, conn, SIGMA_ERROR,
12081 "ErrorCode,Missing peer address");
12082 return 0;
12083 }
12084 if (hwaddr_aton(sta, addr) < 0) {
12085 send_resp(dut, conn, SIGMA_ERROR,
12086 "ErrorCode,Invalid peer address");
12087 return 0;
12088 }
12089
12090 val = get_param(cmd, "type");
12091 if (val == NULL)
12092 return -1;
12093
12094 if (strcasecmp(val, "DISCOVERY") == 0) {
12095 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
12096 if (wpa_command(intf, buf) < 0) {
12097 send_resp(dut, conn, SIGMA_ERROR,
12098 "ErrorCode,Failed to send TDLS discovery");
12099 return 0;
12100 }
12101 return 1;
12102 }
12103
12104 if (strcasecmp(val, "SETUP") == 0) {
12105 int status = 0, timeout = 0;
12106
12107 val = get_param(cmd, "Status");
12108 if (val)
12109 status = atoi(val);
12110
12111 val = get_param(cmd, "Timeout");
12112 if (val)
12113 timeout = atoi(val);
12114
12115 if (status != 0 && status != 37) {
12116 send_resp(dut, conn, SIGMA_ERROR,
12117 "ErrorCode,Unsupported status value");
12118 return 0;
12119 }
12120
12121 if (timeout != 0 && timeout != 301) {
12122 send_resp(dut, conn, SIGMA_ERROR,
12123 "ErrorCode,Unsupported timeout value");
12124 return 0;
12125 }
12126
12127 if (status && timeout) {
12128 send_resp(dut, conn, SIGMA_ERROR,
12129 "ErrorCode,Unsupported timeout+status "
12130 "combination");
12131 return 0;
12132 }
12133
12134 if (status == 37 &&
12135 wpa_command(intf, "SET tdls_testing 0x200")) {
12136 send_resp(dut, conn, SIGMA_ERROR,
12137 "ErrorCode,Failed to enable "
12138 "decline setup response test mode");
12139 return 0;
12140 }
12141
12142 if (timeout == 301) {
12143 int res;
12144 if (dut->no_tpk_expiration)
12145 res = wpa_command(intf,
12146 "SET tdls_testing 0x108");
12147 else
12148 res = wpa_command(intf,
12149 "SET tdls_testing 0x8");
12150 if (res) {
12151 send_resp(dut, conn, SIGMA_ERROR,
12152 "ErrorCode,Failed to set short TPK "
12153 "lifetime");
12154 return 0;
12155 }
12156 }
12157
12158 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
12159 if (wpa_command(intf, buf) < 0) {
12160 send_resp(dut, conn, SIGMA_ERROR,
12161 "ErrorCode,Failed to send TDLS setup");
12162 return 0;
12163 }
12164 return 1;
12165 }
12166
12167 if (strcasecmp(val, "TEARDOWN") == 0) {
12168 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
12169 if (wpa_command(intf, buf) < 0) {
12170 send_resp(dut, conn, SIGMA_ERROR,
12171 "ErrorCode,Failed to send TDLS teardown");
12172 return 0;
12173 }
12174 return 1;
12175 }
12176
12177 send_resp(dut, conn, SIGMA_ERROR,
12178 "ErrorCode,Unsupported TDLS frame");
12179 return 0;
12180}
12181
12182
12183static int sta_ap_known(const char *ifname, const char *bssid)
12184{
12185 char buf[4096];
12186
Jouni Malinendd32f192018-09-15 02:55:19 +030012187 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012188 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
12189 return 0;
12190 if (strncmp(buf, "id=", 3) != 0)
12191 return 0;
12192 return 1;
12193}
12194
12195
12196static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
12197 const char *bssid)
12198{
12199 int res;
12200 struct wpa_ctrl *ctrl;
12201 char buf[256];
12202
12203 if (sta_ap_known(ifname, bssid))
12204 return 0;
12205 sigma_dut_print(dut, DUT_MSG_DEBUG,
12206 "AP not in BSS table - start scan");
12207
12208 ctrl = open_wpa_mon(ifname);
12209 if (ctrl == NULL) {
12210 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12211 "wpa_supplicant monitor connection");
12212 return -1;
12213 }
12214
12215 if (wpa_command(ifname, "SCAN") < 0) {
12216 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
12217 wpa_ctrl_detach(ctrl);
12218 wpa_ctrl_close(ctrl);
12219 return -1;
12220 }
12221
12222 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12223 buf, sizeof(buf));
12224
12225 wpa_ctrl_detach(ctrl);
12226 wpa_ctrl_close(ctrl);
12227
12228 if (res < 0) {
12229 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
12230 return -1;
12231 }
12232
12233 if (sta_ap_known(ifname, bssid))
12234 return 0;
12235 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
12236 return -1;
12237}
12238
12239
12240static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
12241 struct sigma_conn *conn,
12242 struct sigma_cmd *cmd,
12243 const char *intf)
12244{
12245 char buf[200];
12246
12247 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
12248 if (system(buf) != 0) {
12249 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
12250 "ndsend");
12251 return 0;
12252 }
12253
12254 return 1;
12255}
12256
12257
12258static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
12259 struct sigma_conn *conn,
12260 struct sigma_cmd *cmd,
12261 const char *intf)
12262{
12263 char buf[200];
12264 const char *ip = get_param(cmd, "SenderIP");
12265
Peng Xu26b356d2017-10-04 17:58:16 -070012266 if (!ip)
12267 return 0;
12268
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012269 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
12270 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12271 if (system(buf) == 0) {
12272 sigma_dut_print(dut, DUT_MSG_INFO,
12273 "Neighbor Solicitation got a response "
12274 "for %s@%s", ip, intf);
12275 }
12276
12277 return 1;
12278}
12279
12280
12281static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
12282 struct sigma_conn *conn,
12283 struct sigma_cmd *cmd,
12284 const char *ifname)
12285{
12286 char buf[200];
12287 const char *ip = get_param(cmd, "SenderIP");
12288
12289 if (ip == NULL) {
12290 send_resp(dut, conn, SIGMA_ERROR,
12291 "ErrorCode,Missing SenderIP parameter");
12292 return 0;
12293 }
12294 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
12295 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12296 if (system(buf) != 0) {
12297 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
12298 "for %s@%s", ip, ifname);
12299 }
12300
12301 return 1;
12302}
12303
12304
12305static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
12306 struct sigma_conn *conn,
12307 struct sigma_cmd *cmd,
12308 const char *ifname)
12309{
12310 char buf[200];
12311 char ip[16];
12312 int s;
Peng Xub3756882017-10-04 14:39:09 -070012313 struct ifreq ifr;
12314 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012315
12316 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070012317 if (s < 0) {
12318 perror("socket");
12319 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012320 }
12321
Peng Xub3756882017-10-04 14:39:09 -070012322 memset(&ifr, 0, sizeof(ifr));
12323 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
12324 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
12325 sigma_dut_print(dut, DUT_MSG_INFO,
12326 "Failed to get %s IP address: %s",
12327 ifname, strerror(errno));
12328 close(s);
12329 return -1;
12330 }
12331 close(s);
12332
12333 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
12334 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
12335
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012336 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
12337 ip);
12338 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12339 if (system(buf) != 0) {
12340 }
12341
12342 return 1;
12343}
12344
12345
12346static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
12347 struct sigma_conn *conn,
12348 struct sigma_cmd *cmd,
12349 const char *ifname)
12350{
12351 char buf[200], addr[20];
12352 char dst[ETH_ALEN], src[ETH_ALEN];
12353 short ethtype = htons(ETH_P_ARP);
12354 char *pos;
12355 int s, res;
12356 const char *val;
12357 struct sockaddr_in taddr;
12358
12359 val = get_param(cmd, "dest");
12360 if (val)
12361 hwaddr_aton(val, (unsigned char *) dst);
12362
12363 val = get_param(cmd, "DestIP");
12364 if (val)
12365 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070012366 else
12367 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012368
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012369 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012370 sizeof(addr)) < 0)
12371 return -2;
12372 hwaddr_aton(addr, (unsigned char *) src);
12373
12374 pos = buf;
12375 *pos++ = 0x00;
12376 *pos++ = 0x01;
12377 *pos++ = 0x08;
12378 *pos++ = 0x00;
12379 *pos++ = 0x06;
12380 *pos++ = 0x04;
12381 *pos++ = 0x00;
12382 *pos++ = 0x02;
12383 memcpy(pos, src, ETH_ALEN);
12384 pos += ETH_ALEN;
12385 memcpy(pos, &taddr.sin_addr, 4);
12386 pos += 4;
12387 memcpy(pos, dst, ETH_ALEN);
12388 pos += ETH_ALEN;
12389 memcpy(pos, &taddr.sin_addr, 4);
12390 pos += 4;
12391
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012392 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012393 if (s < 0) {
12394 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
12395 "monitor socket");
12396 return 0;
12397 }
12398
12399 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
12400 if (res < 0) {
12401 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
12402 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053012403 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012404 return 0;
12405 }
12406
12407 close(s);
12408
12409 return 1;
12410}
12411
12412
12413static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
12414 struct sigma_conn *conn,
12415 struct sigma_cmd *cmd,
12416 const char *intf, const char *dest)
12417{
12418 char buf[100];
12419
12420 if (if_nametoindex("sigmadut") == 0) {
12421 snprintf(buf, sizeof(buf),
12422 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012423 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012424 if (system(buf) != 0 ||
12425 if_nametoindex("sigmadut") == 0) {
12426 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12427 "monitor interface with '%s'", buf);
12428 return -2;
12429 }
12430 }
12431
12432 if (system("ifconfig sigmadut up") != 0) {
12433 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12434 "monitor interface up");
12435 return -2;
12436 }
12437
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012438 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012439}
12440
12441
12442static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
12443 struct sigma_conn *conn,
12444 struct sigma_cmd *cmd)
12445{
12446 const char *intf = get_param(cmd, "Interface");
12447 const char *dest = get_param(cmd, "Dest");
12448 const char *type = get_param(cmd, "FrameName");
12449 const char *val;
12450 char buf[200], *pos, *end;
12451 int count, count2;
12452
12453 if (type == NULL)
12454 type = get_param(cmd, "Type");
12455
12456 if (intf == NULL || dest == NULL || type == NULL)
12457 return -1;
12458
12459 if (strcasecmp(type, "NeighAdv") == 0)
12460 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
12461
12462 if (strcasecmp(type, "NeighSolicitReq") == 0)
12463 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
12464
12465 if (strcasecmp(type, "ARPProbe") == 0)
12466 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
12467
12468 if (strcasecmp(type, "ARPAnnounce") == 0)
12469 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
12470
12471 if (strcasecmp(type, "ARPReply") == 0)
12472 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
12473
12474 if (strcasecmp(type, "DLS-request") == 0 ||
12475 strcasecmp(type, "DLSrequest") == 0)
12476 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
12477 dest);
12478
12479 if (strcasecmp(type, "ANQPQuery") != 0 &&
12480 strcasecmp(type, "Query") != 0) {
12481 send_resp(dut, conn, SIGMA_ERROR,
12482 "ErrorCode,Unsupported HS 2.0 send frame type");
12483 return 0;
12484 }
12485
12486 if (sta_scan_ap(dut, intf, dest) < 0) {
12487 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
12488 "the requested AP");
12489 return 0;
12490 }
12491
12492 pos = buf;
12493 end = buf + sizeof(buf);
12494 count = 0;
12495 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
12496
12497 val = get_param(cmd, "ANQP_CAP_LIST");
12498 if (val && atoi(val)) {
12499 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
12500 count++;
12501 }
12502
12503 val = get_param(cmd, "VENUE_NAME");
12504 if (val && atoi(val)) {
12505 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
12506 count++;
12507 }
12508
12509 val = get_param(cmd, "NETWORK_AUTH_TYPE");
12510 if (val && atoi(val)) {
12511 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
12512 count++;
12513 }
12514
12515 val = get_param(cmd, "ROAMING_CONS");
12516 if (val && atoi(val)) {
12517 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
12518 count++;
12519 }
12520
12521 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
12522 if (val && atoi(val)) {
12523 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
12524 count++;
12525 }
12526
12527 val = get_param(cmd, "NAI_REALM_LIST");
12528 if (val && atoi(val)) {
12529 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
12530 count++;
12531 }
12532
12533 val = get_param(cmd, "3GPP_INFO");
12534 if (val && atoi(val)) {
12535 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
12536 count++;
12537 }
12538
12539 val = get_param(cmd, "DOMAIN_LIST");
12540 if (val && atoi(val)) {
12541 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
12542 count++;
12543 }
12544
Jouni Malinen34cf9532018-04-29 19:26:33 +030012545 val = get_param(cmd, "Venue_URL");
12546 if (val && atoi(val)) {
12547 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
12548 count++;
12549 }
12550
Jouni Malinend3bca5d2018-04-29 17:25:23 +030012551 val = get_param(cmd, "Advice_Of_Charge");
12552 if (val && atoi(val)) {
12553 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
12554 count++;
12555 }
12556
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012557 if (count && wpa_command(intf, buf)) {
12558 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
12559 return 0;
12560 }
12561
12562 pos = buf;
12563 end = buf + sizeof(buf);
12564 count2 = 0;
12565 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
12566
12567 val = get_param(cmd, "HS_CAP_LIST");
12568 if (val && atoi(val)) {
12569 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
12570 count2++;
12571 }
12572
12573 val = get_param(cmd, "OPER_NAME");
12574 if (val && atoi(val)) {
12575 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
12576 count2++;
12577 }
12578
12579 val = get_param(cmd, "WAN_METRICS");
12580 if (!val)
12581 val = get_param(cmd, "WAN_MAT");
12582 if (!val)
12583 val = get_param(cmd, "WAN_MET");
12584 if (val && atoi(val)) {
12585 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
12586 count2++;
12587 }
12588
12589 val = get_param(cmd, "CONNECTION_CAPABILITY");
12590 if (val && atoi(val)) {
12591 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
12592 count2++;
12593 }
12594
12595 val = get_param(cmd, "OP_CLASS");
12596 if (val && atoi(val)) {
12597 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
12598 count2++;
12599 }
12600
12601 val = get_param(cmd, "OSU_PROVIDER_LIST");
12602 if (val && atoi(val)) {
12603 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
12604 count2++;
12605 }
12606
Jouni Malinenf67afec2018-04-29 19:24:58 +030012607 val = get_param(cmd, "OPER_ICON_METADATA");
12608 if (!val)
12609 val = get_param(cmd, "OPERATOR_ICON_METADATA");
12610 if (val && atoi(val)) {
12611 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
12612 count2++;
12613 }
12614
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012615 if (count && count2) {
12616 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
12617 "second query");
12618 sleep(1);
12619 }
12620
12621 if (count2 && wpa_command(intf, buf)) {
12622 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
12623 "failed");
12624 return 0;
12625 }
12626
12627 val = get_param(cmd, "NAI_HOME_REALM_LIST");
12628 if (val) {
12629 if (count || count2) {
12630 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12631 "sending out second query");
12632 sleep(1);
12633 }
12634
12635 if (strcmp(val, "1") == 0)
12636 val = "mail.example.com";
12637 snprintf(buf, end - pos,
12638 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
12639 dest, val);
12640 if (wpa_command(intf, buf)) {
12641 send_resp(dut, conn, SIGMA_ERROR,
12642 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
12643 "failed");
12644 return 0;
12645 }
12646 }
12647
12648 val = get_param(cmd, "ICON_REQUEST");
12649 if (val) {
12650 if (count || count2) {
12651 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12652 "sending out second query");
12653 sleep(1);
12654 }
12655
12656 snprintf(buf, end - pos,
12657 "HS20_ICON_REQUEST %s %s", dest, val);
12658 if (wpa_command(intf, buf)) {
12659 send_resp(dut, conn, SIGMA_ERROR,
12660 "ErrorCode,HS20_ICON_REQUEST failed");
12661 return 0;
12662 }
12663 }
12664
12665 return 1;
12666}
12667
12668
12669static int ath_sta_send_frame_vht(struct sigma_dut *dut,
12670 struct sigma_conn *conn,
12671 struct sigma_cmd *cmd)
12672{
12673 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012674 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012675 int chwidth, nss;
12676
12677 val = get_param(cmd, "framename");
12678 if (!val)
12679 return -1;
12680 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12681
12682 /* Command sequence to generate Op mode notification */
12683 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012684 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012685
12686 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012687 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012688
12689 /* Extract Channel width */
12690 val = get_param(cmd, "Channel_width");
12691 if (val) {
12692 switch (atoi(val)) {
12693 case 20:
12694 chwidth = 0;
12695 break;
12696 case 40:
12697 chwidth = 1;
12698 break;
12699 case 80:
12700 chwidth = 2;
12701 break;
12702 case 160:
12703 chwidth = 3;
12704 break;
12705 default:
12706 chwidth = 2;
12707 break;
12708 }
12709
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012710 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012711 }
12712
12713 /* Extract NSS */
12714 val = get_param(cmd, "NSS");
12715 if (val) {
12716 switch (atoi(val)) {
12717 case 1:
12718 nss = 1;
12719 break;
12720 case 2:
12721 nss = 3;
12722 break;
12723 case 3:
12724 nss = 7;
12725 break;
12726 default:
12727 /* We do not support NSS > 3 */
12728 nss = 3;
12729 break;
12730 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012731 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012732 }
12733
12734 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012735 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012736 }
12737
12738 return 1;
12739}
12740
12741
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012742static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
12743 enum send_frame_protection protected)
12744{
12745#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012746 return wcn_wifi_test_config_set_u8(
12747 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
12748 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012749#else /* NL80211_SUPPORT */
12750 sigma_dut_print(dut, DUT_MSG_ERROR,
12751 "PMF config cannot be set without NL80211_SUPPORT defined");
12752 return -1;
12753#endif /* NL80211_SUPPORT */
12754}
12755
12756
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012757static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
12758 struct sigma_conn *conn,
12759 struct sigma_cmd *cmd)
12760{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012761 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012762 case DRIVER_ATHEROS:
12763 return ath_sta_send_frame_vht(dut, conn, cmd);
12764 default:
12765 send_resp(dut, conn, SIGMA_ERROR,
12766 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
12767 return 0;
12768 }
12769}
12770
12771
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012772static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
12773{
12774#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012775 return wcn_wifi_test_config_set_flag(
12776 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012777#else /* NL80211_SUPPORT */
12778 sigma_dut_print(dut, DUT_MSG_ERROR,
12779 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
12780 return -1;
12781#endif /* NL80211_SUPPORT */
12782}
12783
12784
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012785static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
12786 struct sigma_cmd *cmd)
12787{
12788 const char *val;
12789 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012790 enum send_frame_protection protected;
12791 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012792
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012793 if (!intf)
12794 return -1;
12795
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012796 val = get_param(cmd, "framename");
12797 if (!val)
12798 return -1;
12799 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12800
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012801 pmf = get_param(cmd, "PMFProtected");
12802 if (!pmf)
12803 pmf = get_param(cmd, "Protected");
12804 if (pmf) {
12805 if (strcasecmp(pmf, "Correct-key") == 0 ||
12806 strcasecmp(pmf, "CorrectKey") == 0) {
12807 protected = CORRECT_KEY;
12808 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
12809 protected = INCORRECT_KEY;
12810 } else if (strcasecmp(pmf, "Unprotected") == 0) {
12811 protected = UNPROTECTED;
12812 } else {
12813 send_resp(dut, conn, SIGMA_ERROR,
12814 "errorCode,Unsupported PMFProtected");
12815 return STATUS_SENT_ERROR;
12816 }
12817 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
12818 protected);
12819 wcn_sta_set_pmf_config(dut, intf, protected);
12820 }
12821
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012822 /* Command sequence to generate Op mode notification */
12823 if (val && strcasecmp(val, "action") == 0) {
12824 val = get_param(cmd, "PPDUTxType");
12825 if (val && strcasecmp(val, "TB") == 0) {
12826 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
12827 sigma_dut_print(dut, DUT_MSG_ERROR,
12828 "failed to send TB PPDU Tx cfg");
12829 send_resp(dut, conn, SIGMA_ERROR,
12830 "ErrorCode,set TB PPDU Tx cfg failed");
12831 return 0;
12832 }
12833 return 1;
12834 }
12835
12836 sigma_dut_print(dut, DUT_MSG_ERROR,
12837 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012838
12839 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012840 }
12841
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012842 if (strcasecmp(val, "disassoc") == 0)
12843 wcn_sta_send_disassoc(dut, intf);
12844
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012845 return 1;
12846}
12847
12848
12849static int cmd_sta_send_frame_he(struct sigma_dut *dut,
12850 struct sigma_conn *conn,
12851 struct sigma_cmd *cmd)
12852{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012853 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012854 case DRIVER_WCN:
12855 return wcn_sta_send_frame_he(dut, conn, cmd);
12856 default:
12857 send_resp(dut, conn, SIGMA_ERROR,
12858 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
12859 return 0;
12860 }
12861}
12862
12863
Lior David0fe101e2017-03-09 16:09:50 +020012864#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012865
12866static int
12867wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
12868 const char *frame_name, const char *dest_mac)
12869{
12870 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
12871 const char *ssid = get_param(cmd, "ssid");
12872 const char *countstr = get_param(cmd, "count");
12873 const char *channelstr = get_param(cmd, "channel");
12874 const char *group_id = get_param(cmd, "groupid");
12875 const char *client_id = get_param(cmd, "clientmac");
12876 int count, channel, freq, i;
12877 const char *fname;
12878 char frame[1024], src_mac[20], group_id_attr[25],
12879 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
12880 const char *group_ssid;
12881 const int group_ssid_prefix_len = 9;
12882 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
12883 size_t framelen = sizeof(frame);
12884 struct template_frame_tag tags[2];
12885 size_t tags_total = ARRAY_SIZE(tags);
12886 int tag_index, len, dst_len;
12887
12888 if (!countstr || !channelstr) {
12889 sigma_dut_print(dut, DUT_MSG_ERROR,
12890 "Missing argument: count, channel");
12891 return -1;
12892 }
12893 if (isprobereq && !ssid) {
12894 sigma_dut_print(dut, DUT_MSG_ERROR,
12895 "Missing argument: ssid");
12896 return -1;
12897 }
12898 if (!isprobereq && (!group_id || !client_id)) {
12899 sigma_dut_print(dut, DUT_MSG_ERROR,
12900 "Missing argument: group_id, client_id");
12901 return -1;
12902 }
12903
12904 count = atoi(countstr);
12905 channel = atoi(channelstr);
12906 freq = channel_to_freq(dut, channel);
12907
12908 if (!freq) {
12909 sigma_dut_print(dut, DUT_MSG_ERROR,
12910 "invalid channel: %s", channelstr);
12911 return -1;
12912 }
12913
12914 if (isprobereq) {
12915 if (strcasecmp(ssid, "wildcard") == 0) {
12916 fname = "probe_req_wildcard.txt";
12917 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
12918 fname = "probe_req_P2P_Wildcard.txt";
12919 } else {
12920 sigma_dut_print(dut, DUT_MSG_ERROR,
12921 "invalid probe request type");
12922 return -1;
12923 }
12924 } else {
12925 fname = "P2P_device_discovery_req.txt";
12926 }
12927
12928 if (parse_template_frame_file(dut, fname, frame, &framelen,
12929 tags, &tags_total)) {
12930 sigma_dut_print(dut, DUT_MSG_ERROR,
12931 "invalid frame template: %s", fname);
12932 return -1;
12933 }
12934
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012935 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012936 src_mac, sizeof(src_mac)) < 0 ||
12937 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
12938 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
12939 return -1;
12940 /* Use wildcard BSSID, since we are in PBSS */
12941 memset(&hdr->addr3, 0xFF, ETH_ALEN);
12942
12943 if (!isprobereq) {
12944 tag_index = find_template_frame_tag(tags, tags_total, 1);
12945 if (tag_index < 0) {
12946 sigma_dut_print(dut, DUT_MSG_ERROR,
12947 "can't find device id attribute");
12948 return -1;
12949 }
12950 if (parse_mac_address(dut, client_id,
12951 (unsigned char *) client_mac)) {
12952 sigma_dut_print(dut, DUT_MSG_ERROR,
12953 "invalid client_id: %s", client_id);
12954 return -1;
12955 }
12956 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
12957 framelen - tags[tag_index].offset,
12958 IEEE80211_P2P_ATTR_DEVICE_ID,
12959 client_mac, ETH_ALEN)) {
12960 sigma_dut_print(dut, DUT_MSG_ERROR,
12961 "fail to replace device id attribute");
12962 return -1;
12963 }
12964
12965 /*
12966 * group_id arg contains device MAC address followed by
12967 * space and SSID (DIRECT-somessid).
12968 * group id attribute contains device address (6 bytes)
12969 * followed by SSID prefix DIRECT-XX (9 bytes)
12970 */
12971 if (strlen(group_id) < sizeof(device_macstr)) {
12972 sigma_dut_print(dut, DUT_MSG_ERROR,
12973 "group_id arg too short");
12974 return -1;
12975 }
12976 memcpy(device_macstr, group_id, sizeof(device_macstr));
12977 device_macstr[sizeof(device_macstr) - 1] = '\0';
12978 if (parse_mac_address(dut, device_macstr,
12979 (unsigned char *) group_id_attr)) {
12980 sigma_dut_print(dut, DUT_MSG_ERROR,
12981 "fail to parse device address from group_id");
12982 return -1;
12983 }
12984 group_ssid = strchr(group_id, ' ');
12985 if (!group_ssid) {
12986 sigma_dut_print(dut, DUT_MSG_ERROR,
12987 "invalid group_id arg, no ssid");
12988 return -1;
12989 }
12990 group_ssid++;
12991 len = strlen(group_ssid);
12992 if (len < group_ssid_prefix_len) {
12993 sigma_dut_print(dut, DUT_MSG_ERROR,
12994 "group_id SSID too short");
12995 return -1;
12996 }
12997 dst_len = sizeof(group_id_attr) - ETH_ALEN;
12998 if (len > dst_len) {
12999 sigma_dut_print(dut, DUT_MSG_ERROR,
13000 "group_id SSID (%s) too long",
13001 group_ssid);
13002 return -1;
13003 }
13004
13005 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
13006 tag_index = find_template_frame_tag(tags, tags_total, 2);
13007 if (tag_index < 0) {
13008 sigma_dut_print(dut, DUT_MSG_ERROR,
13009 "can't find group id attribute");
13010 return -1;
13011 }
13012 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13013 framelen - tags[tag_index].offset,
13014 IEEE80211_P2P_ATTR_GROUP_ID,
13015 group_id_attr,
13016 sizeof(group_id_attr))) {
13017 sigma_dut_print(dut, DUT_MSG_ERROR,
13018 "fail to replace group id attribute");
13019 return -1;
13020 }
13021 }
13022
13023 for (i = 0; i < count; i++) {
13024 if (wil6210_transmit_frame(dut, freq,
13025 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
13026 frame, framelen)) {
13027 sigma_dut_print(dut, DUT_MSG_ERROR,
13028 "fail to transmit probe request frame");
13029 return -1;
13030 }
13031 }
13032
13033 return 0;
13034}
13035
13036
Lior David0fe101e2017-03-09 16:09:50 +020013037int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
13038 struct sigma_cmd *cmd)
13039{
13040 const char *frame_name = get_param(cmd, "framename");
13041 const char *mac = get_param(cmd, "dest_mac");
13042
13043 if (!frame_name || !mac) {
13044 sigma_dut_print(dut, DUT_MSG_ERROR,
13045 "framename and dest_mac must be provided");
13046 return -1;
13047 }
13048
13049 if (strcasecmp(frame_name, "brp") == 0) {
13050 const char *l_rx = get_param(cmd, "L-RX");
13051 int l_rx_i;
13052
13053 if (!l_rx) {
13054 sigma_dut_print(dut, DUT_MSG_ERROR,
13055 "L-RX must be provided");
13056 return -1;
13057 }
13058 l_rx_i = atoi(l_rx);
13059
13060 sigma_dut_print(dut, DUT_MSG_INFO,
13061 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
13062 mac, l_rx);
13063 if (l_rx_i != 16) {
13064 sigma_dut_print(dut, DUT_MSG_ERROR,
13065 "unsupported L-RX: %s", l_rx);
13066 return -1;
13067 }
13068
13069 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
13070 return -1;
13071 } else if (strcasecmp(frame_name, "ssw") == 0) {
13072 sigma_dut_print(dut, DUT_MSG_INFO,
13073 "dev_send_frame: SLS, dest_mac %s", mac);
13074 if (wil6210_send_sls(dut, mac))
13075 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013076 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
13077 (strcasecmp(frame_name, "devdiscreq") == 0)) {
13078 sigma_dut_print(dut, DUT_MSG_INFO,
13079 "dev_send_frame: %s, dest_mac %s", frame_name,
13080 mac);
13081 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
13082 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020013083 } else {
13084 sigma_dut_print(dut, DUT_MSG_ERROR,
13085 "unsupported frame type: %s", frame_name);
13086 return -1;
13087 }
13088
13089 return 1;
13090}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013091
Lior David0fe101e2017-03-09 16:09:50 +020013092#endif /* __linux__ */
13093
13094
13095static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
13096 struct sigma_conn *conn,
13097 struct sigma_cmd *cmd)
13098{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013099 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020013100#ifdef __linux__
13101 case DRIVER_WIL6210:
13102 return wil6210_send_frame_60g(dut, conn, cmd);
13103#endif /* __linux__ */
13104 default:
13105 send_resp(dut, conn, SIGMA_ERROR,
13106 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
13107 return 0;
13108 }
13109}
13110
13111
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013112static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13113 const char *intf, struct sigma_cmd *cmd)
13114{
13115 const char *val, *addr;
13116 char buf[100];
13117
13118 addr = get_param(cmd, "DestMac");
13119 if (!addr) {
13120 send_resp(dut, conn, SIGMA_INVALID,
13121 "ErrorCode,AP MAC address is missing");
13122 return 0;
13123 }
13124
13125 val = get_param(cmd, "ANQPQuery_ID");
13126 if (!val) {
13127 send_resp(dut, conn, SIGMA_INVALID,
13128 "ErrorCode,Missing ANQPQuery_ID");
13129 return 0;
13130 }
13131
13132 if (strcasecmp(val, "NeighborReportReq") == 0) {
13133 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
13134 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
13135 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
13136 } else {
13137 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
13138 val);
13139 send_resp(dut, conn, SIGMA_INVALID,
13140 "ErrorCode,Invalid ANQPQuery_ID");
13141 return 0;
13142 }
13143
Ashwini Patild174f2c2017-04-13 16:49:46 +053013144 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
13145 * (Address3 = Wildcard BSSID when sent to not-associated AP;
13146 * if associated, AP BSSID).
13147 */
13148 if (wpa_command(intf, "SET gas_address3 1") < 0) {
13149 send_resp(dut, conn, SIGMA_ERROR,
13150 "ErrorCode,Failed to set gas_address3");
13151 return 0;
13152 }
13153
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013154 if (wpa_command(intf, buf) < 0) {
13155 send_resp(dut, conn, SIGMA_ERROR,
13156 "ErrorCode,Failed to send ANQP query");
13157 return 0;
13158 }
13159
13160 return 1;
13161}
13162
13163
13164static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
13165 struct sigma_conn *conn,
13166 const char *intf,
13167 struct sigma_cmd *cmd)
13168{
13169 const char *val = get_param(cmd, "FrameName");
13170
13171 if (val && strcasecmp(val, "ANQPQuery") == 0)
13172 return mbo_send_anqp_query(dut, conn, intf, cmd);
13173
13174 return 2;
13175}
13176
13177
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013178static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
13179 struct sigma_conn *conn,
13180 const char *intf,
13181 struct sigma_cmd *cmd)
13182{
13183 const char *val = get_param(cmd, "framename");
13184
13185 if (!val)
13186 return INVALID_SEND_STATUS;
13187
13188 if (strcasecmp(val, "SAQueryReq") == 0) {
13189 val = get_param(cmd, "OCIChannel");
13190
13191 if (!val) {
13192 send_resp(dut, conn, SIGMA_ERROR,
13193 "errorCode,OCIChannel not present");
13194 return STATUS_SENT_ERROR;
13195 }
13196
13197 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
13198 if (!dut->saquery_oci_freq) {
13199 send_resp(dut, conn, SIGMA_ERROR,
13200 "errorCode,Invalid OCIChannel number");
13201 return STATUS_SENT_ERROR;
13202 }
13203
13204 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
13205 NULL, 0);
13206 }
13207
13208 if (strcasecmp(val, "reassocreq") == 0)
13209 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
13210 CORRECT_KEY, NULL, 0);
13211
Veerendranath9f81dfb2020-08-10 01:21:29 -070013212 if (strcasecmp(val, "ANQPQuery") == 0) {
13213 char buf[50];
13214 const char *dest = get_param(cmd, "DestMac");
13215 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013216 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070013217 int len, freq;
13218
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013219 if (freq_str)
13220 freq = atoi(freq_str);
13221 else
13222 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
13223
Veerendranath9f81dfb2020-08-10 01:21:29 -070013224 if (!dest || !freq)
13225 return INVALID_SEND_STATUS;
13226
13227 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
13228 dest, freq);
13229 if (len < 0 || len >= sizeof(buf)) {
13230 sigma_dut_print(dut, DUT_MSG_ERROR,
13231 "Failed to allocate buf");
13232 return ERROR_SEND_STATUS;
13233 }
13234
13235 if (wpa_command(intf, buf) != 0) {
13236 send_resp(dut, conn, SIGMA_ERROR,
13237 "ErrorCode,Failed to send ANQP Query frame");
13238 return STATUS_SENT_ERROR;
13239 }
13240
13241 sigma_dut_print(dut, DUT_MSG_DEBUG,
13242 "ANQP Query sent: %s", buf);
13243
13244 return SUCCESS_SEND_STATUS;
13245 }
13246
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013247 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
13248 return STATUS_SENT_ERROR;
13249}
13250
13251
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013252static int
13253get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13254 char *pos, int rem_len, int num_of_scs_desc,
13255 int num_of_tclas_elem)
13256{
13257 const char *val;
13258 int ipv6;
13259 int len, total_len = 0;
13260
13261 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
13262 num_of_tclas_elem);
13263 if (!val) {
13264 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
13265 __func__);
13266 return -1;
13267 }
13268
13269 if (strcmp(val, "6") == 0) {
13270 ipv6 = 1;
13271 } else if (strcmp(val, "4") == 0) {
13272 ipv6 = 0;
13273 } else {
13274 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
13275 __func__);
13276 return -1;
13277 }
13278
13279 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
13280 if (len < 0 || len >= rem_len)
13281 return -1;
13282
13283 pos += len;
13284 rem_len -= len;
13285 total_len += len;
13286
13287 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
13288 num_of_scs_desc, num_of_tclas_elem);
13289 if (val) {
13290 len = snprintf(pos, rem_len, " src_ip=%s", val);
13291 if (len < 0 || len >= rem_len)
13292 return -1;
13293
13294 pos += len;
13295 rem_len -= len;
13296 total_len += len;
13297 }
13298
13299 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
13300 num_of_scs_desc, num_of_tclas_elem);
13301 if (val) {
13302 len = snprintf(pos, rem_len, " dst_ip=%s", val);
13303 if (len < 0 || len >= rem_len)
13304 return -1;
13305
13306 pos += len;
13307 rem_len -= len;
13308 total_len += len;
13309 }
13310
13311 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
13312 num_of_tclas_elem);
13313 if (val) {
13314 len = snprintf(pos, rem_len, " src_port=%s", val);
13315 if (len < 0 || len >= rem_len)
13316 return -1;
13317
13318 pos += len;
13319 rem_len -= len;
13320 total_len += len;
13321 }
13322
13323 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
13324 num_of_scs_desc, num_of_tclas_elem);
13325 if (val) {
13326 len = snprintf(pos, rem_len, " dst_port=%s", val);
13327 if (len < 0 || len >= rem_len)
13328 return -1;
13329
13330 pos += len;
13331 rem_len -= len;
13332 total_len += len;
13333 }
13334
13335 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
13336 num_of_tclas_elem);
13337 if (val) {
13338 len = snprintf(pos, rem_len, " dscp=%s", val);
13339 if (len < 0 || len >= rem_len)
13340 return -1;
13341
13342 pos += len;
13343 rem_len -= len;
13344 total_len += len;
13345 }
13346
13347 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
13348 num_of_scs_desc, num_of_tclas_elem);
13349 if (val) {
13350 char *prot;
13351
13352 switch (atoi(val)) {
13353 case 17:
13354 prot = "udp";
13355 break;
13356 case 6:
13357 prot = "tcp";
13358 break;
13359 case 50:
13360 prot = "esp";
13361 break;
13362 default:
13363 sigma_dut_print(dut, DUT_MSG_ERROR,
13364 "Invalid protocol %d", atoi(val));
13365 return -1;
13366 }
13367
13368 if (ipv6)
13369 len = snprintf(pos, rem_len, " next_header=%s", prot);
13370 else
13371 len = snprintf(pos, rem_len, " protocol=%s", prot);
13372 if (len < 0 || len >= rem_len)
13373 return -1;
13374
13375 pos += len;
13376 rem_len -= len;
13377 total_len += len;
13378 }
13379
13380 return total_len;
13381}
13382
13383
13384static int
13385get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13386 char *pos, int rem_len, int num_of_scs_desc,
13387 int num_of_tclas_elem)
13388{
13389 const char *val;
13390 int len, total_len = 0;
13391
13392 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
13393 num_of_scs_desc, num_of_tclas_elem);
13394 if (val) {
13395 len = snprintf(pos, rem_len, " prot_instance=%s",
13396 val);
13397 if (len < 0 || len >= rem_len)
13398 return -1;
13399
13400 pos += len;
13401 rem_len -= len;
13402 total_len += len;
13403 }
13404
13405 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
13406 num_of_scs_desc, num_of_tclas_elem);
13407 if (val) {
13408 char *prot;
13409
13410 switch (atoi(val)) {
13411 case 17:
13412 prot = "udp";
13413 break;
13414 case 6:
13415 prot = "tcp";
13416 break;
13417 case 50:
13418 prot = "esp";
13419 break;
13420 default:
13421 sigma_dut_print(dut, DUT_MSG_ERROR,
13422 "Invalid protocol %d",
13423 atoi(val));
13424 return -1;
13425 }
13426
13427 len = snprintf(pos, rem_len, " prot_number=%s", prot);
13428 if (len < 0 || len >= rem_len)
13429 return -1;
13430
13431 pos += len;
13432 rem_len -= len;
13433 total_len += len;
13434 }
13435
13436 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
13437 num_of_scs_desc, num_of_tclas_elem);
13438 if (val) {
13439 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
13440 if (len < 0 || len >= rem_len)
13441 return -1;
13442
13443 pos += len;
13444 rem_len -= len;
13445 total_len += len;
13446 }
13447
13448 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
13449 num_of_tclas_elem);
13450 if (val && strlen(val) >= 2) {
13451 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
13452 if (len < 0 || len >= rem_len)
13453 return -1;
13454
13455 pos += len;
13456 rem_len -= len;
13457 total_len += len;
13458 }
13459
13460 return total_len;
13461}
13462
13463
13464static enum sigma_cmd_result
13465cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
13466 const char *intf, struct sigma_cmd *cmd)
13467{
13468 char buf[4096], *pos;
13469 const char *val, *scs_id, *classifier_type;
13470 int len, rem_len, total_bytes;
13471 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
13472
13473 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
13474 if (!scs_id) {
13475 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
13476 return INVALID_SEND_STATUS;
13477 }
13478
13479 rem_len = sizeof(buf);
13480 pos = buf;
13481
13482 len = snprintf(buf, sizeof(buf), "SCS");
13483 if (len < 0 || len > rem_len)
13484 goto fail;
13485
13486 pos += len;
13487 rem_len -= len;
13488
13489 while (scs_id) {
13490 num_of_scs_desc++;
13491
13492 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
13493 num_of_scs_desc);
13494 if (!val)
13495 return INVALID_SEND_STATUS;
13496
13497 if (strcasecmp(val, "Add") == 0) {
13498 len = snprintf(pos, rem_len, " scs_id=%s add",
13499 scs_id);
13500 } else if (strcasecmp(val, "Change") == 0) {
13501 len = snprintf(pos, rem_len, " scs_id=%s change",
13502 scs_id);
13503 } else if (strcasecmp(val, "Remove") == 0) {
13504 len = snprintf(pos, rem_len, " scs_id=%s remove",
13505 scs_id);
13506 if (len < 0 || len >= rem_len)
13507 goto fail;
13508
13509 pos += len;
13510 rem_len -= len;
13511 goto scs_desc_end;
13512 } else {
13513 sigma_dut_print(dut, DUT_MSG_ERROR,
13514 "%s: request type - %s is invalid",
13515 __func__, val);
13516 return INVALID_SEND_STATUS;
13517 }
13518
13519 if (len < 0 || len >= rem_len)
13520 goto fail;
13521
13522 pos += len;
13523 rem_len -= len;
13524
13525 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
13526 num_of_scs_desc);
13527 if (!val) {
13528 sigma_dut_print(dut, DUT_MSG_ERROR,
13529 "IntraAccess Priority empty");
13530 return INVALID_SEND_STATUS;
13531 }
13532
13533 len = snprintf(pos, rem_len, " scs_up=%s", val);
13534 if (len < 0 || len >= rem_len)
13535 goto fail;
13536
13537 pos += len;
13538 rem_len -= len;
13539
13540 classifier_type = get_param_fmt(cmd,
13541 "TCLASElem_ClassifierType_%d_1",
13542 num_of_scs_desc);
13543 if (!classifier_type) {
13544 sigma_dut_print(dut, DUT_MSG_ERROR,
13545 "classifier type missing");
13546 return INVALID_SEND_STATUS;
13547 }
13548
13549 while (classifier_type) {
13550 num_of_tclas_elem++;
13551
13552 len = snprintf(pos, rem_len, " classifier_type=%s",
13553 classifier_type);
13554 if (len < 0 || len >= rem_len)
13555 goto fail;
13556
13557 pos += len;
13558 rem_len -= len;
13559
13560 if (strcmp(classifier_type, "10") == 0) {
13561 total_bytes = get_type10_frame_classifier(
13562 dut, cmd, pos, rem_len,
13563 num_of_scs_desc,
13564 num_of_tclas_elem);
13565 } else if (strcmp(classifier_type, "4") == 0) {
13566 total_bytes = get_type4_frame_classifier(
13567 dut, cmd, pos, rem_len,
13568 num_of_scs_desc,
13569 num_of_tclas_elem);
13570 } else {
13571 sigma_dut_print(dut, DUT_MSG_ERROR,
13572 "classifier_type invalid");
13573 goto fail;
13574 }
13575
13576 if (total_bytes < 0)
13577 goto fail;
13578
13579 pos += total_bytes;
13580 rem_len -= total_bytes;
13581
13582 classifier_type = get_param_fmt(
13583 cmd, "TCLASElem_ClassifierType_%d_%d",
13584 num_of_scs_desc, num_of_tclas_elem + 1);
13585 }
13586
13587 if (num_of_tclas_elem > 1) {
13588 val = get_param_fmt(cmd,
13589 "TCLASProcessingElem_Processing_%d",
13590 num_of_scs_desc);
13591 if (!val) {
13592 sigma_dut_print(dut, DUT_MSG_ERROR,
13593 "Tclas_processing element %d empty",
13594 num_of_scs_desc);
13595 goto fail;
13596 }
13597
13598 len = snprintf(pos, rem_len,
13599 " tclas_processing=%s", val);
13600 if (len < 0 || len >= rem_len)
13601 goto fail;
13602
13603 pos += len;
13604 rem_len -= len;
13605 }
13606scs_desc_end:
13607 num_of_tclas_elem = 0;
13608 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
13609 num_of_scs_desc + 1);
13610 }
13611
13612 if (wpa_command(intf, buf) != 0) {
13613 send_resp(dut, conn, SIGMA_ERROR,
13614 "ErrorCode,Failed to send SCS frame request");
13615 return STATUS_SENT_ERROR;
13616 }
13617
13618 sigma_dut_print(dut, DUT_MSG_DEBUG,
13619 "SCS frame request sent: %s", buf);
13620
13621 return SUCCESS_SEND_STATUS;
13622fail:
13623 sigma_dut_print(dut, DUT_MSG_ERROR,
13624 "Failed to create SCS frame request");
13625 return ERROR_SEND_STATUS;
13626}
13627
13628
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013629static enum sigma_cmd_result
13630cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
13631 const char *intf, struct sigma_cmd *cmd)
13632{
13633 char buf[128], *pos;
13634 const char *val, *classifier_type = "04", *type;
13635 int len, rem_len;
13636 u8 up_bitmap;
13637
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013638 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013639 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013640 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013641 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013642 return INVALID_SEND_STATUS;
13643 }
13644
13645 rem_len = sizeof(buf);
13646 pos = buf;
13647 if (strcasecmp(type, "add") == 0) {
13648 len = snprintf(pos, rem_len, "MSCS add");
13649 } else if (strcasecmp(type, "update") == 0) {
13650 len = snprintf(pos, rem_len, "MSCS change");
13651 } else if (strcasecmp(type, "remove") == 0) {
13652 if (wpa_command(intf, "MSCS remove") != 0) {
13653 send_resp(dut, conn, SIGMA_ERROR,
13654 "ErrorCode,Failed to send MSCS frame req");
13655 return STATUS_SENT_ERROR;
13656 }
13657 return SUCCESS_SEND_STATUS;
13658 } else {
13659 sigma_dut_print(dut, DUT_MSG_ERROR,
13660 "%s: request type invalid", __func__);
13661 return INVALID_SEND_STATUS;
13662 }
13663
13664 if (len < 0 || len >= rem_len)
13665 goto fail;
13666
13667 pos += len;
13668 rem_len -= len;
13669
13670 val = get_param(cmd, "User_Priority_Bitmap");
13671 if (!val) {
13672 sigma_dut_print(dut, DUT_MSG_ERROR,
13673 "%s: user priority bitmap empty", __func__);
13674 return INVALID_SEND_STATUS;
13675 }
13676
13677 switch (atoi(val)) {
13678 case 0:
13679 up_bitmap = 0x00;
13680 break;
13681 case 1:
13682 up_bitmap = 0xF0;
13683 break;
13684 case 2:
13685 up_bitmap = 0xF6;
13686 break;
13687 default:
13688 sigma_dut_print(dut, DUT_MSG_ERROR,
13689 "%s: Unknown User_Priority_Bitmap value %d",
13690 __func__, atoi(val));
13691 return INVALID_SEND_STATUS;
13692 }
13693
13694 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
13695 if (len < 0 || len >= rem_len)
13696 goto fail;
13697
13698 pos += len;
13699 rem_len -= len;
13700
13701 val = get_param(cmd, "User_Priority_Limit");
13702 if (!val) {
13703 sigma_dut_print(dut, DUT_MSG_ERROR,
13704 "%s: invalid user priority limit", __func__);
13705 return INVALID_SEND_STATUS;
13706 }
13707
13708 len = snprintf(pos, rem_len, " up_limit=%s", val);
13709 if (len < 0 || len >= rem_len)
13710 goto fail;
13711
13712 pos += len;
13713 rem_len -= len;
13714
13715 val = get_param(cmd, "Stream_Timeout");
13716 if (!val)
13717 val = get_param(cmd, "Stream_Timtout");
13718 if (!val) {
13719 sigma_dut_print(dut, DUT_MSG_ERROR,
13720 "%s: invalid stream timeout", __func__);
13721 return INVALID_SEND_STATUS;
13722 }
13723
13724 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
13725 if (len < 0 || len >= rem_len)
13726 goto fail;
13727
13728 pos += len;
13729 rem_len -= len;
13730
13731 val = get_param(cmd, "TCLAS_Mask");
13732 if (!val) {
13733 sigma_dut_print(dut, DUT_MSG_ERROR,
13734 "%s: invalid tclas mask", __func__);
13735 return INVALID_SEND_STATUS;
13736 }
13737
13738 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
13739 classifier_type, strtol(val, NULL, 2), 0);
13740 if (len < 0 || len >= rem_len)
13741 goto fail;
13742
13743 if (wpa_command(intf, buf) != 0) {
13744 send_resp(dut, conn, SIGMA_ERROR,
13745 "ErrorCode,Failed to send MSCS frame req");
13746 return STATUS_SENT_ERROR;
13747 }
13748
13749 sigma_dut_print(dut, DUT_MSG_DEBUG,
13750 "MSCS frame request sent: %s", buf);
13751
13752 return SUCCESS_SEND_STATUS;
13753fail:
13754 sigma_dut_print(dut, DUT_MSG_ERROR,
13755 "Failed to create MSCS frame req");
13756 return ERROR_SEND_STATUS;
13757}
13758
13759
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013760static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013761cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13762 const char *intf, struct sigma_cmd *cmd)
13763{
13764 char buf[150], *pos;
13765 const char *val;
13766 int len, rem_len;
13767
13768 rem_len = sizeof(buf);
13769 pos = buf;
13770
13771 len = snprintf(pos, rem_len, "DSCP_QUERY");
13772 if (len < 0 || len >= rem_len)
13773 goto fail;
13774
13775 pos += len;
13776 rem_len -= len;
13777
13778 val = get_param(cmd, "Wildcard");
13779 if (val && strcasecmp(val, "Yes") == 0) {
13780 len = snprintf(pos, rem_len, " wildcard");
13781 if (len < 0 || len >= rem_len)
13782 goto fail;
13783 } else if (strlen(dut->qm_domain_name)) {
13784 len = snprintf(pos, rem_len, " domain_name=%s",
13785 dut->qm_domain_name);
13786 if (len < 0 || len >= rem_len)
13787 goto fail;
13788 } else {
13789 sigma_dut_print(dut, DUT_MSG_ERROR,
13790 "Invalid DSCP Query configuration");
13791 return INVALID_SEND_STATUS;
13792 }
13793
13794 if (wpa_command(intf, buf) != 0) {
13795 send_resp(dut, conn, SIGMA_ERROR,
13796 "ErrorCode,Failed to send DSCP policy query frame");
13797 return STATUS_SENT_ERROR;
13798 }
13799
13800 sigma_dut_print(dut, DUT_MSG_DEBUG,
13801 "DSCP policy query frame sent: %s", buf);
13802 return SUCCESS_SEND_STATUS;
13803fail:
13804 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
13805 return ERROR_SEND_STATUS;
13806}
13807
13808
13809static enum sigma_cmd_result
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013810cmd_sta_send_frame_dscp_response(struct sigma_dut *dut, struct sigma_conn *conn,
13811 const char *intf, struct sigma_cmd *cmd)
13812{
13813 char buf[256], *pos, *item, *list, *saveptr;
13814 const char *val;
13815 int len, rem_len;
13816
13817 pos = buf;
13818 rem_len = sizeof(buf);
13819
13820 len = snprintf(pos, rem_len, "DSCP_RESP");
13821 if (snprintf_error(rem_len, len)) {
13822 sigma_dut_print(dut, DUT_MSG_ERROR,
13823 "Failed to create DSCP Policy Response command");
13824 return ERROR_SEND_STATUS;
13825 }
13826
13827 pos += len;
13828 rem_len -= len;
13829
13830 val = get_param(cmd, "PolicyID_List");
13831 if (!val) {
13832 sigma_dut_print(dut, DUT_MSG_ERROR,
13833 "DSCP policy ID list missing");
13834 return INVALID_SEND_STATUS;
13835 }
13836
13837 list = strdup(val);
13838 if (!list)
13839 return ERROR_SEND_STATUS;
13840
13841 item = strtok_r(list, "_", &saveptr);
13842 while (item) {
13843 unsigned int i;
13844 int policy_id = atoi(item);
13845
13846 for (i = 0; i < dut->num_dscp_status; i++)
13847 if (dut->dscp_status[i].id == policy_id)
13848 break;
13849
13850 if (i == dut->num_dscp_status) {
13851 free(list);
13852 send_resp(dut, conn, SIGMA_ERROR,
13853 "ErrorCode,DSCP policy id not found in status list");
13854 return STATUS_SENT_ERROR;
13855 }
13856
13857 len = snprintf(pos, rem_len, " policy_id=%d status=%d",
13858 policy_id, dut->dscp_status[i].status);
13859 if (snprintf_error(rem_len, len)) {
13860 free(list);
13861 sigma_dut_print(dut, DUT_MSG_ERROR,
13862 "Failed to write DSCP policy list");
13863 return ERROR_SEND_STATUS;
13864 }
13865
13866 pos += len;
13867 rem_len -= len;
13868
13869 if (dut->dscp_status[i].status)
13870 remove_dscp_policy(dut, policy_id);
13871
13872 item = strtok_r(NULL, "_", &saveptr);
13873 }
13874
13875 free(list);
13876
13877 if (wpa_command(intf, buf) != 0) {
13878 send_resp(dut, conn, SIGMA_ERROR,
13879 "ErrorCode,Failed to send DSCP Policy Response frame");
13880 return STATUS_SENT_ERROR;
13881 }
13882
13883 sigma_dut_print(dut, DUT_MSG_DEBUG,
13884 "DSCP Policy Response frame sent: %s", buf);
13885 return SUCCESS_SEND_STATUS;
13886}
13887
13888
13889static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013890cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
13891 const char *intf, struct sigma_cmd *cmd)
13892{
13893 const char *val;
13894
13895 val = get_param(cmd, "FrameName");
13896 if (val) {
13897 if (strcasecmp(val, "MSCSReq") == 0)
13898 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
13899 if (strcasecmp(val, "SCSReq") == 0)
13900 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013901 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
13902 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
13903 cmd);
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013904 if (strcasecmp(val, "DSCPPolicyResponse") == 0)
13905 return cmd_sta_send_frame_dscp_response(dut, conn, intf,
13906 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013907
13908 sigma_dut_print(dut, DUT_MSG_ERROR,
13909 "%s: frame name - %s is invalid",
13910 __func__, val);
13911 }
13912
13913 return INVALID_SEND_STATUS;
13914}
13915
13916
Jouni Malinenf7222712019-06-13 01:50:21 +030013917enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
13918 struct sigma_conn *conn,
13919 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013920{
13921 const char *intf = get_param(cmd, "Interface");
13922 const char *val;
13923 enum send_frame_type frame;
13924 enum send_frame_protection protected;
13925 char buf[100];
13926 unsigned char addr[ETH_ALEN];
13927 int res;
13928
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030013929 if (!intf)
13930 return -1;
13931
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013932 val = get_param(cmd, "program");
13933 if (val == NULL)
13934 val = get_param(cmd, "frame");
13935 if (val && strcasecmp(val, "TDLS") == 0)
13936 return cmd_sta_send_frame_tdls(dut, conn, cmd);
13937 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030013938 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020013939 strcasecmp(val, "HS2-R3") == 0 ||
13940 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013941 return cmd_sta_send_frame_hs2(dut, conn, cmd);
13942 if (val && strcasecmp(val, "VHT") == 0)
13943 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070013944 if (val && strcasecmp(val, "HE") == 0)
13945 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070013946 if (val && strcasecmp(val, "LOC") == 0)
13947 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020013948 if (val && strcasecmp(val, "60GHz") == 0)
13949 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013950 if (val && strcasecmp(val, "MBO") == 0) {
13951 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
13952 if (res != 2)
13953 return res;
13954 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013955 if (val && strcasecmp(val, "WPA3") == 0)
13956 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013957 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013958 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013959
13960 val = get_param(cmd, "TD_DISC");
13961 if (val) {
13962 if (hwaddr_aton(val, addr) < 0)
13963 return -1;
13964 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
13965 if (wpa_command(intf, buf) < 0) {
13966 send_resp(dut, conn, SIGMA_ERROR,
13967 "ErrorCode,Failed to send TDLS discovery");
13968 return 0;
13969 }
13970 return 1;
13971 }
13972
13973 val = get_param(cmd, "TD_Setup");
13974 if (val) {
13975 if (hwaddr_aton(val, addr) < 0)
13976 return -1;
13977 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
13978 if (wpa_command(intf, buf) < 0) {
13979 send_resp(dut, conn, SIGMA_ERROR,
13980 "ErrorCode,Failed to start TDLS setup");
13981 return 0;
13982 }
13983 return 1;
13984 }
13985
13986 val = get_param(cmd, "TD_TearDown");
13987 if (val) {
13988 if (hwaddr_aton(val, addr) < 0)
13989 return -1;
13990 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
13991 if (wpa_command(intf, buf) < 0) {
13992 send_resp(dut, conn, SIGMA_ERROR,
13993 "ErrorCode,Failed to tear down TDLS link");
13994 return 0;
13995 }
13996 return 1;
13997 }
13998
13999 val = get_param(cmd, "TD_ChannelSwitch");
14000 if (val) {
14001 /* TODO */
14002 send_resp(dut, conn, SIGMA_ERROR,
14003 "ErrorCode,TD_ChannelSwitch not yet supported");
14004 return 0;
14005 }
14006
14007 val = get_param(cmd, "TD_NF");
14008 if (val) {
14009 /* TODO */
14010 send_resp(dut, conn, SIGMA_ERROR,
14011 "ErrorCode,TD_NF not yet supported");
14012 return 0;
14013 }
14014
14015 val = get_param(cmd, "PMFFrameType");
14016 if (val == NULL)
14017 val = get_param(cmd, "FrameName");
14018 if (val == NULL)
14019 val = get_param(cmd, "Type");
14020 if (val == NULL)
14021 return -1;
14022 if (strcasecmp(val, "disassoc") == 0)
14023 frame = DISASSOC;
14024 else if (strcasecmp(val, "deauth") == 0)
14025 frame = DEAUTH;
14026 else if (strcasecmp(val, "saquery") == 0)
14027 frame = SAQUERY;
14028 else if (strcasecmp(val, "auth") == 0)
14029 frame = AUTH;
14030 else if (strcasecmp(val, "assocreq") == 0)
14031 frame = ASSOCREQ;
14032 else if (strcasecmp(val, "reassocreq") == 0)
14033 frame = REASSOCREQ;
14034 else if (strcasecmp(val, "neigreq") == 0) {
14035 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
14036
14037 val = get_param(cmd, "ssid");
14038 if (val == NULL)
14039 return -1;
14040
14041 res = send_neighbor_request(dut, intf, val);
14042 if (res) {
14043 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14044 "Failed to send neighbor report request");
14045 return 0;
14046 }
14047
14048 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053014049 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
14050 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014051 sigma_dut_print(dut, DUT_MSG_DEBUG,
14052 "Got Transition Management Query");
14053
Ashwini Patil5acd7382017-04-13 15:55:04 +053014054 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014055 if (res) {
14056 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14057 "Failed to send Transition Management Query");
14058 return 0;
14059 }
14060
14061 return 1;
14062 } else {
14063 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14064 "PMFFrameType");
14065 return 0;
14066 }
14067
14068 val = get_param(cmd, "PMFProtected");
14069 if (val == NULL)
14070 val = get_param(cmd, "Protected");
14071 if (val == NULL)
14072 return -1;
14073 if (strcasecmp(val, "Correct-key") == 0 ||
14074 strcasecmp(val, "CorrectKey") == 0)
14075 protected = CORRECT_KEY;
14076 else if (strcasecmp(val, "IncorrectKey") == 0)
14077 protected = INCORRECT_KEY;
14078 else if (strcasecmp(val, "Unprotected") == 0)
14079 protected = UNPROTECTED;
14080 else {
14081 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14082 "PMFProtected");
14083 return 0;
14084 }
14085
14086 if (protected != UNPROTECTED &&
14087 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
14088 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
14089 "PMFProtected for auth/assocreq/reassocreq");
14090 return 0;
14091 }
14092
14093 if (if_nametoindex("sigmadut") == 0) {
14094 snprintf(buf, sizeof(buf),
14095 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014096 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014097 if (system(buf) != 0 ||
14098 if_nametoindex("sigmadut") == 0) {
14099 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
14100 "monitor interface with '%s'", buf);
14101 return -2;
14102 }
14103 }
14104
14105 if (system("ifconfig sigmadut up") != 0) {
14106 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
14107 "monitor interface up");
14108 return -2;
14109 }
14110
Veerendranath Jakkam49774122020-07-05 09:52:18 +053014111 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014112}
14113
14114
14115static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
14116 struct sigma_conn *conn,
14117 struct sigma_cmd *cmd,
14118 const char *ifname)
14119{
14120 char buf[200];
14121 const char *val;
14122
14123 val = get_param(cmd, "ClearARP");
14124 if (val && atoi(val) == 1) {
14125 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
14126 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14127 if (system(buf) != 0) {
14128 send_resp(dut, conn, SIGMA_ERROR,
14129 "errorCode,Failed to clear ARP cache");
14130 return 0;
14131 }
14132 }
14133
14134 return 1;
14135}
14136
14137
14138int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
14139 struct sigma_cmd *cmd)
14140{
14141 const char *intf = get_param(cmd, "Interface");
14142 const char *val;
14143
14144 if (intf == NULL)
14145 return -1;
14146
14147 val = get_param(cmd, "program");
14148 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014149 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014150 strcasecmp(val, "HS2-R3") == 0 ||
14151 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014152 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
14153
14154 return -1;
14155}
14156
14157
Jouni Malinenf7222712019-06-13 01:50:21 +030014158static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
14159 struct sigma_conn *conn,
14160 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014161{
14162 const char *intf = get_param(cmd, "Interface");
14163 const char *mac = get_param(cmd, "MAC");
14164
14165 if (intf == NULL || mac == NULL)
14166 return -1;
14167
14168 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
14169 "interface %s to %s", intf, mac);
14170
14171 if (dut->set_macaddr) {
14172 char buf[128];
14173 int res;
14174 if (strcasecmp(mac, "default") == 0) {
14175 res = snprintf(buf, sizeof(buf), "%s",
14176 dut->set_macaddr);
14177 dut->tmp_mac_addr = 0;
14178 } else {
14179 res = snprintf(buf, sizeof(buf), "%s %s",
14180 dut->set_macaddr, mac);
14181 dut->tmp_mac_addr = 1;
14182 }
14183 if (res < 0 || res >= (int) sizeof(buf))
14184 return -1;
14185 if (system(buf) != 0) {
14186 send_resp(dut, conn, SIGMA_ERROR,
14187 "errorCode,Failed to set MAC "
14188 "address");
14189 return 0;
14190 }
14191 return 1;
14192 }
14193
14194 if (strcasecmp(mac, "default") == 0)
14195 return 1;
14196
14197 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14198 "command");
14199 return 0;
14200}
14201
14202
14203static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
14204 struct sigma_conn *conn, const char *intf,
14205 int val)
14206{
14207 char buf[200];
14208 int res;
14209
14210 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
14211 intf, val);
14212 if (res < 0 || res >= (int) sizeof(buf))
14213 return -1;
14214 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14215 if (system(buf) != 0) {
14216 send_resp(dut, conn, SIGMA_ERROR,
14217 "errorCode,Failed to configure offchannel mode");
14218 return 0;
14219 }
14220
14221 return 1;
14222}
14223
14224
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014225static int off_chan_val(enum sec_ch_offset off)
14226{
14227 switch (off) {
14228 case SEC_CH_NO:
14229 return 0;
14230 case SEC_CH_40ABOVE:
14231 return 40;
14232 case SEC_CH_40BELOW:
14233 return -40;
14234 }
14235
14236 return 0;
14237}
14238
14239
14240static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
14241 const char *intf, int off_ch_num,
14242 enum sec_ch_offset sec)
14243{
14244 char buf[200];
14245 int res;
14246
14247 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
14248 intf, off_ch_num);
14249 if (res < 0 || res >= (int) sizeof(buf))
14250 return -1;
14251 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14252 if (system(buf) != 0) {
14253 send_resp(dut, conn, SIGMA_ERROR,
14254 "errorCode,Failed to set offchan");
14255 return 0;
14256 }
14257
14258 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
14259 intf, off_chan_val(sec));
14260 if (res < 0 || res >= (int) sizeof(buf))
14261 return -1;
14262 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14263 if (system(buf) != 0) {
14264 send_resp(dut, conn, SIGMA_ERROR,
14265 "errorCode,Failed to set sec chan offset");
14266 return 0;
14267 }
14268
14269 return 1;
14270}
14271
14272
14273static int tdls_set_offchannel_offset(struct sigma_dut *dut,
14274 struct sigma_conn *conn,
14275 const char *intf, int off_ch_num,
14276 enum sec_ch_offset sec)
14277{
14278 char buf[200];
14279 int res;
14280
14281 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
14282 off_ch_num);
14283 if (res < 0 || res >= (int) sizeof(buf))
14284 return -1;
14285 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14286
14287 if (wpa_command(intf, buf) < 0) {
14288 send_resp(dut, conn, SIGMA_ERROR,
14289 "ErrorCode,Failed to set offchan");
14290 return 0;
14291 }
14292 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
14293 off_chan_val(sec));
14294 if (res < 0 || res >= (int) sizeof(buf))
14295 return -1;
14296
14297 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14298
14299 if (wpa_command(intf, buf) < 0) {
14300 send_resp(dut, conn, SIGMA_ERROR,
14301 "ErrorCode,Failed to set sec chan offset");
14302 return 0;
14303 }
14304
14305 return 1;
14306}
14307
14308
14309static int tdls_set_offchannel_mode(struct sigma_dut *dut,
14310 struct sigma_conn *conn,
14311 const char *intf, int val)
14312{
14313 char buf[200];
14314 int res;
14315
14316 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
14317 val);
14318 if (res < 0 || res >= (int) sizeof(buf))
14319 return -1;
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 configure offchannel mode");
14325 return 0;
14326 }
14327
14328 return 1;
14329}
14330
14331
14332static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
14333 struct sigma_conn *conn,
14334 struct sigma_cmd *cmd)
14335{
14336 const char *val;
14337 enum {
14338 CHSM_NOT_SET,
14339 CHSM_ENABLE,
14340 CHSM_DISABLE,
14341 CHSM_REJREQ,
14342 CHSM_UNSOLRESP
14343 } chsm = CHSM_NOT_SET;
14344 int off_ch_num = -1;
14345 enum sec_ch_offset sec_ch = SEC_CH_NO;
14346 int res;
14347
14348 val = get_param(cmd, "Uapsd");
14349 if (val) {
14350 char buf[100];
14351 if (strcasecmp(val, "Enable") == 0)
14352 snprintf(buf, sizeof(buf), "SET ps 99");
14353 else if (strcasecmp(val, "Disable") == 0)
14354 snprintf(buf, sizeof(buf), "SET ps 98");
14355 else {
14356 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14357 "Unsupported uapsd parameter value");
14358 return 0;
14359 }
14360 if (wpa_command(intf, buf)) {
14361 send_resp(dut, conn, SIGMA_ERROR,
14362 "ErrorCode,Failed to change U-APSD "
14363 "powersave mode");
14364 return 0;
14365 }
14366 }
14367
14368 val = get_param(cmd, "TPKTIMER");
14369 if (val && strcasecmp(val, "DISABLE") == 0) {
14370 if (wpa_command(intf, "SET tdls_testing 0x100")) {
14371 send_resp(dut, conn, SIGMA_ERROR,
14372 "ErrorCode,Failed to enable no TPK "
14373 "expiration test mode");
14374 return 0;
14375 }
14376 dut->no_tpk_expiration = 1;
14377 }
14378
14379 val = get_param(cmd, "ChSwitchMode");
14380 if (val) {
14381 if (strcasecmp(val, "Enable") == 0 ||
14382 strcasecmp(val, "Initiate") == 0)
14383 chsm = CHSM_ENABLE;
14384 else if (strcasecmp(val, "Disable") == 0 ||
14385 strcasecmp(val, "passive") == 0)
14386 chsm = CHSM_DISABLE;
14387 else if (strcasecmp(val, "RejReq") == 0)
14388 chsm = CHSM_REJREQ;
14389 else if (strcasecmp(val, "UnSolResp") == 0)
14390 chsm = CHSM_UNSOLRESP;
14391 else {
14392 send_resp(dut, conn, SIGMA_ERROR,
14393 "ErrorCode,Unknown ChSwitchMode value");
14394 return 0;
14395 }
14396 }
14397
14398 val = get_param(cmd, "OffChNum");
14399 if (val) {
14400 off_ch_num = atoi(val);
14401 if (off_ch_num == 0) {
14402 send_resp(dut, conn, SIGMA_ERROR,
14403 "ErrorCode,Invalid OffChNum");
14404 return 0;
14405 }
14406 }
14407
14408 val = get_param(cmd, "SecChOffset");
14409 if (val) {
14410 if (strcmp(val, "20") == 0)
14411 sec_ch = SEC_CH_NO;
14412 else if (strcasecmp(val, "40above") == 0)
14413 sec_ch = SEC_CH_40ABOVE;
14414 else if (strcasecmp(val, "40below") == 0)
14415 sec_ch = SEC_CH_40BELOW;
14416 else {
14417 send_resp(dut, conn, SIGMA_ERROR,
14418 "ErrorCode,Unknown SecChOffset value");
14419 return 0;
14420 }
14421 }
14422
14423 if (chsm == CHSM_NOT_SET) {
14424 /* no offchannel changes requested */
14425 return 1;
14426 }
14427
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014428 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
14429 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014430 send_resp(dut, conn, SIGMA_ERROR,
14431 "ErrorCode,Unknown interface");
14432 return 0;
14433 }
14434
14435 switch (chsm) {
14436 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030014437 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014438 break;
14439 case CHSM_ENABLE:
14440 if (off_ch_num < 0) {
14441 send_resp(dut, conn, SIGMA_ERROR,
14442 "ErrorCode,Missing OffChNum argument");
14443 return 0;
14444 }
14445 if (wifi_chip_type == DRIVER_WCN) {
14446 res = tdls_set_offchannel_offset(dut, conn, intf,
14447 off_ch_num, sec_ch);
14448 } else {
14449 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14450 sec_ch);
14451 }
14452 if (res != 1)
14453 return res;
14454 if (wifi_chip_type == DRIVER_WCN)
14455 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
14456 else
14457 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
14458 break;
14459 case CHSM_DISABLE:
14460 if (wifi_chip_type == DRIVER_WCN)
14461 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
14462 else
14463 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
14464 break;
14465 case CHSM_REJREQ:
14466 if (wifi_chip_type == DRIVER_WCN)
14467 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
14468 else
14469 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
14470 break;
14471 case CHSM_UNSOLRESP:
14472 if (off_ch_num < 0) {
14473 send_resp(dut, conn, SIGMA_ERROR,
14474 "ErrorCode,Missing OffChNum argument");
14475 return 0;
14476 }
14477 if (wifi_chip_type == DRIVER_WCN) {
14478 res = tdls_set_offchannel_offset(dut, conn, intf,
14479 off_ch_num, sec_ch);
14480 } else {
14481 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14482 sec_ch);
14483 }
14484 if (res != 1)
14485 return res;
14486 if (wifi_chip_type == DRIVER_WCN)
14487 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
14488 else
14489 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
14490 break;
14491 }
14492
14493 return res;
14494}
14495
14496
14497static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14498 struct sigma_conn *conn,
14499 struct sigma_cmd *cmd)
14500{
14501 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014502 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014503
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070014504 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080014505
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014506 val = get_param(cmd, "nss_mcs_opt");
14507 if (val) {
14508 /* String (nss_operating_mode; mcs_operating_mode) */
14509 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014510 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014511
14512 token = strdup(val);
14513 if (!token)
14514 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014515 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014516 if (!result) {
14517 sigma_dut_print(dut, DUT_MSG_ERROR,
14518 "VHT NSS not specified");
14519 goto failed;
14520 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014521 if (strcasecmp(result, "def") != 0) {
14522 nss = atoi(result);
14523 if (nss == 4)
14524 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014525 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014526 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014527
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014528 }
14529
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014530 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014531 if (!result) {
14532 sigma_dut_print(dut, DUT_MSG_ERROR,
14533 "VHT MCS not specified");
14534 goto failed;
14535 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014536 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014537 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014538 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014539 } else {
14540 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014541 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014542 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014543 }
14544 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014545 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014546 }
14547
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014548 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014549 return 1;
14550failed:
14551 free(token);
14552 return 0;
14553}
14554
14555
14556static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14557 struct sigma_conn *conn,
14558 struct sigma_cmd *cmd)
14559{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014560 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014561 case DRIVER_ATHEROS:
14562 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
14563 default:
14564 send_resp(dut, conn, SIGMA_ERROR,
14565 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
14566 return 0;
14567 }
14568}
14569
14570
Jouni Malinen1702fe32021-06-08 19:08:01 +030014571static enum sigma_cmd_result
14572wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14573 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014574{
14575 const char *val;
14576 char *token = NULL, *result;
14577 char buf[60];
14578
14579 val = get_param(cmd, "nss_mcs_opt");
14580 if (val) {
14581 /* String (nss_operating_mode; mcs_operating_mode) */
14582 int nss, mcs, ratecode;
14583 char *saveptr;
14584
14585 token = strdup(val);
14586 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014587 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014588
14589 result = strtok_r(token, ";", &saveptr);
14590 if (!result) {
14591 sigma_dut_print(dut, DUT_MSG_ERROR,
14592 "HE NSS not specified");
14593 goto failed;
14594 }
14595 nss = 1;
14596 if (strcasecmp(result, "def") != 0)
14597 nss = atoi(result);
14598
14599 result = strtok_r(NULL, ";", &saveptr);
14600 if (!result) {
14601 sigma_dut_print(dut, DUT_MSG_ERROR,
14602 "HE MCS not specified");
14603 goto failed;
14604 }
14605 mcs = 7;
14606 if (strcasecmp(result, "def") != 0)
14607 mcs = atoi(result);
14608
Arif Hussain557bf412018-05-25 17:29:36 -070014609 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014610 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070014611 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014612 } else if (nss > 2) {
14613 sigma_dut_print(dut, DUT_MSG_ERROR,
14614 "HE NSS %d not supported", nss);
14615 goto failed;
14616 }
14617
Arif Hussain557bf412018-05-25 17:29:36 -070014618 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
14619 if (system(buf) != 0) {
14620 sigma_dut_print(dut, DUT_MSG_ERROR,
14621 "nss_mcs_opt: iwpriv %s nss %d failed",
14622 intf, nss);
14623 goto failed;
14624 }
Arif Hussainac6c5112018-05-25 17:34:00 -070014625 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070014626
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014627 /* Add the MCS to the ratecode */
14628 if (mcs >= 0 && mcs <= 11) {
14629 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070014630#ifdef NL80211_SUPPORT
14631 if (dut->device_type == STA_testbed) {
14632 enum he_mcs_config mcs_config;
14633 int ret;
14634
14635 if (mcs <= 7)
14636 mcs_config = HE_80_MCS0_7;
14637 else if (mcs <= 9)
14638 mcs_config = HE_80_MCS0_9;
14639 else
14640 mcs_config = HE_80_MCS0_11;
14641 ret = sta_set_he_mcs(dut, intf, mcs_config);
14642 if (ret) {
14643 sigma_dut_print(dut, DUT_MSG_ERROR,
14644 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
14645 mcs, mcs_config, ret);
14646 goto failed;
14647 }
14648 }
14649#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014650 } else {
14651 sigma_dut_print(dut, DUT_MSG_ERROR,
14652 "HE MCS %d not supported", mcs);
14653 goto failed;
14654 }
14655 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
14656 intf, ratecode);
14657 if (system(buf) != 0) {
14658 sigma_dut_print(dut, DUT_MSG_ERROR,
14659 "iwpriv setting of 11ax rates failed");
14660 goto failed;
14661 }
14662 free(token);
14663 }
14664
14665 val = get_param(cmd, "GI");
14666 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014667 int fix_rate_sgi;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014668 u8 he_gi_val = 0;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014669
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014670 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014671 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014672 fix_rate_sgi = 1;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014673 he_gi_val = NL80211_RATE_INFO_HE_GI_0_8;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014674 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014675 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
14676 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014677 fix_rate_sgi = 2;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014678 he_gi_val = NL80211_RATE_INFO_HE_GI_1_6;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014679 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014680 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
14681 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014682 fix_rate_sgi = 3;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014683 he_gi_val = NL80211_RATE_INFO_HE_GI_3_2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014684 } else {
14685 send_resp(dut, conn, SIGMA_ERROR,
14686 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014687 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014688 }
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014689 if (wcn_set_he_gi(dut, intf, he_gi_val)) {
14690 sigma_dut_print(dut, DUT_MSG_INFO,
14691 "wcn_set_he_gi failed, using iwpriv");
14692 if (system(buf) != 0) {
14693 send_resp(dut, conn, SIGMA_ERROR,
14694 "errorCode,Failed to set shortgi");
14695 return STATUS_SENT_ERROR;
14696 }
14697 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
14698 intf, fix_rate_sgi);
14699 if (system(buf) != 0) {
14700 send_resp(dut, conn, SIGMA_ERROR,
14701 "errorCode,Failed to set fix rate shortgi");
14702 return STATUS_SENT_ERROR;
14703 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014704 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014705 }
14706
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014707 val = get_param(cmd, "LTF");
14708 if (val) {
14709#ifdef NL80211_SUPPORT
14710 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014711 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014712 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014713 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014714 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014715 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014716 } else {
14717 send_resp(dut, conn, SIGMA_ERROR,
14718 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014719 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014720 }
14721#else /* NL80211_SUPPORT */
14722 sigma_dut_print(dut, DUT_MSG_ERROR,
14723 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014724 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014725#endif /* NL80211_SUPPORT */
14726 }
14727
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070014728 val = get_param(cmd, "KeepAlive");
14729 if (val) {
14730 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
14731
14732 if (strcasecmp(val, "Data") == 0)
14733 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
14734 else if (strcasecmp(val, "Mgmt") == 0)
14735 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
14736
14737 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
14738 send_resp(dut, conn, SIGMA_ERROR,
14739 "ErrorCode,Failed to set keep alive type config");
14740 return STATUS_SENT_ERROR;
14741 }
14742 }
14743
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014744 val = get_param(cmd, "TxSUPPDU");
14745 if (val) {
14746 int set_val = 1;
14747
14748 if (strcasecmp(val, "Enable") == 0)
14749 set_val = 1;
14750 else if (strcasecmp(val, "Disable") == 0)
14751 set_val = 0;
14752
14753 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
14754 send_resp(dut, conn, SIGMA_ERROR,
14755 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014756 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014757 }
14758 }
14759
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070014760 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
14761 if (val) {
14762 int set_val = 0;
14763
14764 if (strcasecmp(val, "Enable") == 0)
14765 set_val = 0;
14766 else if (strcasecmp(val, "Disable") == 0)
14767 set_val = 1;
14768
14769 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
14770 send_resp(dut, conn, SIGMA_ERROR,
14771 "ErrorCode,Failed to set mgmt/data Tx disable config");
14772 return STATUS_SENT_ERROR;
14773 }
14774 }
14775
Arif Hussain480d5f42019-03-12 14:40:42 -070014776 val = get_param(cmd, "TWT_Setup");
14777 if (val) {
14778 if (strcasecmp(val, "Request") == 0) {
Kiran Kumar Lokereafac46a2021-11-29 14:03:20 -080014779 if (set_power_save_wcn(dut, intf, 1) < 0)
14780 sigma_dut_print(dut, DUT_MSG_ERROR,
14781 "Failed to enable power save");
Arif Hussain480d5f42019-03-12 14:40:42 -070014782 if (sta_twt_request(dut, conn, cmd)) {
14783 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014784 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014785 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014786 }
14787 } else if (strcasecmp(val, "Teardown") == 0) {
14788 if (sta_twt_teardown(dut, conn, cmd)) {
14789 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014790 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014791 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014792 }
14793 }
14794 }
14795
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014796 val = get_param(cmd, "TWT_Operation");
14797 if (val) {
14798 if (strcasecmp(val, "Suspend") == 0) {
14799 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
14800 send_resp(dut, conn, SIGMA_ERROR,
14801 "ErrorCode,TWT suspend failed");
14802 return STATUS_SENT_ERROR;
14803 }
14804 } else if (strcasecmp(val, "Resume") == 0) {
14805 if (sta_twt_resume(dut, conn, cmd)) {
14806 send_resp(dut, conn, SIGMA_ERROR,
14807 "ErrorCode,TWT resume failed");
14808 return STATUS_SENT_ERROR;
14809 }
14810 }
14811 }
14812
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080014813 val = get_param(cmd, "transmitOMI");
14814 if (val && sta_transmit_omi(dut, conn, cmd)) {
14815 send_resp(dut, conn, SIGMA_ERROR,
14816 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014817 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070014818 }
14819
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014820 val = get_param(cmd, "Powersave");
14821 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014822 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014823
14824 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014825 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014826 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014827 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014828 } else {
14829 sigma_dut_print(dut, DUT_MSG_ERROR,
14830 "Unsupported Powersave value '%s'",
14831 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014832 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014833 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014834 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014835 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014836 }
14837
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080014838 val = get_param(cmd, "MU_EDCA");
14839 if (val) {
14840 if (strcasecmp(val, "Override") == 0) {
14841 if (sta_set_mu_edca_override(dut, intf, 1)) {
14842 send_resp(dut, conn, SIGMA_ERROR,
14843 "errorCode,MU EDCA override set failed");
14844 return STATUS_SENT;
14845 }
14846 } else if (strcasecmp(val, "Disable") == 0) {
14847 if (sta_set_mu_edca_override(dut, intf, 0)) {
14848 send_resp(dut, conn, SIGMA_ERROR,
14849 "errorCode,MU EDCA override disable failed");
14850 return STATUS_SENT;
14851 }
14852 }
14853 }
14854
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070014855 val = get_param(cmd, "RUAllocTone");
14856 if (val && strcasecmp(val, "242") == 0) {
14857 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
14858 send_resp(dut, conn, SIGMA_ERROR,
14859 "ErrorCode,Failed to set RU 242 tone Tx");
14860 return STATUS_SENT_ERROR;
14861 }
14862 }
14863
14864 val = get_param(cmd, "PPDUTxType");
14865 if (val && strcasecmp(val, "ER-SU") == 0) {
14866 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
14867 send_resp(dut, conn, SIGMA_ERROR,
14868 "ErrorCode,Failed to set ER-SU PPDU type Tx");
14869 return STATUS_SENT_ERROR;
14870 }
14871 }
14872
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070014873 val = get_param(cmd, "Ch_Pref");
14874 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14875 return STATUS_SENT;
14876
14877 val = get_param(cmd, "Cellular_Data_Cap");
14878 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14879 return STATUS_SENT;
14880
Jouni Malinen1702fe32021-06-08 19:08:01 +030014881 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014882
14883failed:
14884 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014885 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014886}
14887
14888
Jouni Malinen1702fe32021-06-08 19:08:01 +030014889static enum sigma_cmd_result
14890cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14891 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014892{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014893 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014894 case DRIVER_WCN:
14895 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
14896 default:
14897 send_resp(dut, conn, SIGMA_ERROR,
14898 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014899 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014900 }
14901}
14902
14903
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014904static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
14905 struct sigma_conn *conn,
14906 struct sigma_cmd *cmd)
14907{
14908 const char *val;
14909
14910 val = get_param(cmd, "powersave");
14911 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014912 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014913
14914 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014915 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014916 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014917 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014918 } else {
14919 sigma_dut_print(dut, DUT_MSG_ERROR,
14920 "Unsupported power save config");
14921 return -1;
14922 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014923 if (set_power_save_wcn(dut, intf, ps) < 0)
14924 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014925 return 1;
14926 }
14927
14928 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
14929
14930 return 0;
14931}
14932
14933
Ashwini Patil5acd7382017-04-13 15:55:04 +053014934static int btm_query_candidate_list(struct sigma_dut *dut,
14935 struct sigma_conn *conn,
14936 struct sigma_cmd *cmd)
14937{
14938 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
14939 int len, ret;
14940 char buf[10];
14941
14942 /*
14943 * Neighbor Report elements format:
14944 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
14945 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
14946 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
14947 */
14948
14949 bssid = get_param(cmd, "Nebor_BSSID");
14950 if (!bssid) {
14951 send_resp(dut, conn, SIGMA_INVALID,
14952 "errorCode,Nebor_BSSID is missing");
14953 return 0;
14954 }
14955
14956 info = get_param(cmd, "Nebor_Bssid_Info");
14957 if (!info) {
14958 sigma_dut_print(dut, DUT_MSG_INFO,
14959 "Using default value for Nebor_Bssid_Info: %s",
14960 DEFAULT_NEIGHBOR_BSSID_INFO);
14961 info = DEFAULT_NEIGHBOR_BSSID_INFO;
14962 }
14963
14964 op_class = get_param(cmd, "Nebor_Op_Class");
14965 if (!op_class) {
14966 send_resp(dut, conn, SIGMA_INVALID,
14967 "errorCode,Nebor_Op_Class is missing");
14968 return 0;
14969 }
14970
14971 ch = get_param(cmd, "Nebor_Op_Ch");
14972 if (!ch) {
14973 send_resp(dut, conn, SIGMA_INVALID,
14974 "errorCode,Nebor_Op_Ch is missing");
14975 return 0;
14976 }
14977
14978 phy_type = get_param(cmd, "Nebor_Phy_Type");
14979 if (!phy_type) {
14980 sigma_dut_print(dut, DUT_MSG_INFO,
14981 "Using default value for Nebor_Phy_Type: %s",
14982 DEFAULT_NEIGHBOR_PHY_TYPE);
14983 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
14984 }
14985
14986 /* Parse optional subelements */
14987 buf[0] = '\0';
14988 pref = get_param(cmd, "Nebor_Pref");
14989 if (pref) {
14990 /* hexdump for preferrence subelement */
14991 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
14992 if (ret < 0 || ret >= (int) sizeof(buf)) {
14993 sigma_dut_print(dut, DUT_MSG_ERROR,
14994 "snprintf failed for optional subelement ret: %d",
14995 ret);
14996 send_resp(dut, conn, SIGMA_ERROR,
14997 "errorCode,snprintf failed for subelement");
14998 return 0;
14999 }
15000 }
15001
15002 if (!dut->btm_query_cand_list) {
15003 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
15004 if (!dut->btm_query_cand_list) {
15005 send_resp(dut, conn, SIGMA_ERROR,
15006 "errorCode,Failed to allocate memory for btm_query_cand_list");
15007 return 0;
15008 }
15009 }
15010
15011 len = strlen(dut->btm_query_cand_list);
15012 ret = snprintf(dut->btm_query_cand_list + len,
15013 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
15014 bssid, info, op_class, ch, phy_type, buf);
15015 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
15016 sigma_dut_print(dut, DUT_MSG_ERROR,
15017 "snprintf failed for neighbor report list ret: %d",
15018 ret);
15019 send_resp(dut, conn, SIGMA_ERROR,
15020 "errorCode,snprintf failed for neighbor report");
15021 free(dut->btm_query_cand_list);
15022 dut->btm_query_cand_list = NULL;
15023 return 0;
15024 }
15025
15026 return 1;
15027}
15028
15029
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015030int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
15031 struct sigma_ese_alloc *allocs, int *allocs_size)
15032{
15033 int max_count = *allocs_size;
15034 int count = 0, i;
15035 const char *val;
15036
15037 do {
15038 val = get_param_indexed(cmd, "AllocID", count);
15039 if (val)
15040 count++;
15041 } while (val);
15042
15043 if (count == 0 || count > max_count) {
15044 sigma_dut_print(dut, DUT_MSG_ERROR,
15045 "Invalid number of allocations(%d)", count);
15046 return -1;
15047 }
15048
15049 for (i = 0; i < count; i++) {
15050 val = get_param_indexed(cmd, "PercentBI", i);
15051 if (!val) {
15052 sigma_dut_print(dut, DUT_MSG_ERROR,
15053 "Missing PercentBI parameter at index %d",
15054 i);
15055 return -1;
15056 }
15057 allocs[i].percent_bi = atoi(val);
15058
15059 val = get_param_indexed(cmd, "SrcAID", i);
15060 if (val)
15061 allocs[i].src_aid = strtol(val, NULL, 0);
15062 else
15063 allocs[i].src_aid = ESE_BCAST_AID;
15064
15065 val = get_param_indexed(cmd, "DestAID", i);
15066 if (val)
15067 allocs[i].dst_aid = strtol(val, NULL, 0);
15068 else
15069 allocs[i].dst_aid = ESE_BCAST_AID;
15070
15071 allocs[i].type = ESE_CBAP;
15072 sigma_dut_print(dut, DUT_MSG_INFO,
15073 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
15074 i, allocs[i].percent_bi, allocs[i].src_aid,
15075 allocs[i].dst_aid);
15076 }
15077
15078 *allocs_size = count;
15079 return 0;
15080}
15081
15082
15083static int sta_set_60g_ese(struct sigma_dut *dut, int count,
15084 struct sigma_ese_alloc *allocs)
15085{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015086 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015087#ifdef __linux__
15088 case DRIVER_WIL6210:
15089 if (wil6210_set_ese(dut, count, allocs))
15090 return -1;
15091 return 1;
15092#endif /* __linux__ */
15093 default:
15094 sigma_dut_print(dut, DUT_MSG_ERROR,
15095 "Unsupported sta_set_60g_ese with the current driver");
15096 return -1;
15097 }
15098}
15099
15100
15101static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
15102 struct sigma_conn *conn,
15103 struct sigma_cmd *cmd)
15104{
15105 const char *val;
15106
15107 val = get_param(cmd, "ExtSchIE");
15108 if (val && !strcasecmp(val, "Enable")) {
15109 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
15110 int count = MAX_ESE_ALLOCS;
15111
15112 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
15113 return -1;
15114 return sta_set_60g_ese(dut, count, allocs);
15115 }
15116
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015117 val = get_param(cmd, "MCS_FixedRate");
15118 if (val) {
15119 int sta_mcs = atoi(val);
15120
15121 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
15122 sta_mcs);
15123 wil6210_set_force_mcs(dut, 1, sta_mcs);
15124
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015125 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015126 }
15127
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015128 send_resp(dut, conn, SIGMA_ERROR,
15129 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015130 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015131}
15132
15133
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015134static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
15135 const char *oci_frametype, uint32_t oci_freq)
15136{
15137#ifdef NL80211_SUPPORT
15138 struct nl_msg *msg;
15139 int ret = 0;
15140 struct nlattr *params;
15141 struct nlattr *attr;
15142 int ifindex;
15143 u8 frame_type;
15144
15145 ifindex = if_nametoindex(intf);
15146 if (ifindex == 0) {
15147 sigma_dut_print(dut, DUT_MSG_ERROR,
15148 "%s: Index for interface %s failed",
15149 __func__, intf);
15150 return -1;
15151 }
15152
15153 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15154 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
15155 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15156 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
15157 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15158 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
15159 } else {
15160 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
15161 __func__, oci_frametype);
15162 return -1;
15163 }
15164
15165
15166 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
15167 NL80211_CMD_VENDOR)) ||
15168 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
15169 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
15170 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
15171 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
15172 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
15173 !(params = nla_nest_start(
15174 msg,
15175 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
15176 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
15177 frame_type) ||
15178 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
15179 oci_freq)) {
15180 sigma_dut_print(dut, DUT_MSG_ERROR,
15181 "%s: err in adding vendor_cmd and vendor_data",
15182 __func__);
15183 nlmsg_free(msg);
15184 return -1;
15185 }
15186 nla_nest_end(msg, params);
15187 nla_nest_end(msg, attr);
15188
15189 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
15190 if (ret) {
15191 sigma_dut_print(dut, DUT_MSG_ERROR,
15192 "%s: err in send_and_recv_msgs, ret=%d",
15193 __func__, ret);
15194 }
15195 return ret;
15196#else /* NL80211_SUPPORT */
15197 sigma_dut_print(dut, DUT_MSG_ERROR,
15198 "OCI override not possible without NL80211_SUPPORT defined");
15199 return -1;
15200#endif /* NL80211_SUPPORT */
15201}
15202
15203
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015204static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
15205 uint8_t ignore_csa)
15206{
15207#ifdef NL80211_SUPPORT
15208 return wcn_wifi_test_config_set_u8(
15209 dut, intf,
15210 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
15211#else /* NL80211_SUPPORT */
15212 sigma_dut_print(dut, DUT_MSG_ERROR,
15213 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
15214 return -1;
15215#endif /* NL80211_SUPPORT */
15216}
15217
15218
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015219static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
15220 uint8_t rsnxe_used)
15221{
15222#ifdef NL80211_SUPPORT
15223 return wcn_wifi_test_config_set_u8(
15224 dut, intf,
15225 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
15226 rsnxe_used);
15227#else /* NL80211_SUPPORT */
15228 sigma_dut_print(dut, DUT_MSG_ERROR,
15229 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
15230 return -1;
15231#endif /* NL80211_SUPPORT */
15232}
15233
15234
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015235static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
15236 const char *intf,
15237 uint8_t ignore_sa_query_timeout)
15238{
15239#ifdef NL80211_SUPPORT
15240 return wcn_wifi_test_config_set_u8(
15241 dut, intf,
15242 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
15243 ignore_sa_query_timeout);
15244#else /* NL80211_SUPPORT */
15245 sigma_dut_print(dut, DUT_MSG_ERROR,
15246 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
15247 return -1;
15248#endif /* NL80211_SUPPORT */
15249}
15250
15251
Jouni Malinen6250cb02020-04-15 13:54:45 +030015252static enum sigma_cmd_result
15253cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
15254 struct sigma_conn *conn,
15255 struct sigma_cmd *cmd)
15256{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015257 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030015258
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053015259 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030015260 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015261 if (wifi_chip_type == DRIVER_WCN) {
15262 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
15263 send_resp(dut, conn, SIGMA_ERROR,
15264 "errorCode,Failed to set ft_rsnxe_used");
15265 return STATUS_SENT_ERROR;
15266 }
15267 return SUCCESS_SEND_STATUS;
15268 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030015269 send_resp(dut, conn, SIGMA_ERROR,
15270 "errorCode,Failed to set ft_rsnxe_used");
15271 return STATUS_SENT_ERROR;
15272 }
15273 return SUCCESS_SEND_STATUS;
15274 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015275
15276 oci_chan = get_param(cmd, "OCIChannel");
15277 oci_frametype = get_param(cmd, "OCIFrameType");
15278 if (oci_chan && oci_frametype) {
15279 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
15280 char buf[100];
15281
15282 if (!oci_freq) {
15283 send_resp(dut, conn, SIGMA_ERROR,
15284 "errorCode,Invalid OCIChannel number");
15285 return STATUS_SENT_ERROR;
15286 }
15287
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015288 if (wifi_chip_type == DRIVER_WCN &&
15289 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
15290 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
15291 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
15292 if (wcn_sta_override_oci(dut, intf, oci_frametype,
15293 oci_freq)) {
15294 send_resp(dut, conn, SIGMA_ERROR,
15295 "errorCode,Failed to override OCI");
15296 return STATUS_SENT_ERROR;
15297 }
15298 return SUCCESS_SEND_STATUS;
15299 }
15300
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015301 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
15302 snprintf(buf, sizeof(buf),
15303 "SET oci_freq_override_eapol %d", oci_freq);
15304 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15305 snprintf(buf, sizeof(buf),
15306 "SET oci_freq_override_saquery_req %d",
15307 oci_freq);
15308 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15309 snprintf(buf, sizeof(buf),
15310 "SET oci_freq_override_saquery_resp %d",
15311 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015312 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
15313 snprintf(buf, sizeof(buf),
15314 "SET oci_freq_override_eapol_g2 %d",
15315 oci_freq);
15316 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15317 snprintf(buf, sizeof(buf),
15318 "SET oci_freq_override_ft_assoc %d",
15319 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015320 } else {
15321 send_resp(dut, conn, SIGMA_ERROR,
15322 "errorCode,Unsupported OCIFrameType");
15323 return STATUS_SENT_ERROR;
15324 }
15325 if (wpa_command(intf, buf) < 0) {
15326 send_resp(dut, conn, SIGMA_ERROR,
15327 "errorCode,Failed to set oci_freq_override");
15328 return STATUS_SENT_ERROR;
15329 }
15330 return SUCCESS_SEND_STATUS;
15331 }
15332
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015333 val = get_param(cmd, "IgnoreCSA");
15334 if (val && atoi(val) == 1) {
15335 if (wifi_chip_type == DRIVER_WCN) {
15336 if (wcn_sta_ignore_csa(dut, intf, 1)) {
15337 send_resp(dut, conn, SIGMA_ERROR,
15338 "errorCode,Failed to set ignore CSA");
15339 return STATUS_SENT_ERROR;
15340 }
15341 return SUCCESS_SEND_STATUS;
15342 }
15343 }
15344
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015345 val = get_param(cmd, "Deauth_Per_SAQueryResp");
15346 if (val && atoi(val) == 0) {
15347 if (wifi_chip_type == DRIVER_WCN) {
15348 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
15349 send_resp(dut, conn, SIGMA_ERROR,
15350 "errorCode,Failed to set ignore SA Query timeout");
15351 return STATUS_SENT_ERROR;
15352 }
15353 return SUCCESS_SEND_STATUS;
15354 }
15355 }
15356
Jouni Malinen6250cb02020-04-15 13:54:45 +030015357 send_resp(dut, conn, SIGMA_ERROR,
15358 "errorCode,Unsupported WPA3 rfeature");
15359 return STATUS_SENT_ERROR;
15360}
15361
15362
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015363static enum sigma_cmd_result
15364cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
15365 struct sigma_conn *conn, struct sigma_cmd *cmd)
15366{
15367 const char *val;
15368
15369 val = get_param(cmd, "DomainName_Domain");
15370 if (val) {
15371 if (strlen(val) >= sizeof(dut->qm_domain_name))
15372 return ERROR_SEND_STATUS;
15373
15374 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
15375 return SUCCESS_SEND_STATUS;
15376 }
15377
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053015378 val = get_param(cmd, "DSCPPolicy_PolicyID");
15379 if (val) {
15380 unsigned int i;
15381 int policy_id = atoi(val);
15382
15383 val = get_param(cmd, "DSCPPolicy_RequestType");
15384
15385 if (!policy_id || !val)
15386 return INVALID_SEND_STATUS;
15387
15388 if (dut->num_dscp_status >= ARRAY_SIZE(dut->dscp_status)) {
15389 send_resp(dut, conn, SIGMA_ERROR,
15390 "errorCode,DSCP status list full");
15391 return STATUS_SENT_ERROR;
15392 }
15393
15394 for (i = 0; i < dut->num_dscp_status; i++)
15395 if (dut->dscp_status[i].id == policy_id)
15396 break;
15397
15398 /* New policy configured */
15399 if (i == dut->num_dscp_status) {
15400 dut->dscp_status[i].id = policy_id;
15401 dut->num_dscp_status++;
15402 }
15403
15404 dut->dscp_status[i].status = strcasecmp(val, "Remove") ?
15405 DSCP_POLICY_SUCCESS : DSCP_POLICY_REJECT;
15406
15407 return SUCCESS_SEND_STATUS;
15408 }
15409
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015410 send_resp(dut, conn, SIGMA_ERROR,
15411 "errorCode,Unsupported QM rfeature");
15412 return STATUS_SENT_ERROR;
15413}
15414
15415
Jouni Malinenf7222712019-06-13 01:50:21 +030015416static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
15417 struct sigma_conn *conn,
15418 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015419{
15420 const char *intf = get_param(cmd, "Interface");
15421 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015422 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015423
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015424 if (!prog)
15425 prog = get_param(cmd, "Program");
15426
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015427 if (intf == NULL || prog == NULL)
15428 return -1;
15429
Ashwini Patil5acd7382017-04-13 15:55:04 +053015430 /* BSS Transition candidate list for BTM query */
15431 val = get_param(cmd, "Nebor_BSSID");
15432 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
15433 return 0;
15434
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015435 if (strcasecmp(prog, "TDLS") == 0)
15436 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
15437
15438 if (strcasecmp(prog, "VHT") == 0)
15439 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
15440
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015441 if (strcasecmp(prog, "HE") == 0)
15442 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
15443
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015444 if (strcasecmp(prog, "MBO") == 0) {
15445 val = get_param(cmd, "Cellular_Data_Cap");
15446 if (val &&
15447 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
15448 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053015449
15450 val = get_param(cmd, "Ch_Pref");
15451 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
15452 return 0;
15453
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015454 return 1;
15455 }
15456
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015457 if (strcasecmp(prog, "60GHz") == 0)
15458 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
15459
Jouni Malinen6250cb02020-04-15 13:54:45 +030015460 if (strcasecmp(prog, "WPA3") == 0)
15461 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015462 if (strcasecmp(prog, "QM") == 0)
15463 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030015464
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015465 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
15466 return 0;
15467}
15468
15469
Jouni Malinenf7222712019-06-13 01:50:21 +030015470static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
15471 struct sigma_conn *conn,
15472 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015473{
15474 const char *intf = get_param(cmd, "Interface");
15475 const char *mode = get_param(cmd, "Mode");
15476 int res;
15477
15478 if (intf == NULL || mode == NULL)
15479 return -1;
15480
15481 if (strcasecmp(mode, "On") == 0)
15482 res = wpa_command(intf, "SET radio_disabled 0");
15483 else if (strcasecmp(mode, "Off") == 0)
15484 res = wpa_command(intf, "SET radio_disabled 1");
15485 else
15486 return -1;
15487
15488 if (res) {
15489 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15490 "radio mode");
15491 return 0;
15492 }
15493
15494 return 1;
15495}
15496
15497
Jouni Malinenf7222712019-06-13 01:50:21 +030015498static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
15499 struct sigma_conn *conn,
15500 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015501{
15502 const char *intf = get_param(cmd, "Interface");
15503 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015504 const char *prog = get_param(cmd, "program");
15505 const char *powersave = get_param(cmd, "powersave");
15506 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015507
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015508 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015509 return -1;
15510
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015511 if (prog && strcasecmp(prog, "60GHz") == 0) {
15512 /*
15513 * The CAPI mode parameter does not exist in 60G
15514 * unscheduled PS.
15515 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080015516 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015517 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015518 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020015519 strcasecmp(prog, "HE") == 0) {
15520 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015521 } else {
15522 if (mode == NULL)
15523 return -1;
15524
15525 if (strcasecmp(mode, "On") == 0)
15526 res = set_ps(intf, dut, 1);
15527 else if (strcasecmp(mode, "Off") == 0)
15528 res = set_ps(intf, dut, 0);
15529 else
15530 return -1;
15531 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015532
15533 if (res) {
15534 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15535 "power save mode");
15536 return 0;
15537 }
15538
15539 return 1;
15540}
15541
15542
Jouni Malinenf7222712019-06-13 01:50:21 +030015543static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
15544 struct sigma_conn *conn,
15545 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015546{
15547 const char *intf = get_param(cmd, "Interface");
15548 const char *val, *bssid;
15549 int res;
15550 char *buf;
15551 size_t buf_len;
15552
15553 val = get_param(cmd, "BSSID_FILTER");
15554 if (val == NULL)
15555 return -1;
15556
15557 bssid = get_param(cmd, "BSSID_List");
15558 if (atoi(val) == 0 || bssid == NULL) {
15559 /* Disable BSSID filter */
15560 if (wpa_command(intf, "SET bssid_filter ")) {
15561 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
15562 "to disable BSSID filter");
15563 return 0;
15564 }
15565
15566 return 1;
15567 }
15568
15569 buf_len = 100 + strlen(bssid);
15570 buf = malloc(buf_len);
15571 if (buf == NULL)
15572 return -1;
15573
15574 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
15575 res = wpa_command(intf, buf);
15576 free(buf);
15577 if (res) {
15578 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
15579 "BSSID filter");
15580 return 0;
15581 }
15582
15583 return 1;
15584}
15585
15586
Jouni Malinenf7222712019-06-13 01:50:21 +030015587static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
15588 struct sigma_conn *conn,
15589 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015590{
15591 const char *intf = get_param(cmd, "Interface");
15592 const char *val;
15593
15594 /* TODO: ARP */
15595
15596 val = get_param(cmd, "HS2_CACHE_PROFILE");
15597 if (val && strcasecmp(val, "All") == 0)
15598 hs2_clear_credentials(intf);
15599
15600 return 1;
15601}
15602
15603
Jouni Malinenf7222712019-06-13 01:50:21 +030015604static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
15605 struct sigma_conn *conn,
15606 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015607{
15608 const char *intf = get_param(cmd, "Interface");
15609 const char *key_type = get_param(cmd, "KeyType");
15610 char buf[100], resp[200];
15611
15612 if (key_type == NULL)
15613 return -1;
15614
15615 if (strcasecmp(key_type, "GTK") == 0) {
15616 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
15617 strncmp(buf, "FAIL", 4) == 0) {
15618 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15619 "not fetch current GTK");
15620 return 0;
15621 }
15622 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
15623 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15624 return 0;
15625 } else {
15626 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
15627 "KeyType");
15628 return 0;
15629 }
15630
15631 return 1;
15632}
15633
15634
15635static int hs2_set_policy(struct sigma_dut *dut)
15636{
15637#ifdef ANDROID
15638 system("ip rule del prio 23000");
15639 if (system("ip rule add from all lookup main prio 23000") != 0) {
15640 sigma_dut_print(dut, DUT_MSG_ERROR,
15641 "Failed to run:ip rule add from all lookup main prio");
15642 return -1;
15643 }
15644 if (system("ip route flush cache") != 0) {
15645 sigma_dut_print(dut, DUT_MSG_ERROR,
15646 "Failed to run ip route flush cache");
15647 return -1;
15648 }
15649 return 1;
15650#else /* ANDROID */
15651 return 0;
15652#endif /* ANDROID */
15653}
15654
15655
Jouni Malinenf7222712019-06-13 01:50:21 +030015656static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
15657 struct sigma_conn *conn,
15658 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015659{
15660 const char *intf = get_param(cmd, "Interface");
15661 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030015662 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015663 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030015664 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015665 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
15666 int tries = 0;
15667 int ignore_blacklist = 0;
15668 const char *events[] = {
15669 "CTRL-EVENT-CONNECTED",
15670 "INTERWORKING-BLACKLISTED",
15671 "INTERWORKING-NO-MATCH",
15672 NULL
15673 };
15674
15675 start_sta_mode(dut);
15676
Jouni Malinen439352d2018-09-13 03:42:23 +030015677 if (band) {
15678 if (strcmp(band, "2.4") == 0) {
15679 wpa_command(intf, "SET setband 2G");
15680 } else if (strcmp(band, "5") == 0) {
15681 wpa_command(intf, "SET setband 5G");
15682 } else {
15683 send_resp(dut, conn, SIGMA_ERROR,
15684 "errorCode,Unsupported band");
15685 return 0;
15686 }
15687 }
15688
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015689 blacklisted[0] = '\0';
15690 if (val && atoi(val))
15691 ignore_blacklist = 1;
15692
15693try_again:
15694 ctrl = open_wpa_mon(intf);
15695 if (ctrl == NULL) {
15696 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15697 "wpa_supplicant monitor connection");
15698 return -2;
15699 }
15700
15701 tries++;
15702 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
15703 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
15704 "Interworking connection");
15705 wpa_ctrl_detach(ctrl);
15706 wpa_ctrl_close(ctrl);
15707 return 0;
15708 }
15709
15710 buf[0] = '\0';
15711 while (1) {
15712 char *pos;
15713 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15714 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
15715 if (!pos)
15716 break;
15717 pos += 25;
15718 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
15719 pos);
15720 if (!blacklisted[0])
15721 memcpy(blacklisted, pos, strlen(pos) + 1);
15722 }
15723
15724 if (ignore_blacklist && blacklisted[0]) {
15725 char *end;
15726 end = strchr(blacklisted, ' ');
15727 if (end)
15728 *end = '\0';
15729 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
15730 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030015731 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
15732 blacklisted);
15733 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015734 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
15735 wpa_ctrl_detach(ctrl);
15736 wpa_ctrl_close(ctrl);
15737 return 0;
15738 }
15739 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15740 buf, sizeof(buf));
15741 }
15742
15743 wpa_ctrl_detach(ctrl);
15744 wpa_ctrl_close(ctrl);
15745
15746 if (res < 0) {
15747 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15748 "connect");
15749 return 0;
15750 }
15751
15752 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
15753 strstr(buf, "INTERWORKING-BLACKLISTED")) {
15754 if (tries < 2) {
15755 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
15756 goto try_again;
15757 }
15758 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
15759 "matching credentials found");
15760 return 0;
15761 }
15762
15763 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15764 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15765 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15766 "get current BSSID/SSID");
15767 return 0;
15768 }
15769
15770 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
15771 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15772 hs2_set_policy(dut);
15773 return 0;
15774}
15775
15776
Jouni Malinenf7222712019-06-13 01:50:21 +030015777static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
15778 struct sigma_conn *conn,
15779 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015780{
15781 const char *intf = get_param(cmd, "Interface");
15782 const char *display = get_param(cmd, "Display");
15783 struct wpa_ctrl *ctrl;
15784 char buf[300], params[400], *pos;
15785 char bssid[20];
15786 int info_avail = 0;
15787 unsigned int old_timeout;
15788 int res;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015789 const char *events[] = { "RX-VENUE-URL", "ANQP-QUERY-DONE", NULL };
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015790
15791 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
15792 send_resp(dut, conn, SIGMA_ERROR,
15793 "ErrorCode,Could not get current BSSID");
15794 return 0;
15795 }
15796 ctrl = open_wpa_mon(intf);
15797 if (!ctrl) {
15798 sigma_dut_print(dut, DUT_MSG_ERROR,
15799 "Failed to open wpa_supplicant monitor connection");
15800 return -2;
15801 }
15802
15803 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
15804 wpa_command(intf, buf);
15805
15806 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
15807 if (res < 0) {
15808 send_resp(dut, conn, SIGMA_ERROR,
15809 "ErrorCode,Could not complete GAS query");
15810 goto fail;
15811 }
15812
15813 old_timeout = dut->default_timeout;
15814 dut->default_timeout = 2;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015815 for (;;) {
15816 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15817 if (res < 0)
15818 break;
15819 if (strstr(buf, "ANQP-QUERY-DONE") != NULL) {
15820 res = -1;
15821 break;
15822 }
15823 pos = strchr(buf, ' ');
15824 if (!pos)
15825 continue;
15826 pos++;
15827 pos = strchr(pos, ' ');
15828 if (!pos)
15829 continue;
15830 pos++;
15831
15832 if (strncmp(pos, "https://", 8) == 0)
15833 break;
15834
15835 sigma_dut_print(dut, DUT_MSG_DEBUG,
15836 "Ignore non-HTTPS venue URL: %s", pos);
15837 }
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015838 dut->default_timeout = old_timeout;
15839 if (res < 0)
15840 goto done;
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015841 info_avail = 1;
15842 snprintf(params, sizeof(params), "browser %s", pos);
15843
15844 if (display && strcasecmp(display, "Yes") == 0) {
15845 pid_t pid;
15846
15847 pid = fork();
15848 if (pid < 0) {
15849 perror("fork");
15850 return -1;
15851 }
15852
15853 if (pid == 0) {
15854 run_hs20_osu(dut, params);
15855 exit(0);
15856 }
15857 }
15858
15859done:
15860 snprintf(buf, sizeof(buf), "Info_available,%s",
15861 info_avail ? "Yes" : "No");
15862 send_resp(dut, conn, SIGMA_COMPLETE, buf);
15863fail:
15864 wpa_ctrl_detach(ctrl);
15865 wpa_ctrl_close(ctrl);
15866 return 0;
15867}
15868
15869
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015870static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
15871 struct sigma_conn *conn,
15872 const char *ifname,
15873 struct sigma_cmd *cmd)
15874{
15875 const char *val;
15876 int id;
15877
15878 id = add_cred(ifname);
15879 if (id < 0)
15880 return -2;
15881 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15882
15883 val = get_param(cmd, "prefer");
15884 if (val && atoi(val) > 0)
15885 set_cred(ifname, id, "priority", "1");
15886
15887 val = get_param(cmd, "REALM");
15888 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
15889 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15890 "realm");
15891 return 0;
15892 }
15893
15894 val = get_param(cmd, "HOME_FQDN");
15895 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
15896 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15897 "home_fqdn");
15898 return 0;
15899 }
15900
15901 val = get_param(cmd, "Username");
15902 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
15903 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15904 "username");
15905 return 0;
15906 }
15907
15908 val = get_param(cmd, "Password");
15909 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
15910 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15911 "password");
15912 return 0;
15913 }
15914
15915 val = get_param(cmd, "ROOT_CA");
15916 if (val) {
15917 char fname[200];
15918 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
15919#ifdef __linux__
15920 if (!file_exists(fname)) {
15921 char msg[300];
15922 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
15923 "file (%s) not found", fname);
15924 send_resp(dut, conn, SIGMA_ERROR, msg);
15925 return 0;
15926 }
15927#endif /* __linux__ */
15928 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
15929 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15930 "not set root CA");
15931 return 0;
15932 }
15933 }
15934
15935 return 1;
15936}
15937
15938
15939static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
15940{
15941 FILE *in, *out;
15942 char buf[500];
15943 int found = 0;
15944
15945 in = fopen("devdetail.xml", "r");
15946 if (in == NULL)
15947 return -1;
15948 out = fopen("devdetail.xml.tmp", "w");
15949 if (out == NULL) {
15950 fclose(in);
15951 return -1;
15952 }
15953
15954 while (fgets(buf, sizeof(buf), in)) {
15955 char *pos = strstr(buf, "<IMSI>");
15956 if (pos) {
15957 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
15958 imsi);
15959 pos += 6;
15960 *pos = '\0';
15961 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
15962 found++;
15963 } else {
15964 fprintf(out, "%s", buf);
15965 }
15966 }
15967
15968 fclose(out);
15969 fclose(in);
15970 if (found)
15971 rename("devdetail.xml.tmp", "devdetail.xml");
15972 else
15973 unlink("devdetail.xml.tmp");
15974
15975 return 0;
15976}
15977
15978
15979static int sta_add_credential_sim(struct sigma_dut *dut,
15980 struct sigma_conn *conn,
15981 const char *ifname, struct sigma_cmd *cmd)
15982{
15983 const char *val, *imsi = NULL;
15984 int id;
15985 char buf[200];
15986 int res;
15987 const char *pos;
15988 size_t mnc_len;
15989 char plmn_mcc[4];
15990 char plmn_mnc[4];
15991
15992 id = add_cred(ifname);
15993 if (id < 0)
15994 return -2;
15995 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15996
15997 val = get_param(cmd, "prefer");
15998 if (val && atoi(val) > 0)
15999 set_cred(ifname, id, "priority", "1");
16000
16001 val = get_param(cmd, "PLMN_MCC");
16002 if (val == NULL) {
16003 send_resp(dut, conn, SIGMA_ERROR,
16004 "errorCode,Missing PLMN_MCC");
16005 return 0;
16006 }
16007 if (strlen(val) != 3) {
16008 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
16009 return 0;
16010 }
16011 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
16012
16013 val = get_param(cmd, "PLMN_MNC");
16014 if (val == NULL) {
16015 send_resp(dut, conn, SIGMA_ERROR,
16016 "errorCode,Missing PLMN_MNC");
16017 return 0;
16018 }
16019 if (strlen(val) != 2 && strlen(val) != 3) {
16020 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
16021 return 0;
16022 }
16023 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
16024
16025 val = get_param(cmd, "IMSI");
16026 if (val == NULL) {
16027 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
16028 "IMSI");
16029 return 0;
16030 }
16031
16032 imsi = pos = val;
16033
16034 if (strncmp(plmn_mcc, pos, 3) != 0) {
16035 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
16036 return 0;
16037 }
16038 pos += 3;
16039
16040 mnc_len = strlen(plmn_mnc);
16041 if (mnc_len < 2) {
16042 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
16043 return 0;
16044 }
16045
16046 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
16047 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
16048 return 0;
16049 }
16050 pos += mnc_len;
16051
16052 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
16053 if (res < 0 || res >= (int) sizeof(buf))
16054 return -1;
16055 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
16056 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16057 "not set IMSI");
16058 return 0;
16059 }
16060
16061 val = get_param(cmd, "Password");
16062 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
16063 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16064 "not set password");
16065 return 0;
16066 }
16067
Jouni Malinen9a742ff2022-01-27 00:43:14 +020016068 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
16069 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016070 /*
16071 * Set provisioning_sp for the test cases where SIM/USIM
16072 * provisioning is used.
16073 */
16074 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
16075 "wi-fi.org") < 0) {
16076 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16077 "not set provisioning_sp");
16078 return 0;
16079 }
16080
16081 update_devdetail_imsi(dut, imsi);
16082 }
16083
16084 return 1;
16085}
16086
16087
16088static int sta_add_credential_cert(struct sigma_dut *dut,
16089 struct sigma_conn *conn,
16090 const char *ifname,
16091 struct sigma_cmd *cmd)
16092{
16093 const char *val;
16094 int id;
16095
16096 id = add_cred(ifname);
16097 if (id < 0)
16098 return -2;
16099 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16100
16101 val = get_param(cmd, "prefer");
16102 if (val && atoi(val) > 0)
16103 set_cred(ifname, id, "priority", "1");
16104
16105 val = get_param(cmd, "REALM");
16106 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
16107 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16108 "realm");
16109 return 0;
16110 }
16111
16112 val = get_param(cmd, "HOME_FQDN");
16113 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
16114 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16115 "home_fqdn");
16116 return 0;
16117 }
16118
16119 val = get_param(cmd, "Username");
16120 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
16121 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16122 "username");
16123 return 0;
16124 }
16125
16126 val = get_param(cmd, "clientCertificate");
16127 if (val) {
16128 char fname[200];
16129 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16130#ifdef __linux__
16131 if (!file_exists(fname)) {
16132 char msg[300];
16133 snprintf(msg, sizeof(msg),
16134 "ErrorCode,clientCertificate "
16135 "file (%s) not found", fname);
16136 send_resp(dut, conn, SIGMA_ERROR, msg);
16137 return 0;
16138 }
16139#endif /* __linux__ */
16140 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
16141 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16142 "not set client_cert");
16143 return 0;
16144 }
16145 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
16146 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16147 "not set private_key");
16148 return 0;
16149 }
16150 }
16151
16152 val = get_param(cmd, "ROOT_CA");
16153 if (val) {
16154 char fname[200];
16155 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16156#ifdef __linux__
16157 if (!file_exists(fname)) {
16158 char msg[300];
16159 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16160 "file (%s) not found", fname);
16161 send_resp(dut, conn, SIGMA_ERROR, msg);
16162 return 0;
16163 }
16164#endif /* __linux__ */
16165 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16166 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16167 "not set root CA");
16168 return 0;
16169 }
16170 }
16171
16172 return 1;
16173}
16174
16175
Jouni Malinenf7222712019-06-13 01:50:21 +030016176static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
16177 struct sigma_conn *conn,
16178 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016179{
16180 const char *intf = get_param(cmd, "Interface");
16181 const char *type;
16182
16183 start_sta_mode(dut);
16184
16185 type = get_param(cmd, "Type");
16186 if (!type)
16187 return -1;
16188
16189 if (strcasecmp(type, "uname_pwd") == 0)
16190 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
16191
16192 if (strcasecmp(type, "sim") == 0)
16193 return sta_add_credential_sim(dut, conn, intf, cmd);
16194
16195 if (strcasecmp(type, "cert") == 0)
16196 return sta_add_credential_cert(dut, conn, intf, cmd);
16197
16198 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
16199 "type");
16200 return 0;
16201}
16202
16203
Jouni Malinenf7222712019-06-13 01:50:21 +030016204static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
16205 struct sigma_conn *conn,
16206 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016207{
16208 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016209 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070016210 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053016211 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016212 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016213 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016214 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016215 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016216
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020016217 start_sta_mode(dut);
16218
Arif Hussain66a4af02019-02-07 15:04:51 -080016219 val = get_param(cmd, "GetParameter");
16220 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016221 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080016222 buf, sizeof(buf)) < 0) {
16223 sigma_dut_print(dut, DUT_MSG_ERROR,
16224 "Could not get ssid bssid");
16225 return ERROR_SEND_STATUS;
16226 }
16227
16228 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
16229 send_resp(dut, conn, SIGMA_COMPLETE, buf);
16230 return STATUS_SENT;
16231 }
16232
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016233 val = get_param(cmd, "HESSID");
16234 if (val) {
16235 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
16236 if (res < 0 || res >= (int) sizeof(buf))
16237 return -1;
16238 wpa_command(intf, buf);
16239 }
16240
16241 val = get_param(cmd, "ACCS_NET_TYPE");
16242 if (val) {
16243 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
16244 val);
16245 if (res < 0 || res >= (int) sizeof(buf))
16246 return -1;
16247 wpa_command(intf, buf);
16248 }
16249
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016250 if (get_param(cmd, "RxMac"))
16251 sta_set_scan_unicast_probe(dut, intf, 1);
16252
vamsi krishna89ad8c62017-09-19 12:51:18 +053016253 bssid = get_param(cmd, "Bssid");
16254 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016255 if (!bssid)
16256 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053016257
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016258 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
16259 dut->device_type == STA_testbed) {
16260 ssid = NULL;
16261 wildcard_ssid = 1;
16262 }
16263
vamsi krishna89ad8c62017-09-19 12:51:18 +053016264 if (ssid) {
16265 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
16266 send_resp(dut, conn, SIGMA_ERROR,
16267 "ErrorCode,Too long SSID");
16268 return 0;
16269 }
16270 ascii2hexstr(ssid, ssid_hex);
16271 }
16272
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016273 short_ssid = get_param(cmd, "ShortSSID");
16274 if (short_ssid) {
16275 uint32_t short_ssid_hex;
16276
16277 short_ssid_hex = strtoul(short_ssid, NULL, 16);
16278 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
16279 (((short_ssid_hex >> 8) & 0xFF) << 16) |
16280 (((short_ssid_hex >> 16) & 0xFF) << 8) |
16281 ((short_ssid_hex >> 24) & 0xFF);
16282
16283 res = snprintf(buf, sizeof(buf),
16284 "VENDOR_ELEM_ADD 14 ff053a%08x",
16285 short_ssid_hex);
16286 if (res < 0 || res >= (int) sizeof(buf) ||
16287 wpa_command(intf, buf)) {
16288 send_resp(dut, conn, SIGMA_ERROR,
16289 "errorCode,Failed to add short SSID");
16290 return STATUS_SENT_ERROR;
16291 }
16292 }
16293
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016294 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053016295 if (scan_freq) {
16296 if (strcasecmp(scan_freq, "2G") == 0)
16297 scan_freq = "2412-2462";
16298 else if (strcasecmp(scan_freq, "5G") == 0)
16299 scan_freq = "5180-5925";
16300 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016301
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016302 val = get_param(cmd, "WaitCompletion");
16303 if (val && atoi(val) == 1) {
16304 ctrl = open_wpa_mon(intf);
16305 if (!ctrl) {
16306 send_resp(dut, conn, SIGMA_ERROR,
16307 "errorCode,Failed to open monitor socket");
16308 return STATUS_SENT_ERROR;
16309 }
16310 }
16311
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016312 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053016313 bssid ? " bssid=": "",
16314 bssid ? bssid : "",
16315 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016316 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016317 wildcard_ssid ? " wildcard_ssid=1" : "",
16318 scan_freq ? " freq=" : "",
16319 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016320 if (res < 0 || res >= (int) sizeof(buf)) {
16321 send_resp(dut, conn, SIGMA_ERROR,
16322 "errorCode,Could not build scan command");
16323 status = STATUS_SENT_ERROR;
16324 goto remove_s_ssid;
16325 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053016326
Veerendranathdc581b52020-08-10 03:29:08 -070016327 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
16328 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
16329 sigma_dut_print(dut, DUT_MSG_DEBUG,
16330 "Scan request rejected with busy status, abort ongoing scan and try again");
16331 wpa_command(intf, "ABORT_SCAN");
16332 res = wpa_command(intf, buf);
16333 }
16334
16335 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016336 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
16337 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016338 status = STATUS_SENT_ERROR;
16339 } else {
16340 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016341 }
16342
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016343remove_s_ssid:
16344 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
16345 sigma_dut_print(dut, DUT_MSG_ERROR,
16346 "Failed to delete vendor element");
16347
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016348 if (ctrl) {
16349 if (status == SUCCESS_SEND_STATUS) {
16350 res = get_wpa_cli_event(dut, ctrl,
16351 "CTRL-EVENT-SCAN-RESULTS",
16352 buf, sizeof(buf));
16353 if (res < 0) {
16354 send_resp(dut, conn, SIGMA_ERROR,
16355 "ErrorCode,scan did not complete");
16356 status = STATUS_SENT_ERROR;
16357 }
16358 }
16359
16360 wpa_ctrl_detach(ctrl);
16361 wpa_ctrl_close(ctrl);
16362 }
16363
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016364 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016365}
16366
16367
Jouni Malinenf7222712019-06-13 01:50:21 +030016368static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
16369 struct sigma_conn *conn,
16370 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016371{
16372 const char *intf = get_param(cmd, "Interface");
16373 const char *bssid;
16374 char buf[4096], *pos;
16375 int freq, chan;
16376 char *ssid;
16377 char resp[100];
16378 int res;
16379 struct wpa_ctrl *ctrl;
16380
16381 bssid = get_param(cmd, "BSSID");
16382 if (!bssid) {
16383 send_resp(dut, conn, SIGMA_INVALID,
16384 "errorCode,BSSID argument is missing");
16385 return 0;
16386 }
16387
16388 ctrl = open_wpa_mon(intf);
16389 if (!ctrl) {
16390 sigma_dut_print(dut, DUT_MSG_ERROR,
16391 "Failed to open wpa_supplicant monitor connection");
16392 return -1;
16393 }
16394
16395 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
16396 send_resp(dut, conn, SIGMA_ERROR,
16397 "errorCode,Could not start scan");
16398 wpa_ctrl_detach(ctrl);
16399 wpa_ctrl_close(ctrl);
16400 return 0;
16401 }
16402
16403 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
16404 buf, sizeof(buf));
16405
16406 wpa_ctrl_detach(ctrl);
16407 wpa_ctrl_close(ctrl);
16408
16409 if (res < 0) {
16410 send_resp(dut, conn, SIGMA_ERROR,
16411 "errorCode,Scan did not complete");
16412 return 0;
16413 }
16414
16415 snprintf(buf, sizeof(buf), "BSS %s", bssid);
16416 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
16417 strncmp(buf, "id=", 3) != 0) {
16418 send_resp(dut, conn, SIGMA_ERROR,
16419 "errorCode,Specified BSSID not found");
16420 return 0;
16421 }
16422
16423 pos = strstr(buf, "\nfreq=");
16424 if (!pos) {
16425 send_resp(dut, conn, SIGMA_ERROR,
16426 "errorCode,Channel not found");
16427 return 0;
16428 }
16429 freq = atoi(pos + 6);
16430 chan = freq_to_channel(freq);
16431
16432 pos = strstr(buf, "\nssid=");
16433 if (!pos) {
16434 send_resp(dut, conn, SIGMA_ERROR,
16435 "errorCode,SSID not found");
16436 return 0;
16437 }
16438 ssid = pos + 6;
16439 pos = strchr(ssid, '\n');
16440 if (pos)
16441 *pos = '\0';
16442 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
16443 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16444 return 0;
16445}
16446
16447
Jouni Malinenf7222712019-06-13 01:50:21 +030016448static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
16449 struct sigma_conn *conn,
16450 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016451{
16452#ifdef __linux__
16453 struct timeval tv;
16454 struct tm tm;
16455 time_t t;
16456 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016457 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016458
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016459 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016460
16461 memset(&tm, 0, sizeof(tm));
16462 val = get_param(cmd, "seconds");
16463 if (val)
16464 tm.tm_sec = atoi(val);
16465 val = get_param(cmd, "minutes");
16466 if (val)
16467 tm.tm_min = atoi(val);
16468 val = get_param(cmd, "hours");
16469 if (val)
16470 tm.tm_hour = atoi(val);
16471 val = get_param(cmd, "date");
16472 if (val)
16473 tm.tm_mday = atoi(val);
16474 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016475 if (val) {
16476 v = atoi(val);
16477 if (v < 1 || v > 12) {
16478 send_resp(dut, conn, SIGMA_INVALID,
16479 "errorCode,Invalid month");
16480 return 0;
16481 }
16482 tm.tm_mon = v - 1;
16483 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016484 val = get_param(cmd, "year");
16485 if (val) {
16486 int year = atoi(val);
16487#ifdef ANDROID
16488 if (year > 2035)
16489 year = 2035; /* years beyond 2035 not supported */
16490#endif /* ANDROID */
16491 tm.tm_year = year - 1900;
16492 }
16493 t = mktime(&tm);
16494 if (t == (time_t) -1) {
16495 send_resp(dut, conn, SIGMA_ERROR,
16496 "errorCode,Invalid date or time");
16497 return 0;
16498 }
16499
16500 memset(&tv, 0, sizeof(tv));
16501 tv.tv_sec = t;
16502
16503 if (settimeofday(&tv, NULL) < 0) {
16504 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
16505 strerror(errno));
16506 send_resp(dut, conn, SIGMA_ERROR,
16507 "errorCode,Failed to set time");
16508 return 0;
16509 }
16510
16511 return 1;
16512#endif /* __linux__ */
16513
16514 return -1;
16515}
16516
16517
Jouni Malinenf7222712019-06-13 01:50:21 +030016518static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
16519 struct sigma_conn *conn,
16520 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016521{
16522 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016523 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016524 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016525 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016526 int res;
16527 struct wpa_ctrl *ctrl;
16528
16529 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016530 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016531
16532 val = get_param(cmd, "ProdESSAssoc");
16533 if (val)
16534 prod_ess_assoc = atoi(val);
16535
16536 kill_dhcp_client(dut, intf);
16537 if (start_dhcp_client(dut, intf) < 0)
16538 return -2;
16539
16540 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
16541 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16542 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016543 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016544 prod_ess_assoc ? "" : "-N",
16545 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016546 name ? "'" : "",
16547 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
16548 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016549
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053016550 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016551 if (run_hs20_osu(dut, buf) < 0) {
16552 FILE *f;
16553
16554 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
16555
16556 f = fopen("hs20-osu-client.res", "r");
16557 if (f) {
16558 char resp[400], res[300], *pos;
16559 if (!fgets(res, sizeof(res), f))
16560 res[0] = '\0';
16561 pos = strchr(res, '\n');
16562 if (pos)
16563 *pos = '\0';
16564 fclose(f);
16565 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
16566 res);
16567 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
16568 if (system(resp) != 0) {
16569 }
16570 snprintf(resp, sizeof(resp),
16571 "SSID,,BSSID,,failureReason,%s", res);
16572 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16573 return 0;
16574 }
16575
16576 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16577 return 0;
16578 }
16579
16580 if (!prod_ess_assoc)
16581 goto report;
16582
16583 ctrl = open_wpa_mon(intf);
16584 if (ctrl == NULL) {
16585 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16586 "wpa_supplicant monitor connection");
16587 return -1;
16588 }
16589
16590 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
16591 buf, sizeof(buf));
16592
16593 wpa_ctrl_detach(ctrl);
16594 wpa_ctrl_close(ctrl);
16595
16596 if (res < 0) {
16597 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
16598 "network after OSU");
16599 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16600 return 0;
16601 }
16602
16603report:
16604 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
16605 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
16606 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
16607 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16608 return 0;
16609 }
16610
16611 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
16612 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016613 return 0;
16614}
16615
16616
Jouni Malinenf7222712019-06-13 01:50:21 +030016617static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
16618 struct sigma_conn *conn,
16619 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016620{
16621 const char *val;
16622 int timeout = 120;
16623
16624 val = get_param(cmd, "PolicyUpdate");
16625 if (val == NULL || atoi(val) == 0)
16626 return 1; /* No operation requested */
16627
16628 val = get_param(cmd, "Timeout");
16629 if (val)
16630 timeout = atoi(val);
16631
16632 if (timeout) {
16633 /* TODO: time out the command and return
16634 * PolicyUpdateStatus,TIMEOUT if needed. */
16635 }
16636
16637 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
16638 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16639 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
16640 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
16641 return 0;
16642 }
16643
16644 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
16645 return 0;
16646}
16647
16648
Jouni Malinenf7222712019-06-13 01:50:21 +030016649static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
16650 struct sigma_conn *conn,
16651 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016652{
16653 struct wpa_ctrl *ctrl;
16654 const char *intf = get_param(cmd, "Interface");
16655 const char *bssid = get_param(cmd, "Bssid");
16656 const char *ssid = get_param(cmd, "SSID");
16657 const char *security = get_param(cmd, "Security");
16658 const char *passphrase = get_param(cmd, "Passphrase");
16659 const char *pin = get_param(cmd, "PIN");
16660 char buf[1000];
16661 char ssid_hex[200], passphrase_hex[200];
16662 const char *keymgmt, *cipher;
16663
16664 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016665 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016666
16667 if (!bssid) {
16668 send_resp(dut, conn, SIGMA_ERROR,
16669 "ErrorCode,Missing Bssid argument");
16670 return 0;
16671 }
16672
16673 if (!ssid) {
16674 send_resp(dut, conn, SIGMA_ERROR,
16675 "ErrorCode,Missing SSID argument");
16676 return 0;
16677 }
16678
16679 if (!security) {
16680 send_resp(dut, conn, SIGMA_ERROR,
16681 "ErrorCode,Missing Security argument");
16682 return 0;
16683 }
16684
16685 if (!passphrase) {
16686 send_resp(dut, conn, SIGMA_ERROR,
16687 "ErrorCode,Missing Passphrase argument");
16688 return 0;
16689 }
16690
16691 if (!pin) {
16692 send_resp(dut, conn, SIGMA_ERROR,
16693 "ErrorCode,Missing PIN argument");
16694 return 0;
16695 }
16696
vamsi krishna8c9c1562017-05-12 15:51:46 +053016697 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
16698 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016699 send_resp(dut, conn, SIGMA_ERROR,
16700 "ErrorCode,Too long SSID/passphrase");
16701 return 0;
16702 }
16703
16704 ctrl = open_wpa_mon(intf);
16705 if (ctrl == NULL) {
16706 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16707 "wpa_supplicant monitor connection");
16708 return -2;
16709 }
16710
16711 if (strcasecmp(security, "wpa2-psk") == 0) {
16712 keymgmt = "WPA2PSK";
16713 cipher = "CCMP";
16714 } else {
16715 wpa_ctrl_detach(ctrl);
16716 wpa_ctrl_close(ctrl);
16717 send_resp(dut, conn, SIGMA_ERROR,
16718 "ErrorCode,Unsupported Security value");
16719 return 0;
16720 }
16721
16722 ascii2hexstr(ssid, ssid_hex);
16723 ascii2hexstr(passphrase, passphrase_hex);
16724 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
16725 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
16726
16727 if (wpa_command(intf, buf) < 0) {
16728 wpa_ctrl_detach(ctrl);
16729 wpa_ctrl_close(ctrl);
16730 send_resp(dut, conn, SIGMA_ERROR,
16731 "ErrorCode,Failed to start registrar");
16732 return 0;
16733 }
16734
16735 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
16736 dut->er_oper_performed = 1;
16737
16738 return wps_connection_event(dut, conn, ctrl, intf, 0);
16739}
16740
16741
Jouni Malinenf7222712019-06-13 01:50:21 +030016742static enum sigma_cmd_result
16743cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
16744 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016745{
16746 struct wpa_ctrl *ctrl;
16747 const char *intf = get_param(cmd, "Interface");
16748 const char *bssid = get_param(cmd, "Bssid");
16749 char buf[100];
16750
16751 if (!bssid) {
16752 send_resp(dut, conn, SIGMA_ERROR,
16753 "ErrorCode,Missing Bssid argument");
16754 return 0;
16755 }
16756
16757 ctrl = open_wpa_mon(intf);
16758 if (ctrl == NULL) {
16759 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16760 "wpa_supplicant monitor connection");
16761 return -2;
16762 }
16763
16764 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
16765
16766 if (wpa_command(intf, buf) < 0) {
16767 wpa_ctrl_detach(ctrl);
16768 wpa_ctrl_close(ctrl);
16769 send_resp(dut, conn, SIGMA_ERROR,
16770 "ErrorCode,Failed to start registrar");
16771 return 0;
16772 }
16773
16774 return wps_connection_event(dut, conn, ctrl, intf, 0);
16775}
16776
16777
Jouni Malinenf7222712019-06-13 01:50:21 +030016778static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
16779 struct sigma_conn *conn,
16780 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053016781{
16782 struct wpa_ctrl *ctrl;
16783 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016784 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016785 const char *config_method = get_param(cmd, "WPSConfigMethod");
16786 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053016787 int res;
16788 char buf[256];
16789 const char *events[] = {
16790 "CTRL-EVENT-CONNECTED",
16791 "WPS-OVERLAP-DETECTED",
16792 "WPS-TIMEOUT",
16793 "WPS-FAIL",
16794 NULL
16795 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016796 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053016797
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016798 /* 60G WPS tests do not pass Interface parameter */
16799 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016800 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016801
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016802 if (dut->mode == SIGMA_MODE_AP)
16803 return ap_wps_registration(dut, conn, cmd);
16804
16805 if (config_method) {
16806 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
16807 * sta_wps_enter_pin before calling start_wps_registration. */
16808 if (strcasecmp(config_method, "PBC") == 0)
16809 dut->wps_method = WFA_CS_WPS_PBC;
16810 }
16811 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
16812 send_resp(dut, conn, SIGMA_ERROR,
16813 "ErrorCode,WPS parameters not yet set");
16814 return STATUS_SENT;
16815 }
16816
16817 /* Make sure WPS is enabled (also for STA mode) */
16818 dut->wps_disable = 0;
16819
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016820 if (dut->band == WPS_BAND_60G && network_mode &&
16821 strcasecmp(network_mode, "PBSS") == 0) {
16822 sigma_dut_print(dut, DUT_MSG_DEBUG,
16823 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016824 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016825 return -2;
16826 }
16827
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016828 if (dut->force_rsn_ie) {
16829 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
16830 dut->force_rsn_ie);
16831 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
16832 sigma_dut_print(dut, DUT_MSG_INFO,
16833 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020016834 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016835 }
16836 }
16837
vamsi krishna9b144002017-09-20 13:28:13 +053016838 ctrl = open_wpa_mon(intf);
16839 if (!ctrl) {
16840 sigma_dut_print(dut, DUT_MSG_ERROR,
16841 "Failed to open wpa_supplicant monitor connection");
16842 return -2;
16843 }
16844
16845 role = get_param(cmd, "WpsRole");
16846 if (!role) {
16847 send_resp(dut, conn, SIGMA_INVALID,
16848 "ErrorCode,WpsRole not provided");
16849 goto fail;
16850 }
16851
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016852 if (strcasecmp(role, "Enrollee") != 0) {
16853 /* Registrar role for STA not supported */
16854 send_resp(dut, conn, SIGMA_ERROR,
16855 "ErrorCode,Unsupported WpsRole value");
16856 goto fail;
16857 }
16858
16859 if (is_60g_sigma_dut(dut)) {
16860 if (dut->wps_method == WFA_CS_WPS_PBC)
16861 snprintf(buf, sizeof(buf), "WPS_PBC");
16862 else /* WFA_CS_WPS_PIN_KEYPAD */
16863 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
16864 dut->wps_pin);
16865 if (wpa_command(intf, buf) < 0) {
16866 send_resp(dut, conn, SIGMA_ERROR,
16867 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053016868 goto fail;
16869 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016870 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16871 if (res < 0) {
16872 send_resp(dut, conn, SIGMA_ERROR,
16873 "ErrorCode,WPS connection did not complete");
16874 goto fail;
16875 }
16876 if (strstr(buf, "WPS-TIMEOUT")) {
16877 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
16878 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16879 send_resp(dut, conn, SIGMA_COMPLETE,
16880 "WpsState,OverlapSession");
16881 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16882 send_resp(dut, conn, SIGMA_COMPLETE,
16883 "WpsState,Successful");
16884 } else {
16885 send_resp(dut, conn, SIGMA_COMPLETE,
16886 "WpsState,Failure");
16887 }
16888 } else {
16889 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053016890 if (wpa_command(intf, "WPS_PBC") < 0) {
16891 send_resp(dut, conn, SIGMA_ERROR,
16892 "ErrorCode,Failed to enable PBC");
16893 goto fail;
16894 }
16895 } else {
16896 /* TODO: PIN method */
16897 send_resp(dut, conn, SIGMA_ERROR,
16898 "ErrorCode,Unsupported WpsConfigMethod value");
16899 goto fail;
16900 }
16901 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16902 if (res < 0) {
16903 send_resp(dut, conn, SIGMA_ERROR,
16904 "ErrorCode,WPS connection did not complete");
16905 goto fail;
16906 }
16907 if (strstr(buf, "WPS-TIMEOUT")) {
16908 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
16909 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16910 send_resp(dut, conn, SIGMA_ERROR,
16911 "ErrorCode,OverlapSession");
16912 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16913 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
16914 } else {
16915 send_resp(dut, conn, SIGMA_ERROR,
16916 "ErrorCode,WPS operation failed");
16917 }
vamsi krishna9b144002017-09-20 13:28:13 +053016918 }
16919
16920fail:
16921 wpa_ctrl_detach(ctrl);
16922 wpa_ctrl_close(ctrl);
16923 return 0;
16924}
16925
16926
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016927static int req_intf(struct sigma_cmd *cmd)
16928{
16929 return get_param(cmd, "interface") == NULL ? -1 : 0;
16930}
16931
16932
16933void sta_register_cmds(void)
16934{
16935 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
16936 cmd_sta_get_ip_config);
16937 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
16938 cmd_sta_set_ip_config);
16939 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
16940 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
16941 cmd_sta_get_mac_address);
16942 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
16943 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
16944 cmd_sta_verify_ip_connection);
16945 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
16946 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
16947 cmd_sta_set_encryption);
16948 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
16949 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
16950 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
16951 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
16952 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
16953 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
16954 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
16955 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
16956 cmd_sta_set_eapakaprime);
16957 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
16958 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
16959 /* TODO: sta_set_ibss */
16960 /* TODO: sta_set_mode */
16961 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
16962 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
16963 /* TODO: sta_up_load */
16964 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
16965 cmd_sta_preset_testparameters);
16966 /* TODO: sta_set_system */
16967 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
16968 /* TODO: sta_set_rifs_test */
16969 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
16970 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
16971 /* TODO: sta_send_coexist_mgmt */
16972 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
16973 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
16974 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
16975 sigma_dut_reg_cmd("sta_reset_default", req_intf,
16976 cmd_sta_reset_default);
16977 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
16978 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
16979 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
16980 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
16981 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020016982 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016983 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
16984 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
16985 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
16986 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
16987 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030016988 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
16989 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016990 sigma_dut_reg_cmd("sta_add_credential", req_intf,
16991 cmd_sta_add_credential);
16992 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016993 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016994 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
16995 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
16996 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
16997 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
16998 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
16999 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030017000 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017001 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
17002 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020017003 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053017004 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017005}