blob: 5230febda7b5a1a53207af1210542516bb7d0f48 [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 Lokere94829ce2022-01-20 10:49:08 -08008916 nl80211_close_event_sock(dut);
8917
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08008918 /* Reset the device HE capabilities to its default supported
8919 * configuration. */
8920 sta_set_he_testbed_def(dut, intf, 0);
8921
Amarnath Hullur Subramanyam5f32d572018-03-02 00:02:33 -08008922 /* Disable noackpolicy for all AC */
8923 if (nlvendor_sta_set_noack(dut, intf, 0, QCA_WLAN_AC_ALL)) {
8924 sigma_dut_print(dut, DUT_MSG_ERROR,
8925 "Disable of noackpolicy for all AC failed");
8926 }
8927#endif /* NL80211_SUPPORT */
8928
Amarnath Hullur Subramanyamb1724a52018-03-07 14:31:46 -08008929 /* Enable WMM by default */
8930 if (wcn_sta_set_wmm(dut, intf, "on")) {
8931 sigma_dut_print(dut, DUT_MSG_ERROR,
8932 "Enable of WMM in sta_reset_default_wcn failed");
8933 }
8934
8935 /* Disable ADDBA_REJECT by default */
8936 if (nlvendor_sta_set_addba_reject(dut, intf, 0)) {
8937 sigma_dut_print(dut, DUT_MSG_ERROR,
8938 "Disable of addba_reject in sta_reset_default_wcn failed");
8939 }
8940
Amarnath Hullur Subramanyam1f65a672018-03-07 14:50:29 -08008941 /* Enable sending of ADDBA by default */
8942 if (nlvendor_config_send_addba(dut, intf, 1)) {
8943 sigma_dut_print(dut, DUT_MSG_ERROR,
8944 "Enable sending of ADDBA in sta_reset_default_wcn failed");
8945 }
8946
Amarnath Hullur Subramanyam63c590a2018-03-07 15:26:21 -08008947 /* Enable AMPDU by default */
8948 iwpriv_sta_set_ampdu(dut, intf, 1);
8949
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008950#ifdef NL80211_SUPPORT
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -08008951 if (wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_AUTO)) {
Subhani Shaik8e7a3052018-04-24 14:03:00 -07008952 sigma_dut_print(dut, DUT_MSG_ERROR,
8953 "Set LTF config to default in sta_reset_default_wcn failed");
8954 }
Arif Hussain9765f7d2018-07-03 08:28:26 -07008955
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08008956 /* set the beamformee NSTS(maximum number of
8957 * space-time streams) to default DUT config
8958 */
8959 if (sta_set_beamformee_sts(dut, intf, 7)) {
Arif Hussain9765f7d2018-07-03 08:28:26 -07008960 sigma_dut_print(dut, DUT_MSG_ERROR,
8961 "Failed to set BeamformeeSTS");
8962 }
Arif Hussain68d23f52018-07-11 13:39:08 -07008963
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -07008964 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, 0)) {
8965 sigma_dut_print(dut, DUT_MSG_ERROR,
8966 "Failed to reset mgmt/data Tx disable config");
8967 }
8968
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -07008969 if (sta_set_mac_padding_duration(
8970 dut, intf,
8971 QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME)) {
Arif Hussain68d23f52018-07-11 13:39:08 -07008972 sigma_dut_print(dut, DUT_MSG_ERROR,
8973 "Failed to set MAC padding duration");
8974 }
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -07008975
8976 if (sta_set_mu_edca_override(dut, intf, 0)) {
8977 sigma_dut_print(dut, DUT_MSG_ERROR,
8978 "ErrorCode,Failed to set MU EDCA override disable");
8979 }
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008980
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -07008981 if (sta_set_ru_242_tone_tx(dut, intf, 0)) {
8982 sigma_dut_print(dut, DUT_MSG_ERROR,
8983 "Failed to set RU 242 tone Tx");
8984 }
8985
8986 if (sta_set_er_su_ppdu_type_tx(dut, intf, 0)) {
8987 sigma_dut_print(dut, DUT_MSG_ERROR,
8988 "Failed to set ER-SU PPDU type Tx");
8989 }
8990
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -07008991 if (sta_set_om_ctrl_supp(dut, intf, 1)) {
8992 sigma_dut_print(dut, DUT_MSG_ERROR,
8993 "Failed to set OM ctrl supp");
8994 }
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -07008995
8996 if (sta_set_tx_su_ppdu_cfg(dut, intf, 1)) {
8997 sigma_dut_print(dut, DUT_MSG_ERROR,
8998 "Failed to set Tx SU PPDU enable");
8999 }
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009000
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -07009001 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 0)) {
9002 sigma_dut_print(dut, DUT_MSG_ERROR,
9003 "failed to send TB PPDU Tx cfg");
9004 }
9005
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -07009006 if (sta_set_he_om_ctrl_reset(dut, intf)) {
9007 sigma_dut_print(dut, DUT_MSG_ERROR,
9008 "Failed to set OM ctrl reset");
9009 }
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009010
9011 /* +HTC-HE support default on */
9012 if (sta_set_he_htc_supp(dut, intf, 1)) {
9013 sigma_dut_print(dut, DUT_MSG_ERROR,
9014 "Setting of +HTC-HE support failed");
9015 }
Subhani Shaik8e7a3052018-04-24 14:03:00 -07009016#endif /* NL80211_SUPPORT */
9017
Arif Hussain8d5b27b2018-05-14 14:31:03 -07009018 if (sta_set_tx_beamformee(dut, intf, 1)) {
9019 sigma_dut_print(dut, DUT_MSG_ERROR,
9020 "Set tx beamformee enable by default in sta_reset_default_wcn failed");
9021 }
9022
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009023 wpa_command(intf, "SET oce 1");
9024
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009025 /* Set nss to 1 and MCS 0-7 in case of testbed */
9026 if (type && strcasecmp(type, "Testbed") == 0) {
9027#ifdef NL80211_SUPPORT
9028 int ret;
9029#endif /* NL80211_SUPPORT */
9030
Kiran Kumar Lokereb55ff442020-07-15 00:20:40 -07009031 wpa_command(intf, "SET oce 0");
9032
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009033 snprintf(buf, sizeof(buf), "iwpriv %s nss 1", intf);
9034 if (system(buf) != 0) {
9035 sigma_dut_print(dut, DUT_MSG_ERROR,
9036 "iwpriv %s nss failed", intf);
9037 }
9038
9039#ifdef NL80211_SUPPORT
9040 ret = sta_set_he_mcs(dut, intf, HE_80_MCS0_7);
9041 if (ret) {
9042 sigma_dut_print(dut, DUT_MSG_ERROR,
9043 "Setting of MCS failed, ret:%d",
9044 ret);
9045 }
9046#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyamc67621d2018-02-04 23:18:01 -08009047
9048 /* Disable STBC as default */
9049 wcn_sta_set_stbc(dut, intf, "0");
Amarnath Hullur Subramanyamd5bb5732018-02-22 15:50:38 -08009050
9051 /* Disable AMSDU as default */
9052 iwpriv_sta_set_amsdu(dut, intf, "0");
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009053
9054#ifdef NL80211_SUPPORT
9055 /* HE fragmentation default off */
9056 if (sta_set_he_fragmentation(dut, intf,
9057 HE_FRAG_DISABLE)) {
9058 sigma_dut_print(dut, DUT_MSG_ERROR,
9059 "Setting of HE fragmentation failed");
9060 }
Kiran Kumar Lokerebad51122018-12-12 19:03:36 -08009061
9062 /* set the beamformee NSTS(maximum number of
9063 * space-time streams) to default testbed config
9064 */
9065 if (sta_set_beamformee_sts(dut, intf, 3)) {
9066 sigma_dut_print(dut, DUT_MSG_ERROR,
9067 "Failed to set BeamformeeSTS");
9068 }
9069
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -07009070 if (sta_set_punctured_preamble_rx(dut, intf, 0)) {
9071 sigma_dut_print(dut, DUT_MSG_ERROR,
9072 "Failed to reset PreamblePunctRx support");
9073 }
9074
Kiran Kumar Lokere727687f2021-06-24 00:35:49 -07009075 if (sta_set_bss_max_idle_period(dut, intf, 0)) {
9076 sigma_dut_print(dut, DUT_MSG_ERROR,
9077 "Failed to reset BSS max idle period");
9078 }
9079
Kiran Kumar Lokeree5ed4422018-12-18 18:25:02 -08009080 /* +HTC-HE support default off */
9081 if (sta_set_he_htc_supp(dut, intf, 0)) {
9082 sigma_dut_print(dut, DUT_MSG_ERROR,
9083 "Setting of +HTC-HE support failed");
9084 }
Kiran Kumar Lokere765bdd82019-02-24 22:14:43 -08009085
9086 /* Set device HE capabilities to testbed default
9087 * configuration. */
9088 if (sta_set_he_testbed_def(dut, intf, 1)) {
9089 sigma_dut_print(dut, DUT_MSG_DEBUG,
9090 "Failed to set HE defaults");
9091 }
Kiran Kumar Lokere642f7ce2019-02-25 18:28:10 -08009092
9093 /* Disable VHT support in 2.4 GHz for testbed */
9094 sta_set_2g_vht_supp(dut, intf, 0);
Amarnath Hullur Subramanyam474a17d2018-02-22 18:45:54 -08009095#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam4622a212018-02-23 12:12:14 -08009096
9097 /* Enable WEP/TKIP with HE capability in testbed */
9098 if (sta_set_heconfig_and_wep_tkip(dut, intf, 1)) {
9099 sigma_dut_print(dut, DUT_MSG_ERROR,
9100 "Enabling HE config with WEP/TKIP failed");
9101 }
Amarnath Hullur Subramanyam2538acc2018-02-02 16:15:25 -08009102 }
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009103
9104 /* Defaults in case of DUT */
9105 if (type && strcasecmp(type, "DUT") == 0) {
Arif Hussaind48fcc72018-05-01 18:34:18 -07009106 /* Enable STBC by default */
9107 wcn_sta_set_stbc(dut, intf, "1");
9108
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009109 /* set nss to 2 */
9110 snprintf(buf, sizeof(buf), "iwpriv %s nss 2", intf);
9111 if (system(buf) != 0) {
9112 sigma_dut_print(dut, DUT_MSG_ERROR,
9113 "iwpriv %s nss 2 failed", intf);
9114 }
Arif Hussainac6c5112018-05-25 17:34:00 -07009115 dut->sta_nss = 2;
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009116
9117#ifdef NL80211_SUPPORT
Arif Hussainae239842018-05-01 18:20:05 -07009118 /* Set HE_MCS to 0-11 */
9119 if (sta_set_he_mcs(dut, intf, HE_80_MCS0_11)) {
Amarnath Hullur Subramanyam0acce2c2018-03-06 06:05:17 -08009120 sigma_dut_print(dut, DUT_MSG_ERROR,
9121 "Setting of MCS failed");
9122 }
9123#endif /* NL80211_SUPPORT */
9124
9125 /* Disable WEP/TKIP with HE capability in DUT */
9126 if (sta_set_heconfig_and_wep_tkip(dut, intf, 0)) {
9127 sigma_dut_print(dut, DUT_MSG_ERROR,
9128 "Enabling HE config with WEP/TKIP failed");
9129 }
9130 }
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009131 }
9132}
9133
9134
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309135static int sta_set_client_privacy(struct sigma_dut *dut,
9136 struct sigma_conn *conn, const char *intf,
9137 int enable)
9138{
9139 if (enable &&
9140 (wpa_command(intf, "SET mac_addr 1") < 0 ||
9141 wpa_command(intf, "SET rand_addr_lifetime 1") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309142 (wpa_command(intf, "MAC_RAND_SCAN enable=1 all") < 0 &&
9143 wpa_command(intf, "SET preassoc_mac_addr 1") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309144 wpa_command(intf, "SET gas_rand_mac_addr 1") < 0 ||
9145 wpa_command(intf, "SET gas_rand_addr_lifetime 1") < 0))
9146 return -1;
9147
9148 if (!enable &&
9149 (wpa_command(intf, "SET mac_addr 0") < 0 ||
Veerendranath Jakkam39fd5c42020-12-21 02:02:21 +05309150 (wpa_command(intf, "MAC_RAND_SCAN enable=0 all") < 0 &&
9151 wpa_command(intf, "SET preassoc_mac_addr 0") < 0) ||
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309152 wpa_command(intf, "SET gas_rand_mac_addr 0") < 0))
9153 return -1;
9154
9155 dut->client_privacy = enable;
9156 return 0;
9157}
9158
9159
Jouni Malinenf7222712019-06-13 01:50:21 +03009160static enum sigma_cmd_result cmd_sta_reset_default(struct sigma_dut *dut,
9161 struct sigma_conn *conn,
9162 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009163{
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009164 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009165 const char *band = get_param(cmd, "band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009166 const char *type;
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009167 const char *program = get_param(cmd, "program");
Ankita Bajaj0d5825b2017-10-25 16:20:17 +05309168 const char *dev_role = get_param(cmd, "DevRole");
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309169 char resp[20];
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309170 char buf[100];
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309171 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009172
Jouni Malinenb21f0542019-11-04 17:53:38 +02009173 if (dut->station_ifname_2g &&
9174 strcmp(dut->station_ifname_2g, intf) == 0)
9175 dut->use_5g = 0;
9176 else if (dut->station_ifname_5g &&
9177 strcmp(dut->station_ifname_5g, intf) == 0)
9178 dut->use_5g = 1;
9179
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009180 if (!program)
9181 program = get_param(cmd, "prog");
9182 dut->program = sigma_program_to_enum(program);
Vinita S. Maloof7a2cbf2020-11-18 19:29:44 +05309183
9184 if (dut->program == PROGRAM_WFD && dut->user_config_timeout)
9185 dut->default_timeout = dut->user_config_timeout;
9186
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009187 dut->device_type = STA_unknown;
9188 type = get_param(cmd, "type");
9189 if (type && strcasecmp(type, "Testbed") == 0)
9190 dut->device_type = STA_testbed;
9191 if (type && strcasecmp(type, "DUT") == 0)
9192 dut->device_type = STA_dut;
9193
9194 if (dut->program == PROGRAM_TDLS) {
9195 /* Clear TDLS testing mode */
9196 wpa_command(intf, "SET tdls_disabled 0");
9197 wpa_command(intf, "SET tdls_testing 0");
9198 dut->no_tpk_expiration = 0;
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009199 if (get_driver_type(dut) == DRIVER_WCN) {
Pradeep Reddy POTTETI8ce2a232016-10-28 12:17:32 +05309200 /* Enable the WCN driver in TDLS Explicit trigger mode
9201 */
9202 wpa_command(intf, "SET tdls_external_control 0");
9203 wpa_command(intf, "SET tdls_trigger_control 0");
9204 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009205 }
9206
Amarnath Hullur Subramanyam9c381f52017-03-17 00:04:41 -07009207#ifdef MIRACAST
9208 if (dut->program == PROGRAM_WFD ||
9209 dut->program == PROGRAM_DISPLAYR2)
9210 miracast_sta_reset_default(dut, conn, cmd);
9211#endif /* MIRACAST */
9212
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009213 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009214 case DRIVER_ATHEROS:
9215 sta_reset_default_ath(dut, intf, type);
9216 break;
Amarnath Hullur Subramanyam58f2a6e2018-01-31 03:36:00 -08009217 case DRIVER_WCN:
9218 sta_reset_default_wcn(dut, intf, type);
9219 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009220 default:
9221 break;
9222 }
9223
9224#ifdef ANDROID_NAN
9225 if (dut->program == PROGRAM_NAN)
9226 nan_cmd_sta_reset_default(dut, conn, cmd);
9227#endif /* ANDROID_NAN */
9228
Vinay Gannevaram3b9fdd32019-06-14 17:55:44 +05309229 if (dut->program == PROGRAM_LOC &&
9230 lowi_cmd_sta_reset_default(dut, conn, cmd) < 0)
9231 return ERROR_SEND_STATUS;
9232
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009233 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
9234 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009235 unlink("SP/wi-fi.org/pps.xml");
9236 if (system("rm -r SP/*") != 0) {
9237 }
9238 unlink("next-client-cert.pem");
9239 unlink("next-client-key.pem");
9240 }
9241
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009242 /* For WPS program of the 60 GHz band the band type needs to be saved */
9243 if (dut->program == PROGRAM_WPS) {
9244 if (band && strcasecmp(band, "60GHz") == 0) {
9245 dut->band = WPS_BAND_60G;
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009246 /* For 60 GHz enable WPS for WPS TCs */
9247 dut->wps_disable = 0;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009248 } else {
9249 dut->band = WPS_BAND_NON_60G;
9250 }
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009251 } else if (dut->program == PROGRAM_60GHZ) {
9252 /* For 60 GHz MAC/PHY TCs WPS must be disabled */
9253 dut->wps_disable = 1;
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009254 }
9255
Alexei Avshalom Lazar157ba062018-12-23 16:15:26 +02009256 if (is_60g_sigma_dut(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009257 const char *dev_role = get_param(cmd, "DevRole");
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009258 char buf[256];
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009259
Alexei Avshalom Lazareee9ab02018-12-24 16:27:48 +02009260 sigma_dut_print(dut, DUT_MSG_INFO,
9261 "WPS 60 GHz program, wps_disable = %d",
9262 dut->wps_disable);
9263
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009264 if (!dev_role) {
9265 send_resp(dut, conn, SIGMA_ERROR,
9266 "errorCode,Missing DevRole argument");
9267 return 0;
9268 }
9269
9270 if (strcasecmp(dev_role, "STA") == 0)
9271 dut->dev_role = DEVROLE_STA;
9272 else if (strcasecmp(dev_role, "PCP") == 0)
9273 dut->dev_role = DEVROLE_PCP;
9274 else {
9275 send_resp(dut, conn, SIGMA_ERROR,
9276 "errorCode,Unknown DevRole");
9277 return 0;
9278 }
9279
9280 if (dut->device_type == STA_unknown) {
9281 sigma_dut_print(dut, DUT_MSG_ERROR,
9282 "Device type is not STA testbed or DUT");
9283 send_resp(dut, conn, SIGMA_ERROR,
9284 "errorCode,Unknown device type");
9285 return 0;
9286 }
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009287
9288 sigma_dut_print(dut, DUT_MSG_DEBUG,
9289 "Setting msdu_size to MAX: 7912");
9290 snprintf(buf, sizeof(buf), "ifconfig %s mtu 7912",
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009291 get_station_ifname(dut));
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009292
9293 if (system(buf) != 0) {
9294 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set %s",
9295 buf);
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009296 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarc2a5bb12018-12-23 16:12:06 +02009297 }
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009298
9299 if (sta_set_force_mcs(dut, 0, 1)) {
9300 sigma_dut_print(dut, DUT_MSG_ERROR,
9301 "Failed to reset force MCS");
Jouni Malinen0e29cf22019-02-19 01:13:21 +02009302 return ERROR_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +02009303 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009304 }
9305
9306 wpa_command(intf, "WPS_ER_STOP");
9307 wpa_command(intf, "FLUSH");
vamsi krishnaf39bc1e2017-08-23 17:37:53 +05309308 wpa_command(intf, "ERP_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009309 wpa_command(intf, "SET radio_disabled 0");
9310
Alexei Avshalom Lazar744ae8a2019-01-31 17:26:46 +02009311 dut->wps_forced_version = 0;
9312
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009313 if (dut->wsc_fragment) {
9314 dut->wsc_fragment = 0;
9315 wpa_command(intf, "SET device_name Test client");
9316 wpa_command(intf, "SET manufacturer ");
9317 wpa_command(intf, "SET model_name ");
9318 wpa_command(intf, "SET model_number ");
9319 wpa_command(intf, "SET serial_number ");
9320 }
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +02009321 if (is_60g_sigma_dut(dut) && dut->force_rsn_ie) {
9322 dut->force_rsn_ie = FORCE_RSN_IE_NONE;
9323 sta_60g_force_rsn_ie(dut, FORCE_RSN_IE_NONE);
9324 }
Alexei Avshalom Lazar33f700c2018-12-18 16:00:39 +02009325
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009326 if (dut->tmp_mac_addr && dut->set_macaddr) {
9327 dut->tmp_mac_addr = 0;
9328 if (system(dut->set_macaddr) != 0) {
9329 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to clear "
9330 "temporary MAC address");
9331 }
9332 }
9333
9334 set_ps(intf, dut, 0);
9335
Jouni Malinenba630452018-06-22 11:49:59 +03009336 if (dut->program == PROGRAM_HS2 || dut->program == PROGRAM_HS2_R2 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009337 dut->program == PROGRAM_HS2_R3 || dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009338 wpa_command(intf, "SET interworking 1");
9339 wpa_command(intf, "SET hs20 1");
9340 }
9341
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009342 if (dut->program == PROGRAM_HS2_R2 ||
Jouni Malinenba630452018-06-22 11:49:59 +03009343 dut->program == PROGRAM_HS2_R3 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +02009344 dut->program == PROGRAM_HS2_R4 ||
Deepak Dhamdhere0fe0e452017-12-18 14:52:09 -08009345 dut->program == PROGRAM_OCE) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009346 wpa_command(intf, "SET pmf 1");
9347 } else {
9348 wpa_command(intf, "SET pmf 0");
9349 }
9350
9351 hs2_clear_credentials(intf);
9352 wpa_command(intf, "SET hessid 00:00:00:00:00:00");
9353 wpa_command(intf, "SET access_network_type 15");
9354
9355 static_ip_file(0, NULL, NULL, NULL);
9356 kill_dhcp_client(dut, intf);
9357 clear_ip_addr(dut, intf);
9358
9359 dut->er_oper_performed = 0;
9360 dut->er_oper_bssid[0] = '\0';
9361
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009362 if (dut->program == PROGRAM_LOC) {
9363 /* Disable Interworking by default */
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009364 wpa_command(get_station_ifname(dut), "SET interworking 0");
priyadharshini gowthamanad6cbba2016-10-04 10:39:58 -07009365 }
9366
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -07009367 if (dut->program == PROGRAM_MBO || dut->program == PROGRAM_HE) {
Ashwini Patil00402582017-04-13 12:29:39 +05309368 free(dut->non_pref_ch_list);
9369 dut->non_pref_ch_list = NULL;
Ashwini Patil5acd7382017-04-13 15:55:04 +05309370 free(dut->btm_query_cand_list);
9371 dut->btm_query_cand_list = NULL;
Ashwini Patilc63161e2017-04-13 16:30:23 +05309372 wpa_command(intf, "SET reject_btm_req_reason 0");
Ashwini Patila75de5a2017-04-13 16:35:05 +05309373 wpa_command(intf, "SET ignore_assoc_disallow 0");
Ashwini Patild174f2c2017-04-13 16:49:46 +05309374 wpa_command(intf, "SET gas_address3 0");
Ashwini Patil9183fdb2017-04-13 16:58:25 +05309375 wpa_command(intf, "SET roaming 1");
Ankita Bajaj1d974552018-09-18 16:56:44 +05309376 wpa_command(intf, "SET interworking 1");
Ashwini Patil00402582017-04-13 12:29:39 +05309377 }
9378
Jouni Malinen3c367e82017-06-23 17:01:47 +03009379 free(dut->rsne_override);
9380 dut->rsne_override = NULL;
9381
Jouni Malinen68143132017-09-02 02:34:08 +03009382 free(dut->sae_commit_override);
9383 dut->sae_commit_override = NULL;
Jouni Malinen4b3769d2019-10-10 16:20:29 +03009384 wpa_command(intf, "SET sae_pmkid_in_assoc 0");
Jouni Malinen11e55212019-11-22 21:46:59 +02009385 dut->sae_pwe = SAE_PWE_DEFAULT;
Jouni Malinen68143132017-09-02 02:34:08 +03009386
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009387 dut->sta_associate_wait_connect = 0;
9388 dut->server_cert_hash[0] = '\0';
Jouni Malinen37d5c692019-08-19 16:56:55 +03009389 dut->server_cert_tod = 0;
Jouni Malinen134fe3c2019-06-12 04:16:49 +03009390 dut->sta_tod_policy = 0;
9391
Jouni Malinend86e5822017-08-29 03:55:32 +03009392 dut->dpp_conf_id = -1;
Jouni Malinenb1dd21f2017-11-13 19:14:29 +02009393 free(dut->dpp_peer_uri);
9394 dut->dpp_peer_uri = NULL;
Jouni Malinen63d50412017-11-24 11:55:38 +02009395 dut->dpp_local_bootstrap = -1;
Jouni Malinen5011fb52017-12-05 21:00:15 +02009396 wpa_command(intf, "SET dpp_config_processing 2");
Jouni Malinen90776b12020-05-04 15:34:46 +03009397 wpa_command(intf, "SET dpp_mud_url ");
Jouni Malinend86e5822017-08-29 03:55:32 +03009398
Jouni Malinenfac9cad2017-10-10 18:35:55 +03009399 wpa_command(intf, "VENDOR_ELEM_REMOVE 13 *");
9400
vamsi krishnaa2799492017-12-05 14:28:01 +05309401 if (dut->program == PROGRAM_OCE) {
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309402 wpa_command(intf, "SET oce 1");
vamsi krishnaa2799492017-12-05 14:28:01 +05309403 wpa_command(intf, "SET disable_fils 0");
Ankita Bajaj1bde7942018-01-09 19:15:01 +05309404 wpa_command(intf, "FILS_HLP_REQ_FLUSH");
9405 dut->fils_hlp = 0;
9406#ifdef ANDROID
9407 hlp_thread_cleanup(dut);
9408#endif /* ANDROID */
vamsi krishnaa2799492017-12-05 14:28:01 +05309409 }
Ankita Bajaja2cb5672017-10-25 16:08:28 +05309410
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309411 if (dut->program == PROGRAM_QM) {
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309412 wpa_command(intf, "SET interworking 1");
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309413 wpa_command(intf, "SET enable_dscp_policy_capa 1");
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +05309414 dut->qm_domain_name[0] = '\0';
Veerendranath Jakkama16cdc82021-09-12 16:44:22 +05309415 dut->reject_dscp_policies = 0;
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +05309416 dut->num_dscp_status = 0;
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309417 snprintf(buf, sizeof(buf),
9418 "ip -6 route replace fe80::/64 dev %s table local",
9419 intf);
9420 if (system(buf) != 0)
9421 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to run: %s",
9422 buf);
Veerendranath Jakkam9ceb3b12021-09-10 03:18:17 +05309423
9424 stop_dscp_policy_mon_thread(dut);
9425 clear_all_dscp_policies(dut);
Veerendranath Jakkamea7f0692021-08-11 19:13:12 +05309426 }
Vamsi Krishnaf642d6a2020-03-27 12:33:14 +05309427
Jouni Malinen8179fee2019-03-28 03:19:47 +02009428 dut->akm_values = 0;
Shivani Baranwal7aa48602021-09-29 10:53:38 +05309429
9430#ifdef NL80211_SUPPORT
9431 if (get_driver_type(dut) == DRIVER_WCN)
9432 sta_config_params(dut, intf, STA_SET_FT_DS, 0);
9433#endif /* NL80211_SUPPORT */
9434
Jouni Malinen6a7c9b42019-08-20 00:15:59 +03009435 dut->sta_ft_ds = 0;
Jouni Malinen8179fee2019-03-28 03:19:47 +02009436
Sunil Dutt076081f2018-02-05 19:45:50 +05309437#ifdef NL80211_SUPPORT
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009438 if (get_driver_type(dut) == DRIVER_WCN &&
Sunil Dutt44595082018-02-12 19:41:45 +05309439 dut->config_rsnie == 1) {
9440 dut->config_rsnie = 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +05309441 sta_config_params(dut, intf, STA_SET_RSNIE, 0);
Sunil Dutt076081f2018-02-05 19:45:50 +05309442 }
9443#endif /* NL80211_SUPPORT */
9444
Sunil Duttfebf8a82018-02-09 18:50:13 +05309445 if (dev_role && strcasecmp(dev_role, "STA-CFON") == 0) {
9446 dut->dev_role = DEVROLE_STA_CFON;
9447 return sta_cfon_reset_default(dut, conn, cmd);
9448 }
9449
Jouni Malinen439352d2018-09-13 03:42:23 +03009450 wpa_command(intf, "SET setband AUTO");
9451
Veerendranath Jakkamc1f71b62021-01-23 03:09:51 +05309452 ret = wpa_command_resp(intf, "GET_CAPABILITY ocv", resp, sizeof(resp));
9453 dut->ocvc = ret == 0 && strncmp(resp, "supported", 9) == 0;
9454
9455 ret = wpa_command_resp(intf, "GET_CAPABILITY beacon_prot", resp,
9456 sizeof(resp));
9457 dut->beacon_prot = ret == 0 && strncmp(resp, "supported", 9) == 0;
9458
Veerendranath Jakkam47867202020-12-21 01:53:52 +05309459 if (sta_set_client_privacy(dut, conn, intf,
9460 dut->program == PROGRAM_WPA3 &&
9461 dut->device_type == STA_dut &&
9462 dut->client_privacy_default)) {
9463 sigma_dut_print(dut, DUT_MSG_ERROR,
9464 "Failed to set client privacy functionality");
9465 /* sta_reset_default command is not really supposed to fail,
9466 * so allow this to continue. */
9467 }
9468
Veerendranath Jakkamca239592021-10-11 20:48:00 +05309469 if (get_driver_type(dut) == DRIVER_WCN)
9470 wcn_set_ignore_h2e_rsnxe(dut, intf, 0);
9471
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +05309472 dut->saquery_oci_freq = 0;
Shivani Baranwalebde8f62021-10-19 12:26:02 +05309473 dut->prev_disable_scs_support = 0;
9474 dut->prev_disable_mscs_support = 0;
Vamsi Krishnac1633d22020-05-06 18:31:21 +05309475
Sunil Duttfebf8a82018-02-09 18:50:13 +05309476 if (dut->program != PROGRAM_VHT)
9477 return cmd_sta_p2p_reset(dut, conn, cmd);
9478
Priyadharshini Gowthamana7dfd492015-11-09 14:34:08 -08009479 return 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009480}
9481
9482
Jouni Malinenf7222712019-06-13 01:50:21 +03009483static enum sigma_cmd_result cmd_sta_get_events(struct sigma_dut *dut,
9484 struct sigma_conn *conn,
9485 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009486{
9487 const char *program = get_param(cmd, "Program");
9488
9489 if (program == NULL)
9490 return -1;
9491#ifdef ANDROID_NAN
9492 if (strcasecmp(program, "NAN") == 0)
9493 return nan_cmd_sta_get_events(dut, conn, cmd);
9494#endif /* ANDROID_NAN */
9495 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9496 return 0;
9497}
9498
9499
Jouni Malinen82905202018-04-29 17:20:10 +03009500static int sta_exec_action_url(struct sigma_dut *dut, struct sigma_conn *conn,
9501 struct sigma_cmd *cmd)
9502{
9503 const char *url = get_param(cmd, "url");
9504 const char *method = get_param(cmd, "method");
9505 pid_t pid;
9506 int status;
9507
9508 if (!url || !method)
9509 return -1;
9510
9511 /* TODO: Add support for method,post */
9512 if (strcasecmp(method, "get") != 0) {
9513 send_resp(dut, conn, SIGMA_ERROR,
9514 "ErrorCode,Unsupported method");
9515 return 0;
9516 }
9517
9518 pid = fork();
9519 if (pid < 0) {
9520 perror("fork");
9521 return -1;
9522 }
9523
9524 if (pid == 0) {
9525 char * argv[5] = { "wget", "-O", "/dev/null",
9526 (char *) url, NULL };
9527
9528 execv("/usr/bin/wget", argv);
9529 perror("execv");
9530 exit(0);
9531 return -1;
9532 }
9533
9534 if (waitpid(pid, &status, 0) < 0) {
9535 perror("waitpid");
9536 return -1;
9537 }
9538
9539 if (WIFEXITED(status)) {
9540 const char *errmsg;
9541
9542 if (WEXITSTATUS(status) == 0)
9543 return 1;
9544 sigma_dut_print(dut, DUT_MSG_INFO, "wget exit status %d",
9545 WEXITSTATUS(status));
9546 switch (WEXITSTATUS(status)) {
9547 case 4:
9548 errmsg = "errmsg,Network failure";
9549 break;
9550 case 8:
9551 errmsg = "errmsg,Server issued an error response";
9552 break;
9553 default:
9554 errmsg = "errmsg,Unknown failure from wget";
9555 break;
9556 }
9557 send_resp(dut, conn, SIGMA_ERROR, errmsg);
9558 return 0;
9559 }
9560
9561 send_resp(dut, conn, SIGMA_ERROR, "errmsg,Unknown failure");
9562 return 0;
9563}
9564
9565
Jouni Malinenf7222712019-06-13 01:50:21 +03009566static enum sigma_cmd_result cmd_sta_exec_action(struct sigma_dut *dut,
9567 struct sigma_conn *conn,
9568 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009569{
9570 const char *program = get_param(cmd, "Prog");
9571
Jouni Malinen82905202018-04-29 17:20:10 +03009572 if (program && !get_param(cmd, "interface"))
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009573 return -1;
9574#ifdef ANDROID_NAN
Jouni Malinen82905202018-04-29 17:20:10 +03009575 if (program && strcasecmp(program, "NAN") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009576 return nan_cmd_sta_exec_action(dut, conn, cmd);
9577#endif /* ANDROID_NAN */
Jouni Malinen82905202018-04-29 17:20:10 +03009578
9579 if (program && strcasecmp(program, "Loc") == 0)
priyadharshini gowthamand66913a2016-07-29 15:11:17 -07009580 return loc_cmd_sta_exec_action(dut, conn, cmd);
Jouni Malinen82905202018-04-29 17:20:10 +03009581
9582 if (get_param(cmd, "url"))
9583 return sta_exec_action_url(dut, conn, cmd);
9584
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009585 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported parameter");
9586 return 0;
9587}
9588
9589
Jouni Malinenf7222712019-06-13 01:50:21 +03009590static enum sigma_cmd_result cmd_sta_set_11n(struct sigma_dut *dut,
9591 struct sigma_conn *conn,
9592 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009593{
9594 const char *intf = get_param(cmd, "Interface");
9595 const char *val, *mcs32, *rate;
9596
9597 val = get_param(cmd, "GREENFIELD");
9598 if (val) {
9599 if (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0) {
9600 /* Enable GD */
9601 send_resp(dut, conn, SIGMA_ERROR,
9602 "ErrorCode,GF not supported");
9603 return 0;
9604 }
9605 }
9606
9607 val = get_param(cmd, "SGI20");
9608 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009609 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009610 case DRIVER_ATHEROS:
9611 ath_sta_set_sgi(dut, intf, val);
9612 break;
9613 default:
9614 send_resp(dut, conn, SIGMA_ERROR,
9615 "ErrorCode,SGI20 not supported");
9616 return 0;
9617 }
9618 }
9619
9620 mcs32 = get_param(cmd, "MCS32"); /* HT Duplicate Mode Enable/Disable */
9621 rate = get_param(cmd, "MCS_FIXEDRATE"); /* Fixed MCS rate (0..31) */
9622 if (mcs32 && rate) {
9623 /* TODO */
9624 send_resp(dut, conn, SIGMA_ERROR,
9625 "ErrorCode,MCS32,MCS_FIXEDRATE not supported");
9626 return 0;
9627 } else if (mcs32 && !rate) {
9628 /* TODO */
9629 send_resp(dut, conn, SIGMA_ERROR,
9630 "ErrorCode,MCS32 not supported");
9631 return 0;
9632 } else if (!mcs32 && rate) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +02009633 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009634 case DRIVER_ATHEROS:
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -07009635 novap_reset(dut, intf, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +02009636 ath_sta_set_11nrates(dut, intf, rate);
9637 break;
9638 default:
9639 send_resp(dut, conn, SIGMA_ERROR,
9640 "ErrorCode,MCS32_FIXEDRATE not supported");
9641 return 0;
9642 }
9643 }
9644
9645 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
9646}
9647
9648
Arif Hussain7b47d2d2018-05-09 10:44:02 -07009649static void cmd_set_max_he_mcs(struct sigma_dut *dut, const char *intf,
9650 int mcs_config)
9651{
9652#ifdef NL80211_SUPPORT
9653 int ret;
9654
9655 switch (mcs_config) {
9656 case HE_80_MCS0_7:
9657 case HE_80_MCS0_9:
9658 case HE_80_MCS0_11:
9659 ret = sta_set_he_mcs(dut, intf, mcs_config);
9660 if (ret) {
9661 sigma_dut_print(dut, DUT_MSG_ERROR,
9662 "cmd_set_max_he_mcs: Setting of MCS:%d failed, ret:%d",
9663 mcs_config, ret);
9664 }
9665 break;
9666 default:
9667 sigma_dut_print(dut, DUT_MSG_ERROR,
9668 "cmd_set_max_he_mcs: Invalid mcs %d",
9669 mcs_config);
9670 break;
9671 }
9672#else /* NL80211_SUPPORT */
9673 sigma_dut_print(dut, DUT_MSG_ERROR,
9674 "max HE MCS cannot be changed without NL80211_SUPPORT defined");
9675#endif /* NL80211_SUPPORT */
9676}
9677
9678
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009679struct wait_event {
9680 struct sigma_dut *dut;
9681 int cmd;
9682 unsigned int twt_op;
9683};
9684
9685#ifdef NL80211_SUPPORT
9686
9687static int twt_event_handler(struct nl_msg *msg, void *arg)
9688{
9689 struct wait_event *wait = arg;
9690 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
9691 struct nlattr *tb[NL80211_ATTR_MAX + 1];
9692 uint32_t subcmd;
9693 uint8_t *data = NULL;
9694 size_t len = 0;
9695 struct nlattr *twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX + 1];
9696 struct nlattr *twt_status[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
9697 int cmd_id;
9698 unsigned char val;
9699
9700 if (!wait)
9701 return NL_SKIP;
9702
9703 if (gnlh->cmd != NL80211_CMD_VENDOR) {
9704 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9705 "%s: NL cmd is not vendor %d", __func__,
9706 gnlh->cmd);
9707 return NL_SKIP;
9708 }
9709
9710 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
9711 genlmsg_attrlen(gnlh, 0), NULL);
9712
9713 if (!tb[NL80211_ATTR_VENDOR_ID] || !tb[NL80211_ATTR_VENDOR_SUBCMD]) {
9714 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9715 "%s: vendor ID not found", __func__);
9716 return NL_SKIP;
9717 }
9718 subcmd = nla_get_u32(tb[NL80211_ATTR_VENDOR_SUBCMD]);
9719
9720 if (subcmd != QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) {
9721 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9722 "%s: Not a TWT_cmd %d", __func__, subcmd);
9723 return NL_SKIP;
9724 }
9725 if (tb[NL80211_ATTR_VENDOR_DATA]) {
9726 data = nla_data(tb[NL80211_ATTR_VENDOR_DATA]);
9727 len = nla_len(tb[NL80211_ATTR_VENDOR_DATA]);
9728 } else {
9729 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9730 "%s: vendor data not present", __func__);
9731 return NL_SKIP;
9732 }
9733 if (!data || !len) {
9734 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9735 "Invalid vendor data or len");
9736 return NL_SKIP;
9737 }
9738 sigma_dut_print(wait->dut, DUT_MSG_DEBUG,
9739 "event data len %ld", len);
9740 hex_dump(wait->dut, data, len);
9741 if (nla_parse(twt_rsp, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_MAX,
9742 (struct nlattr *) data, len, NULL)) {
9743 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9744 "vendor data parse error");
9745 return NL_SKIP;
9746 }
9747
9748 val = nla_get_u8(twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION]);
9749 if (val != wait->twt_op) {
9750 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9751 "Invalid TWT operation, expected %d, rcvd %d",
9752 wait->twt_op, val);
9753 return NL_SKIP;
9754 }
9755 if (nla_parse_nested(twt_status, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
9756 twt_rsp[QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS],
9757 NULL)) {
9758 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9759 "nla_parse failed for TWT event");
9760 return NL_SKIP;
9761 }
9762
9763 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS;
9764 if (!twt_status[cmd_id]) {
9765 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9766 "%s TWT resp status missing", __func__);
9767 wait->cmd = -1;
9768 } else {
9769 val = nla_get_u8(twt_status[cmd_id]);
9770 if (val != QCA_WLAN_VENDOR_TWT_STATUS_OK) {
9771 sigma_dut_print(wait->dut, DUT_MSG_ERROR,
9772 "%s TWT resp status %d", __func__, val);
9773 wait->cmd = -1;
9774 } else {
9775 wait->cmd = 1;
9776 }
9777 }
9778
9779 return NL_SKIP;
9780}
9781
9782
9783static int wait_on_nl_socket(struct nl_sock *sock, struct sigma_dut *dut,
9784 unsigned int timeout)
9785{
9786 fd_set read_fd_set;
9787 int retval;
9788 int sock_fd;
9789 struct timeval time_out;
9790
9791 time_out.tv_sec = timeout;
9792 time_out.tv_usec = 0;
9793
9794 FD_ZERO(&read_fd_set);
9795
9796 if (!sock)
9797 return -1;
9798
9799 sock_fd = nl_socket_get_fd(sock);
9800 FD_SET(sock_fd, &read_fd_set);
9801
9802 retval = select(sock_fd + 1, &read_fd_set, NULL, NULL, &time_out);
9803
9804 if (retval == 0)
9805 sigma_dut_print(dut, DUT_MSG_ERROR,
9806 "%s: TWT event response timedout", __func__);
9807
9808 if (retval < 0)
9809 sigma_dut_print(dut, DUT_MSG_ERROR, "%s:no NL msgs, ret=%d",
9810 __func__, retval);
9811
9812 return retval;
9813}
9814
9815
9816#define TWT_ASYNC_EVENT_WAIT_TIME_SEC 6
9817
9818static int twt_async_event_wait(struct sigma_dut *dut, unsigned int twt_op)
9819{
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009820 struct nl_cb *cb = NULL;
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009821 int err_code = 0, select_retval = 0;
9822 struct wait_event wait_info;
9823
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -08009824 if (dut->nl_ctx->event_sock)
9825 cb = nl_socket_get_cb(dut->nl_ctx->event_sock);
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009826 if (!cb) {
9827 sigma_dut_print(dut, DUT_MSG_ERROR,
9828 "event callback not found");
9829 return ERROR_SEND_STATUS;
9830 }
9831
9832 wait_info.cmd = 0;
9833 wait_info.dut = dut;
9834 wait_info.twt_op = twt_op;
9835
9836 nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, twt_event_handler, &wait_info);
9837
9838 while (!wait_info.cmd) {
9839 select_retval = wait_on_nl_socket(
9840 dut->nl_ctx->event_sock, dut,
9841 TWT_ASYNC_EVENT_WAIT_TIME_SEC);
9842
9843 if (select_retval > 0) {
9844 err_code = nl_recvmsgs(dut->nl_ctx->event_sock, cb);
9845 if (err_code < 0) {
9846 sigma_dut_print(dut, DUT_MSG_ERROR,
9847 "%s: nl rcv failed, err_code %d",
9848 __func__, err_code);
9849 break;
9850 }
9851 } else {
9852 sigma_dut_print(dut, DUT_MSG_ERROR,
9853 "%s: wait on socket failed %d",
9854 __func__, select_retval);
9855 err_code = 1;
9856 break;
9857 }
9858
9859 }
9860 nl_cb_put(cb);
9861
9862 if (wait_info.cmd < 0)
9863 err_code = 1;
9864
9865 sigma_dut_print(dut, DUT_MSG_DEBUG,
9866 "%s: rcvd cmd %d, err_code %d, s_ret %d",
9867 __func__, wait_info.cmd, err_code, select_retval);
9868
9869 return err_code;
9870}
9871
9872#endif /* NL80211_SUPPORT */
9873
9874
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009875static int sta_twt_send_suspend(struct sigma_dut *dut, struct sigma_conn *conn,
9876 struct sigma_cmd *cmd)
9877{
9878#ifdef NL80211_SUPPORT
9879 struct nlattr *attr, *attr1;
9880 struct nl_msg *msg;
9881 int ifindex, ret;
9882 const char *intf = get_param(cmd, "Interface");
9883
9884 ifindex = if_nametoindex(intf);
9885 if (ifindex == 0) {
9886 sigma_dut_print(dut, DUT_MSG_ERROR,
9887 "%s: Index for interface %s failed",
9888 __func__, intf);
9889 return ERROR_SEND_STATUS;
9890 }
9891
9892 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9893 NL80211_CMD_VENDOR)) ||
9894 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9895 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9896 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9897 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9898 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9899 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9900 QCA_WLAN_TWT_SUSPEND) ||
9901 !(attr1 = nla_nest_start(msg,
Kiran Kumar Lokere7ede00c2021-08-09 00:59:52 -07009902 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS))) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009903 sigma_dut_print(dut, DUT_MSG_ERROR,
9904 "%s: err in adding vendor_cmd and vendor_data",
9905 __func__);
9906 nlmsg_free(msg);
9907 return ERROR_SEND_STATUS;
9908 }
9909 nla_nest_end(msg, attr1);
9910 nla_nest_end(msg, attr);
9911
9912 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9913 if (ret) {
9914 sigma_dut_print(dut, DUT_MSG_ERROR,
9915 "%s: err in send_and_recv_msgs, ret=%d",
9916 __func__, ret);
9917 }
9918
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009919 if (!dut->sta_async_twt_supp)
9920 return ret;
9921
9922 return twt_async_event_wait(dut, QCA_WLAN_TWT_SUSPEND);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009923#else /* NL80211_SUPPORT */
9924 sigma_dut_print(dut, DUT_MSG_ERROR,
9925 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9926 return ERROR_SEND_STATUS;
9927#endif /* NL80211_SUPPORT */
9928}
9929
9930
9931static int sta_twt_send_nudge(struct sigma_dut *dut, struct sigma_conn *conn,
9932 struct sigma_cmd *cmd,
9933 unsigned int suspend_duration)
9934{
9935#ifdef NL80211_SUPPORT
9936 struct nlattr *attr, *attr1;
9937 struct nl_msg *msg;
9938 int ifindex, ret;
9939 const char *intf = get_param(cmd, "Interface");
9940 int next_twt_size = 1;
9941
9942 ifindex = if_nametoindex(intf);
9943 if (ifindex == 0) {
9944 sigma_dut_print(dut, DUT_MSG_ERROR,
9945 "%s: Index for interface %s failed",
9946 __func__, intf);
9947 return ERROR_SEND_STATUS;
9948 }
9949
9950 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
9951 NL80211_CMD_VENDOR)) ||
9952 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
9953 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
9954 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
9955 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
9956 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
9957 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
9958 QCA_WLAN_TWT_NUDGE) ||
9959 !(attr1 = nla_nest_start(msg,
9960 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
9961 (suspend_duration &&
9962 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME,
9963 suspend_duration)) ||
9964 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_NEXT_TWT_SIZE,
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -07009965 next_twt_size) ||
9966 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, 0)) {
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009967 sigma_dut_print(dut, DUT_MSG_ERROR,
9968 "%s: err in adding vendor_cmd and vendor_data",
9969 __func__);
9970 nlmsg_free(msg);
9971 return ERROR_SEND_STATUS;
9972 }
9973 nla_nest_end(msg, attr1);
9974 nla_nest_end(msg, attr);
9975
9976 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
9977 if (ret) {
9978 sigma_dut_print(dut, DUT_MSG_ERROR,
9979 "%s: err in send_and_recv_msgs, ret=%d",
9980 __func__, ret);
9981 }
9982
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -07009983 if (!dut->sta_async_twt_supp)
9984 return ret;
9985
9986 return twt_async_event_wait(dut, QCA_WLAN_TWT_NUDGE);
Srinivas Girigowda6707f032020-10-26 15:24:46 -07009987#else /* NL80211_SUPPORT */
9988 sigma_dut_print(dut, DUT_MSG_ERROR,
9989 "TWT suspend cannot be done without NL80211_SUPPORT defined");
9990 return ERROR_SEND_STATUS;
9991#endif /* NL80211_SUPPORT */
9992}
9993
9994
9995static int sta_twt_suspend_or_nudge(struct sigma_dut *dut,
9996 struct sigma_conn *conn,
9997 struct sigma_cmd *cmd)
9998{
9999 const char *val;
10000
10001 val = get_param(cmd, "TWT_SuspendDuration");
10002 if (val) {
10003 unsigned int suspend_duration;
10004
10005 suspend_duration = atoi(val);
10006 suspend_duration = suspend_duration * 1000 * 1000;
10007 return sta_twt_send_nudge(dut, conn, cmd, suspend_duration);
10008 }
10009
10010 return sta_twt_send_suspend(dut, conn, cmd);
10011}
10012
10013
10014static int sta_twt_resume(struct sigma_dut *dut, struct sigma_conn *conn,
10015 struct sigma_cmd *cmd)
10016{
10017#ifdef NL80211_SUPPORT
10018 struct nlattr *attr, *attr1;
10019 struct nl_msg *msg;
10020 int ifindex, ret;
10021 const char *intf = get_param(cmd, "Interface");
10022 int next2_twt_size = 1;
10023 unsigned int resume_duration = 0;
10024 const char *val;
10025
10026 ifindex = if_nametoindex(intf);
10027 if (ifindex == 0) {
10028 sigma_dut_print(dut, DUT_MSG_ERROR,
10029 "%s: Index for interface %s failed",
10030 __func__, intf);
10031 return ERROR_SEND_STATUS;
10032 }
10033
10034 val = get_param(cmd, "TWT_ResumeDuration");
10035 if (val) {
10036 resume_duration = atoi(val);
10037 resume_duration = resume_duration * 1000 * 1000;
10038 }
10039
10040 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10041 NL80211_CMD_VENDOR)) ||
10042 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10043 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10044 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10045 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
10046 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10047 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10048 QCA_WLAN_TWT_RESUME) ||
10049 !(attr1 = nla_nest_start(msg,
10050 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
10051 (resume_duration &&
10052 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT2_TWT,
10053 resume_duration)) ||
10054 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_NEXT_TWT_SIZE,
10055 next2_twt_size)) {
10056 sigma_dut_print(dut, DUT_MSG_ERROR,
10057 "%s: err in adding vendor_cmd and vendor_data",
10058 __func__);
10059 nlmsg_free(msg);
10060 return ERROR_SEND_STATUS;
10061 }
10062 nla_nest_end(msg, attr1);
10063 nla_nest_end(msg, attr);
10064
10065 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10066 if (ret) {
10067 sigma_dut_print(dut, DUT_MSG_ERROR,
10068 "%s: err in send_and_recv_msgs, ret=%d",
10069 __func__, ret);
10070 }
10071
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010072 if (!dut->sta_async_twt_supp)
10073 return ret;
10074
10075 return twt_async_event_wait(dut, QCA_WLAN_TWT_RESUME);
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010076#else /* NL80211_SUPPORT */
10077 sigma_dut_print(dut, DUT_MSG_ERROR,
10078 "TWT resume cannot be done without NL80211_SUPPORT defined");
10079 return ERROR_SEND_STATUS;
10080#endif /* NL80211_SUPPORT */
10081}
10082
10083
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010084#define TWT_REQUEST_CMD 0
10085#define TWT_SUGGEST_CMD 1
10086#define TWT_DEMAND_CMD 2
10087
Arif Hussain480d5f42019-03-12 14:40:42 -070010088static int sta_twt_request(struct sigma_dut *dut, struct sigma_conn *conn,
10089 struct sigma_cmd *cmd)
10090{
10091#ifdef NL80211_SUPPORT
10092 struct nlattr *params;
10093 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010094 struct nl_msg *msg;
10095 int ifindex, ret;
10096 const char *val;
10097 const char *intf = get_param(cmd, "Interface");
10098 int wake_interval_exp = 10, nominal_min_wake_dur = 255,
10099 wake_interval_mantissa = 512;
10100 int flow_type = 0, twt_trigger = 0, target_wake_time = 0,
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010101 protection = 0, cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010102 int bcast_twt = 0;
10103 int bcast_twt_id = 0, bcast_twt_recommdn = 0, bcast_twt_persis = 0;
Arif Hussain480d5f42019-03-12 14:40:42 -070010104
10105 ifindex = if_nametoindex(intf);
10106 if (ifindex == 0) {
10107 sigma_dut_print(dut, DUT_MSG_ERROR,
10108 "%s: Index for interface %s failed",
10109 __func__, intf);
10110 return -1;
10111 }
10112
10113 val = get_param(cmd, "FlowType");
10114 if (val) {
10115 flow_type = atoi(val);
10116 if (flow_type != 0 && flow_type != 1) {
10117 sigma_dut_print(dut, DUT_MSG_ERROR,
10118 "TWT: Invalid FlowType %d", flow_type);
10119 return -1;
10120 }
10121 }
10122
10123 val = get_param(cmd, "TWT_Trigger");
10124 if (val) {
10125 twt_trigger = atoi(val);
10126 if (twt_trigger != 0 && twt_trigger != 1) {
10127 sigma_dut_print(dut, DUT_MSG_ERROR,
10128 "TWT: Invalid TWT_Trigger %d",
10129 twt_trigger);
10130 return -1;
10131 }
10132 }
10133
10134 val = get_param(cmd, "Protection");
10135 if (val) {
10136 protection = atoi(val);
10137 if (protection != 0 && protection != 1) {
10138 sigma_dut_print(dut, DUT_MSG_ERROR,
10139 "TWT: Invalid Protection %d",
10140 protection);
10141 return -1;
10142 }
10143 }
10144
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010145 val = get_param(cmd, "SetupCommand");
10146 if (val) {
10147 cmd_type = atoi(val);
10148 if (cmd_type == TWT_REQUEST_CMD)
10149 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_REQUEST;
10150 else if (cmd_type == TWT_SUGGEST_CMD)
10151 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_SUGGEST;
10152 else if (cmd_type == TWT_DEMAND_CMD)
10153 cmd_type = QCA_WLAN_VENDOR_TWT_SETUP_DEMAND;
10154 else
10155 sigma_dut_print(dut, DUT_MSG_ERROR,
10156 "Default suggest is used for cmd %d",
10157 cmd_type);
10158 }
10159
Arif Hussain480d5f42019-03-12 14:40:42 -070010160 val = get_param(cmd, "TargetWakeTime");
10161 if (val)
10162 target_wake_time = atoi(val);
10163
10164 val = get_param(cmd, "WakeIntervalMantissa");
10165 if (val)
10166 wake_interval_mantissa = atoi(val);
10167
10168 val = get_param(cmd, "WakeIntervalExp");
10169 if (val)
10170 wake_interval_exp = atoi(val);
10171
10172 val = get_param(cmd, "NominalMinWakeDur");
10173 if (val)
10174 nominal_min_wake_dur = atoi(val);
10175
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010176 val = get_param(cmd, "BTWT_ID");
10177 if (val) {
10178 bcast_twt_id = atoi(val);
10179 bcast_twt = 1;
10180 }
10181
10182 val = get_param(cmd, "BTWT_Persistence");
10183 if (val) {
10184 bcast_twt_persis = atoi(val);
10185 bcast_twt = 1;
10186 }
10187
10188 val = get_param(cmd, "BTWT_Recommendation");
10189 if (val) {
10190 bcast_twt_recommdn = atoi(val);
10191 bcast_twt = 1;
10192 }
10193
10194 if (bcast_twt)
10195 sigma_dut_print(dut, DUT_MSG_DEBUG,
10196 "BCAST_TWT: ID %d, RECOMM %d, PERSIS %d",
10197 bcast_twt_id, bcast_twt_recommdn,
10198 bcast_twt_persis);
10199
Arif Hussain480d5f42019-03-12 14:40:42 -070010200 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10201 NL80211_CMD_VENDOR)) ||
10202 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10203 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10204 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010205 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010206 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010207 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10208 QCA_WLAN_TWT_SET) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010209 !(params = nla_nest_start(
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010210 msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010211 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP,
10212 wake_interval_exp) ||
Kiran Kumar Lokerebd396102020-04-27 12:01:09 -070010213 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE, cmd_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010214 (twt_trigger &&
10215 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010216 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE,
10217 flow_type) ||
Kiran Kumar Lokere2cffae52019-09-26 18:44:15 -070010218 (protection &&
10219 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010220 (bcast_twt &&
10221 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10222 (bcast_twt &&
10223 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10224 bcast_twt_id)) ||
10225 (bcast_twt &&
10226 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_PERSISTENCE,
10227 bcast_twt_persis)) ||
10228 (bcast_twt &&
10229 nla_put_u8(msg,
10230 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_RECOMMENDATION,
10231 bcast_twt_recommdn)) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010232 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME,
10233 target_wake_time) ||
10234 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION,
10235 nominal_min_wake_dur) ||
10236 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA,
10237 wake_interval_mantissa)) {
10238 sigma_dut_print(dut, DUT_MSG_ERROR,
10239 "%s: err in adding vendor_cmd and vendor_data",
10240 __func__);
10241 nlmsg_free(msg);
10242 return -1;
10243 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010244 nla_nest_end(msg, params);
10245 nla_nest_end(msg, attr);
10246
10247 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10248 if (ret) {
10249 sigma_dut_print(dut, DUT_MSG_ERROR,
10250 "%s: err in send_and_recv_msgs, ret=%d",
10251 __func__, ret);
10252 }
10253
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010254 if (!dut->sta_async_twt_supp)
10255 return ret;
10256
10257 return twt_async_event_wait(dut, QCA_WLAN_TWT_SET);
Arif Hussain480d5f42019-03-12 14:40:42 -070010258#else /* NL80211_SUPPORT */
10259 sigma_dut_print(dut, DUT_MSG_ERROR,
10260 "TWT request cannot be done without NL80211_SUPPORT defined");
10261 return -1;
10262#endif /* NL80211_SUPPORT */
10263}
10264
10265
10266static int sta_twt_teardown(struct sigma_dut *dut, struct sigma_conn *conn,
10267 struct sigma_cmd *cmd)
10268{
10269 #ifdef NL80211_SUPPORT
10270 struct nlattr *params;
10271 struct nlattr *attr;
Arif Hussain480d5f42019-03-12 14:40:42 -070010272 int ifindex, ret;
10273 struct nl_msg *msg;
10274 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010275 int bcast_twt = 0;
10276 int bcast_twt_id = 0;
10277 const char *val;
Arif Hussain480d5f42019-03-12 14:40:42 -070010278
10279 ifindex = if_nametoindex(intf);
10280 if (ifindex == 0) {
10281 sigma_dut_print(dut, DUT_MSG_ERROR,
10282 "%s: Index for interface %s failed",
10283 __func__, intf);
10284 return -1;
10285 }
10286
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010287 val = get_param(cmd, "BTWT_ID");
10288 if (val) {
10289 bcast_twt_id = atoi(val);
10290 bcast_twt = 1;
10291 }
10292
Arif Hussain480d5f42019-03-12 14:40:42 -070010293 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10294 NL80211_CMD_VENDOR)) ||
10295 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10296 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10297 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010298 QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010299 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010300 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
10301 QCA_WLAN_TWT_TERMINATE) ||
Arif Hussain480d5f42019-03-12 14:40:42 -070010302 !(params = nla_nest_start(
10303 msg,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010304 QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS)) ||
Kiran Kumar Lokere68c93de2021-06-24 01:06:47 -070010305 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE, 0) ||
10306 (bcast_twt &&
10307 nla_put_flag(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST)) ||
10308 (bcast_twt &&
10309 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST_ID,
10310 bcast_twt_id))) {
Arif Hussain480d5f42019-03-12 14:40:42 -070010311 sigma_dut_print(dut, DUT_MSG_ERROR,
10312 "%s: err in adding vendor_cmd and vendor_data",
10313 __func__);
10314 nlmsg_free(msg);
10315 return -1;
10316 }
Arif Hussain480d5f42019-03-12 14:40:42 -070010317 nla_nest_end(msg, params);
10318 nla_nest_end(msg, attr);
10319
10320 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10321 if (ret) {
10322 sigma_dut_print(dut, DUT_MSG_ERROR,
10323 "%s: err in send_and_recv_msgs, ret=%d",
10324 __func__, ret);
10325 }
10326
Kiran Kumar Lokeref61a7432021-06-24 00:19:19 -070010327 if (!dut->sta_async_twt_supp)
10328 return ret;
10329
10330 return twt_async_event_wait(dut, QCA_WLAN_TWT_TERMINATE);
Arif Hussain480d5f42019-03-12 14:40:42 -070010331#else /* NL80211_SUPPORT */
10332 sigma_dut_print(dut, DUT_MSG_ERROR,
10333 "TWT teardown cannot be done without NL80211_SUPPORT defined");
10334 return -1;
10335#endif /* NL80211_SUPPORT */
10336}
10337
10338
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080010339static int sta_transmit_omi(struct sigma_dut *dut, struct sigma_conn *conn,
10340 struct sigma_cmd *cmd)
10341{
10342#ifdef NL80211_SUPPORT
10343 struct nlattr *params;
10344 struct nlattr *attr;
10345 struct nlattr *attr1;
10346 struct nl_msg *msg;
10347 int ifindex, ret;
10348 const char *val;
10349 const char *intf = get_param(cmd, "Interface");
10350 uint8_t rx_nss = 0xFF, ch_bw = 0xFF, tx_nsts = 0xFF, ulmu_dis = 0,
10351 ulmu_data_dis = 0;
10352
10353 ifindex = if_nametoindex(intf);
10354 if (ifindex == 0) {
10355 sigma_dut_print(dut, DUT_MSG_ERROR,
10356 "%s: Index for interface %s failed",
10357 __func__, intf);
10358 return -1;
10359 }
10360 val = get_param(cmd, "OMCtrl_RxNSS");
10361 if (val)
10362 rx_nss = atoi(val);
10363
10364 val = get_param(cmd, "OMCtrl_ChnlWidth");
10365 if (val)
10366 ch_bw = atoi(val);
10367
10368 val = get_param(cmd, "OMCtrl_ULMUDisable");
10369 if (val)
10370 ulmu_dis = atoi(val);
10371
10372 val = get_param(cmd, "OMCtrl_TxNSTS");
10373 if (val)
10374 tx_nsts = atoi(val);
10375
10376 val = get_param(cmd, "OMCtrl_ULMUDataDisable");
10377 if (val)
10378 ulmu_data_dis = atoi(val);
10379
10380 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
10381 NL80211_CMD_VENDOR)) ||
10382 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
10383 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
10384 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
10385 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
10386 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10387 !(params = nla_nest_start(
10388 msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX)) ||
10389 !(attr1 = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
10390 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS, rx_nss) ||
10391 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW, ch_bw) ||
10392 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS, tx_nsts) ||
10393 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE,
10394 ulmu_data_dis) ||
10395 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE,
10396 ulmu_dis)) {
10397 sigma_dut_print(dut, DUT_MSG_ERROR,
10398 "%s: err in adding vendor_cmd and vendor_data",
10399 __func__);
10400 nlmsg_free(msg);
10401 return -1;
10402 }
10403 nla_nest_end(msg, attr1);
10404 nla_nest_end(msg, params);
10405 nla_nest_end(msg, attr);
10406
10407 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
10408 if (ret) {
10409 sigma_dut_print(dut, DUT_MSG_ERROR,
10410 "%s: err in send_and_recv_msgs, ret=%d",
10411 __func__, ret);
10412 }
10413
10414 return ret;
10415#else /* NL80211_SUPPORT */
10416 sigma_dut_print(dut, DUT_MSG_ERROR,
10417 "OMI TX cannot be processed without NL80211_SUPPORT defined");
10418 return -1;
10419#endif /* NL80211_SUPPORT */
10420}
10421
10422
Jouni Malinen224e3902021-06-09 16:41:27 +030010423static enum sigma_cmd_result
10424cmd_sta_set_wireless_vht(struct sigma_dut *dut, struct sigma_conn *conn,
10425 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010426{
10427 const char *intf = get_param(cmd, "Interface");
10428 const char *val;
Arif Hussaina37e9552018-06-20 17:05:59 -070010429 const char *program;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010430 int tkip = -1;
10431 int wep = -1;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010432 int iwpriv_status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010433
Arif Hussaina37e9552018-06-20 17:05:59 -070010434 program = get_param(cmd, "Program");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010435 val = get_param(cmd, "SGI80");
10436 if (val) {
10437 int sgi80;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010438 enum nl80211_txrate_gi gi_val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010439
10440 sgi80 = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080010441 if (sgi80)
10442 gi_val = NL80211_TXRATE_FORCE_LGI;
10443 else
10444 gi_val = NL80211_TXRATE_FORCE_SGI;
10445 if (sta_set_vht_gi(dut, intf, (u8) gi_val)) {
10446 sigma_dut_print(dut, DUT_MSG_INFO,
10447 "sta_set_vht_gi failed, using iwpriv");
10448 run_iwpriv(dut, intf, "shortgi %d", sgi80);
10449 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010450 }
10451
10452 val = get_param(cmd, "TxBF");
10453 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010454 switch (get_driver_type(dut)) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010455 case DRIVER_WCN:
10456 if (sta_set_tx_beamformee(dut, intf, 1)) {
10457 send_resp(dut, conn, SIGMA_ERROR,
10458 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010459 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010460 }
10461 break;
10462 case DRIVER_ATHEROS:
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010463 if (run_iwpriv(dut, intf, "vhtsubfee 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010464 send_resp(dut, conn, SIGMA_ERROR,
10465 "ErrorCode,Setting vhtsubfee failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010466 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010467 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010468 if (run_iwpriv(dut, intf, "vhtsubfer 1") < 0) {
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010469 send_resp(dut, conn, SIGMA_ERROR,
10470 "ErrorCode,Setting vhtsubfer failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030010471 return STATUS_SENT_ERROR;
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010472 }
10473 break;
10474 default:
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010475 sigma_dut_print(dut, DUT_MSG_ERROR,
Kiran Kumar Lokerecb57d822018-07-06 16:37:42 -070010476 "Unsupported driver type");
10477 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010478 }
10479 }
10480
10481 val = get_param(cmd, "MU_TxBF");
10482 if (val && (strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0)) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010483 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010484 case DRIVER_ATHEROS:
10485 ath_sta_set_txsp_stream(dut, intf, "1SS");
10486 ath_sta_set_rxsp_stream(dut, intf, "1SS");
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010487 run_iwpriv(dut, intf, "vhtmubfee 1");
10488 run_iwpriv(dut, intf, "vhtmubfer 1");
Sunil Duttae9e5d12018-06-29 11:50:47 +053010489 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010490 case DRIVER_WCN:
10491 if (wcn_sta_set_sp_stream(dut, intf, "1SS") < 0) {
10492 send_resp(dut, conn, SIGMA_ERROR,
10493 "ErrorCode,Failed to set RX/TXSP_STREAM");
Jouni Malinen224e3902021-06-09 16:41:27 +030010494 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010495 }
Sunil Duttae9e5d12018-06-29 11:50:47 +053010496 break;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010497 default:
10498 sigma_dut_print(dut, DUT_MSG_ERROR,
10499 "Setting SP_STREAM not supported");
10500 break;
10501 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010502 }
10503
10504 val = get_param(cmd, "LDPC");
10505 if (val) {
10506 int ldpc;
10507
10508 ldpc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010509 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", ldpc);
10510 if (iwpriv_status)
10511 sta_config_params(dut, intf, STA_SET_LDPC, ldpc);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010512 }
10513
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010514 val = get_param(cmd, "BCC");
10515 if (val) {
10516 int bcc;
10517
10518 bcc = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10519 /* use LDPC iwpriv itself to set bcc coding, bcc coding
10520 * is mutually exclusive to bcc */
Mohammad Asaad Akram50848402020-05-28 14:10:24 +053010521 iwpriv_status = run_iwpriv(dut, intf, "ldpc %d", !bcc);
10522 if (iwpriv_status)
10523 sta_config_params(dut, intf, STA_SET_LDPC, !bcc);
Amarnath Hullur Subramanyam7bae60e2018-01-31 03:46:50 -080010524 }
10525
Arif Hussain7b47d2d2018-05-09 10:44:02 -070010526 val = get_param(cmd, "MaxHE-MCS_1SS_RxMapLTE80");
10527 if (val && dut->sta_nss == 1)
10528 cmd_set_max_he_mcs(dut, intf, atoi(val));
10529
10530 val = get_param(cmd, "MaxHE-MCS_2SS_RxMapLTE80");
10531 if (val && dut->sta_nss == 2)
10532 cmd_set_max_he_mcs(dut, intf, atoi(val));
10533
Arif Hussainac6c5112018-05-25 17:34:00 -070010534 val = get_param(cmd, "MCS_FixedRate");
10535 if (val) {
10536#ifdef NL80211_SUPPORT
10537 int mcs, ratecode = 0;
10538 enum he_mcs_config mcs_config;
10539 int ret;
Jouni Malinenb9b671d2019-04-26 13:23:17 +030010540 char buf[60];
Arif Hussainac6c5112018-05-25 17:34:00 -070010541
10542 ratecode = (0x07 & dut->sta_nss) << 5;
10543 mcs = atoi(val);
10544 /* Add the MCS to the ratecode */
10545 if (mcs >= 0 && mcs <= 11) {
10546 ratecode += mcs;
10547 if (dut->device_type == STA_testbed &&
10548 mcs > 7 && mcs <= 11) {
10549 if (mcs <= 9)
10550 mcs_config = HE_80_MCS0_9;
10551 else
10552 mcs_config = HE_80_MCS0_11;
10553 ret = sta_set_he_mcs(dut, intf, mcs_config);
10554 if (ret) {
10555 sigma_dut_print(dut, DUT_MSG_ERROR,
10556 "MCS_FixedRate: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
10557 mcs, mcs_config, ret);
10558 }
10559 }
10560 snprintf(buf, sizeof(buf),
10561 "iwpriv %s set_11ax_rate 0x%03x",
10562 intf, ratecode);
10563 if (system(buf) != 0) {
10564 sigma_dut_print(dut, DUT_MSG_ERROR,
10565 "MCS_FixedRate: iwpriv setting of 11ax rates 0x%03x failed",
10566 ratecode);
10567 }
10568 } else {
10569 sigma_dut_print(dut, DUT_MSG_ERROR,
10570 "MCS_FixedRate: HE MCS %d not supported",
10571 mcs);
10572 }
10573#else /* NL80211_SUPPORT */
10574 sigma_dut_print(dut, DUT_MSG_ERROR,
10575 "MCS_FixedRate cannot be changed without NL80211_SUPPORT defined");
10576#endif /* NL80211_SUPPORT */
10577 }
10578
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010579 val = get_param(cmd, "opt_md_notif_ie");
10580 if (val) {
10581 char *result = NULL;
10582 char delim[] = ";";
10583 char token[30];
10584 int value, config_val = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010585 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010586
Peng Xub8fc5cc2017-05-10 17:27:28 -070010587 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010588 result = strtok_r(token, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010589
10590 /* Extract the NSS information */
10591 if (result) {
10592 value = atoi(result);
10593 switch (value) {
10594 case 1:
10595 config_val = 1;
10596 break;
10597 case 2:
10598 config_val = 3;
10599 break;
10600 case 3:
10601 config_val = 7;
10602 break;
10603 case 4:
10604 config_val = 15;
10605 break;
10606 default:
10607 config_val = 3;
10608 break;
10609 }
10610
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010611 run_iwpriv(dut, intf, "rxchainmask %d", config_val);
10612 run_iwpriv(dut, intf, "txchainmask %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010613
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010614 }
10615
10616 /* Extract the channel width information */
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010617 result = strtok_r(NULL, delim, &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010618 if (result) {
10619 value = atoi(result);
10620 switch (value) {
10621 case 20:
10622 config_val = 0;
10623 break;
10624 case 40:
10625 config_val = 1;
10626 break;
10627 case 80:
10628 config_val = 2;
10629 break;
10630 case 160:
10631 config_val = 3;
10632 break;
10633 default:
10634 config_val = 2;
10635 break;
10636 }
10637
10638 dut->chwidth = config_val;
10639
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010640 run_iwpriv(dut, intf, "chwidth %d", config_val);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010641 }
10642
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010643 run_iwpriv(dut, intf, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010644 }
10645
10646 val = get_param(cmd, "nss_mcs_cap");
10647 if (val) {
10648 int nss, mcs;
10649 char token[20];
10650 char *result = NULL;
10651 unsigned int vht_mcsmap = 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010652 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010653
Peng Xub8fc5cc2017-05-10 17:27:28 -070010654 strlcpy(token, val, sizeof(token));
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010655 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010656 if (!result) {
10657 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010658 "NSS not specified");
10659 send_resp(dut, conn, SIGMA_ERROR,
10660 "errorCode,NSS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010661 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010662 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010663 nss = atoi(result);
10664
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010665 run_iwpriv(dut, intf, "nss %d", nss);
Arif Hussainac6c5112018-05-25 17:34:00 -070010666 dut->sta_nss = nss;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010667
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010668 result = strtok_r(NULL, ";", &saveptr);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010669 if (result == NULL) {
10670 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010671 "MCS not specified");
10672 send_resp(dut, conn, SIGMA_ERROR,
10673 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010674 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010675 }
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053010676 result = strtok_r(result, "-", &saveptr);
10677 result = strtok_r(NULL, "-", &saveptr);
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010678 if (!result) {
10679 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010680 "MCS not specified");
10681 send_resp(dut, conn, SIGMA_ERROR,
10682 "errorCode,MCS not specified");
Jouni Malinen224e3902021-06-09 16:41:27 +030010683 return STATUS_SENT_ERROR;
Pradeep Reddy POTTETIcd649a22016-01-29 12:55:59 +053010684 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010685 mcs = atoi(result);
10686
Arif Hussaina37e9552018-06-20 17:05:59 -070010687 if (program && strcasecmp(program, "HE") == 0) {
10688#ifdef NL80211_SUPPORT
10689 enum he_mcs_config mcs_config;
10690 int ret;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010691
Arif Hussaina37e9552018-06-20 17:05:59 -070010692 if (mcs >= 0 && mcs <= 7) {
10693 mcs_config = HE_80_MCS0_7;
10694 } else if (mcs > 7 && mcs <= 9) {
10695 mcs_config = HE_80_MCS0_9;
10696 } else if (mcs > 9 && mcs <= 11) {
10697 mcs_config = HE_80_MCS0_11;
10698 } else {
10699 sigma_dut_print(dut, DUT_MSG_ERROR,
10700 "nss_mcs_cap: HE: Invalid mcs: %d",
10701 mcs);
10702 send_resp(dut, conn, SIGMA_ERROR,
10703 "errorCode,Invalid MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010704 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010705 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010706
10707 ret = sta_set_he_mcs(dut, intf, mcs_config);
10708 if (ret) {
10709 sigma_dut_print(dut, DUT_MSG_ERROR,
10710 "nss_mcs_cap: HE: Setting of MCS failed, mcs_config: %d, ret: %d",
10711 mcs_config, ret);
10712 send_resp(dut, conn, SIGMA_ERROR,
10713 "errorCode,Failed to set MCS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010714 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010715 }
Arif Hussaina37e9552018-06-20 17:05:59 -070010716#else /* NL80211_SUPPORT */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010717 sigma_dut_print(dut, DUT_MSG_ERROR,
Arif Hussaina37e9552018-06-20 17:05:59 -070010718 "nss_mcs_cap: HE: MCS cannot be changed without NL80211_SUPPORT defined");
10719#endif /* NL80211_SUPPORT */
10720 } else {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010721 run_iwpriv(dut, intf, "vhtmcs %d", mcs);
Arif Hussaina37e9552018-06-20 17:05:59 -070010722
10723 switch (nss) {
10724 case 1:
10725 switch (mcs) {
10726 case 7:
10727 vht_mcsmap = 0xfffc;
10728 break;
10729 case 8:
10730 vht_mcsmap = 0xfffd;
10731 break;
10732 case 9:
10733 vht_mcsmap = 0xfffe;
10734 break;
10735 default:
10736 vht_mcsmap = 0xfffe;
10737 break;
10738 }
10739 break;
10740 case 2:
10741 switch (mcs) {
10742 case 7:
10743 vht_mcsmap = 0xfff0;
10744 break;
10745 case 8:
10746 vht_mcsmap = 0xfff5;
10747 break;
10748 case 9:
10749 vht_mcsmap = 0xfffa;
10750 break;
10751 default:
10752 vht_mcsmap = 0xfffa;
10753 break;
10754 }
10755 break;
10756 case 3:
10757 switch (mcs) {
10758 case 7:
10759 vht_mcsmap = 0xffc0;
10760 break;
10761 case 8:
10762 vht_mcsmap = 0xffd5;
10763 break;
10764 case 9:
10765 vht_mcsmap = 0xffea;
10766 break;
10767 default:
10768 vht_mcsmap = 0xffea;
10769 break;
10770 }
10771 break;
10772 default:
10773 vht_mcsmap = 0xffea;
10774 break;
10775 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010776 run_iwpriv(dut, intf, "vht_mcsmap 0x%04x", vht_mcsmap);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010777 }
10778 }
10779
10780 /* UNSUPPORTED: val = get_param(cmd, "Tx_lgi_rate"); */
10781
10782 val = get_param(cmd, "Vht_tkip");
10783 if (val)
10784 tkip = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10785
10786 val = get_param(cmd, "Vht_wep");
10787 if (val)
10788 wep = strcmp(val, "1") == 0 || strcasecmp(val, "Enable") == 0;
10789
10790 if (tkip != -1 || wep != -1) {
10791 if ((tkip == 1 && wep != 0) || (wep == 1 && tkip != 0)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010792 run_iwpriv(dut, intf, "htweptkip 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010793 } else if ((tkip == 0 && wep != 1) || (wep == 0 && tkip != 1)) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070010794 run_iwpriv(dut, intf, "htweptkip 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010795 } else {
Jouni Malinen224e3902021-06-09 16:41:27 +030010796 send_resp(dut, conn, SIGMA_ERROR,
10797 "ErrorCode,mixed mode of VHT TKIP/WEP not supported");
10798 return STATUS_SENT_ERROR;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010799 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010800 }
10801
Kiran Kumar Lokere09dbcef2021-08-09 00:01:41 -070010802 val = get_param(cmd, "TWTSchedSTASupport");
10803 if (val) {
10804 int set_val;
10805
10806 switch (get_driver_type(dut)) {
10807 case DRIVER_WCN:
10808 if (strcasecmp(val, "Enable") == 0) {
10809 set_val = 1;
10810 } else if (strcasecmp(val, "Disable") == 0) {
10811 set_val = 0;
10812 } else {
10813 send_resp(dut, conn, SIGMA_ERROR,
10814 "ErrorCode,Invalid TWTSchedSTASupport");
10815 return STATUS_SENT_ERROR;
10816 }
10817
10818 if (sta_set_bcast_twt_support(dut, intf, set_val)) {
10819 send_resp(dut, conn, SIGMA_ERROR,
10820 "ErrorCode,Failed to set TWTSchedSTASupport");
10821 return STATUS_SENT_ERROR;
10822 }
10823 break;
10824 default:
10825 sigma_dut_print(dut, DUT_MSG_ERROR,
10826 "Setting TWTSchedSTASupport not supported");
10827 break;
10828 }
10829 }
10830
10831 val = get_param(cmd, "MBSSID_RxCtrl");
10832 if (val) {
10833 int set_val;
10834
10835 switch (get_driver_type(dut)) {
10836 case DRIVER_WCN:
10837 if (strcasecmp(val, "Enable") == 0) {
10838 set_val = 1;
10839 } else if (strcasecmp(val, "Disable") == 0) {
10840 set_val = 0;
10841 } else {
10842 send_resp(dut, conn, SIGMA_ERROR,
10843 "ErrorCode,Invalid MBSSID_RxCtrl");
10844 return STATUS_SENT_ERROR;
10845 }
10846
10847 if (sta_set_rx_ctrl_multi_bss(dut, intf, set_val)) {
10848 send_resp(dut, conn, SIGMA_ERROR,
10849 "ErrorCode,Failed to set MBSSID_RxCtrl");
10850 return STATUS_SENT_ERROR;
10851 }
10852 break;
10853 default:
10854 sigma_dut_print(dut, DUT_MSG_ERROR,
10855 "Setting MBSSID_RxCtrl not supported");
10856 break;
10857 }
10858 }
10859
Arif Hussain55f00da2018-07-03 08:28:26 -070010860 val = get_param(cmd, "txBandwidth");
10861 if (val) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020010862 switch (get_driver_type(dut)) {
Arif Hussain55f00da2018-07-03 08:28:26 -070010863 case DRIVER_WCN:
10864 if (wcn_sta_set_width(dut, intf, val) < 0) {
10865 send_resp(dut, conn, SIGMA_ERROR,
10866 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010867 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010868 }
10869 break;
10870 case DRIVER_ATHEROS:
10871 if (ath_set_width(dut, conn, intf, val) < 0) {
10872 send_resp(dut, conn, SIGMA_ERROR,
10873 "ErrorCode,Failed to set txBandwidth");
Jouni Malinen224e3902021-06-09 16:41:27 +030010874 return STATUS_SENT_ERROR;
Arif Hussain55f00da2018-07-03 08:28:26 -070010875 }
10876 break;
10877 default:
10878 sigma_dut_print(dut, DUT_MSG_ERROR,
10879 "Setting txBandwidth not supported");
10880 break;
10881 }
10882 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020010883
Arif Hussain9765f7d2018-07-03 08:28:26 -070010884 val = get_param(cmd, "BeamformeeSTS");
10885 if (val) {
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010886 if (sta_set_tx_beamformee(dut, intf, 1)) {
10887 send_resp(dut, conn, SIGMA_ERROR,
10888 "ErrorCode,Failed to set TX beamformee enable");
Jouni Malinen224e3902021-06-09 16:41:27 +030010889 return STATUS_SENT_ERROR;
Kiran Kumar Lokerebc89d432018-07-10 12:20:13 -070010890 }
10891
Arif Hussain9765f7d2018-07-03 08:28:26 -070010892 if (sta_set_beamformee_sts(dut, intf, atoi(val))) {
10893 send_resp(dut, conn, SIGMA_ERROR,
10894 "ErrorCode,Failed to set BeamformeeSTS");
Jouni Malinen224e3902021-06-09 16:41:27 +030010895 return STATUS_SENT_ERROR;
Arif Hussain9765f7d2018-07-03 08:28:26 -070010896 }
10897 }
10898
Arif Hussain68d23f52018-07-11 13:39:08 -070010899 val = get_param(cmd, "Trig_MAC_Padding_Dur");
10900 if (val) {
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010901#ifdef NL80211_SUPPORT
10902 enum qca_wlan_he_mac_padding_dur set_val;
10903
10904 switch (atoi(val)) {
10905 case 16:
10906 set_val = QCA_WLAN_HE_16US_OF_PROCESS_TIME;
10907 break;
10908 case 8:
10909 set_val = QCA_WLAN_HE_8US_OF_PROCESS_TIME;
10910 break;
10911 default:
10912 set_val = QCA_WLAN_HE_NO_ADDITIONAL_PROCESS_TIME;
10913 break;
10914 }
10915 if (sta_set_mac_padding_duration(dut, intf, set_val)) {
Arif Hussain68d23f52018-07-11 13:39:08 -070010916 send_resp(dut, conn, SIGMA_ERROR,
10917 "ErrorCode,Failed to set MAC padding duration");
Jouni Malinen224e3902021-06-09 16:41:27 +030010918 return STATUS_SENT_ERROR;
Arif Hussain68d23f52018-07-11 13:39:08 -070010919 }
Kiran Kumar Lokere55eb5582018-08-19 20:03:26 -070010920#else /* NL80211_SUPPORT */
10921 sigma_dut_print(dut, DUT_MSG_ERROR,
10922 "MAC padding duration cannot be changed without NL80211_SUPPORT defined");
10923#endif /* NL80211_SUPPORT */
Arif Hussain68d23f52018-07-11 13:39:08 -070010924 }
10925
Arif Hussain480d5f42019-03-12 14:40:42 -070010926 val = get_param(cmd, "TWT_ReqSupport");
10927 if (val) {
10928 int set_val;
10929
10930 if (strcasecmp(val, "Enable") == 0) {
10931 set_val = 1;
10932 } else if (strcasecmp(val, "Disable") == 0) {
10933 set_val = 0;
10934 } else {
10935 send_resp(dut, conn, SIGMA_ERROR,
10936 "ErrorCode,Invalid TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010937 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010938 }
10939
10940 if (sta_set_twt_req_support(dut, intf, set_val)) {
10941 sigma_dut_print(dut, DUT_MSG_ERROR,
10942 "Failed to set TWT req support %d",
10943 set_val);
10944 send_resp(dut, conn, SIGMA_ERROR,
10945 "ErrorCode,Failed to set TWT_ReqSupport");
Jouni Malinen224e3902021-06-09 16:41:27 +030010946 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070010947 }
10948 }
10949
Kiran Kumar Lokered0ec5ed2021-04-01 00:15:04 -070010950 val = get_param(cmd, "PreamblePunctRx");
10951 if (val && get_driver_type(dut) == DRIVER_WCN) {
10952 int set_val;
10953
10954 if (strcasecmp(val, "Enable") == 0) {
10955 set_val = 1;
10956 } else if (strcasecmp(val, "Disable") == 0) {
10957 set_val = 0;
10958 } else {
10959 send_resp(dut, conn, SIGMA_ERROR,
10960 "ErrorCode,Invalid PreamblePunctRx");
10961 return STATUS_SENT_ERROR;
10962 }
10963
10964 if (sta_set_punctured_preamble_rx(dut, intf, set_val)) {
10965 sigma_dut_print(dut, DUT_MSG_ERROR,
10966 "Failed to set PreamblePunctRx support %d",
10967 set_val);
10968 send_resp(dut, conn, SIGMA_ERROR,
10969 "ErrorCode,Failed to set PreamblePunctRx");
10970 return STATUS_SENT_ERROR;
10971 }
10972 }
10973
Srinivas Girigowda0525e292020-11-12 13:28:21 -080010974 val = get_param(cmd, "FullBW_ULMUMIMO");
10975 if (val) {
10976 int set_val;
10977
10978 if (strcasecmp(val, "Enable") == 0) {
10979 set_val = 1;
10980 } else if (strcasecmp(val, "Disable") == 0) {
10981 set_val = 0;
10982 } else {
10983 send_resp(dut, conn, SIGMA_ERROR,
10984 "ErrorCode,Invalid FullBW_ULMUMIMO");
10985 return STATUS_SENT_ERROR;
10986 }
10987
10988 if (sta_set_fullbw_ulmumimo(dut, intf, set_val)) {
10989 sigma_dut_print(dut, DUT_MSG_ERROR,
10990 "Failed to set FullBW_ULMUMIMO %d",
10991 set_val);
10992 send_resp(dut, conn, SIGMA_ERROR,
10993 "ErrorCode,Failed to set FullBW_ULMUMIMO");
10994 return STATUS_SENT_ERROR;
10995 }
10996 }
10997
Srinivas Girigowda6707f032020-10-26 15:24:46 -070010998 val = get_param(cmd, "TWTInfoFrameTx");
10999 if (val) {
11000 if (strcasecmp(val, "Enable") == 0) {
11001 /* No-op */
11002 } else if (strcasecmp(val, "Disable") == 0) {
11003 /* No-op */
11004 } else {
11005 send_resp(dut, conn, SIGMA_ERROR,
11006 "ErrorCode,Invalid TWTInfoFrameTx");
11007 return STATUS_SENT_ERROR;
11008 }
11009 }
11010
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011011 val = get_param(cmd, "MU_EDCA");
11012 if (val && (strcasecmp(val, "Override") == 0)) {
11013 if (sta_set_mu_edca_override(dut, intf, 1)) {
11014 send_resp(dut, conn, SIGMA_ERROR,
11015 "ErrorCode,Failed to set MU EDCA override");
Jouni Malinen224e3902021-06-09 16:41:27 +030011016 return STATUS_SENT_ERROR;
Kiran Kumar Lokereb1012682018-08-08 17:48:32 -070011017 }
11018 }
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011019
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070011020 val = get_param(cmd, "PPDUTxType");
11021 if (val && strcasecmp(val, "ER-SU") == 0) {
11022 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
11023 send_resp(dut, conn, SIGMA_ERROR,
11024 "ErrorCode,Failed to set ER-SU PPDU type Tx");
11025 return STATUS_SENT_ERROR;
11026 }
11027 }
11028
11029 val = get_param(cmd, "RUAllocTone");
11030 if (val && strcasecmp(val, "242") == 0) {
11031 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
11032 send_resp(dut, conn, SIGMA_ERROR,
11033 "ErrorCode,Failed to set RU 242 tone Tx");
11034 return STATUS_SENT_ERROR;
11035 }
11036 }
11037
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011038 val = get_param(cmd, "OMControl");
11039 if (val) {
11040 int set_val = 1;
11041
11042 if (strcasecmp(val, "Enable") == 0)
11043 set_val = 1;
11044 else if (strcasecmp(val, "Disable") == 0)
11045 set_val = 0;
11046
11047 if (sta_set_om_ctrl_supp(dut, intf, set_val)) {
11048 send_resp(dut, conn, SIGMA_ERROR,
11049 "ErrorCode,Failed to set OM ctrl supp");
Jouni Malinen224e3902021-06-09 16:41:27 +030011050 return STATUS_SENT_ERROR;
Kiran Kumar Lokerede33e372018-08-29 16:26:24 -070011051 }
11052 }
11053
Kiran Kumar Lokere4f2d4b02021-04-01 00:07:39 -070011054 val = get_param(cmd, "BSSMaxIdlePeriod");
11055 if (val && sta_set_bss_max_idle_period(dut, intf, atoi(val))) {
11056 send_resp(dut, conn, SIGMA_ERROR,
11057 "ErrorCode,Failed to set BSS max idle period");
11058 return STATUS_SENT_ERROR;
11059 }
11060
Kiran Kumar Lokere07ad92b2021-08-09 00:27:14 -070011061 val = get_param(cmd, "BSS_max_idle");
11062 if (val) {
11063 int set_val = 0;
11064
11065 if (strcasecmp(val, "Enable") == 0)
11066 set_val = 1;
11067 else if (strcasecmp(val, "Disable") == 0)
11068 set_val = 0;
11069 if (sta_set_bss_max_idle_support(dut, intf, set_val)) {
11070 send_resp(dut, conn, SIGMA_ERROR,
11071 "ErrorCode,Failed to set BSS max idle support");
11072 return STATUS_SENT_ERROR;
11073 }
11074 }
11075
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011076 val = get_param(cmd, "ADDBAResp_BufSize");
11077 if (val) {
11078 int buf_size;
11079
11080 if (strcasecmp(val, "gt64") == 0)
11081 buf_size = 256;
11082 else
11083 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011084 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011085 sta_set_addba_buf_size(dut, intf, buf_size)) {
11086 send_resp(dut, conn, SIGMA_ERROR,
11087 "ErrorCode,set addbaresp_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011088 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011089 }
11090 }
11091
11092 val = get_param(cmd, "ADDBAReq_BufSize");
11093 if (val) {
11094 int buf_size;
11095
11096 if (strcasecmp(val, "gt64") == 0)
11097 buf_size = 256;
11098 else
11099 buf_size = 64;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011100 if (get_driver_type(dut) == DRIVER_WCN &&
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011101 sta_set_addba_buf_size(dut, intf, buf_size)) {
11102 send_resp(dut, conn, SIGMA_ERROR,
11103 "ErrorCode,set addbareq_buff_size failed");
Jouni Malinen224e3902021-06-09 16:41:27 +030011104 return STATUS_SENT_ERROR;
Kiran Kumar Lokerec6581822018-08-01 16:18:34 -070011105 }
11106 }
11107
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011108 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11109}
11110
11111
11112static int sta_set_wireless_60g(struct sigma_dut *dut,
11113 struct sigma_conn *conn,
11114 struct sigma_cmd *cmd)
11115{
11116 const char *dev_role = get_param(cmd, "DevRole");
11117
11118 if (!dev_role) {
11119 send_resp(dut, conn, SIGMA_INVALID,
11120 "ErrorCode,DevRole not specified");
11121 return 0;
11122 }
11123
11124 if (strcasecmp(dev_role, "PCP") == 0)
11125 return sta_set_60g_pcp(dut, conn, cmd);
11126 if (strcasecmp(dev_role, "STA") == 0)
11127 return sta_set_60g_sta(dut, conn, cmd);
11128 send_resp(dut, conn, SIGMA_INVALID,
11129 "ErrorCode,DevRole not supported");
11130 return 0;
11131}
11132
11133
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011134static int sta_set_wireless_oce(struct sigma_dut *dut, struct sigma_conn *conn,
11135 struct sigma_cmd *cmd)
11136{
11137 int status;
11138 const char *intf = get_param(cmd, "Interface");
11139 const char *val = get_param(cmd, "DevRole");
11140
11141 if (val && strcasecmp(val, "STA-CFON") == 0) {
11142 status = sta_cfon_set_wireless(dut, conn, cmd);
11143 if (status)
11144 return status;
11145 }
11146 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11147}
11148
11149
Jouni Malinen67433fc2020-06-26 22:50:33 +030011150static enum sigma_cmd_result
11151sta_set_wireless_wpa3(struct sigma_dut *dut, struct sigma_conn *conn,
11152 struct sigma_cmd *cmd)
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011153{
11154 const char *intf = get_param(cmd, "Interface");
11155 const char *val;
11156
11157 val = get_param(cmd, "ocvc");
11158 if (val)
11159 dut->ocvc = atoi(val);
11160
Jouni Malinen67433fc2020-06-26 22:50:33 +030011161 val = get_param(cmd, "ClientPrivacy");
Veerendranath Jakkam47867202020-12-21 01:53:52 +053011162 if (val && dut->client_privacy != atoi(val) &&
11163 sta_set_client_privacy(dut, conn, intf, atoi(val))) {
11164 send_resp(dut, conn, SIGMA_ERROR,
11165 "errorCode,Failed to configure random MAC address use");
11166 return STATUS_SENT_ERROR;
Jouni Malinen67433fc2020-06-26 22:50:33 +030011167 }
11168
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011169 return cmd_sta_set_wireless_common(intf, dut, conn, cmd);
11170}
11171
11172
Jouni Malinenf7222712019-06-13 01:50:21 +030011173static enum sigma_cmd_result cmd_sta_set_wireless(struct sigma_dut *dut,
11174 struct sigma_conn *conn,
11175 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011176{
11177 const char *val;
11178
11179 val = get_param(cmd, "Program");
11180 if (val) {
11181 if (strcasecmp(val, "11n") == 0)
11182 return cmd_sta_set_11n(dut, conn, cmd);
Amarnath Hullur Subramanyam4f860292018-01-31 03:49:35 -080011183 if (strcasecmp(val, "VHT") == 0 || strcasecmp(val, "HE") == 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011184 return cmd_sta_set_wireless_vht(dut, conn, cmd);
11185 if (strcasecmp(val, "60ghz") == 0)
11186 return sta_set_wireless_60g(dut, conn, cmd);
Ankita Bajaj0d5825b2017-10-25 16:20:17 +053011187 if (strcasecmp(val, "OCE") == 0)
11188 return sta_set_wireless_oce(dut, conn, cmd);
Alexei Avshalom Lazar66bb9972018-12-18 16:01:43 +020011189 /* sta_set_wireless in WPS program is only used for 60G */
11190 if (is_60g_sigma_dut(dut))
11191 return sta_set_wireless_60g(dut, conn, cmd);
Vamsi Krishnac1633d22020-05-06 18:31:21 +053011192 if (strcasecmp(val, "WPA3") == 0)
11193 return sta_set_wireless_wpa3(dut, conn, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011194 send_resp(dut, conn, SIGMA_ERROR,
11195 "ErrorCode,Program value not supported");
11196 } else {
11197 send_resp(dut, conn, SIGMA_ERROR,
11198 "ErrorCode,Program argument not available");
11199 }
11200
11201 return 0;
11202}
11203
11204
11205static void ath_sta_inject_frame(struct sigma_dut *dut, const char *intf,
11206 int tid)
11207{
11208 char buf[100];
11209 int tid_to_dscp [] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0 };
11210
Pradeep Reddy POTTETId31d1322016-10-13 17:22:03 +053011211 if (tid < 0 ||
11212 tid >= (int) (sizeof(tid_to_dscp) / sizeof(tid_to_dscp[0]))) {
11213 sigma_dut_print(dut, DUT_MSG_ERROR, "Unsupported TID: %d", tid);
11214 return;
11215 }
11216
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011217 /*
11218 * Two ways to ensure that addba request with a
11219 * non zero TID could be sent out. EV 117296
11220 */
11221 snprintf(buf, sizeof(buf),
11222 "ping -c 8 -Q %d `arp -a | grep wlan0 | awk '{print $2}' | tr -d '()'`",
11223 tid);
11224 if (system(buf) != 0) {
11225 sigma_dut_print(dut, DUT_MSG_ERROR,
11226 "Ping did not send out");
11227 }
11228
11229 snprintf(buf, sizeof(buf),
11230 "iwconfig %s | grep Access | awk '{print $6}' > %s",
11231 intf, VI_QOS_TMP_FILE);
11232 if (system(buf) != 0)
11233 return;
11234
11235 snprintf(buf, sizeof(buf),
11236 "ifconfig %s | grep HWaddr | cut -b 39-56 >> %s",
11237 intf, VI_QOS_TMP_FILE);
11238 if (system(buf) != 0)
11239 sigma_dut_print(dut, DUT_MSG_ERROR, "HWaddr matching failed");
11240
11241 snprintf(buf,sizeof(buf), "sed -n '3,$p' %s >> %s",
11242 VI_QOS_REFFILE, VI_QOS_TMP_FILE);
11243 if (system(buf) != 0) {
11244 sigma_dut_print(dut, DUT_MSG_ERROR,
11245 "VI_QOS_TEMP_FILE generation error failed");
11246 }
11247 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11248 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11249 if (system(buf) != 0) {
11250 sigma_dut_print(dut, DUT_MSG_ERROR,
11251 "VI_QOS_FILE generation failed");
11252 }
11253
11254 snprintf(buf, sizeof(buf), "sed '5 c %x' %s > %s",
11255 tid_to_dscp[tid], VI_QOS_TMP_FILE, VI_QOS_FILE);
11256 if (system(buf) != 0) {
11257 sigma_dut_print(dut, DUT_MSG_ERROR,
11258 "VI_QOS_FILE generation failed");
11259 }
11260
11261 snprintf(buf, sizeof(buf), "ethinject %s %s", intf, VI_QOS_FILE);
11262 if (system(buf) != 0) {
11263 }
11264}
11265
11266
11267static int ath_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11268 struct sigma_cmd *cmd)
11269{
11270 const char *intf = get_param(cmd, "Interface");
11271 const char *val;
11272 int tid = 0;
11273 char buf[100];
11274
11275 val = get_param(cmd, "TID");
11276 if (val) {
11277 tid = atoi(val);
11278 if (tid)
11279 ath_sta_inject_frame(dut, intf, tid);
11280 }
11281
11282 /* Command sequence for ADDBA request on Peregrine based devices */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070011283 run_iwpriv(dut, intf, "setaddbaoper 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011284
11285 snprintf(buf, sizeof(buf), "wifitool %s senddelba 1 %d 1 4", intf, tid);
11286 if (system(buf) != 0) {
11287 sigma_dut_print(dut, DUT_MSG_ERROR,
11288 "wifitool senddelba failed");
11289 }
11290
11291 snprintf(buf, sizeof(buf), "wifitool %s sendaddba 1 %d 64", intf, tid);
11292 if (system(buf) != 0) {
11293 sigma_dut_print(dut, DUT_MSG_ERROR,
11294 "wifitool sendaddba failed");
11295 }
11296
11297 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11298
11299 return 1;
11300}
11301
11302
Lior David9981b512017-01-20 13:16:40 +020011303#ifdef __linux__
11304
11305static int wil6210_send_addba(struct sigma_dut *dut, const char *dest_mac,
11306 int agg_size)
11307{
11308 char dir[128], buf[128];
11309 FILE *f;
11310 regex_t re;
11311 regmatch_t m[2];
Jouni Malinen3aa72862019-05-29 23:14:51 +030011312 int rc, ret = -1, vring_id, found, res;
Lior David9981b512017-01-20 13:16:40 +020011313
11314 if (wil6210_get_debugfs_dir(dut, dir, sizeof(dir))) {
11315 sigma_dut_print(dut, DUT_MSG_ERROR,
11316 "failed to get wil6210 debugfs dir");
11317 return -1;
11318 }
11319
Jouni Malinen3aa72862019-05-29 23:14:51 +030011320 res = snprintf(buf, sizeof(buf), "%s/vrings", dir);
11321 if (res < 0 || res >= sizeof(buf))
11322 return -1;
Lior David9981b512017-01-20 13:16:40 +020011323 f = fopen(buf, "r");
11324 if (!f) {
11325 sigma_dut_print(dut, DUT_MSG_ERROR, "failed to open: %s", buf);
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011326 /* newer wil6210 driver renamed file to "rings" */
Jouni Malinen3aa72862019-05-29 23:14:51 +030011327 res = snprintf(buf, sizeof(buf), "%s/rings", dir);
11328 if (res < 0 || res >= sizeof(buf))
11329 return -1;
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011330 f = fopen(buf, "r");
11331 if (!f) {
11332 sigma_dut_print(dut, DUT_MSG_ERROR,
11333 "failed to open: %s", buf);
11334 return -1;
11335 }
Lior David9981b512017-01-20 13:16:40 +020011336 }
11337
Alexei Avshalom Lazar2af1d252018-11-13 14:10:13 +020011338 /* can be either VRING tx... or RING... */
11339 if (regcomp(&re, "RING tx_[ \t]*([0-9]+)", REG_EXTENDED)) {
Lior David9981b512017-01-20 13:16:40 +020011340 sigma_dut_print(dut, DUT_MSG_ERROR, "regcomp failed");
11341 goto out;
11342 }
11343
11344 /* find TX VRING for the mac address */
11345 found = 0;
11346 while (fgets(buf, sizeof(buf), f)) {
11347 if (strcasestr(buf, dest_mac)) {
11348 found = 1;
11349 break;
11350 }
11351 }
11352
11353 if (!found) {
11354 sigma_dut_print(dut, DUT_MSG_ERROR,
11355 "no TX VRING for %s", dest_mac);
11356 goto out;
11357 }
11358
11359 /* extract VRING ID, "VRING tx_<id> = {" */
11360 if (!fgets(buf, sizeof(buf), f)) {
11361 sigma_dut_print(dut, DUT_MSG_ERROR,
11362 "no VRING start line for %s", dest_mac);
11363 goto out;
11364 }
11365
11366 rc = regexec(&re, buf, 2, m, 0);
11367 regfree(&re);
11368 if (rc || m[1].rm_so < 0) {
11369 sigma_dut_print(dut, DUT_MSG_ERROR,
11370 "no VRING TX ID for %s", dest_mac);
11371 goto out;
11372 }
11373 buf[m[1].rm_eo] = 0;
11374 vring_id = atoi(&buf[m[1].rm_so]);
11375
11376 /* send the addba command */
11377 fclose(f);
Jouni Malinen3aa72862019-05-29 23:14:51 +030011378 res = snprintf(buf, sizeof(buf), "%s/back", dir);
11379 if (res < 0 || res >= sizeof(buf))
11380 return -1;
Lior David9981b512017-01-20 13:16:40 +020011381 f = fopen(buf, "w");
11382 if (!f) {
11383 sigma_dut_print(dut, DUT_MSG_ERROR,
11384 "failed to open: %s", buf);
11385 return -1;
11386 }
11387
11388 fprintf(f, "add %d %d\n", vring_id, agg_size);
11389
11390 ret = 0;
11391
11392out:
11393 fclose(f);
11394
11395 return ret;
11396}
11397
11398
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011399int send_addba_60g(struct sigma_dut *dut, struct sigma_conn *conn,
11400 struct sigma_cmd *cmd, const char *mac_param)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011401{
11402 const char *val;
11403 int tid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011404
11405 val = get_param(cmd, "TID");
11406 if (val) {
11407 tid = atoi(val);
11408 if (tid != 0) {
11409 sigma_dut_print(dut, DUT_MSG_ERROR,
11410 "Ignore TID %d for send_addba use TID 0 for 60g since only 0 required on TX",
11411 tid);
11412 }
11413 }
11414
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011415 val = get_param(cmd, mac_param);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011416 if (!val) {
11417 sigma_dut_print(dut, DUT_MSG_ERROR,
11418 "Currently not supporting addba for 60G without Dest_mac");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020011419 return ERROR_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011420 }
11421
Lior David9981b512017-01-20 13:16:40 +020011422 if (wil6210_send_addba(dut, val, dut->back_rcv_buf))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011423 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011424
11425 return 1;
11426}
11427
Lior David9981b512017-01-20 13:16:40 +020011428#endif /* __linux__ */
11429
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011430
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011431static int wcn_sta_send_addba(struct sigma_dut *dut, struct sigma_conn *conn,
11432 struct sigma_cmd *cmd)
11433{
11434#ifdef NL80211_SUPPORT
11435 const char *intf = get_param(cmd, "Interface");
11436 const char *val;
11437 int tid = -1;
11438 int bufsize = 64;
11439 struct nl_msg *msg;
11440 int ret = 0;
11441 struct nlattr *params;
11442 int ifindex;
11443
11444 val = get_param(cmd, "TID");
11445 if (val)
11446 tid = atoi(val);
11447
11448 if (tid == -1) {
11449 send_resp(dut, conn, SIGMA_ERROR,
11450 "ErrorCode,sta_send_addba tid invalid");
11451 return 0;
11452 }
11453
11454 /* UNSUPPORTED: val = get_param(cmd, "Dest_mac"); */
11455
11456 ifindex = if_nametoindex(intf);
11457 if (ifindex == 0) {
11458 sigma_dut_print(dut, DUT_MSG_ERROR,
11459 "%s: Index for interface %s failed",
11460 __func__, intf);
11461 send_resp(dut, conn, SIGMA_ERROR,
11462 "ErrorCode,sta_send_addba interface invalid");
11463 return 0;
11464 }
11465
11466 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11467 NL80211_CMD_VENDOR)) ||
11468 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
11469 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
11470 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
11471 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
11472 !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
11473 nla_put_u8(msg,
11474 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION,
11475 QCA_WLAN_ADD_BA) ||
11476 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID,
11477 tid) ||
Kiran Kumar Lokere26e27582018-08-01 16:18:34 -070011478 nla_put_u16(msg,
11479 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE,
11480 bufsize)) {
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011481 sigma_dut_print(dut, DUT_MSG_ERROR,
11482 "%s: err in adding vendor_cmd and vendor_data",
11483 __func__);
11484 nlmsg_free(msg);
11485 send_resp(dut, conn, SIGMA_ERROR,
11486 "ErrorCode,sta_send_addba err in adding vendor_cmd and vendor_data");
11487 return 0;
11488 }
11489 nla_nest_end(msg, params);
11490
11491 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11492 if (ret) {
11493 sigma_dut_print(dut, DUT_MSG_ERROR,
11494 "%s: err in send_and_recv_msgs, ret=%d",
11495 __func__, ret);
Sunil Dutt30605592018-05-04 20:35:50 +053011496 if (ret == -EOPNOTSUPP)
11497 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011498 send_resp(dut, conn, SIGMA_ERROR,
11499 "ErrorCode,sta_send_addba err in send_and_recv_msgs");
11500 return 0;
11501 }
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011502#else /* NL80211_SUPPORT */
11503 sigma_dut_print(dut, DUT_MSG_ERROR,
11504 "sta_send_addba not supported without NL80211_SUPPORT defined");
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011505#endif /* NL80211_SUPPORT */
Sunil Dutt30605592018-05-04 20:35:50 +053011506
11507 return 1;
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011508}
11509
11510
Jouni Malinenf7222712019-06-13 01:50:21 +030011511static enum sigma_cmd_result cmd_sta_send_addba(struct sigma_dut *dut,
11512 struct sigma_conn *conn,
11513 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011514{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011515 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011516 case DRIVER_ATHEROS:
11517 return ath_sta_send_addba(dut, conn, cmd);
Amarnath Hullur Subramanyama72c0162018-02-27 14:49:09 -080011518 case DRIVER_WCN:
11519 return wcn_sta_send_addba(dut, conn, cmd);
Lior David9981b512017-01-20 13:16:40 +020011520#ifdef __linux__
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011521 case DRIVER_WIL6210:
Alexei Avshalom Lazar79fa3fe2018-12-24 15:43:33 +020011522 return send_addba_60g(dut, conn, cmd, "Dest_mac");
Lior David9981b512017-01-20 13:16:40 +020011523#endif /* __linux__ */
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011524 default:
11525 /*
11526 * There is no driver specific implementation for other drivers.
11527 * Ignore the command and report COMPLETE since the following
11528 * throughput test operation will end up sending ADDBA anyway.
11529 */
11530 return 1;
11531 }
11532}
11533
11534
11535int inject_eth_frame(int s, const void *data, size_t len,
11536 unsigned short ethtype, char *dst, char *src)
11537{
11538 struct iovec iov[4] = {
11539 {
11540 .iov_base = dst,
11541 .iov_len = ETH_ALEN,
11542 },
11543 {
11544 .iov_base = src,
11545 .iov_len = ETH_ALEN,
11546 },
11547 {
11548 .iov_base = &ethtype,
11549 .iov_len = sizeof(unsigned short),
11550 },
11551 {
11552 .iov_base = (void *) data,
11553 .iov_len = len,
11554 }
11555 };
11556 struct msghdr msg = {
11557 .msg_name = NULL,
11558 .msg_namelen = 0,
11559 .msg_iov = iov,
11560 .msg_iovlen = 4,
11561 .msg_control = NULL,
11562 .msg_controllen = 0,
11563 .msg_flags = 0,
11564 };
11565
11566 return sendmsg(s, &msg, 0);
11567}
11568
11569#if defined(__linux__) || defined(__QNXNTO__)
11570
11571int inject_frame(int s, const void *data, size_t len, int encrypt)
11572{
11573#define IEEE80211_RADIOTAP_F_WEP 0x04
11574#define IEEE80211_RADIOTAP_F_FRAG 0x08
11575 unsigned char rtap_hdr[] = {
11576 0x00, 0x00, /* radiotap version */
11577 0x0e, 0x00, /* radiotap length */
11578 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
11579 IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
11580 0x00, /* padding */
11581 0x00, 0x00, /* RX and TX flags to indicate that */
11582 0x00, 0x00, /* this is the injected frame directly */
11583 };
11584 struct iovec iov[2] = {
11585 {
11586 .iov_base = &rtap_hdr,
11587 .iov_len = sizeof(rtap_hdr),
11588 },
11589 {
11590 .iov_base = (void *) data,
11591 .iov_len = len,
11592 }
11593 };
11594 struct msghdr msg = {
11595 .msg_name = NULL,
11596 .msg_namelen = 0,
11597 .msg_iov = iov,
11598 .msg_iovlen = 2,
11599 .msg_control = NULL,
11600 .msg_controllen = 0,
11601 .msg_flags = 0,
11602 };
11603
11604 if (encrypt)
11605 rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP;
11606
11607 return sendmsg(s, &msg, 0);
11608}
11609
11610
11611int open_monitor(const char *ifname)
11612{
11613#ifdef __QNXNTO__
11614 struct sockaddr_dl ll;
11615 int s;
11616
11617 memset(&ll, 0, sizeof(ll));
11618 ll.sdl_family = AF_LINK;
11619 ll.sdl_index = if_nametoindex(ifname);
11620 if (ll.sdl_index == 0) {
11621 perror("if_nametoindex");
11622 return -1;
11623 }
11624 s = socket(PF_INET, SOCK_RAW, 0);
11625#else /* __QNXNTO__ */
11626 struct sockaddr_ll ll;
11627 int s;
11628
11629 memset(&ll, 0, sizeof(ll));
11630 ll.sll_family = AF_PACKET;
11631 ll.sll_ifindex = if_nametoindex(ifname);
11632 if (ll.sll_ifindex == 0) {
11633 perror("if_nametoindex");
11634 return -1;
11635 }
11636 s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
11637#endif /* __QNXNTO__ */
11638 if (s < 0) {
11639 perror("socket[PF_PACKET,SOCK_RAW]");
11640 return -1;
11641 }
11642
11643 if (bind(s, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
11644 perror("monitor socket bind");
11645 close(s);
11646 return -1;
11647 }
11648
11649 return s;
11650}
11651
11652
11653static int hex2num(char c)
11654{
11655 if (c >= '0' && c <= '9')
11656 return c - '0';
11657 if (c >= 'a' && c <= 'f')
11658 return c - 'a' + 10;
11659 if (c >= 'A' && c <= 'F')
11660 return c - 'A' + 10;
11661 return -1;
11662}
11663
11664
11665int hwaddr_aton(const char *txt, unsigned char *addr)
11666{
11667 int i;
11668
11669 for (i = 0; i < 6; i++) {
11670 int a, b;
11671
11672 a = hex2num(*txt++);
11673 if (a < 0)
11674 return -1;
11675 b = hex2num(*txt++);
11676 if (b < 0)
11677 return -1;
11678 *addr++ = (a << 4) | b;
11679 if (i < 5 && *txt++ != ':')
11680 return -1;
11681 }
11682
11683 return 0;
11684}
11685
11686#endif /* defined(__linux__) || defined(__QNXNTO__) */
11687
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011688
11689#ifdef NL80211_SUPPORT
11690static int nl80211_send_frame_cmd(struct sigma_dut *dut, const char *intf,
11691 const u8 *data, size_t data_len, int freq)
11692{
11693 struct nl_msg *msg;
11694 int ret = 0;
11695 int ifindex;
11696
11697 ifindex = if_nametoindex(intf);
11698 if (ifindex == 0) {
11699 sigma_dut_print(dut, DUT_MSG_ERROR,
11700 "%s: Index for interface %s failed",
11701 __func__, intf);
11702 return -1;
11703 }
11704
11705 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
11706 NL80211_CMD_FRAME)) ||
11707 (freq && nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
11708 nla_put(msg, NL80211_ATTR_FRAME, data_len, data)) {
11709 sigma_dut_print(dut, DUT_MSG_ERROR,
11710 "%s: Error in adding NL80211_CMD_FRAME",
11711 __func__);
11712 nlmsg_free(msg);
11713 return -1;
11714 }
11715
11716 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
11717 if (ret) {
11718 sigma_dut_print(dut, DUT_MSG_ERROR,
11719 "nl80211: Frame command failed: ret=%d (%s) req=%u",
11720 ret, strerror(-ret), freq);
11721 return -1;
11722 }
11723
11724 return 0;
11725}
11726#endif /* NL80211_SUPPORT */
11727
11728
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011729enum send_frame_type {
11730 DISASSOC, DEAUTH, SAQUERY, AUTH, ASSOCREQ, REASSOCREQ, DLS_REQ
11731};
11732enum send_frame_protection {
11733 CORRECT_KEY, INCORRECT_KEY, UNPROTECTED
11734};
11735
11736
11737static int sta_inject_frame(struct sigma_dut *dut, struct sigma_conn *conn,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011738 const char *intf, enum send_frame_type frame,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011739 enum send_frame_protection protected,
Veerendranath Jakkam49774122020-07-05 09:52:18 +053011740 const char *dest, int use_monitor)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011741{
11742#ifdef __linux__
11743 unsigned char buf[1000], *pos;
11744 int s, res;
11745 char bssid[20], addr[20];
11746 char result[32], ssid[100];
11747 size_t ssid_len;
11748
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011749 if (get_wpa_status(get_station_ifname(dut), "wpa_state", result,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011750 sizeof(result)) < 0 ||
11751 strncmp(result, "COMPLETED", 9) != 0) {
11752 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Not connected");
11753 return 0;
11754 }
11755
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011756 if (get_wpa_status(get_station_ifname(dut), "bssid",
11757 bssid, sizeof(bssid)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011758 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11759 "current BSSID");
11760 return 0;
11761 }
11762
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011763 if (get_wpa_status(get_station_ifname(dut), "address",
11764 addr, sizeof(addr)) < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011765 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11766 "own MAC address");
11767 return 0;
11768 }
11769
Jouni Malinen016ae6c2019-11-04 17:00:01 +020011770 if (get_wpa_status(get_station_ifname(dut), "ssid", ssid, sizeof(ssid))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011771 < 0) {
11772 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not get "
11773 "current SSID");
11774 return 0;
11775 }
11776 ssid_len = strlen(ssid);
11777
11778 pos = buf;
11779
11780 /* Frame Control */
11781 switch (frame) {
11782 case DISASSOC:
11783 *pos++ = 0xa0;
11784 break;
11785 case DEAUTH:
11786 *pos++ = 0xc0;
11787 break;
11788 case SAQUERY:
11789 *pos++ = 0xd0;
11790 break;
11791 case AUTH:
11792 *pos++ = 0xb0;
11793 break;
11794 case ASSOCREQ:
11795 *pos++ = 0x00;
11796 break;
11797 case REASSOCREQ:
11798 *pos++ = 0x20;
11799 break;
11800 case DLS_REQ:
11801 *pos++ = 0xd0;
11802 break;
11803 }
11804
11805 if (protected == INCORRECT_KEY)
11806 *pos++ = 0x40; /* Set Protected field to 1 */
11807 else
11808 *pos++ = 0x00;
11809
11810 /* Duration */
11811 *pos++ = 0x00;
11812 *pos++ = 0x00;
11813
11814 /* addr1 = DA (current AP) */
11815 hwaddr_aton(bssid, pos);
11816 pos += 6;
11817 /* addr2 = SA (own address) */
11818 hwaddr_aton(addr, pos);
11819 pos += 6;
11820 /* addr3 = BSSID (current AP) */
11821 hwaddr_aton(bssid, pos);
11822 pos += 6;
11823
11824 /* Seq# (to be filled by driver/mac80211) */
11825 *pos++ = 0x00;
11826 *pos++ = 0x00;
11827
11828 if (protected == INCORRECT_KEY) {
11829 /* CCMP parameters */
11830 memcpy(pos, "\x61\x01\x00\x20\x00\x10\x00\x00", 8);
11831 pos += 8;
11832 }
11833
11834 if (protected == INCORRECT_KEY) {
11835 switch (frame) {
11836 case DEAUTH:
11837 /* Reason code (encrypted) */
11838 memcpy(pos, "\xa7\x39", 2);
11839 pos += 2;
11840 break;
11841 case DISASSOC:
11842 /* Reason code (encrypted) */
11843 memcpy(pos, "\xa7\x39", 2);
11844 pos += 2;
11845 break;
11846 case SAQUERY:
11847 /* Category|Action|TransID (encrypted) */
11848 memcpy(pos, "\x6f\xbd\xe9\x4d", 4);
11849 pos += 4;
11850 break;
11851 default:
11852 return -1;
11853 }
11854
11855 /* CCMP MIC */
11856 memcpy(pos, "\xc8\xd8\x3b\x06\x5d\xb7\x25\x68", 8);
11857 pos += 8;
11858 } else {
11859 switch (frame) {
11860 case DEAUTH:
11861 /* reason code = 8 */
11862 *pos++ = 0x08;
11863 *pos++ = 0x00;
11864 break;
11865 case DISASSOC:
11866 /* reason code = 8 */
11867 *pos++ = 0x08;
11868 *pos++ = 0x00;
11869 break;
11870 case SAQUERY:
11871 /* Category - SA Query */
11872 *pos++ = 0x08;
11873 /* SA query Action - Request */
11874 *pos++ = 0x00;
11875 /* Transaction ID */
11876 *pos++ = 0x12;
11877 *pos++ = 0x34;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011878 if (dut->saquery_oci_freq) {
11879 /* OCI IE - Extended ID */
11880 *pos++ = 0xFF;
11881 *pos++ = 0x04;
11882 *pos++ = 0x36;
11883 /* Operating Class */
11884 *pos++ = 0x74;
11885 /* Primary Channel */
11886 *pos++ = freq_to_channel(dut->saquery_oci_freq);
11887 /* Frequency Segment 1 Channel Number */
11888 *pos++ = 0x00;
11889 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011890 break;
11891 case AUTH:
11892 /* Auth Alg (Open) */
11893 *pos++ = 0x00;
11894 *pos++ = 0x00;
11895 /* Seq# */
11896 *pos++ = 0x01;
11897 *pos++ = 0x00;
11898 /* Status code */
11899 *pos++ = 0x00;
11900 *pos++ = 0x00;
11901 break;
11902 case ASSOCREQ:
11903 /* Capability Information */
11904 *pos++ = 0x31;
11905 *pos++ = 0x04;
11906 /* Listen Interval */
11907 *pos++ = 0x0a;
11908 *pos++ = 0x00;
11909 /* SSID */
11910 *pos++ = 0x00;
11911 *pos++ = ssid_len;
11912 memcpy(pos, ssid, ssid_len);
11913 pos += ssid_len;
11914 /* Supported Rates */
11915 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11916 10);
11917 pos += 10;
11918 /* Extended Supported Rates */
11919 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11920 pos += 6;
11921 /* RSN */
11922 memcpy(pos, "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00"
11923 "\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x02\xc0"
11924 "\x00\x00\x00\x00\x0f\xac\x06", 28);
11925 pos += 28;
11926 break;
11927 case REASSOCREQ:
11928 /* Capability Information */
11929 *pos++ = 0x31;
11930 *pos++ = 0x04;
11931 /* Listen Interval */
11932 *pos++ = 0x0a;
11933 *pos++ = 0x00;
11934 /* Current AP */
11935 hwaddr_aton(bssid, pos);
11936 pos += 6;
11937 /* SSID */
11938 *pos++ = 0x00;
11939 *pos++ = ssid_len;
11940 memcpy(pos, ssid, ssid_len);
11941 pos += ssid_len;
11942 /* Supported Rates */
11943 memcpy(pos, "\x01\x08\x02\x04\x0b\x16\x0c\x12\x18\x24",
11944 10);
11945 pos += 10;
11946 /* Extended Supported Rates */
11947 memcpy(pos, "\x32\x04\x30\x48\x60\x6c", 6);
11948 pos += 6;
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053011949 /* RSNE - Group and Pairwise ciphers */
11950 memcpy(pos,
11951 "\x30\x1a\x01\x00\x00\x0f\xac\x04\x01\x00\x00\x0f\xac\x04",
11952 14);
11953 pos += 14;
11954 /* RSNE - AKM Suite count */
11955 *pos++ = 0x01;
11956 *pos++ = 0x00;
11957 /* RSNE - AKM Suites */
11958 if (dut->program == PROGRAM_WPA3)
11959 memcpy(pos, "\x00\x0f\xac\x08", 4);
11960 else
11961 memcpy(pos, "\x00\x0f\xac\x02", 4);
11962 pos += 4;
11963 /* RSNE - Capabilities */
11964 *pos++ = 0xc0;
11965 if (dut->ocvc)
11966 *pos++ = 0x40;
11967 else
11968 *pos++ = 0x00;
11969 /* RSNE - PMKID list and Group Management Ciphers */
11970 memcpy(pos, "\x00\x00\x00\x0f\xac\x06", 6);
11971 pos += 6;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020011972 break;
11973 case DLS_REQ:
11974 /* Category - DLS */
11975 *pos++ = 0x02;
11976 /* DLS Action - Request */
11977 *pos++ = 0x00;
11978 /* Destination MACAddress */
11979 if (dest)
11980 hwaddr_aton(dest, pos);
11981 else
11982 memset(pos, 0, 6);
11983 pos += 6;
11984 /* Source MACAddress */
11985 hwaddr_aton(addr, pos);
11986 pos += 6;
11987 /* Capability Information */
11988 *pos++ = 0x10; /* Privacy */
11989 *pos++ = 0x06; /* QoS */
11990 /* DLS Timeout Value */
11991 *pos++ = 0x00;
11992 *pos++ = 0x01;
11993 /* Supported rates */
11994 *pos++ = 0x01;
11995 *pos++ = 0x08;
11996 *pos++ = 0x0c; /* 6 Mbps */
11997 *pos++ = 0x12; /* 9 Mbps */
11998 *pos++ = 0x18; /* 12 Mbps */
11999 *pos++ = 0x24; /* 18 Mbps */
12000 *pos++ = 0x30; /* 24 Mbps */
12001 *pos++ = 0x48; /* 36 Mbps */
12002 *pos++ = 0x60; /* 48 Mbps */
12003 *pos++ = 0x6c; /* 54 Mbps */
12004 /* TODO: Extended Supported Rates */
12005 /* TODO: HT Capabilities */
12006 break;
12007 }
12008 }
12009
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012010 if (use_monitor) {
12011 s = open_monitor("sigmadut");
12012 if (s < 0) {
12013 send_resp(dut, conn, SIGMA_ERROR,
12014 "errorCode,Failed to open monitor socket");
12015 return 0;
12016 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012017
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012018 res = inject_frame(s, buf, pos - buf, protected == CORRECT_KEY);
12019 if (res < 0) {
12020 send_resp(dut, conn, SIGMA_ERROR,
12021 "errorCode,Failed to inject frame");
12022 close(s);
12023 return 0;
12024 }
12025 if (res < pos - buf) {
12026 send_resp(dut, conn, SIGMA_ERROR,
12027 "errorCode,Only partial frame sent");
12028 close(s);
12029 return 0;
12030 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012031
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012032 close(s);
12033 } else {
12034#ifdef NL80211_SUPPORT
12035 int freq;
12036 char freq_str[10];
12037
12038 if (get_wpa_status(get_station_ifname(dut), "freq",
12039 freq_str, sizeof(freq_str)) < 0) {
12040 send_resp(dut, conn, SIGMA_ERROR,
12041 "errorCode,Could not get current operating frequency");
12042 return 0;
12043 }
12044 freq = atoi(freq_str);
12045
12046 if (nl80211_send_frame_cmd(dut, intf, buf, pos - buf, freq)) {
12047 send_resp(dut, conn, SIGMA_ERROR,
12048 "errorCode,Failed to inject frame");
12049 return 0;
12050 }
12051#else /* NL80211_SUPPORT */
12052 send_resp(dut, conn, SIGMA_ERROR,
12053 "errorCode,Failed to inject frame (no NL80211_SUPPORT)");
12054 return 0;
12055#endif /* NL80211_SUPPORT */
12056 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012057
12058 return 1;
12059#else /* __linux__ */
12060 send_resp(dut, conn, SIGMA_ERROR, "errorCode,sta_send_frame not "
12061 "yet supported");
12062 return 0;
12063#endif /* __linux__ */
12064}
12065
12066
12067static int cmd_sta_send_frame_tdls(struct sigma_dut *dut,
12068 struct sigma_conn *conn,
12069 struct sigma_cmd *cmd)
12070{
12071 const char *intf = get_param(cmd, "Interface");
12072 const char *sta, *val;
12073 unsigned char addr[ETH_ALEN];
12074 char buf[100];
12075
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012076 if (!intf)
12077 return -1;
12078
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012079 sta = get_param(cmd, "peer");
12080 if (sta == NULL)
12081 sta = get_param(cmd, "station");
12082 if (sta == NULL) {
12083 send_resp(dut, conn, SIGMA_ERROR,
12084 "ErrorCode,Missing peer address");
12085 return 0;
12086 }
12087 if (hwaddr_aton(sta, addr) < 0) {
12088 send_resp(dut, conn, SIGMA_ERROR,
12089 "ErrorCode,Invalid peer address");
12090 return 0;
12091 }
12092
12093 val = get_param(cmd, "type");
12094 if (val == NULL)
12095 return -1;
12096
12097 if (strcasecmp(val, "DISCOVERY") == 0) {
12098 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", sta);
12099 if (wpa_command(intf, buf) < 0) {
12100 send_resp(dut, conn, SIGMA_ERROR,
12101 "ErrorCode,Failed to send TDLS discovery");
12102 return 0;
12103 }
12104 return 1;
12105 }
12106
12107 if (strcasecmp(val, "SETUP") == 0) {
12108 int status = 0, timeout = 0;
12109
12110 val = get_param(cmd, "Status");
12111 if (val)
12112 status = atoi(val);
12113
12114 val = get_param(cmd, "Timeout");
12115 if (val)
12116 timeout = atoi(val);
12117
12118 if (status != 0 && status != 37) {
12119 send_resp(dut, conn, SIGMA_ERROR,
12120 "ErrorCode,Unsupported status value");
12121 return 0;
12122 }
12123
12124 if (timeout != 0 && timeout != 301) {
12125 send_resp(dut, conn, SIGMA_ERROR,
12126 "ErrorCode,Unsupported timeout value");
12127 return 0;
12128 }
12129
12130 if (status && timeout) {
12131 send_resp(dut, conn, SIGMA_ERROR,
12132 "ErrorCode,Unsupported timeout+status "
12133 "combination");
12134 return 0;
12135 }
12136
12137 if (status == 37 &&
12138 wpa_command(intf, "SET tdls_testing 0x200")) {
12139 send_resp(dut, conn, SIGMA_ERROR,
12140 "ErrorCode,Failed to enable "
12141 "decline setup response test mode");
12142 return 0;
12143 }
12144
12145 if (timeout == 301) {
12146 int res;
12147 if (dut->no_tpk_expiration)
12148 res = wpa_command(intf,
12149 "SET tdls_testing 0x108");
12150 else
12151 res = wpa_command(intf,
12152 "SET tdls_testing 0x8");
12153 if (res) {
12154 send_resp(dut, conn, SIGMA_ERROR,
12155 "ErrorCode,Failed to set short TPK "
12156 "lifetime");
12157 return 0;
12158 }
12159 }
12160
12161 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", sta);
12162 if (wpa_command(intf, buf) < 0) {
12163 send_resp(dut, conn, SIGMA_ERROR,
12164 "ErrorCode,Failed to send TDLS setup");
12165 return 0;
12166 }
12167 return 1;
12168 }
12169
12170 if (strcasecmp(val, "TEARDOWN") == 0) {
12171 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", sta);
12172 if (wpa_command(intf, buf) < 0) {
12173 send_resp(dut, conn, SIGMA_ERROR,
12174 "ErrorCode,Failed to send TDLS teardown");
12175 return 0;
12176 }
12177 return 1;
12178 }
12179
12180 send_resp(dut, conn, SIGMA_ERROR,
12181 "ErrorCode,Unsupported TDLS frame");
12182 return 0;
12183}
12184
12185
12186static int sta_ap_known(const char *ifname, const char *bssid)
12187{
12188 char buf[4096];
12189
Jouni Malinendd32f192018-09-15 02:55:19 +030012190 snprintf(buf, sizeof(buf), "BSS MASK=1 %s", bssid);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012191 if (wpa_command_resp(ifname, buf, buf, sizeof(buf)) < 0)
12192 return 0;
12193 if (strncmp(buf, "id=", 3) != 0)
12194 return 0;
12195 return 1;
12196}
12197
12198
12199static int sta_scan_ap(struct sigma_dut *dut, const char *ifname,
12200 const char *bssid)
12201{
12202 int res;
12203 struct wpa_ctrl *ctrl;
12204 char buf[256];
12205
12206 if (sta_ap_known(ifname, bssid))
12207 return 0;
12208 sigma_dut_print(dut, DUT_MSG_DEBUG,
12209 "AP not in BSS table - start scan");
12210
12211 ctrl = open_wpa_mon(ifname);
12212 if (ctrl == NULL) {
12213 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
12214 "wpa_supplicant monitor connection");
12215 return -1;
12216 }
12217
12218 if (wpa_command(ifname, "SCAN") < 0) {
12219 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to start scan");
12220 wpa_ctrl_detach(ctrl);
12221 wpa_ctrl_close(ctrl);
12222 return -1;
12223 }
12224
12225 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
12226 buf, sizeof(buf));
12227
12228 wpa_ctrl_detach(ctrl);
12229 wpa_ctrl_close(ctrl);
12230
12231 if (res < 0) {
12232 sigma_dut_print(dut, DUT_MSG_INFO, "Scan did not complete");
12233 return -1;
12234 }
12235
12236 if (sta_ap_known(ifname, bssid))
12237 return 0;
12238 sigma_dut_print(dut, DUT_MSG_INFO, "AP not in BSS table");
12239 return -1;
12240}
12241
12242
12243static int cmd_sta_send_frame_hs2_neighadv(struct sigma_dut *dut,
12244 struct sigma_conn *conn,
12245 struct sigma_cmd *cmd,
12246 const char *intf)
12247{
12248 char buf[200];
12249
12250 snprintf(buf, sizeof(buf), "ndsend 2001:DB8::1 %s", intf);
12251 if (system(buf) != 0) {
12252 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Failed to run "
12253 "ndsend");
12254 return 0;
12255 }
12256
12257 return 1;
12258}
12259
12260
12261static int cmd_sta_send_frame_hs2_neighsolreq(struct sigma_dut *dut,
12262 struct sigma_conn *conn,
12263 struct sigma_cmd *cmd,
12264 const char *intf)
12265{
12266 char buf[200];
12267 const char *ip = get_param(cmd, "SenderIP");
12268
Peng Xu26b356d2017-10-04 17:58:16 -070012269 if (!ip)
12270 return 0;
12271
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012272 snprintf(buf, sizeof(buf), "ndisc6 -nm %s %s -r 4", ip, intf);
12273 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12274 if (system(buf) == 0) {
12275 sigma_dut_print(dut, DUT_MSG_INFO,
12276 "Neighbor Solicitation got a response "
12277 "for %s@%s", ip, intf);
12278 }
12279
12280 return 1;
12281}
12282
12283
12284static int cmd_sta_send_frame_hs2_arpprobe(struct sigma_dut *dut,
12285 struct sigma_conn *conn,
12286 struct sigma_cmd *cmd,
12287 const char *ifname)
12288{
12289 char buf[200];
12290 const char *ip = get_param(cmd, "SenderIP");
12291
12292 if (ip == NULL) {
12293 send_resp(dut, conn, SIGMA_ERROR,
12294 "ErrorCode,Missing SenderIP parameter");
12295 return 0;
12296 }
12297 snprintf(buf, sizeof(buf), "arping -I %s -D %s -c 4", ifname, ip);
12298 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12299 if (system(buf) != 0) {
12300 sigma_dut_print(dut, DUT_MSG_INFO, "arping DAD got a response "
12301 "for %s@%s", ip, ifname);
12302 }
12303
12304 return 1;
12305}
12306
12307
12308static int cmd_sta_send_frame_hs2_arpannounce(struct sigma_dut *dut,
12309 struct sigma_conn *conn,
12310 struct sigma_cmd *cmd,
12311 const char *ifname)
12312{
12313 char buf[200];
12314 char ip[16];
12315 int s;
Peng Xub3756882017-10-04 14:39:09 -070012316 struct ifreq ifr;
12317 struct sockaddr_in saddr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012318
12319 s = socket(PF_INET, SOCK_DGRAM, 0);
Peng Xub3756882017-10-04 14:39:09 -070012320 if (s < 0) {
12321 perror("socket");
12322 return -1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012323 }
12324
Peng Xub3756882017-10-04 14:39:09 -070012325 memset(&ifr, 0, sizeof(ifr));
12326 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
12327 if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
12328 sigma_dut_print(dut, DUT_MSG_INFO,
12329 "Failed to get %s IP address: %s",
12330 ifname, strerror(errno));
12331 close(s);
12332 return -1;
12333 }
12334 close(s);
12335
12336 memcpy(&saddr, &ifr.ifr_addr, sizeof(struct sockaddr_in));
12337 strlcpy(ip, inet_ntoa(saddr.sin_addr), sizeof(ip));
12338
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012339 snprintf(buf, sizeof(buf), "arping -I %s -s %s %s -c 4", ifname, ip,
12340 ip);
12341 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
12342 if (system(buf) != 0) {
12343 }
12344
12345 return 1;
12346}
12347
12348
12349static int cmd_sta_send_frame_hs2_arpreply(struct sigma_dut *dut,
12350 struct sigma_conn *conn,
12351 struct sigma_cmd *cmd,
12352 const char *ifname)
12353{
12354 char buf[200], addr[20];
12355 char dst[ETH_ALEN], src[ETH_ALEN];
12356 short ethtype = htons(ETH_P_ARP);
12357 char *pos;
12358 int s, res;
12359 const char *val;
12360 struct sockaddr_in taddr;
12361
12362 val = get_param(cmd, "dest");
12363 if (val)
12364 hwaddr_aton(val, (unsigned char *) dst);
12365
12366 val = get_param(cmd, "DestIP");
12367 if (val)
12368 inet_aton(val, &taddr.sin_addr);
Peng Xu151c9e12017-10-04 14:39:09 -070012369 else
12370 return -2;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012371
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012372 if (get_wpa_status(get_station_ifname(dut), "address", addr,
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012373 sizeof(addr)) < 0)
12374 return -2;
12375 hwaddr_aton(addr, (unsigned char *) src);
12376
12377 pos = buf;
12378 *pos++ = 0x00;
12379 *pos++ = 0x01;
12380 *pos++ = 0x08;
12381 *pos++ = 0x00;
12382 *pos++ = 0x06;
12383 *pos++ = 0x04;
12384 *pos++ = 0x00;
12385 *pos++ = 0x02;
12386 memcpy(pos, src, ETH_ALEN);
12387 pos += ETH_ALEN;
12388 memcpy(pos, &taddr.sin_addr, 4);
12389 pos += 4;
12390 memcpy(pos, dst, ETH_ALEN);
12391 pos += ETH_ALEN;
12392 memcpy(pos, &taddr.sin_addr, 4);
12393 pos += 4;
12394
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012395 s = open_monitor(get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012396 if (s < 0) {
12397 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to open "
12398 "monitor socket");
12399 return 0;
12400 }
12401
12402 res = inject_eth_frame(s, buf, pos - buf, ethtype, dst, src);
12403 if (res < 0) {
12404 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to "
12405 "inject frame");
Pradeep Reddy POTTETI673d85c2016-07-26 19:08:07 +053012406 close(s);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012407 return 0;
12408 }
12409
12410 close(s);
12411
12412 return 1;
12413}
12414
12415
12416static int cmd_sta_send_frame_hs2_dls_req(struct sigma_dut *dut,
12417 struct sigma_conn *conn,
12418 struct sigma_cmd *cmd,
12419 const char *intf, const char *dest)
12420{
12421 char buf[100];
12422
12423 if (if_nametoindex("sigmadut") == 0) {
12424 snprintf(buf, sizeof(buf),
12425 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012426 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012427 if (system(buf) != 0 ||
12428 if_nametoindex("sigmadut") == 0) {
12429 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
12430 "monitor interface with '%s'", buf);
12431 return -2;
12432 }
12433 }
12434
12435 if (system("ifconfig sigmadut up") != 0) {
12436 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
12437 "monitor interface up");
12438 return -2;
12439 }
12440
Veerendranath Jakkam49774122020-07-05 09:52:18 +053012441 return sta_inject_frame(dut, conn, intf, DLS_REQ, UNPROTECTED, dest, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012442}
12443
12444
12445static int cmd_sta_send_frame_hs2(struct sigma_dut *dut,
12446 struct sigma_conn *conn,
12447 struct sigma_cmd *cmd)
12448{
12449 const char *intf = get_param(cmd, "Interface");
12450 const char *dest = get_param(cmd, "Dest");
12451 const char *type = get_param(cmd, "FrameName");
12452 const char *val;
12453 char buf[200], *pos, *end;
12454 int count, count2;
12455
12456 if (type == NULL)
12457 type = get_param(cmd, "Type");
12458
12459 if (intf == NULL || dest == NULL || type == NULL)
12460 return -1;
12461
12462 if (strcasecmp(type, "NeighAdv") == 0)
12463 return cmd_sta_send_frame_hs2_neighadv(dut, conn, cmd, intf);
12464
12465 if (strcasecmp(type, "NeighSolicitReq") == 0)
12466 return cmd_sta_send_frame_hs2_neighsolreq(dut, conn, cmd, intf);
12467
12468 if (strcasecmp(type, "ARPProbe") == 0)
12469 return cmd_sta_send_frame_hs2_arpprobe(dut, conn, cmd, intf);
12470
12471 if (strcasecmp(type, "ARPAnnounce") == 0)
12472 return cmd_sta_send_frame_hs2_arpannounce(dut, conn, cmd, intf);
12473
12474 if (strcasecmp(type, "ARPReply") == 0)
12475 return cmd_sta_send_frame_hs2_arpreply(dut, conn, cmd, intf);
12476
12477 if (strcasecmp(type, "DLS-request") == 0 ||
12478 strcasecmp(type, "DLSrequest") == 0)
12479 return cmd_sta_send_frame_hs2_dls_req(dut, conn, cmd, intf,
12480 dest);
12481
12482 if (strcasecmp(type, "ANQPQuery") != 0 &&
12483 strcasecmp(type, "Query") != 0) {
12484 send_resp(dut, conn, SIGMA_ERROR,
12485 "ErrorCode,Unsupported HS 2.0 send frame type");
12486 return 0;
12487 }
12488
12489 if (sta_scan_ap(dut, intf, dest) < 0) {
12490 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not find "
12491 "the requested AP");
12492 return 0;
12493 }
12494
12495 pos = buf;
12496 end = buf + sizeof(buf);
12497 count = 0;
12498 pos += snprintf(pos, end - pos, "ANQP_GET %s ", dest);
12499
12500 val = get_param(cmd, "ANQP_CAP_LIST");
12501 if (val && atoi(val)) {
12502 pos += snprintf(pos, end - pos, "%s257", count > 0 ? "," : "");
12503 count++;
12504 }
12505
12506 val = get_param(cmd, "VENUE_NAME");
12507 if (val && atoi(val)) {
12508 pos += snprintf(pos, end - pos, "%s258", count > 0 ? "," : "");
12509 count++;
12510 }
12511
12512 val = get_param(cmd, "NETWORK_AUTH_TYPE");
12513 if (val && atoi(val)) {
12514 pos += snprintf(pos, end - pos, "%s260", count > 0 ? "," : "");
12515 count++;
12516 }
12517
12518 val = get_param(cmd, "ROAMING_CONS");
12519 if (val && atoi(val)) {
12520 pos += snprintf(pos, end - pos, "%s261", count > 0 ? "," : "");
12521 count++;
12522 }
12523
12524 val = get_param(cmd, "IP_ADDR_TYPE_AVAILABILITY");
12525 if (val && atoi(val)) {
12526 pos += snprintf(pos, end - pos, "%s262", count > 0 ? "," : "");
12527 count++;
12528 }
12529
12530 val = get_param(cmd, "NAI_REALM_LIST");
12531 if (val && atoi(val)) {
12532 pos += snprintf(pos, end - pos, "%s263", count > 0 ? "," : "");
12533 count++;
12534 }
12535
12536 val = get_param(cmd, "3GPP_INFO");
12537 if (val && atoi(val)) {
12538 pos += snprintf(pos, end - pos, "%s264", count > 0 ? "," : "");
12539 count++;
12540 }
12541
12542 val = get_param(cmd, "DOMAIN_LIST");
12543 if (val && atoi(val)) {
12544 pos += snprintf(pos, end - pos, "%s268", count > 0 ? "," : "");
12545 count++;
12546 }
12547
Jouni Malinen34cf9532018-04-29 19:26:33 +030012548 val = get_param(cmd, "Venue_URL");
12549 if (val && atoi(val)) {
12550 pos += snprintf(pos, end - pos, "%s277", count > 0 ? "," : "");
12551 count++;
12552 }
12553
Jouni Malinend3bca5d2018-04-29 17:25:23 +030012554 val = get_param(cmd, "Advice_Of_Charge");
12555 if (val && atoi(val)) {
12556 pos += snprintf(pos, end - pos, "%s278", count > 0 ? "," : "");
12557 count++;
12558 }
12559
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012560 if (count && wpa_command(intf, buf)) {
12561 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,ANQP_GET failed");
12562 return 0;
12563 }
12564
12565 pos = buf;
12566 end = buf + sizeof(buf);
12567 count2 = 0;
12568 pos += snprintf(pos, end - pos, "HS20_ANQP_GET %s ", dest);
12569
12570 val = get_param(cmd, "HS_CAP_LIST");
12571 if (val && atoi(val)) {
12572 pos += snprintf(pos, end - pos, "%s2", count2 > 0 ? "," : "");
12573 count2++;
12574 }
12575
12576 val = get_param(cmd, "OPER_NAME");
12577 if (val && atoi(val)) {
12578 pos += snprintf(pos, end - pos, "%s3", count2 > 0 ? "," : "");
12579 count2++;
12580 }
12581
12582 val = get_param(cmd, "WAN_METRICS");
12583 if (!val)
12584 val = get_param(cmd, "WAN_MAT");
12585 if (!val)
12586 val = get_param(cmd, "WAN_MET");
12587 if (val && atoi(val)) {
12588 pos += snprintf(pos, end - pos, "%s4", count2 > 0 ? "," : "");
12589 count2++;
12590 }
12591
12592 val = get_param(cmd, "CONNECTION_CAPABILITY");
12593 if (val && atoi(val)) {
12594 pos += snprintf(pos, end - pos, "%s5", count2 > 0 ? "," : "");
12595 count2++;
12596 }
12597
12598 val = get_param(cmd, "OP_CLASS");
12599 if (val && atoi(val)) {
12600 pos += snprintf(pos, end - pos, "%s7", count2 > 0 ? "," : "");
12601 count2++;
12602 }
12603
12604 val = get_param(cmd, "OSU_PROVIDER_LIST");
12605 if (val && atoi(val)) {
12606 pos += snprintf(pos, end - pos, "%s8", count2 > 0 ? "," : "");
12607 count2++;
12608 }
12609
Jouni Malinenf67afec2018-04-29 19:24:58 +030012610 val = get_param(cmd, "OPER_ICON_METADATA");
12611 if (!val)
12612 val = get_param(cmd, "OPERATOR_ICON_METADATA");
12613 if (val && atoi(val)) {
12614 pos += snprintf(pos, end - pos, "%s12", count2 > 0 ? "," : "");
12615 count2++;
12616 }
12617
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012618 if (count && count2) {
12619 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before sending out "
12620 "second query");
12621 sleep(1);
12622 }
12623
12624 if (count2 && wpa_command(intf, buf)) {
12625 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,HS20_ANQP_GET "
12626 "failed");
12627 return 0;
12628 }
12629
12630 val = get_param(cmd, "NAI_HOME_REALM_LIST");
12631 if (val) {
12632 if (count || count2) {
12633 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12634 "sending out second query");
12635 sleep(1);
12636 }
12637
12638 if (strcmp(val, "1") == 0)
12639 val = "mail.example.com";
12640 snprintf(buf, end - pos,
12641 "HS20_GET_NAI_HOME_REALM_LIST %s realm=%s",
12642 dest, val);
12643 if (wpa_command(intf, buf)) {
12644 send_resp(dut, conn, SIGMA_ERROR,
12645 "ErrorCode,HS20_GET_NAI_HOME_REALM_LIST "
12646 "failed");
12647 return 0;
12648 }
12649 }
12650
12651 val = get_param(cmd, "ICON_REQUEST");
12652 if (val) {
12653 if (count || count2) {
12654 sigma_dut_print(dut, DUT_MSG_DEBUG, "Wait before "
12655 "sending out second query");
12656 sleep(1);
12657 }
12658
12659 snprintf(buf, end - pos,
12660 "HS20_ICON_REQUEST %s %s", dest, val);
12661 if (wpa_command(intf, buf)) {
12662 send_resp(dut, conn, SIGMA_ERROR,
12663 "ErrorCode,HS20_ICON_REQUEST failed");
12664 return 0;
12665 }
12666 }
12667
12668 return 1;
12669}
12670
12671
12672static int ath_sta_send_frame_vht(struct sigma_dut *dut,
12673 struct sigma_conn *conn,
12674 struct sigma_cmd *cmd)
12675{
12676 const char *val;
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012677 const char *ifname;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012678 int chwidth, nss;
12679
12680 val = get_param(cmd, "framename");
12681 if (!val)
12682 return -1;
12683 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12684
12685 /* Command sequence to generate Op mode notification */
12686 if (val && strcasecmp(val, "Op_md_notif_frm") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012687 ifname = get_station_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012688
12689 /* Disable STBC */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012690 run_iwpriv(dut, ifname, "tx_stbc 0");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012691
12692 /* Extract Channel width */
12693 val = get_param(cmd, "Channel_width");
12694 if (val) {
12695 switch (atoi(val)) {
12696 case 20:
12697 chwidth = 0;
12698 break;
12699 case 40:
12700 chwidth = 1;
12701 break;
12702 case 80:
12703 chwidth = 2;
12704 break;
12705 case 160:
12706 chwidth = 3;
12707 break;
12708 default:
12709 chwidth = 2;
12710 break;
12711 }
12712
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012713 run_iwpriv(dut, ifname, "chwidth %d", chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012714 }
12715
12716 /* Extract NSS */
12717 val = get_param(cmd, "NSS");
12718 if (val) {
12719 switch (atoi(val)) {
12720 case 1:
12721 nss = 1;
12722 break;
12723 case 2:
12724 nss = 3;
12725 break;
12726 case 3:
12727 nss = 7;
12728 break;
12729 default:
12730 /* We do not support NSS > 3 */
12731 nss = 3;
12732 break;
12733 }
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012734 run_iwpriv(dut, ifname, "rxchainmask %d", nss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012735 }
12736
12737 /* Opmode notify */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070012738 run_iwpriv(dut, ifname, "opmode_notify 1");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012739 }
12740
12741 return 1;
12742}
12743
12744
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012745static int wcn_sta_set_pmf_config(struct sigma_dut *dut, const char *intf,
12746 enum send_frame_protection protected)
12747{
12748#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012749 return wcn_wifi_test_config_set_u8(
12750 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_PMF_PROTECTION,
12751 protected);
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012752#else /* NL80211_SUPPORT */
12753 sigma_dut_print(dut, DUT_MSG_ERROR,
12754 "PMF config cannot be set without NL80211_SUPPORT defined");
12755 return -1;
12756#endif /* NL80211_SUPPORT */
12757}
12758
12759
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012760static int cmd_sta_send_frame_vht(struct sigma_dut *dut,
12761 struct sigma_conn *conn,
12762 struct sigma_cmd *cmd)
12763{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012764 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020012765 case DRIVER_ATHEROS:
12766 return ath_sta_send_frame_vht(dut, conn, cmd);
12767 default:
12768 send_resp(dut, conn, SIGMA_ERROR,
12769 "errorCode,Unsupported sta_set_frame(VHT) with the current driver");
12770 return 0;
12771 }
12772}
12773
12774
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012775static int wcn_sta_send_disassoc(struct sigma_dut *dut, const char *intf)
12776{
12777#ifdef NL80211_SUPPORT
Veerendranath Jakkam050b85a2020-07-04 04:00:32 +053012778 return wcn_wifi_test_config_set_flag(
12779 dut, intf, QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_DISASSOC_TX);
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012780#else /* NL80211_SUPPORT */
12781 sigma_dut_print(dut, DUT_MSG_ERROR,
12782 "Disassoc Tx cannot be done without NL80211_SUPPORT defined");
12783 return -1;
12784#endif /* NL80211_SUPPORT */
12785}
12786
12787
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012788static int wcn_sta_send_frame_he(struct sigma_dut *dut, struct sigma_conn *conn,
12789 struct sigma_cmd *cmd)
12790{
12791 const char *val;
12792 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012793 enum send_frame_protection protected;
12794 const char *pmf;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012795
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030012796 if (!intf)
12797 return -1;
12798
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012799 val = get_param(cmd, "framename");
12800 if (!val)
12801 return -1;
12802 sigma_dut_print(dut, DUT_MSG_DEBUG, "framename is %s", val);
12803
Kiran Kumar Lokere00d74412020-07-23 13:26:51 -070012804 pmf = get_param(cmd, "PMFProtected");
12805 if (!pmf)
12806 pmf = get_param(cmd, "Protected");
12807 if (pmf) {
12808 if (strcasecmp(pmf, "Correct-key") == 0 ||
12809 strcasecmp(pmf, "CorrectKey") == 0) {
12810 protected = CORRECT_KEY;
12811 } else if (strcasecmp(pmf, "IncorrectKey") == 0) {
12812 protected = INCORRECT_KEY;
12813 } else if (strcasecmp(pmf, "Unprotected") == 0) {
12814 protected = UNPROTECTED;
12815 } else {
12816 send_resp(dut, conn, SIGMA_ERROR,
12817 "errorCode,Unsupported PMFProtected");
12818 return STATUS_SENT_ERROR;
12819 }
12820 sigma_dut_print(dut, DUT_MSG_DEBUG, "Config PMF protection %d",
12821 protected);
12822 wcn_sta_set_pmf_config(dut, intf, protected);
12823 }
12824
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012825 /* Command sequence to generate Op mode notification */
12826 if (val && strcasecmp(val, "action") == 0) {
12827 val = get_param(cmd, "PPDUTxType");
12828 if (val && strcasecmp(val, "TB") == 0) {
12829 if (sta_set_action_tx_in_he_tb_ppdu(dut, intf, 1)) {
12830 sigma_dut_print(dut, DUT_MSG_ERROR,
12831 "failed to send TB PPDU Tx cfg");
12832 send_resp(dut, conn, SIGMA_ERROR,
12833 "ErrorCode,set TB PPDU Tx cfg failed");
12834 return 0;
12835 }
12836 return 1;
12837 }
12838
12839 sigma_dut_print(dut, DUT_MSG_ERROR,
12840 "Action Tx type is not defined");
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012841
12842 return SUCCESS_SEND_STATUS;
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012843 }
12844
Kiran Kumar Lokerec2c3b412020-07-23 13:51:27 -070012845 if (strcasecmp(val, "disassoc") == 0)
12846 wcn_sta_send_disassoc(dut, intf);
12847
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012848 return 1;
12849}
12850
12851
12852static int cmd_sta_send_frame_he(struct sigma_dut *dut,
12853 struct sigma_conn *conn,
12854 struct sigma_cmd *cmd)
12855{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012856 switch (get_driver_type(dut)) {
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070012857 case DRIVER_WCN:
12858 return wcn_sta_send_frame_he(dut, conn, cmd);
12859 default:
12860 send_resp(dut, conn, SIGMA_ERROR,
12861 "errorCode,Unsupported sta_set_frame(HE) with the current driver");
12862 return 0;
12863 }
12864}
12865
12866
Lior David0fe101e2017-03-09 16:09:50 +020012867#ifdef __linux__
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012868
12869static int
12870wil6210_send_p2p_frame_60g(struct sigma_dut *dut, struct sigma_cmd *cmd,
12871 const char *frame_name, const char *dest_mac)
12872{
12873 int isprobereq = strcasecmp(frame_name, "probereq") == 0;
12874 const char *ssid = get_param(cmd, "ssid");
12875 const char *countstr = get_param(cmd, "count");
12876 const char *channelstr = get_param(cmd, "channel");
12877 const char *group_id = get_param(cmd, "groupid");
12878 const char *client_id = get_param(cmd, "clientmac");
12879 int count, channel, freq, i;
12880 const char *fname;
12881 char frame[1024], src_mac[20], group_id_attr[25],
12882 device_macstr[3 * ETH_ALEN], client_mac[ETH_ALEN];
12883 const char *group_ssid;
12884 const int group_ssid_prefix_len = 9;
12885 struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) frame;
12886 size_t framelen = sizeof(frame);
12887 struct template_frame_tag tags[2];
12888 size_t tags_total = ARRAY_SIZE(tags);
12889 int tag_index, len, dst_len;
12890
12891 if (!countstr || !channelstr) {
12892 sigma_dut_print(dut, DUT_MSG_ERROR,
12893 "Missing argument: count, channel");
12894 return -1;
12895 }
12896 if (isprobereq && !ssid) {
12897 sigma_dut_print(dut, DUT_MSG_ERROR,
12898 "Missing argument: ssid");
12899 return -1;
12900 }
12901 if (!isprobereq && (!group_id || !client_id)) {
12902 sigma_dut_print(dut, DUT_MSG_ERROR,
12903 "Missing argument: group_id, client_id");
12904 return -1;
12905 }
12906
12907 count = atoi(countstr);
12908 channel = atoi(channelstr);
12909 freq = channel_to_freq(dut, channel);
12910
12911 if (!freq) {
12912 sigma_dut_print(dut, DUT_MSG_ERROR,
12913 "invalid channel: %s", channelstr);
12914 return -1;
12915 }
12916
12917 if (isprobereq) {
12918 if (strcasecmp(ssid, "wildcard") == 0) {
12919 fname = "probe_req_wildcard.txt";
12920 } else if (strcasecmp(ssid, "P2P_Wildcard") == 0) {
12921 fname = "probe_req_P2P_Wildcard.txt";
12922 } else {
12923 sigma_dut_print(dut, DUT_MSG_ERROR,
12924 "invalid probe request type");
12925 return -1;
12926 }
12927 } else {
12928 fname = "P2P_device_discovery_req.txt";
12929 }
12930
12931 if (parse_template_frame_file(dut, fname, frame, &framelen,
12932 tags, &tags_total)) {
12933 sigma_dut_print(dut, DUT_MSG_ERROR,
12934 "invalid frame template: %s", fname);
12935 return -1;
12936 }
12937
Jouni Malinen016ae6c2019-11-04 17:00:01 +020012938 if (get_wpa_status(get_station_ifname(dut), "address",
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030012939 src_mac, sizeof(src_mac)) < 0 ||
12940 parse_mac_address(dut, src_mac, &hdr->addr2[0]) ||
12941 parse_mac_address(dut, dest_mac, &hdr->addr1[0]))
12942 return -1;
12943 /* Use wildcard BSSID, since we are in PBSS */
12944 memset(&hdr->addr3, 0xFF, ETH_ALEN);
12945
12946 if (!isprobereq) {
12947 tag_index = find_template_frame_tag(tags, tags_total, 1);
12948 if (tag_index < 0) {
12949 sigma_dut_print(dut, DUT_MSG_ERROR,
12950 "can't find device id attribute");
12951 return -1;
12952 }
12953 if (parse_mac_address(dut, client_id,
12954 (unsigned char *) client_mac)) {
12955 sigma_dut_print(dut, DUT_MSG_ERROR,
12956 "invalid client_id: %s", client_id);
12957 return -1;
12958 }
12959 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
12960 framelen - tags[tag_index].offset,
12961 IEEE80211_P2P_ATTR_DEVICE_ID,
12962 client_mac, ETH_ALEN)) {
12963 sigma_dut_print(dut, DUT_MSG_ERROR,
12964 "fail to replace device id attribute");
12965 return -1;
12966 }
12967
12968 /*
12969 * group_id arg contains device MAC address followed by
12970 * space and SSID (DIRECT-somessid).
12971 * group id attribute contains device address (6 bytes)
12972 * followed by SSID prefix DIRECT-XX (9 bytes)
12973 */
12974 if (strlen(group_id) < sizeof(device_macstr)) {
12975 sigma_dut_print(dut, DUT_MSG_ERROR,
12976 "group_id arg too short");
12977 return -1;
12978 }
12979 memcpy(device_macstr, group_id, sizeof(device_macstr));
12980 device_macstr[sizeof(device_macstr) - 1] = '\0';
12981 if (parse_mac_address(dut, device_macstr,
12982 (unsigned char *) group_id_attr)) {
12983 sigma_dut_print(dut, DUT_MSG_ERROR,
12984 "fail to parse device address from group_id");
12985 return -1;
12986 }
12987 group_ssid = strchr(group_id, ' ');
12988 if (!group_ssid) {
12989 sigma_dut_print(dut, DUT_MSG_ERROR,
12990 "invalid group_id arg, no ssid");
12991 return -1;
12992 }
12993 group_ssid++;
12994 len = strlen(group_ssid);
12995 if (len < group_ssid_prefix_len) {
12996 sigma_dut_print(dut, DUT_MSG_ERROR,
12997 "group_id SSID too short");
12998 return -1;
12999 }
13000 dst_len = sizeof(group_id_attr) - ETH_ALEN;
13001 if (len > dst_len) {
13002 sigma_dut_print(dut, DUT_MSG_ERROR,
13003 "group_id SSID (%s) too long",
13004 group_ssid);
13005 return -1;
13006 }
13007
13008 memcpy(group_id_attr + ETH_ALEN, group_ssid, len);
13009 tag_index = find_template_frame_tag(tags, tags_total, 2);
13010 if (tag_index < 0) {
13011 sigma_dut_print(dut, DUT_MSG_ERROR,
13012 "can't find group id attribute");
13013 return -1;
13014 }
13015 if (replace_p2p_attribute(dut, &frame[tags[tag_index].offset],
13016 framelen - tags[tag_index].offset,
13017 IEEE80211_P2P_ATTR_GROUP_ID,
13018 group_id_attr,
13019 sizeof(group_id_attr))) {
13020 sigma_dut_print(dut, DUT_MSG_ERROR,
13021 "fail to replace group id attribute");
13022 return -1;
13023 }
13024 }
13025
13026 for (i = 0; i < count; i++) {
13027 if (wil6210_transmit_frame(dut, freq,
13028 WIL_TRANSMIT_FRAME_DEFAULT_ROC,
13029 frame, framelen)) {
13030 sigma_dut_print(dut, DUT_MSG_ERROR,
13031 "fail to transmit probe request frame");
13032 return -1;
13033 }
13034 }
13035
13036 return 0;
13037}
13038
13039
Lior David0fe101e2017-03-09 16:09:50 +020013040int wil6210_send_frame_60g(struct sigma_dut *dut, struct sigma_conn *conn,
13041 struct sigma_cmd *cmd)
13042{
13043 const char *frame_name = get_param(cmd, "framename");
13044 const char *mac = get_param(cmd, "dest_mac");
13045
13046 if (!frame_name || !mac) {
13047 sigma_dut_print(dut, DUT_MSG_ERROR,
13048 "framename and dest_mac must be provided");
13049 return -1;
13050 }
13051
13052 if (strcasecmp(frame_name, "brp") == 0) {
13053 const char *l_rx = get_param(cmd, "L-RX");
13054 int l_rx_i;
13055
13056 if (!l_rx) {
13057 sigma_dut_print(dut, DUT_MSG_ERROR,
13058 "L-RX must be provided");
13059 return -1;
13060 }
13061 l_rx_i = atoi(l_rx);
13062
13063 sigma_dut_print(dut, DUT_MSG_INFO,
13064 "dev_send_frame: BRP-RX, dest_mac %s, L-RX %s",
13065 mac, l_rx);
13066 if (l_rx_i != 16) {
13067 sigma_dut_print(dut, DUT_MSG_ERROR,
13068 "unsupported L-RX: %s", l_rx);
13069 return -1;
13070 }
13071
13072 if (wil6210_send_brp_rx(dut, mac, l_rx_i))
13073 return -1;
13074 } else if (strcasecmp(frame_name, "ssw") == 0) {
13075 sigma_dut_print(dut, DUT_MSG_INFO,
13076 "dev_send_frame: SLS, dest_mac %s", mac);
13077 if (wil6210_send_sls(dut, mac))
13078 return -1;
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013079 } else if ((strcasecmp(frame_name, "probereq") == 0) ||
13080 (strcasecmp(frame_name, "devdiscreq") == 0)) {
13081 sigma_dut_print(dut, DUT_MSG_INFO,
13082 "dev_send_frame: %s, dest_mac %s", frame_name,
13083 mac);
13084 if (wil6210_send_p2p_frame_60g(dut, cmd, frame_name, mac))
13085 return -1;
Lior David0fe101e2017-03-09 16:09:50 +020013086 } else {
13087 sigma_dut_print(dut, DUT_MSG_ERROR,
13088 "unsupported frame type: %s", frame_name);
13089 return -1;
13090 }
13091
13092 return 1;
13093}
Alexei Avshalom Lazara90032d2019-05-02 13:34:02 +030013094
Lior David0fe101e2017-03-09 16:09:50 +020013095#endif /* __linux__ */
13096
13097
13098static int cmd_sta_send_frame_60g(struct sigma_dut *dut,
13099 struct sigma_conn *conn,
13100 struct sigma_cmd *cmd)
13101{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020013102 switch (get_driver_type(dut)) {
Lior David0fe101e2017-03-09 16:09:50 +020013103#ifdef __linux__
13104 case DRIVER_WIL6210:
13105 return wil6210_send_frame_60g(dut, conn, cmd);
13106#endif /* __linux__ */
13107 default:
13108 send_resp(dut, conn, SIGMA_ERROR,
13109 "errorCode,Unsupported sta_set_frame(60G) with the current driver");
13110 return 0;
13111 }
13112}
13113
13114
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013115static int mbo_send_anqp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13116 const char *intf, struct sigma_cmd *cmd)
13117{
13118 const char *val, *addr;
13119 char buf[100];
13120
13121 addr = get_param(cmd, "DestMac");
13122 if (!addr) {
13123 send_resp(dut, conn, SIGMA_INVALID,
13124 "ErrorCode,AP MAC address is missing");
13125 return 0;
13126 }
13127
13128 val = get_param(cmd, "ANQPQuery_ID");
13129 if (!val) {
13130 send_resp(dut, conn, SIGMA_INVALID,
13131 "ErrorCode,Missing ANQPQuery_ID");
13132 return 0;
13133 }
13134
13135 if (strcasecmp(val, "NeighborReportReq") == 0) {
13136 snprintf(buf, sizeof(buf), "ANQP_GET %s 272", addr);
13137 } else if (strcasecmp(val, "QueryListWithCellPref") == 0) {
13138 snprintf(buf, sizeof(buf), "ANQP_GET %s 272,mbo:2", addr);
13139 } else {
13140 sigma_dut_print(dut, DUT_MSG_ERROR, "Invalid ANQPQuery_ID: %s",
13141 val);
13142 send_resp(dut, conn, SIGMA_INVALID,
13143 "ErrorCode,Invalid ANQPQuery_ID");
13144 return 0;
13145 }
13146
Ashwini Patild174f2c2017-04-13 16:49:46 +053013147 /* Set gas_address3 field to IEEE 802.11-2012 standard compliant form
13148 * (Address3 = Wildcard BSSID when sent to not-associated AP;
13149 * if associated, AP BSSID).
13150 */
13151 if (wpa_command(intf, "SET gas_address3 1") < 0) {
13152 send_resp(dut, conn, SIGMA_ERROR,
13153 "ErrorCode,Failed to set gas_address3");
13154 return 0;
13155 }
13156
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013157 if (wpa_command(intf, buf) < 0) {
13158 send_resp(dut, conn, SIGMA_ERROR,
13159 "ErrorCode,Failed to send ANQP query");
13160 return 0;
13161 }
13162
13163 return 1;
13164}
13165
13166
13167static int mbo_cmd_sta_send_frame(struct sigma_dut *dut,
13168 struct sigma_conn *conn,
13169 const char *intf,
13170 struct sigma_cmd *cmd)
13171{
13172 const char *val = get_param(cmd, "FrameName");
13173
13174 if (val && strcasecmp(val, "ANQPQuery") == 0)
13175 return mbo_send_anqp_query(dut, conn, intf, cmd);
13176
13177 return 2;
13178}
13179
13180
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013181static enum sigma_cmd_result cmd_sta_send_frame_wpa3(struct sigma_dut *dut,
13182 struct sigma_conn *conn,
13183 const char *intf,
13184 struct sigma_cmd *cmd)
13185{
13186 const char *val = get_param(cmd, "framename");
13187
13188 if (!val)
13189 return INVALID_SEND_STATUS;
13190
13191 if (strcasecmp(val, "SAQueryReq") == 0) {
13192 val = get_param(cmd, "OCIChannel");
13193
13194 if (!val) {
13195 send_resp(dut, conn, SIGMA_ERROR,
13196 "errorCode,OCIChannel not present");
13197 return STATUS_SENT_ERROR;
13198 }
13199
13200 dut->saquery_oci_freq = channel_to_freq(dut, atoi(val));
13201 if (!dut->saquery_oci_freq) {
13202 send_resp(dut, conn, SIGMA_ERROR,
13203 "errorCode,Invalid OCIChannel number");
13204 return STATUS_SENT_ERROR;
13205 }
13206
13207 return sta_inject_frame(dut, conn, intf, SAQUERY, CORRECT_KEY,
13208 NULL, 0);
13209 }
13210
13211 if (strcasecmp(val, "reassocreq") == 0)
13212 return sta_inject_frame(dut, conn, intf, REASSOCREQ,
13213 CORRECT_KEY, NULL, 0);
13214
Veerendranath9f81dfb2020-08-10 01:21:29 -070013215 if (strcasecmp(val, "ANQPQuery") == 0) {
13216 char buf[50];
13217 const char *dest = get_param(cmd, "DestMac");
13218 const char *chan = get_param(cmd, "channel");
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013219 const char *freq_str = get_param(cmd, "ChnlFreq");
Veerendranath9f81dfb2020-08-10 01:21:29 -070013220 int len, freq;
13221
Veerendranath Jakkam78862fc2020-11-19 21:23:27 +053013222 if (freq_str)
13223 freq = atoi(freq_str);
13224 else
13225 freq = chan ? channel_to_freq(dut, atoi(chan)) : 0;
13226
Veerendranath9f81dfb2020-08-10 01:21:29 -070013227 if (!dest || !freq)
13228 return INVALID_SEND_STATUS;
13229
13230 len = snprintf(buf, sizeof(buf), "ANQP_GET %s freq=%d 257",
13231 dest, freq);
13232 if (len < 0 || len >= sizeof(buf)) {
13233 sigma_dut_print(dut, DUT_MSG_ERROR,
13234 "Failed to allocate buf");
13235 return ERROR_SEND_STATUS;
13236 }
13237
13238 if (wpa_command(intf, buf) != 0) {
13239 send_resp(dut, conn, SIGMA_ERROR,
13240 "ErrorCode,Failed to send ANQP Query frame");
13241 return STATUS_SENT_ERROR;
13242 }
13243
13244 sigma_dut_print(dut, DUT_MSG_DEBUG,
13245 "ANQP Query sent: %s", buf);
13246
13247 return SUCCESS_SEND_STATUS;
13248 }
13249
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013250 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported framename");
13251 return STATUS_SENT_ERROR;
13252}
13253
13254
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013255static int
13256get_type4_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13257 char *pos, int rem_len, int num_of_scs_desc,
13258 int num_of_tclas_elem)
13259{
13260 const char *val;
13261 int ipv6;
13262 int len, total_len = 0;
13263
13264 val = get_param_fmt(cmd, "TCLASElem_Version_%d_%d", num_of_scs_desc,
13265 num_of_tclas_elem);
13266 if (!val) {
13267 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version empty",
13268 __func__);
13269 return -1;
13270 }
13271
13272 if (strcmp(val, "6") == 0) {
13273 ipv6 = 1;
13274 } else if (strcmp(val, "4") == 0) {
13275 ipv6 = 0;
13276 } else {
13277 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: ip_version invalid",
13278 __func__);
13279 return -1;
13280 }
13281
13282 len = snprintf(pos, rem_len, " ip_version=%s", ipv6 ? "ipv6" : "ipv4");
13283 if (len < 0 || len >= rem_len)
13284 return -1;
13285
13286 pos += len;
13287 rem_len -= len;
13288 total_len += len;
13289
13290 val = get_param_fmt(cmd, "TCLASElem_SourceIPAddr_%d_%d",
13291 num_of_scs_desc, num_of_tclas_elem);
13292 if (val) {
13293 len = snprintf(pos, rem_len, " src_ip=%s", val);
13294 if (len < 0 || len >= rem_len)
13295 return -1;
13296
13297 pos += len;
13298 rem_len -= len;
13299 total_len += len;
13300 }
13301
13302 val = get_param_fmt(cmd, "TCLASElem_DestinationIPAddr_%d_%d",
13303 num_of_scs_desc, num_of_tclas_elem);
13304 if (val) {
13305 len = snprintf(pos, rem_len, " dst_ip=%s", val);
13306 if (len < 0 || len >= rem_len)
13307 return -1;
13308
13309 pos += len;
13310 rem_len -= len;
13311 total_len += len;
13312 }
13313
13314 val = get_param_fmt(cmd, "TCLASElem_SourcePort_%d_%d", num_of_scs_desc,
13315 num_of_tclas_elem);
13316 if (val) {
13317 len = snprintf(pos, rem_len, " src_port=%s", val);
13318 if (len < 0 || len >= rem_len)
13319 return -1;
13320
13321 pos += len;
13322 rem_len -= len;
13323 total_len += len;
13324 }
13325
13326 val = get_param_fmt(cmd, "TCLASElem_DestinationPort_%d_%d",
13327 num_of_scs_desc, num_of_tclas_elem);
13328 if (val) {
13329 len = snprintf(pos, rem_len, " dst_port=%s", val);
13330 if (len < 0 || len >= rem_len)
13331 return -1;
13332
13333 pos += len;
13334 rem_len -= len;
13335 total_len += len;
13336 }
13337
13338 val = get_param_fmt(cmd, "TCLASElem_DSCP_%d_%d", num_of_scs_desc,
13339 num_of_tclas_elem);
13340 if (val) {
13341 len = snprintf(pos, rem_len, " dscp=%s", val);
13342 if (len < 0 || len >= rem_len)
13343 return -1;
13344
13345 pos += len;
13346 rem_len -= len;
13347 total_len += len;
13348 }
13349
13350 val = get_param_fmt(cmd, "TCLASElem_ProtocolNxtHeader_%d_%d",
13351 num_of_scs_desc, num_of_tclas_elem);
13352 if (val) {
13353 char *prot;
13354
13355 switch (atoi(val)) {
13356 case 17:
13357 prot = "udp";
13358 break;
13359 case 6:
13360 prot = "tcp";
13361 break;
13362 case 50:
13363 prot = "esp";
13364 break;
13365 default:
13366 sigma_dut_print(dut, DUT_MSG_ERROR,
13367 "Invalid protocol %d", atoi(val));
13368 return -1;
13369 }
13370
13371 if (ipv6)
13372 len = snprintf(pos, rem_len, " next_header=%s", prot);
13373 else
13374 len = snprintf(pos, rem_len, " protocol=%s", prot);
13375 if (len < 0 || len >= rem_len)
13376 return -1;
13377
13378 pos += len;
13379 rem_len -= len;
13380 total_len += len;
13381 }
13382
13383 return total_len;
13384}
13385
13386
13387static int
13388get_type10_frame_classifier(struct sigma_dut *dut, struct sigma_cmd *cmd,
13389 char *pos, int rem_len, int num_of_scs_desc,
13390 int num_of_tclas_elem)
13391{
13392 const char *val;
13393 int len, total_len = 0;
13394
13395 val = get_param_fmt(cmd, "TCLASElem_ProtoInstance_%d_%d",
13396 num_of_scs_desc, num_of_tclas_elem);
13397 if (val) {
13398 len = snprintf(pos, rem_len, " prot_instance=%s",
13399 val);
13400 if (len < 0 || len >= rem_len)
13401 return -1;
13402
13403 pos += len;
13404 rem_len -= len;
13405 total_len += len;
13406 }
13407
13408 val = get_param_fmt(cmd, "TCLASElem_ProtoNumNextHeader_%d_%d",
13409 num_of_scs_desc, num_of_tclas_elem);
13410 if (val) {
13411 char *prot;
13412
13413 switch (atoi(val)) {
13414 case 17:
13415 prot = "udp";
13416 break;
13417 case 6:
13418 prot = "tcp";
13419 break;
13420 case 50:
13421 prot = "esp";
13422 break;
13423 default:
13424 sigma_dut_print(dut, DUT_MSG_ERROR,
13425 "Invalid protocol %d",
13426 atoi(val));
13427 return -1;
13428 }
13429
13430 len = snprintf(pos, rem_len, " prot_number=%s", prot);
13431 if (len < 0 || len >= rem_len)
13432 return -1;
13433
13434 pos += len;
13435 rem_len -= len;
13436 total_len += len;
13437 }
13438
13439 val = get_param_fmt(cmd, "TCLASElem_FilterValue_%d_%d",
13440 num_of_scs_desc, num_of_tclas_elem);
13441 if (val) {
13442 len = snprintf(pos, rem_len, " filter_value=%s", (val + 2));
13443 if (len < 0 || len >= rem_len)
13444 return -1;
13445
13446 pos += len;
13447 rem_len -= len;
13448 total_len += len;
13449 }
13450
13451 val = get_param_fmt(cmd, "TCLASElem_FilterMask_%d_%d", num_of_scs_desc,
13452 num_of_tclas_elem);
13453 if (val && strlen(val) >= 2) {
13454 len = snprintf(pos, rem_len, " filter_mask=%s", val + 2);
13455 if (len < 0 || len >= rem_len)
13456 return -1;
13457
13458 pos += len;
13459 rem_len -= len;
13460 total_len += len;
13461 }
13462
13463 return total_len;
13464}
13465
13466
13467static enum sigma_cmd_result
13468cmd_sta_send_frame_scs(struct sigma_dut *dut, struct sigma_conn *conn,
13469 const char *intf, struct sigma_cmd *cmd)
13470{
13471 char buf[4096], *pos;
13472 const char *val, *scs_id, *classifier_type;
13473 int len, rem_len, total_bytes;
13474 int num_of_scs_desc = 0, num_of_tclas_elem = 0;
13475
13476 scs_id = get_param(cmd, "SCSDescrElem_SCSID_1");
13477 if (!scs_id) {
13478 sigma_dut_print(dut, DUT_MSG_ERROR, "SCS ID empty");
13479 return INVALID_SEND_STATUS;
13480 }
13481
13482 rem_len = sizeof(buf);
13483 pos = buf;
13484
13485 len = snprintf(buf, sizeof(buf), "SCS");
13486 if (len < 0 || len > rem_len)
13487 goto fail;
13488
13489 pos += len;
13490 rem_len -= len;
13491
13492 while (scs_id) {
13493 num_of_scs_desc++;
13494
13495 val = get_param_fmt(cmd, "SCSDescrElem_RequestType_%d",
13496 num_of_scs_desc);
13497 if (!val)
13498 return INVALID_SEND_STATUS;
13499
13500 if (strcasecmp(val, "Add") == 0) {
13501 len = snprintf(pos, rem_len, " scs_id=%s add",
13502 scs_id);
13503 } else if (strcasecmp(val, "Change") == 0) {
13504 len = snprintf(pos, rem_len, " scs_id=%s change",
13505 scs_id);
13506 } else if (strcasecmp(val, "Remove") == 0) {
13507 len = snprintf(pos, rem_len, " scs_id=%s remove",
13508 scs_id);
13509 if (len < 0 || len >= rem_len)
13510 goto fail;
13511
13512 pos += len;
13513 rem_len -= len;
13514 goto scs_desc_end;
13515 } else {
13516 sigma_dut_print(dut, DUT_MSG_ERROR,
13517 "%s: request type - %s is invalid",
13518 __func__, val);
13519 return INVALID_SEND_STATUS;
13520 }
13521
13522 if (len < 0 || len >= rem_len)
13523 goto fail;
13524
13525 pos += len;
13526 rem_len -= len;
13527
13528 val = get_param_fmt(cmd, "IntraAccessCatElem_UP_%d",
13529 num_of_scs_desc);
13530 if (!val) {
13531 sigma_dut_print(dut, DUT_MSG_ERROR,
13532 "IntraAccess Priority empty");
13533 return INVALID_SEND_STATUS;
13534 }
13535
13536 len = snprintf(pos, rem_len, " scs_up=%s", val);
13537 if (len < 0 || len >= rem_len)
13538 goto fail;
13539
13540 pos += len;
13541 rem_len -= len;
13542
13543 classifier_type = get_param_fmt(cmd,
13544 "TCLASElem_ClassifierType_%d_1",
13545 num_of_scs_desc);
13546 if (!classifier_type) {
13547 sigma_dut_print(dut, DUT_MSG_ERROR,
13548 "classifier type missing");
13549 return INVALID_SEND_STATUS;
13550 }
13551
13552 while (classifier_type) {
13553 num_of_tclas_elem++;
13554
13555 len = snprintf(pos, rem_len, " classifier_type=%s",
13556 classifier_type);
13557 if (len < 0 || len >= rem_len)
13558 goto fail;
13559
13560 pos += len;
13561 rem_len -= len;
13562
13563 if (strcmp(classifier_type, "10") == 0) {
13564 total_bytes = get_type10_frame_classifier(
13565 dut, cmd, pos, rem_len,
13566 num_of_scs_desc,
13567 num_of_tclas_elem);
13568 } else if (strcmp(classifier_type, "4") == 0) {
13569 total_bytes = get_type4_frame_classifier(
13570 dut, cmd, pos, rem_len,
13571 num_of_scs_desc,
13572 num_of_tclas_elem);
13573 } else {
13574 sigma_dut_print(dut, DUT_MSG_ERROR,
13575 "classifier_type invalid");
13576 goto fail;
13577 }
13578
13579 if (total_bytes < 0)
13580 goto fail;
13581
13582 pos += total_bytes;
13583 rem_len -= total_bytes;
13584
13585 classifier_type = get_param_fmt(
13586 cmd, "TCLASElem_ClassifierType_%d_%d",
13587 num_of_scs_desc, num_of_tclas_elem + 1);
13588 }
13589
13590 if (num_of_tclas_elem > 1) {
13591 val = get_param_fmt(cmd,
13592 "TCLASProcessingElem_Processing_%d",
13593 num_of_scs_desc);
13594 if (!val) {
13595 sigma_dut_print(dut, DUT_MSG_ERROR,
13596 "Tclas_processing element %d empty",
13597 num_of_scs_desc);
13598 goto fail;
13599 }
13600
13601 len = snprintf(pos, rem_len,
13602 " tclas_processing=%s", val);
13603 if (len < 0 || len >= rem_len)
13604 goto fail;
13605
13606 pos += len;
13607 rem_len -= len;
13608 }
13609scs_desc_end:
13610 num_of_tclas_elem = 0;
13611 scs_id = get_param_fmt(cmd, "SCSDescrElem_SCSID_%d",
13612 num_of_scs_desc + 1);
13613 }
13614
13615 if (wpa_command(intf, buf) != 0) {
13616 send_resp(dut, conn, SIGMA_ERROR,
13617 "ErrorCode,Failed to send SCS frame request");
13618 return STATUS_SENT_ERROR;
13619 }
13620
13621 sigma_dut_print(dut, DUT_MSG_DEBUG,
13622 "SCS frame request sent: %s", buf);
13623
13624 return SUCCESS_SEND_STATUS;
13625fail:
13626 sigma_dut_print(dut, DUT_MSG_ERROR,
13627 "Failed to create SCS frame request");
13628 return ERROR_SEND_STATUS;
13629}
13630
13631
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013632static enum sigma_cmd_result
13633cmd_sta_send_frame_mscs(struct sigma_dut *dut, struct sigma_conn *conn,
13634 const char *intf, struct sigma_cmd *cmd)
13635{
13636 char buf[128], *pos;
13637 const char *val, *classifier_type = "04", *type;
13638 int len, rem_len;
13639 u8 up_bitmap;
13640
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013641 type = get_param(cmd, "Request_Type");
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013642 if (!type) {
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013643 sigma_dut_print(dut, DUT_MSG_ERROR,
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013644 "%s: type not valid", __func__);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013645 return INVALID_SEND_STATUS;
13646 }
13647
13648 rem_len = sizeof(buf);
13649 pos = buf;
13650 if (strcasecmp(type, "add") == 0) {
13651 len = snprintf(pos, rem_len, "MSCS add");
13652 } else if (strcasecmp(type, "update") == 0) {
13653 len = snprintf(pos, rem_len, "MSCS change");
13654 } else if (strcasecmp(type, "remove") == 0) {
13655 if (wpa_command(intf, "MSCS remove") != 0) {
13656 send_resp(dut, conn, SIGMA_ERROR,
13657 "ErrorCode,Failed to send MSCS frame req");
13658 return STATUS_SENT_ERROR;
13659 }
13660 return SUCCESS_SEND_STATUS;
13661 } else {
13662 sigma_dut_print(dut, DUT_MSG_ERROR,
13663 "%s: request type invalid", __func__);
13664 return INVALID_SEND_STATUS;
13665 }
13666
13667 if (len < 0 || len >= rem_len)
13668 goto fail;
13669
13670 pos += len;
13671 rem_len -= len;
13672
13673 val = get_param(cmd, "User_Priority_Bitmap");
13674 if (!val) {
13675 sigma_dut_print(dut, DUT_MSG_ERROR,
13676 "%s: user priority bitmap empty", __func__);
13677 return INVALID_SEND_STATUS;
13678 }
13679
13680 switch (atoi(val)) {
13681 case 0:
13682 up_bitmap = 0x00;
13683 break;
13684 case 1:
13685 up_bitmap = 0xF0;
13686 break;
13687 case 2:
13688 up_bitmap = 0xF6;
13689 break;
13690 default:
13691 sigma_dut_print(dut, DUT_MSG_ERROR,
13692 "%s: Unknown User_Priority_Bitmap value %d",
13693 __func__, atoi(val));
13694 return INVALID_SEND_STATUS;
13695 }
13696
13697 len = snprintf(pos, rem_len, " up_bitmap=%02x", up_bitmap);
13698 if (len < 0 || len >= rem_len)
13699 goto fail;
13700
13701 pos += len;
13702 rem_len -= len;
13703
13704 val = get_param(cmd, "User_Priority_Limit");
13705 if (!val) {
13706 sigma_dut_print(dut, DUT_MSG_ERROR,
13707 "%s: invalid user priority limit", __func__);
13708 return INVALID_SEND_STATUS;
13709 }
13710
13711 len = snprintf(pos, rem_len, " up_limit=%s", val);
13712 if (len < 0 || len >= rem_len)
13713 goto fail;
13714
13715 pos += len;
13716 rem_len -= len;
13717
13718 val = get_param(cmd, "Stream_Timeout");
13719 if (!val)
13720 val = get_param(cmd, "Stream_Timtout");
13721 if (!val) {
13722 sigma_dut_print(dut, DUT_MSG_ERROR,
13723 "%s: invalid stream timeout", __func__);
13724 return INVALID_SEND_STATUS;
13725 }
13726
13727 len = snprintf(pos, rem_len, " stream_timeout=%s", val);
13728 if (len < 0 || len >= rem_len)
13729 goto fail;
13730
13731 pos += len;
13732 rem_len -= len;
13733
13734 val = get_param(cmd, "TCLAS_Mask");
13735 if (!val) {
13736 sigma_dut_print(dut, DUT_MSG_ERROR,
13737 "%s: invalid tclas mask", __func__);
13738 return INVALID_SEND_STATUS;
13739 }
13740
13741 len = snprintf(pos, rem_len, " frame_classifier=%s%lx%032x",
13742 classifier_type, strtol(val, NULL, 2), 0);
13743 if (len < 0 || len >= rem_len)
13744 goto fail;
13745
13746 if (wpa_command(intf, buf) != 0) {
13747 send_resp(dut, conn, SIGMA_ERROR,
13748 "ErrorCode,Failed to send MSCS frame req");
13749 return STATUS_SENT_ERROR;
13750 }
13751
13752 sigma_dut_print(dut, DUT_MSG_DEBUG,
13753 "MSCS frame request sent: %s", buf);
13754
13755 return SUCCESS_SEND_STATUS;
13756fail:
13757 sigma_dut_print(dut, DUT_MSG_ERROR,
13758 "Failed to create MSCS frame req");
13759 return ERROR_SEND_STATUS;
13760}
13761
13762
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013763static enum sigma_cmd_result
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013764cmd_sta_send_frame_dscp_query(struct sigma_dut *dut, struct sigma_conn *conn,
13765 const char *intf, struct sigma_cmd *cmd)
13766{
13767 char buf[150], *pos;
13768 const char *val;
13769 int len, rem_len;
13770
13771 rem_len = sizeof(buf);
13772 pos = buf;
13773
13774 len = snprintf(pos, rem_len, "DSCP_QUERY");
13775 if (len < 0 || len >= rem_len)
13776 goto fail;
13777
13778 pos += len;
13779 rem_len -= len;
13780
13781 val = get_param(cmd, "Wildcard");
13782 if (val && strcasecmp(val, "Yes") == 0) {
13783 len = snprintf(pos, rem_len, " wildcard");
13784 if (len < 0 || len >= rem_len)
13785 goto fail;
13786 } else if (strlen(dut->qm_domain_name)) {
13787 len = snprintf(pos, rem_len, " domain_name=%s",
13788 dut->qm_domain_name);
13789 if (len < 0 || len >= rem_len)
13790 goto fail;
13791 } else {
13792 sigma_dut_print(dut, DUT_MSG_ERROR,
13793 "Invalid DSCP Query configuration");
13794 return INVALID_SEND_STATUS;
13795 }
13796
13797 if (wpa_command(intf, buf) != 0) {
13798 send_resp(dut, conn, SIGMA_ERROR,
13799 "ErrorCode,Failed to send DSCP policy query frame");
13800 return STATUS_SENT_ERROR;
13801 }
13802
13803 sigma_dut_print(dut, DUT_MSG_DEBUG,
13804 "DSCP policy query frame sent: %s", buf);
13805 return SUCCESS_SEND_STATUS;
13806fail:
13807 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to send DSCP query");
13808 return ERROR_SEND_STATUS;
13809}
13810
13811
13812static enum sigma_cmd_result
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013813cmd_sta_send_frame_dscp_response(struct sigma_dut *dut, struct sigma_conn *conn,
13814 const char *intf, struct sigma_cmd *cmd)
13815{
13816 char buf[256], *pos, *item, *list, *saveptr;
13817 const char *val;
13818 int len, rem_len;
13819
13820 pos = buf;
13821 rem_len = sizeof(buf);
13822
13823 len = snprintf(pos, rem_len, "DSCP_RESP");
13824 if (snprintf_error(rem_len, len)) {
13825 sigma_dut_print(dut, DUT_MSG_ERROR,
13826 "Failed to create DSCP Policy Response command");
13827 return ERROR_SEND_STATUS;
13828 }
13829
13830 pos += len;
13831 rem_len -= len;
13832
13833 val = get_param(cmd, "PolicyID_List");
13834 if (!val) {
13835 sigma_dut_print(dut, DUT_MSG_ERROR,
13836 "DSCP policy ID list missing");
13837 return INVALID_SEND_STATUS;
13838 }
13839
13840 list = strdup(val);
13841 if (!list)
13842 return ERROR_SEND_STATUS;
13843
13844 item = strtok_r(list, "_", &saveptr);
13845 while (item) {
13846 unsigned int i;
13847 int policy_id = atoi(item);
13848
13849 for (i = 0; i < dut->num_dscp_status; i++)
13850 if (dut->dscp_status[i].id == policy_id)
13851 break;
13852
13853 if (i == dut->num_dscp_status) {
13854 free(list);
13855 send_resp(dut, conn, SIGMA_ERROR,
13856 "ErrorCode,DSCP policy id not found in status list");
13857 return STATUS_SENT_ERROR;
13858 }
13859
13860 len = snprintf(pos, rem_len, " policy_id=%d status=%d",
13861 policy_id, dut->dscp_status[i].status);
13862 if (snprintf_error(rem_len, len)) {
13863 free(list);
13864 sigma_dut_print(dut, DUT_MSG_ERROR,
13865 "Failed to write DSCP policy list");
13866 return ERROR_SEND_STATUS;
13867 }
13868
13869 pos += len;
13870 rem_len -= len;
13871
13872 if (dut->dscp_status[i].status)
13873 remove_dscp_policy(dut, policy_id);
13874
13875 item = strtok_r(NULL, "_", &saveptr);
13876 }
13877
13878 free(list);
13879
13880 if (wpa_command(intf, buf) != 0) {
13881 send_resp(dut, conn, SIGMA_ERROR,
13882 "ErrorCode,Failed to send DSCP Policy Response frame");
13883 return STATUS_SENT_ERROR;
13884 }
13885
13886 sigma_dut_print(dut, DUT_MSG_DEBUG,
13887 "DSCP Policy Response frame sent: %s", buf);
13888 return SUCCESS_SEND_STATUS;
13889}
13890
13891
13892static enum sigma_cmd_result
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013893cmd_sta_send_frame_qm(struct sigma_dut *dut, struct sigma_conn *conn,
13894 const char *intf, struct sigma_cmd *cmd)
13895{
13896 const char *val;
13897
13898 val = get_param(cmd, "FrameName");
13899 if (val) {
13900 if (strcasecmp(val, "MSCSReq") == 0)
13901 return cmd_sta_send_frame_mscs(dut, conn, intf, cmd);
13902 if (strcasecmp(val, "SCSReq") == 0)
13903 return cmd_sta_send_frame_scs(dut, conn, intf, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053013904 if (strcasecmp(val, "DSCPPolicyQuery") == 0)
13905 return cmd_sta_send_frame_dscp_query(dut, conn, intf,
13906 cmd);
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053013907 if (strcasecmp(val, "DSCPPolicyResponse") == 0)
13908 return cmd_sta_send_frame_dscp_response(dut, conn, intf,
13909 cmd);
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013910
13911 sigma_dut_print(dut, DUT_MSG_ERROR,
13912 "%s: frame name - %s is invalid",
13913 __func__, val);
13914 }
13915
13916 return INVALID_SEND_STATUS;
13917}
13918
13919
Jouni Malinenf7222712019-06-13 01:50:21 +030013920enum sigma_cmd_result cmd_sta_send_frame(struct sigma_dut *dut,
13921 struct sigma_conn *conn,
13922 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013923{
13924 const char *intf = get_param(cmd, "Interface");
13925 const char *val;
13926 enum send_frame_type frame;
13927 enum send_frame_protection protected;
13928 char buf[100];
13929 unsigned char addr[ETH_ALEN];
13930 int res;
13931
Alexei Avshalom Lazar4a3c2f82019-05-02 13:35:37 +030013932 if (!intf)
13933 return -1;
13934
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013935 val = get_param(cmd, "program");
13936 if (val == NULL)
13937 val = get_param(cmd, "frame");
13938 if (val && strcasecmp(val, "TDLS") == 0)
13939 return cmd_sta_send_frame_tdls(dut, conn, cmd);
13940 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030013941 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020013942 strcasecmp(val, "HS2-R3") == 0 ||
13943 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013944 return cmd_sta_send_frame_hs2(dut, conn, cmd);
13945 if (val && strcasecmp(val, "VHT") == 0)
13946 return cmd_sta_send_frame_vht(dut, conn, cmd);
Kiran Kumar Lokere419f6962018-10-24 19:03:04 -070013947 if (val && strcasecmp(val, "HE") == 0)
13948 return cmd_sta_send_frame_he(dut, conn, cmd);
priyadharshini gowthamand66913a2016-07-29 15:11:17 -070013949 if (val && strcasecmp(val, "LOC") == 0)
13950 return loc_cmd_sta_send_frame(dut, conn, cmd);
Lior David0fe101e2017-03-09 16:09:50 +020013951 if (val && strcasecmp(val, "60GHz") == 0)
13952 return cmd_sta_send_frame_60g(dut, conn, cmd);
Ashwini Patildb59b3c2017-04-13 15:19:23 +053013953 if (val && strcasecmp(val, "MBO") == 0) {
13954 res = mbo_cmd_sta_send_frame(dut, conn, intf, cmd);
13955 if (res != 2)
13956 return res;
13957 }
Veerendranath Jakkam54ddc352020-07-05 15:47:54 +053013958 if (val && strcasecmp(val, "WPA3") == 0)
13959 return cmd_sta_send_frame_wpa3(dut, conn, intf, cmd);
Vinita S. Malooee9e7e92020-04-28 16:26:50 +053013960 if (val && strcasecmp(val, "QM") == 0)
Vinita S. Malooca85fd22021-01-15 02:54:34 +053013961 return cmd_sta_send_frame_qm(dut, conn, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020013962
13963 val = get_param(cmd, "TD_DISC");
13964 if (val) {
13965 if (hwaddr_aton(val, addr) < 0)
13966 return -1;
13967 snprintf(buf, sizeof(buf), "TDLS_DISCOVER %s", val);
13968 if (wpa_command(intf, buf) < 0) {
13969 send_resp(dut, conn, SIGMA_ERROR,
13970 "ErrorCode,Failed to send TDLS discovery");
13971 return 0;
13972 }
13973 return 1;
13974 }
13975
13976 val = get_param(cmd, "TD_Setup");
13977 if (val) {
13978 if (hwaddr_aton(val, addr) < 0)
13979 return -1;
13980 snprintf(buf, sizeof(buf), "TDLS_SETUP %s", val);
13981 if (wpa_command(intf, buf) < 0) {
13982 send_resp(dut, conn, SIGMA_ERROR,
13983 "ErrorCode,Failed to start TDLS setup");
13984 return 0;
13985 }
13986 return 1;
13987 }
13988
13989 val = get_param(cmd, "TD_TearDown");
13990 if (val) {
13991 if (hwaddr_aton(val, addr) < 0)
13992 return -1;
13993 snprintf(buf, sizeof(buf), "TDLS_TEARDOWN %s", val);
13994 if (wpa_command(intf, buf) < 0) {
13995 send_resp(dut, conn, SIGMA_ERROR,
13996 "ErrorCode,Failed to tear down TDLS link");
13997 return 0;
13998 }
13999 return 1;
14000 }
14001
14002 val = get_param(cmd, "TD_ChannelSwitch");
14003 if (val) {
14004 /* TODO */
14005 send_resp(dut, conn, SIGMA_ERROR,
14006 "ErrorCode,TD_ChannelSwitch not yet supported");
14007 return 0;
14008 }
14009
14010 val = get_param(cmd, "TD_NF");
14011 if (val) {
14012 /* TODO */
14013 send_resp(dut, conn, SIGMA_ERROR,
14014 "ErrorCode,TD_NF not yet supported");
14015 return 0;
14016 }
14017
14018 val = get_param(cmd, "PMFFrameType");
14019 if (val == NULL)
14020 val = get_param(cmd, "FrameName");
14021 if (val == NULL)
14022 val = get_param(cmd, "Type");
14023 if (val == NULL)
14024 return -1;
14025 if (strcasecmp(val, "disassoc") == 0)
14026 frame = DISASSOC;
14027 else if (strcasecmp(val, "deauth") == 0)
14028 frame = DEAUTH;
14029 else if (strcasecmp(val, "saquery") == 0)
14030 frame = SAQUERY;
14031 else if (strcasecmp(val, "auth") == 0)
14032 frame = AUTH;
14033 else if (strcasecmp(val, "assocreq") == 0)
14034 frame = ASSOCREQ;
14035 else if (strcasecmp(val, "reassocreq") == 0)
14036 frame = REASSOCREQ;
14037 else if (strcasecmp(val, "neigreq") == 0) {
14038 sigma_dut_print(dut, DUT_MSG_INFO, "Got neighbor request");
14039
14040 val = get_param(cmd, "ssid");
14041 if (val == NULL)
14042 return -1;
14043
14044 res = send_neighbor_request(dut, intf, val);
14045 if (res) {
14046 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14047 "Failed to send neighbor report request");
14048 return 0;
14049 }
14050
14051 return 1;
Ashwini Patil5acd7382017-04-13 15:55:04 +053014052 } else if (strcasecmp(val, "transmgmtquery") == 0 ||
14053 strcasecmp(val, "BTMQuery") == 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014054 sigma_dut_print(dut, DUT_MSG_DEBUG,
14055 "Got Transition Management Query");
14056
Ashwini Patil5acd7382017-04-13 15:55:04 +053014057 res = send_trans_mgmt_query(dut, intf, cmd);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014058 if (res) {
14059 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14060 "Failed to send Transition Management Query");
14061 return 0;
14062 }
14063
14064 return 1;
14065 } else {
14066 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14067 "PMFFrameType");
14068 return 0;
14069 }
14070
14071 val = get_param(cmd, "PMFProtected");
14072 if (val == NULL)
14073 val = get_param(cmd, "Protected");
14074 if (val == NULL)
14075 return -1;
14076 if (strcasecmp(val, "Correct-key") == 0 ||
14077 strcasecmp(val, "CorrectKey") == 0)
14078 protected = CORRECT_KEY;
14079 else if (strcasecmp(val, "IncorrectKey") == 0)
14080 protected = INCORRECT_KEY;
14081 else if (strcasecmp(val, "Unprotected") == 0)
14082 protected = UNPROTECTED;
14083 else {
14084 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14085 "PMFProtected");
14086 return 0;
14087 }
14088
14089 if (protected != UNPROTECTED &&
14090 (frame == AUTH || frame == ASSOCREQ || frame == REASSOCREQ)) {
14091 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Impossible "
14092 "PMFProtected for auth/assocreq/reassocreq");
14093 return 0;
14094 }
14095
14096 if (if_nametoindex("sigmadut") == 0) {
14097 snprintf(buf, sizeof(buf),
14098 "iw dev %s interface add sigmadut type monitor",
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014099 get_station_ifname(dut));
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014100 if (system(buf) != 0 ||
14101 if_nametoindex("sigmadut") == 0) {
14102 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to add "
14103 "monitor interface with '%s'", buf);
14104 return -2;
14105 }
14106 }
14107
14108 if (system("ifconfig sigmadut up") != 0) {
14109 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to set "
14110 "monitor interface up");
14111 return -2;
14112 }
14113
Veerendranath Jakkam49774122020-07-05 09:52:18 +053014114 return sta_inject_frame(dut, conn, intf, frame, protected, NULL, 1);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014115}
14116
14117
14118static int cmd_sta_set_parameter_hs2(struct sigma_dut *dut,
14119 struct sigma_conn *conn,
14120 struct sigma_cmd *cmd,
14121 const char *ifname)
14122{
14123 char buf[200];
14124 const char *val;
14125
14126 val = get_param(cmd, "ClearARP");
14127 if (val && atoi(val) == 1) {
14128 snprintf(buf, sizeof(buf), "ip neigh flush dev %s", ifname);
14129 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14130 if (system(buf) != 0) {
14131 send_resp(dut, conn, SIGMA_ERROR,
14132 "errorCode,Failed to clear ARP cache");
14133 return 0;
14134 }
14135 }
14136
14137 return 1;
14138}
14139
14140
14141int cmd_sta_set_parameter(struct sigma_dut *dut, struct sigma_conn *conn,
14142 struct sigma_cmd *cmd)
14143{
14144 const char *intf = get_param(cmd, "Interface");
14145 const char *val;
14146
14147 if (intf == NULL)
14148 return -1;
14149
14150 val = get_param(cmd, "program");
14151 if (val && (strcasecmp(val, "HS2") == 0 ||
Jouni Malinen1f6ae642018-06-07 23:56:13 +030014152 strcasecmp(val, "HS2-R2") == 0 ||
Jouni Malinen9a742ff2022-01-27 00:43:14 +020014153 strcasecmp(val, "HS2-R3") == 0 ||
14154 strcasecmp(val, "HS2-R4") == 0))
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014155 return cmd_sta_set_parameter_hs2(dut, conn, cmd, intf);
14156
14157 return -1;
14158}
14159
14160
Jouni Malinenf7222712019-06-13 01:50:21 +030014161static enum sigma_cmd_result cmd_sta_set_macaddr(struct sigma_dut *dut,
14162 struct sigma_conn *conn,
14163 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014164{
14165 const char *intf = get_param(cmd, "Interface");
14166 const char *mac = get_param(cmd, "MAC");
14167
14168 if (intf == NULL || mac == NULL)
14169 return -1;
14170
14171 sigma_dut_print(dut, DUT_MSG_INFO, "Change local MAC address for "
14172 "interface %s to %s", intf, mac);
14173
14174 if (dut->set_macaddr) {
14175 char buf[128];
14176 int res;
14177 if (strcasecmp(mac, "default") == 0) {
14178 res = snprintf(buf, sizeof(buf), "%s",
14179 dut->set_macaddr);
14180 dut->tmp_mac_addr = 0;
14181 } else {
14182 res = snprintf(buf, sizeof(buf), "%s %s",
14183 dut->set_macaddr, mac);
14184 dut->tmp_mac_addr = 1;
14185 }
14186 if (res < 0 || res >= (int) sizeof(buf))
14187 return -1;
14188 if (system(buf) != 0) {
14189 send_resp(dut, conn, SIGMA_ERROR,
14190 "errorCode,Failed to set MAC "
14191 "address");
14192 return 0;
14193 }
14194 return 1;
14195 }
14196
14197 if (strcasecmp(mac, "default") == 0)
14198 return 1;
14199
14200 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
14201 "command");
14202 return 0;
14203}
14204
14205
14206static int iwpriv_tdlsoffchnmode(struct sigma_dut *dut,
14207 struct sigma_conn *conn, const char *intf,
14208 int val)
14209{
14210 char buf[200];
14211 int res;
14212
14213 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchnmode %d",
14214 intf, val);
14215 if (res < 0 || res >= (int) sizeof(buf))
14216 return -1;
14217 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14218 if (system(buf) != 0) {
14219 send_resp(dut, conn, SIGMA_ERROR,
14220 "errorCode,Failed to configure offchannel mode");
14221 return 0;
14222 }
14223
14224 return 1;
14225}
14226
14227
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014228static int off_chan_val(enum sec_ch_offset off)
14229{
14230 switch (off) {
14231 case SEC_CH_NO:
14232 return 0;
14233 case SEC_CH_40ABOVE:
14234 return 40;
14235 case SEC_CH_40BELOW:
14236 return -40;
14237 }
14238
14239 return 0;
14240}
14241
14242
14243static int iwpriv_set_offchan(struct sigma_dut *dut, struct sigma_conn *conn,
14244 const char *intf, int off_ch_num,
14245 enum sec_ch_offset sec)
14246{
14247 char buf[200];
14248 int res;
14249
14250 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsoffchan %d",
14251 intf, off_ch_num);
14252 if (res < 0 || res >= (int) sizeof(buf))
14253 return -1;
14254 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14255 if (system(buf) != 0) {
14256 send_resp(dut, conn, SIGMA_ERROR,
14257 "errorCode,Failed to set offchan");
14258 return 0;
14259 }
14260
14261 res = snprintf(buf, sizeof(buf), "iwpriv %s tdlsecchnoffst %d",
14262 intf, off_chan_val(sec));
14263 if (res < 0 || res >= (int) sizeof(buf))
14264 return -1;
14265 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14266 if (system(buf) != 0) {
14267 send_resp(dut, conn, SIGMA_ERROR,
14268 "errorCode,Failed to set sec chan offset");
14269 return 0;
14270 }
14271
14272 return 1;
14273}
14274
14275
14276static int tdls_set_offchannel_offset(struct sigma_dut *dut,
14277 struct sigma_conn *conn,
14278 const char *intf, int off_ch_num,
14279 enum sec_ch_offset sec)
14280{
14281 char buf[200];
14282 int res;
14283
14284 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNEL %d",
14285 off_ch_num);
14286 if (res < 0 || res >= (int) sizeof(buf))
14287 return -1;
14288 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14289
14290 if (wpa_command(intf, buf) < 0) {
14291 send_resp(dut, conn, SIGMA_ERROR,
14292 "ErrorCode,Failed to set offchan");
14293 return 0;
14294 }
14295 res = snprintf(buf, sizeof(buf), "DRIVER TDLSSECONDARYCHANNELOFFSET %d",
14296 off_chan_val(sec));
14297 if (res < 0 || res >= (int) sizeof(buf))
14298 return -1;
14299
14300 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14301
14302 if (wpa_command(intf, buf) < 0) {
14303 send_resp(dut, conn, SIGMA_ERROR,
14304 "ErrorCode,Failed to set sec chan offset");
14305 return 0;
14306 }
14307
14308 return 1;
14309}
14310
14311
14312static int tdls_set_offchannel_mode(struct sigma_dut *dut,
14313 struct sigma_conn *conn,
14314 const char *intf, int val)
14315{
14316 char buf[200];
14317 int res;
14318
14319 res = snprintf(buf, sizeof(buf), "DRIVER TDLSOFFCHANNELMODE %d",
14320 val);
14321 if (res < 0 || res >= (int) sizeof(buf))
14322 return -1;
14323 sigma_dut_print(dut, DUT_MSG_DEBUG, "Run: %s", buf);
14324
14325 if (wpa_command(intf, buf) < 0) {
14326 send_resp(dut, conn, SIGMA_ERROR,
14327 "ErrorCode,Failed to configure offchannel mode");
14328 return 0;
14329 }
14330
14331 return 1;
14332}
14333
14334
14335static int cmd_sta_set_rfeature_tdls(const char *intf, struct sigma_dut *dut,
14336 struct sigma_conn *conn,
14337 struct sigma_cmd *cmd)
14338{
14339 const char *val;
14340 enum {
14341 CHSM_NOT_SET,
14342 CHSM_ENABLE,
14343 CHSM_DISABLE,
14344 CHSM_REJREQ,
14345 CHSM_UNSOLRESP
14346 } chsm = CHSM_NOT_SET;
14347 int off_ch_num = -1;
14348 enum sec_ch_offset sec_ch = SEC_CH_NO;
14349 int res;
14350
14351 val = get_param(cmd, "Uapsd");
14352 if (val) {
14353 char buf[100];
14354 if (strcasecmp(val, "Enable") == 0)
14355 snprintf(buf, sizeof(buf), "SET ps 99");
14356 else if (strcasecmp(val, "Disable") == 0)
14357 snprintf(buf, sizeof(buf), "SET ps 98");
14358 else {
14359 send_resp(dut, conn, SIGMA_ERROR, "errorCode,"
14360 "Unsupported uapsd parameter value");
14361 return 0;
14362 }
14363 if (wpa_command(intf, buf)) {
14364 send_resp(dut, conn, SIGMA_ERROR,
14365 "ErrorCode,Failed to change U-APSD "
14366 "powersave mode");
14367 return 0;
14368 }
14369 }
14370
14371 val = get_param(cmd, "TPKTIMER");
14372 if (val && strcasecmp(val, "DISABLE") == 0) {
14373 if (wpa_command(intf, "SET tdls_testing 0x100")) {
14374 send_resp(dut, conn, SIGMA_ERROR,
14375 "ErrorCode,Failed to enable no TPK "
14376 "expiration test mode");
14377 return 0;
14378 }
14379 dut->no_tpk_expiration = 1;
14380 }
14381
14382 val = get_param(cmd, "ChSwitchMode");
14383 if (val) {
14384 if (strcasecmp(val, "Enable") == 0 ||
14385 strcasecmp(val, "Initiate") == 0)
14386 chsm = CHSM_ENABLE;
14387 else if (strcasecmp(val, "Disable") == 0 ||
14388 strcasecmp(val, "passive") == 0)
14389 chsm = CHSM_DISABLE;
14390 else if (strcasecmp(val, "RejReq") == 0)
14391 chsm = CHSM_REJREQ;
14392 else if (strcasecmp(val, "UnSolResp") == 0)
14393 chsm = CHSM_UNSOLRESP;
14394 else {
14395 send_resp(dut, conn, SIGMA_ERROR,
14396 "ErrorCode,Unknown ChSwitchMode value");
14397 return 0;
14398 }
14399 }
14400
14401 val = get_param(cmd, "OffChNum");
14402 if (val) {
14403 off_ch_num = atoi(val);
14404 if (off_ch_num == 0) {
14405 send_resp(dut, conn, SIGMA_ERROR,
14406 "ErrorCode,Invalid OffChNum");
14407 return 0;
14408 }
14409 }
14410
14411 val = get_param(cmd, "SecChOffset");
14412 if (val) {
14413 if (strcmp(val, "20") == 0)
14414 sec_ch = SEC_CH_NO;
14415 else if (strcasecmp(val, "40above") == 0)
14416 sec_ch = SEC_CH_40ABOVE;
14417 else if (strcasecmp(val, "40below") == 0)
14418 sec_ch = SEC_CH_40BELOW;
14419 else {
14420 send_resp(dut, conn, SIGMA_ERROR,
14421 "ErrorCode,Unknown SecChOffset value");
14422 return 0;
14423 }
14424 }
14425
14426 if (chsm == CHSM_NOT_SET) {
14427 /* no offchannel changes requested */
14428 return 1;
14429 }
14430
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014431 if (strcmp(intf, get_main_ifname(dut)) != 0 &&
14432 strcmp(intf, get_station_ifname(dut)) != 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014433 send_resp(dut, conn, SIGMA_ERROR,
14434 "ErrorCode,Unknown interface");
14435 return 0;
14436 }
14437
14438 switch (chsm) {
14439 case CHSM_NOT_SET:
Jouni Malinen280f5ba2016-08-29 21:33:10 +030014440 res = 1;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014441 break;
14442 case CHSM_ENABLE:
14443 if (off_ch_num < 0) {
14444 send_resp(dut, conn, SIGMA_ERROR,
14445 "ErrorCode,Missing OffChNum argument");
14446 return 0;
14447 }
14448 if (wifi_chip_type == DRIVER_WCN) {
14449 res = tdls_set_offchannel_offset(dut, conn, intf,
14450 off_ch_num, sec_ch);
14451 } else {
14452 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14453 sec_ch);
14454 }
14455 if (res != 1)
14456 return res;
14457 if (wifi_chip_type == DRIVER_WCN)
14458 res = tdls_set_offchannel_mode(dut, conn, intf, 1);
14459 else
14460 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 1);
14461 break;
14462 case CHSM_DISABLE:
14463 if (wifi_chip_type == DRIVER_WCN)
14464 res = tdls_set_offchannel_mode(dut, conn, intf, 2);
14465 else
14466 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 2);
14467 break;
14468 case CHSM_REJREQ:
14469 if (wifi_chip_type == DRIVER_WCN)
14470 res = tdls_set_offchannel_mode(dut, conn, intf, 3);
14471 else
14472 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 3);
14473 break;
14474 case CHSM_UNSOLRESP:
14475 if (off_ch_num < 0) {
14476 send_resp(dut, conn, SIGMA_ERROR,
14477 "ErrorCode,Missing OffChNum argument");
14478 return 0;
14479 }
14480 if (wifi_chip_type == DRIVER_WCN) {
14481 res = tdls_set_offchannel_offset(dut, conn, intf,
14482 off_ch_num, sec_ch);
14483 } else {
14484 res = iwpriv_set_offchan(dut, conn, intf, off_ch_num,
14485 sec_ch);
14486 }
14487 if (res != 1)
14488 return res;
14489 if (wifi_chip_type == DRIVER_WCN)
14490 res = tdls_set_offchannel_mode(dut, conn, intf, 4);
14491 else
14492 res = iwpriv_tdlsoffchnmode(dut, conn, intf, 4);
14493 break;
14494 }
14495
14496 return res;
14497}
14498
14499
14500static int ath_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14501 struct sigma_conn *conn,
14502 struct sigma_cmd *cmd)
14503{
14504 const char *val;
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014505 char *token = NULL, *result;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014506
Priyadharshini Gowthaman8c5b9a42019-07-31 14:38:48 -070014507 novap_reset(dut, intf, 1);
priyadharshini gowthamane5e25172015-12-08 14:53:48 -080014508
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014509 val = get_param(cmd, "nss_mcs_opt");
14510 if (val) {
14511 /* String (nss_operating_mode; mcs_operating_mode) */
14512 int nss, mcs;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014513 char *saveptr;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014514
14515 token = strdup(val);
14516 if (!token)
14517 return 0;
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014518 result = strtok_r(token, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014519 if (!result) {
14520 sigma_dut_print(dut, DUT_MSG_ERROR,
14521 "VHT NSS not specified");
14522 goto failed;
14523 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014524 if (strcasecmp(result, "def") != 0) {
14525 nss = atoi(result);
14526 if (nss == 4)
14527 ath_disable_txbf(dut, intf);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014528 if (run_iwpriv(dut, intf, "nss %d", nss) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014529 goto failed;
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014530
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014531 }
14532
Pradeep Reddy POTTETIdbf7d712016-04-28 18:42:07 +053014533 result = strtok_r(NULL, ";", &saveptr);
Pradeep Reddy POTTETI41b8c542016-06-15 16:09:46 +053014534 if (!result) {
14535 sigma_dut_print(dut, DUT_MSG_ERROR,
14536 "VHT MCS not specified");
14537 goto failed;
14538 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014539 if (strcasecmp(result, "def") == 0) {
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014540 if (run_iwpriv(dut, intf, "set11NRates 0") < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014541 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014542 } else {
14543 mcs = atoi(result);
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014544 if (run_iwpriv(dut, intf, "vhtmcs %d", mcs) < 0)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014545 goto failed;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014546 }
14547 /* Channel width gets messed up, fix this */
Priyadharshini Gowthamanb999e9e2019-04-22 15:45:55 -070014548 run_iwpriv(dut, intf, "chwidth %d", dut->chwidth);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014549 }
14550
Srikanth Marepalli5415acf2018-08-27 12:53:11 +053014551 free(token);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014552 return 1;
14553failed:
14554 free(token);
14555 return 0;
14556}
14557
14558
14559static int cmd_sta_set_rfeature_vht(const char *intf, struct sigma_dut *dut,
14560 struct sigma_conn *conn,
14561 struct sigma_cmd *cmd)
14562{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014563 switch (get_driver_type(dut)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020014564 case DRIVER_ATHEROS:
14565 return ath_sta_set_rfeature_vht(intf, dut, conn, cmd);
14566 default:
14567 send_resp(dut, conn, SIGMA_ERROR,
14568 "errorCode,Unsupported sta_set_rfeature(VHT) with the current driver");
14569 return 0;
14570 }
14571}
14572
14573
Jouni Malinen1702fe32021-06-08 19:08:01 +030014574static enum sigma_cmd_result
14575wcn_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14576 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014577{
14578 const char *val;
14579 char *token = NULL, *result;
14580 char buf[60];
14581
14582 val = get_param(cmd, "nss_mcs_opt");
14583 if (val) {
14584 /* String (nss_operating_mode; mcs_operating_mode) */
14585 int nss, mcs, ratecode;
14586 char *saveptr;
14587
14588 token = strdup(val);
14589 if (!token)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014590 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014591
14592 result = strtok_r(token, ";", &saveptr);
14593 if (!result) {
14594 sigma_dut_print(dut, DUT_MSG_ERROR,
14595 "HE NSS not specified");
14596 goto failed;
14597 }
14598 nss = 1;
14599 if (strcasecmp(result, "def") != 0)
14600 nss = atoi(result);
14601
14602 result = strtok_r(NULL, ";", &saveptr);
14603 if (!result) {
14604 sigma_dut_print(dut, DUT_MSG_ERROR,
14605 "HE MCS not specified");
14606 goto failed;
14607 }
14608 mcs = 7;
14609 if (strcasecmp(result, "def") != 0)
14610 mcs = atoi(result);
14611
Arif Hussain557bf412018-05-25 17:29:36 -070014612 ratecode = 0x20; /* for nss:1 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014613 if (nss == 2) {
Arif Hussain557bf412018-05-25 17:29:36 -070014614 ratecode = 0x40; /* for nss:2 MCS 0 */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014615 } else if (nss > 2) {
14616 sigma_dut_print(dut, DUT_MSG_ERROR,
14617 "HE NSS %d not supported", nss);
14618 goto failed;
14619 }
14620
Arif Hussain557bf412018-05-25 17:29:36 -070014621 snprintf(buf, sizeof(buf), "iwpriv %s nss %d", intf, nss);
14622 if (system(buf) != 0) {
14623 sigma_dut_print(dut, DUT_MSG_ERROR,
14624 "nss_mcs_opt: iwpriv %s nss %d failed",
14625 intf, nss);
14626 goto failed;
14627 }
Arif Hussainac6c5112018-05-25 17:34:00 -070014628 dut->sta_nss = nss;
Arif Hussain557bf412018-05-25 17:29:36 -070014629
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014630 /* Add the MCS to the ratecode */
14631 if (mcs >= 0 && mcs <= 11) {
14632 ratecode += mcs;
Arif Hussain557bf412018-05-25 17:29:36 -070014633#ifdef NL80211_SUPPORT
14634 if (dut->device_type == STA_testbed) {
14635 enum he_mcs_config mcs_config;
14636 int ret;
14637
14638 if (mcs <= 7)
14639 mcs_config = HE_80_MCS0_7;
14640 else if (mcs <= 9)
14641 mcs_config = HE_80_MCS0_9;
14642 else
14643 mcs_config = HE_80_MCS0_11;
14644 ret = sta_set_he_mcs(dut, intf, mcs_config);
14645 if (ret) {
14646 sigma_dut_print(dut, DUT_MSG_ERROR,
14647 "nss_mcs_opt: mcs setting failed, mcs:%d, mcs_config %d, ret:%d",
14648 mcs, mcs_config, ret);
14649 goto failed;
14650 }
14651 }
14652#endif /* NL80211_SUPPORT */
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014653 } else {
14654 sigma_dut_print(dut, DUT_MSG_ERROR,
14655 "HE MCS %d not supported", mcs);
14656 goto failed;
14657 }
14658 snprintf(buf, sizeof(buf), "iwpriv %s set_11ax_rate 0x%03x",
14659 intf, ratecode);
14660 if (system(buf) != 0) {
14661 sigma_dut_print(dut, DUT_MSG_ERROR,
14662 "iwpriv setting of 11ax rates failed");
14663 goto failed;
14664 }
14665 free(token);
14666 }
14667
14668 val = get_param(cmd, "GI");
14669 if (val) {
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014670 int fix_rate_sgi;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014671 u8 he_gi_val = 0;
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014672
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014673 if (strcmp(val, "0.8") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014674 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 9", intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014675 fix_rate_sgi = 1;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014676 he_gi_val = NL80211_RATE_INFO_HE_GI_0_8;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014677 } else if (strcmp(val, "1.6") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014678 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 10",
14679 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014680 fix_rate_sgi = 2;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014681 he_gi_val = NL80211_RATE_INFO_HE_GI_1_6;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014682 } else if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokereb8fec522018-05-01 14:26:00 -070014683 snprintf(buf, sizeof(buf), "iwpriv %s shortgi 11",
14684 intf);
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014685 fix_rate_sgi = 3;
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014686 he_gi_val = NL80211_RATE_INFO_HE_GI_3_2;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014687 } else {
14688 send_resp(dut, conn, SIGMA_ERROR,
14689 "errorCode,GI value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014690 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014691 }
Kiran Kumar Lokerebed80952021-11-22 22:47:25 -080014692 if (wcn_set_he_gi(dut, intf, he_gi_val)) {
14693 sigma_dut_print(dut, DUT_MSG_INFO,
14694 "wcn_set_he_gi failed, using iwpriv");
14695 if (system(buf) != 0) {
14696 send_resp(dut, conn, SIGMA_ERROR,
14697 "errorCode,Failed to set shortgi");
14698 return STATUS_SENT_ERROR;
14699 }
14700 snprintf(buf, sizeof(buf), "iwpriv %s shortgi %d",
14701 intf, fix_rate_sgi);
14702 if (system(buf) != 0) {
14703 send_resp(dut, conn, SIGMA_ERROR,
14704 "errorCode,Failed to set fix rate shortgi");
14705 return STATUS_SENT_ERROR;
14706 }
Kiran Kumar Lokeref6592d72019-01-16 18:44:00 -080014707 }
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014708 }
14709
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014710 val = get_param(cmd, "LTF");
14711 if (val) {
14712#ifdef NL80211_SUPPORT
14713 if (strcmp(val, "3.2") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014714 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_1X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014715 } if (strcmp(val, "6.4") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014716 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_2X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014717 } else if (strcmp(val, "12.8") == 0) {
Kiran Kumar Lokere26c0f862020-01-22 11:15:59 -080014718 wcn_set_he_ltf(dut, intf, QCA_WLAN_HE_LTF_4X);
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014719 } else {
14720 send_resp(dut, conn, SIGMA_ERROR,
14721 "errorCode, LTF value not supported");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014722 return STATUS_SENT_ERROR;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014723 }
14724#else /* NL80211_SUPPORT */
14725 sigma_dut_print(dut, DUT_MSG_ERROR,
14726 "LTF cannot be set without NL80211_SUPPORT defined");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014727 return ERROR_SEND_STATUS;
Subhani Shaik8e7a3052018-04-24 14:03:00 -070014728#endif /* NL80211_SUPPORT */
14729 }
14730
Kiran Kumar Lokere1809da12021-06-24 00:45:38 -070014731 val = get_param(cmd, "KeepAlive");
14732 if (val) {
14733 int set_val = QCA_WLAN_KEEP_ALIVE_DEFAULT;
14734
14735 if (strcasecmp(val, "Data") == 0)
14736 set_val = QCA_WLAN_KEEP_ALIVE_DATA;
14737 else if (strcasecmp(val, "Mgmt") == 0)
14738 set_val = QCA_WLAN_KEEP_ALIVE_MGMT;
14739
14740 if (sta_set_keep_alive_data_cfg(dut, intf, set_val)) {
14741 send_resp(dut, conn, SIGMA_ERROR,
14742 "ErrorCode,Failed to set keep alive type config");
14743 return STATUS_SENT_ERROR;
14744 }
14745 }
14746
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014747 val = get_param(cmd, "TxSUPPDU");
14748 if (val) {
14749 int set_val = 1;
14750
14751 if (strcasecmp(val, "Enable") == 0)
14752 set_val = 1;
14753 else if (strcasecmp(val, "Disable") == 0)
14754 set_val = 0;
14755
14756 if (sta_set_tx_su_ppdu_cfg(dut, intf, set_val)) {
14757 send_resp(dut, conn, SIGMA_ERROR,
14758 "ErrorCode,Failed to set Tx SU PPDU config");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014759 return STATUS_SENT_ERROR;
Kiran Kumar Lokere400d68f2018-08-29 18:45:11 -070014760 }
14761 }
14762
Kiran Kumar Lokere54b72522021-04-01 00:22:44 -070014763 val = get_param(cmd, "Mgmt_Data_TX_Resp_Frame");
14764 if (val) {
14765 int set_val = 0;
14766
14767 if (strcasecmp(val, "Enable") == 0)
14768 set_val = 0;
14769 else if (strcasecmp(val, "Disable") == 0)
14770 set_val = 1;
14771
14772 if (sta_set_mgmt_data_tx_disable_cfg(dut, intf, set_val)) {
14773 send_resp(dut, conn, SIGMA_ERROR,
14774 "ErrorCode,Failed to set mgmt/data Tx disable config");
14775 return STATUS_SENT_ERROR;
14776 }
14777 }
14778
Arif Hussain480d5f42019-03-12 14:40:42 -070014779 val = get_param(cmd, "TWT_Setup");
14780 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014781#ifdef NL80211_SUPPORT
14782 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14783 sigma_dut_print(dut, DUT_MSG_ERROR,
14784 "Failed to open nl80211 event socket");
14785#endif /* NL80211_SUPPORT */
Arif Hussain480d5f42019-03-12 14:40:42 -070014786 if (strcasecmp(val, "Request") == 0) {
Kiran Kumar Lokereafac46a2021-11-29 14:03:20 -080014787 if (set_power_save_wcn(dut, intf, 1) < 0)
14788 sigma_dut_print(dut, DUT_MSG_ERROR,
14789 "Failed to enable power save");
Arif Hussain480d5f42019-03-12 14:40:42 -070014790 if (sta_twt_request(dut, conn, cmd)) {
14791 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014792 "ErrorCode,TWT setup failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014793 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014794 }
14795 } else if (strcasecmp(val, "Teardown") == 0) {
14796 if (sta_twt_teardown(dut, conn, cmd)) {
14797 send_resp(dut, conn, SIGMA_ERROR,
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014798 "ErrorCode,TWT teardown failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014799 return STATUS_SENT_ERROR;
Arif Hussain480d5f42019-03-12 14:40:42 -070014800 }
14801 }
14802 }
14803
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014804 val = get_param(cmd, "TWT_Operation");
14805 if (val) {
Kiran Kumar Lokere94829ce2022-01-20 10:49:08 -080014806#ifdef NL80211_SUPPORT
14807 if (dut->sta_async_twt_supp && nl80211_open_event_sock(dut))
14808 sigma_dut_print(dut, DUT_MSG_ERROR,
14809 "Failed to open nl80211 event socket");
14810#endif /* NL80211_SUPPORT */
Srinivas Girigowda6707f032020-10-26 15:24:46 -070014811 if (strcasecmp(val, "Suspend") == 0) {
14812 if (sta_twt_suspend_or_nudge(dut, conn, cmd)) {
14813 send_resp(dut, conn, SIGMA_ERROR,
14814 "ErrorCode,TWT suspend failed");
14815 return STATUS_SENT_ERROR;
14816 }
14817 } else if (strcasecmp(val, "Resume") == 0) {
14818 if (sta_twt_resume(dut, conn, cmd)) {
14819 send_resp(dut, conn, SIGMA_ERROR,
14820 "ErrorCode,TWT resume failed");
14821 return STATUS_SENT_ERROR;
14822 }
14823 }
14824 }
14825
Kiran Kumar Lokere50eb2cd2018-12-18 18:31:28 -080014826 val = get_param(cmd, "transmitOMI");
14827 if (val && sta_transmit_omi(dut, conn, cmd)) {
14828 send_resp(dut, conn, SIGMA_ERROR,
14829 "ErrorCode,sta_transmit_omi failed");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014830 return STATUS_SENT_ERROR;
Kiran Kumar Lokere29c1bb02018-10-08 17:41:02 -070014831 }
14832
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014833 val = get_param(cmd, "Powersave");
14834 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014835 int ps;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014836
14837 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014838 ps = 2;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014839 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014840 ps = 1;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014841 } else {
14842 sigma_dut_print(dut, DUT_MSG_ERROR,
14843 "Unsupported Powersave value '%s'",
14844 val);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014845 return INVALID_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014846 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014847 if (set_power_save_wcn(dut, intf, ps) < 0)
Jouni Malinen1702fe32021-06-08 19:08:01 +030014848 return ERROR_SEND_STATUS;
Kiran Kumar Lokerec310dcd2018-12-17 20:56:06 -080014849 }
14850
Kiran Kumar Lokere2c4b7ce2019-01-30 12:02:28 -080014851 val = get_param(cmd, "MU_EDCA");
14852 if (val) {
14853 if (strcasecmp(val, "Override") == 0) {
14854 if (sta_set_mu_edca_override(dut, intf, 1)) {
14855 send_resp(dut, conn, SIGMA_ERROR,
14856 "errorCode,MU EDCA override set failed");
14857 return STATUS_SENT;
14858 }
14859 } else if (strcasecmp(val, "Disable") == 0) {
14860 if (sta_set_mu_edca_override(dut, intf, 0)) {
14861 send_resp(dut, conn, SIGMA_ERROR,
14862 "errorCode,MU EDCA override disable failed");
14863 return STATUS_SENT;
14864 }
14865 }
14866 }
14867
Kiran Kumar Lokerefa7c7b92021-08-09 00:50:55 -070014868 val = get_param(cmd, "RUAllocTone");
14869 if (val && strcasecmp(val, "242") == 0) {
14870 if (sta_set_ru_242_tone_tx(dut, intf, 1)) {
14871 send_resp(dut, conn, SIGMA_ERROR,
14872 "ErrorCode,Failed to set RU 242 tone Tx");
14873 return STATUS_SENT_ERROR;
14874 }
14875 }
14876
14877 val = get_param(cmd, "PPDUTxType");
14878 if (val && strcasecmp(val, "ER-SU") == 0) {
14879 if (sta_set_er_su_ppdu_type_tx(dut, intf, 1)) {
14880 send_resp(dut, conn, SIGMA_ERROR,
14881 "ErrorCode,Failed to set ER-SU PPDU type Tx");
14882 return STATUS_SENT_ERROR;
14883 }
14884 }
14885
Kiran Kumar Lokeredd086642020-06-04 00:29:26 -070014886 val = get_param(cmd, "Ch_Pref");
14887 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
14888 return STATUS_SENT;
14889
14890 val = get_param(cmd, "Cellular_Data_Cap");
14891 if (val && mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
14892 return STATUS_SENT;
14893
Jouni Malinen1702fe32021-06-08 19:08:01 +030014894 return SUCCESS_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014895
14896failed:
14897 free(token);
Jouni Malinen1702fe32021-06-08 19:08:01 +030014898 return ERROR_SEND_STATUS;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014899}
14900
14901
Jouni Malinen1702fe32021-06-08 19:08:01 +030014902static enum sigma_cmd_result
14903cmd_sta_set_rfeature_he(const char *intf, struct sigma_dut *dut,
14904 struct sigma_conn *conn, struct sigma_cmd *cmd)
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014905{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020014906 switch (get_driver_type(dut)) {
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014907 case DRIVER_WCN:
14908 return wcn_sta_set_rfeature_he(intf, dut, conn, cmd);
14909 default:
14910 send_resp(dut, conn, SIGMA_ERROR,
14911 "errorCode,Unsupported sta_set_rfeature(HE) with the current driver");
Jouni Malinen1702fe32021-06-08 19:08:01 +030014912 return STATUS_SENT_ERROR;
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080014913 }
14914}
14915
14916
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014917static int cmd_sta_set_power_save_he(const char *intf, struct sigma_dut *dut,
14918 struct sigma_conn *conn,
14919 struct sigma_cmd *cmd)
14920{
14921 const char *val;
14922
14923 val = get_param(cmd, "powersave");
14924 if (val) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014925 int ps;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014926
14927 if (strcasecmp(val, "off") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014928 ps = 2;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014929 } else if (strcasecmp(val, "on") == 0) {
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014930 ps = 1;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014931 } else {
14932 sigma_dut_print(dut, DUT_MSG_ERROR,
14933 "Unsupported power save config");
14934 return -1;
14935 }
Vinita S. Malooa8b62722020-04-23 01:45:41 +053014936 if (set_power_save_wcn(dut, intf, ps) < 0)
14937 return 0;
Kiran Kumar Lokeree580c012019-01-03 17:08:53 -080014938 return 1;
14939 }
14940
14941 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported command");
14942
14943 return 0;
14944}
14945
14946
Ashwini Patil5acd7382017-04-13 15:55:04 +053014947static int btm_query_candidate_list(struct sigma_dut *dut,
14948 struct sigma_conn *conn,
14949 struct sigma_cmd *cmd)
14950{
14951 const char *bssid, *info, *op_class, *ch, *phy_type, *pref;
14952 int len, ret;
14953 char buf[10];
14954
14955 /*
14956 * Neighbor Report elements format:
14957 * neighbor=<BSSID>,<BSSID Information>,<Operating Class>,
14958 * <Channel Number>,<PHY Type>[,<hexdump of Optional Subelements>]
14959 * eg: neighbor=aa:bb:cc:dd:ee:ff,17,81,6,1,030101
14960 */
14961
14962 bssid = get_param(cmd, "Nebor_BSSID");
14963 if (!bssid) {
14964 send_resp(dut, conn, SIGMA_INVALID,
14965 "errorCode,Nebor_BSSID is missing");
14966 return 0;
14967 }
14968
14969 info = get_param(cmd, "Nebor_Bssid_Info");
14970 if (!info) {
14971 sigma_dut_print(dut, DUT_MSG_INFO,
14972 "Using default value for Nebor_Bssid_Info: %s",
14973 DEFAULT_NEIGHBOR_BSSID_INFO);
14974 info = DEFAULT_NEIGHBOR_BSSID_INFO;
14975 }
14976
14977 op_class = get_param(cmd, "Nebor_Op_Class");
14978 if (!op_class) {
14979 send_resp(dut, conn, SIGMA_INVALID,
14980 "errorCode,Nebor_Op_Class is missing");
14981 return 0;
14982 }
14983
14984 ch = get_param(cmd, "Nebor_Op_Ch");
14985 if (!ch) {
14986 send_resp(dut, conn, SIGMA_INVALID,
14987 "errorCode,Nebor_Op_Ch is missing");
14988 return 0;
14989 }
14990
14991 phy_type = get_param(cmd, "Nebor_Phy_Type");
14992 if (!phy_type) {
14993 sigma_dut_print(dut, DUT_MSG_INFO,
14994 "Using default value for Nebor_Phy_Type: %s",
14995 DEFAULT_NEIGHBOR_PHY_TYPE);
14996 phy_type = DEFAULT_NEIGHBOR_PHY_TYPE;
14997 }
14998
14999 /* Parse optional subelements */
15000 buf[0] = '\0';
15001 pref = get_param(cmd, "Nebor_Pref");
15002 if (pref) {
15003 /* hexdump for preferrence subelement */
15004 ret = snprintf(buf, sizeof(buf), ",0301%02x", atoi(pref));
15005 if (ret < 0 || ret >= (int) sizeof(buf)) {
15006 sigma_dut_print(dut, DUT_MSG_ERROR,
15007 "snprintf failed for optional subelement ret: %d",
15008 ret);
15009 send_resp(dut, conn, SIGMA_ERROR,
15010 "errorCode,snprintf failed for subelement");
15011 return 0;
15012 }
15013 }
15014
15015 if (!dut->btm_query_cand_list) {
15016 dut->btm_query_cand_list = calloc(1, NEIGHBOR_REPORT_SIZE);
15017 if (!dut->btm_query_cand_list) {
15018 send_resp(dut, conn, SIGMA_ERROR,
15019 "errorCode,Failed to allocate memory for btm_query_cand_list");
15020 return 0;
15021 }
15022 }
15023
15024 len = strlen(dut->btm_query_cand_list);
15025 ret = snprintf(dut->btm_query_cand_list + len,
15026 NEIGHBOR_REPORT_SIZE - len, " neighbor=%s,%s,%s,%s,%s%s",
15027 bssid, info, op_class, ch, phy_type, buf);
15028 if (ret < 0 || ret >= NEIGHBOR_REPORT_SIZE - len) {
15029 sigma_dut_print(dut, DUT_MSG_ERROR,
15030 "snprintf failed for neighbor report list ret: %d",
15031 ret);
15032 send_resp(dut, conn, SIGMA_ERROR,
15033 "errorCode,snprintf failed for neighbor report");
15034 free(dut->btm_query_cand_list);
15035 dut->btm_query_cand_list = NULL;
15036 return 0;
15037 }
15038
15039 return 1;
15040}
15041
15042
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015043int sta_extract_60g_ese(struct sigma_dut *dut, struct sigma_cmd *cmd,
15044 struct sigma_ese_alloc *allocs, int *allocs_size)
15045{
15046 int max_count = *allocs_size;
15047 int count = 0, i;
15048 const char *val;
15049
15050 do {
15051 val = get_param_indexed(cmd, "AllocID", count);
15052 if (val)
15053 count++;
15054 } while (val);
15055
15056 if (count == 0 || count > max_count) {
15057 sigma_dut_print(dut, DUT_MSG_ERROR,
15058 "Invalid number of allocations(%d)", count);
15059 return -1;
15060 }
15061
15062 for (i = 0; i < count; i++) {
15063 val = get_param_indexed(cmd, "PercentBI", i);
15064 if (!val) {
15065 sigma_dut_print(dut, DUT_MSG_ERROR,
15066 "Missing PercentBI parameter at index %d",
15067 i);
15068 return -1;
15069 }
15070 allocs[i].percent_bi = atoi(val);
15071
15072 val = get_param_indexed(cmd, "SrcAID", i);
15073 if (val)
15074 allocs[i].src_aid = strtol(val, NULL, 0);
15075 else
15076 allocs[i].src_aid = ESE_BCAST_AID;
15077
15078 val = get_param_indexed(cmd, "DestAID", i);
15079 if (val)
15080 allocs[i].dst_aid = strtol(val, NULL, 0);
15081 else
15082 allocs[i].dst_aid = ESE_BCAST_AID;
15083
15084 allocs[i].type = ESE_CBAP;
15085 sigma_dut_print(dut, DUT_MSG_INFO,
15086 "Alloc %d PercentBI %d SrcAID %d DstAID %d",
15087 i, allocs[i].percent_bi, allocs[i].src_aid,
15088 allocs[i].dst_aid);
15089 }
15090
15091 *allocs_size = count;
15092 return 0;
15093}
15094
15095
15096static int sta_set_60g_ese(struct sigma_dut *dut, int count,
15097 struct sigma_ese_alloc *allocs)
15098{
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015099 switch (get_driver_type(dut)) {
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015100#ifdef __linux__
15101 case DRIVER_WIL6210:
15102 if (wil6210_set_ese(dut, count, allocs))
15103 return -1;
15104 return 1;
15105#endif /* __linux__ */
15106 default:
15107 sigma_dut_print(dut, DUT_MSG_ERROR,
15108 "Unsupported sta_set_60g_ese with the current driver");
15109 return -1;
15110 }
15111}
15112
15113
15114static int cmd_sta_set_rfeature_60g(const char *intf, struct sigma_dut *dut,
15115 struct sigma_conn *conn,
15116 struct sigma_cmd *cmd)
15117{
15118 const char *val;
15119
15120 val = get_param(cmd, "ExtSchIE");
15121 if (val && !strcasecmp(val, "Enable")) {
15122 struct sigma_ese_alloc allocs[MAX_ESE_ALLOCS];
15123 int count = MAX_ESE_ALLOCS;
15124
15125 if (sta_extract_60g_ese(dut, cmd, allocs, &count))
15126 return -1;
15127 return sta_set_60g_ese(dut, count, allocs);
15128 }
15129
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015130 val = get_param(cmd, "MCS_FixedRate");
15131 if (val) {
15132 int sta_mcs = atoi(val);
15133
15134 sigma_dut_print(dut, DUT_MSG_INFO, "Force STA MCS to %d",
15135 sta_mcs);
15136 wil6210_set_force_mcs(dut, 1, sta_mcs);
15137
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015138 return SUCCESS_SEND_STATUS;
Alexei Avshalom Lazaraad97b02018-12-18 16:01:23 +020015139 }
15140
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015141 send_resp(dut, conn, SIGMA_ERROR,
15142 "errorCode,Invalid sta_set_rfeature(60G)");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020015143 return STATUS_SENT;
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015144}
15145
15146
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015147static int wcn_sta_override_oci(struct sigma_dut *dut, const char *intf,
15148 const char *oci_frametype, uint32_t oci_freq)
15149{
15150#ifdef NL80211_SUPPORT
15151 struct nl_msg *msg;
15152 int ret = 0;
15153 struct nlattr *params;
15154 struct nlattr *attr;
15155 int ifindex;
15156 u8 frame_type;
15157
15158 ifindex = if_nametoindex(intf);
15159 if (ifindex == 0) {
15160 sigma_dut_print(dut, DUT_MSG_ERROR,
15161 "%s: Index for interface %s failed",
15162 __func__, intf);
15163 return -1;
15164 }
15165
15166 if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15167 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_REQ;
15168 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15169 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_SA_QUERY_RESP;
15170 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15171 frame_type = QCA_WLAN_VENDOR_OCI_OVERRIDE_FRAME_FT_REASSOC_REQ;
15172 } else {
15173 sigma_dut_print(dut, DUT_MSG_ERROR, "%s: Unknown frametype %s",
15174 __func__, oci_frametype);
15175 return -1;
15176 }
15177
15178
15179 if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
15180 NL80211_CMD_VENDOR)) ||
15181 nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
15182 nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
15183 nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
15184 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION) ||
15185 !(attr = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
15186 !(params = nla_nest_start(
15187 msg,
15188 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OCI_OVERRIDE)) ||
15189 nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FRAME_TYPE,
15190 frame_type) ||
15191 nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_OCI_OVERRIDE_FREQUENCY,
15192 oci_freq)) {
15193 sigma_dut_print(dut, DUT_MSG_ERROR,
15194 "%s: err in adding vendor_cmd and vendor_data",
15195 __func__);
15196 nlmsg_free(msg);
15197 return -1;
15198 }
15199 nla_nest_end(msg, params);
15200 nla_nest_end(msg, attr);
15201
15202 ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
15203 if (ret) {
15204 sigma_dut_print(dut, DUT_MSG_ERROR,
15205 "%s: err in send_and_recv_msgs, ret=%d",
15206 __func__, ret);
15207 }
15208 return ret;
15209#else /* NL80211_SUPPORT */
15210 sigma_dut_print(dut, DUT_MSG_ERROR,
15211 "OCI override not possible without NL80211_SUPPORT defined");
15212 return -1;
15213#endif /* NL80211_SUPPORT */
15214}
15215
15216
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015217static int wcn_sta_ignore_csa(struct sigma_dut *dut, const char *intf,
15218 uint8_t ignore_csa)
15219{
15220#ifdef NL80211_SUPPORT
15221 return wcn_wifi_test_config_set_u8(
15222 dut, intf,
15223 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_CSA, ignore_csa);
15224#else /* NL80211_SUPPORT */
15225 sigma_dut_print(dut, DUT_MSG_ERROR,
15226 "IgnoreCSA can't be set without NL80211_SUPPORT defined");
15227 return -1;
15228#endif /* NL80211_SUPPORT */
15229}
15230
15231
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015232static int wcn_sta_set_rsnxe_used(struct sigma_dut *dut, const char *intf,
15233 uint8_t rsnxe_used)
15234{
15235#ifdef NL80211_SUPPORT
15236 return wcn_wifi_test_config_set_u8(
15237 dut, intf,
15238 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_FT_REASSOCREQ_RSNXE_USED,
15239 rsnxe_used);
15240#else /* NL80211_SUPPORT */
15241 sigma_dut_print(dut, DUT_MSG_ERROR,
15242 "RSNXE_Used can't be set without NL80211_SUPPORT defined");
15243 return -1;
15244#endif /* NL80211_SUPPORT */
15245}
15246
15247
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015248static int wcn_sta_ignore_sa_query_timeout(struct sigma_dut *dut,
15249 const char *intf,
15250 uint8_t ignore_sa_query_timeout)
15251{
15252#ifdef NL80211_SUPPORT
15253 return wcn_wifi_test_config_set_u8(
15254 dut, intf,
15255 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_IGNORE_SA_QUERY_TIMEOUT,
15256 ignore_sa_query_timeout);
15257#else /* NL80211_SUPPORT */
15258 sigma_dut_print(dut, DUT_MSG_ERROR,
15259 "Ignore SA Query timeout can't be set without NL80211_SUPPORT defined");
15260 return -1;
15261#endif /* NL80211_SUPPORT */
15262}
15263
15264
Jouni Malinen6250cb02020-04-15 13:54:45 +030015265static enum sigma_cmd_result
15266cmd_sta_set_rfeature_wpa3(const char *intf, struct sigma_dut *dut,
15267 struct sigma_conn *conn,
15268 struct sigma_cmd *cmd)
15269{
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015270 const char *val, *oci_chan, *oci_frametype;
Jouni Malinen6250cb02020-04-15 13:54:45 +030015271
Veerendranath Jakkam30bf9072020-04-16 14:37:57 +053015272 val = get_param(cmd, "ReassocReq_RSNXE_Used");
Jouni Malinen6250cb02020-04-15 13:54:45 +030015273 if (val && atoi(val) == 1) {
Veerendranath Jakkamc771fac2020-07-22 01:32:56 +053015274 if (wifi_chip_type == DRIVER_WCN) {
15275 if (wcn_sta_set_rsnxe_used(dut, intf, 1)) {
15276 send_resp(dut, conn, SIGMA_ERROR,
15277 "errorCode,Failed to set ft_rsnxe_used");
15278 return STATUS_SENT_ERROR;
15279 }
15280 return SUCCESS_SEND_STATUS;
15281 } else if (wpa_command(intf, "SET ft_rsnxe_used 1") < 0) {
Jouni Malinen6250cb02020-04-15 13:54:45 +030015282 send_resp(dut, conn, SIGMA_ERROR,
15283 "errorCode,Failed to set ft_rsnxe_used");
15284 return STATUS_SENT_ERROR;
15285 }
15286 return SUCCESS_SEND_STATUS;
15287 }
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015288
15289 oci_chan = get_param(cmd, "OCIChannel");
15290 oci_frametype = get_param(cmd, "OCIFrameType");
15291 if (oci_chan && oci_frametype) {
15292 unsigned int oci_freq = channel_to_freq(dut, atoi(oci_chan));
15293 char buf[100];
15294
15295 if (!oci_freq) {
15296 send_resp(dut, conn, SIGMA_ERROR,
15297 "errorCode,Invalid OCIChannel number");
15298 return STATUS_SENT_ERROR;
15299 }
15300
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015301 if (wifi_chip_type == DRIVER_WCN &&
15302 (strcasecmp(oci_frametype, "SAQueryReq") == 0 ||
15303 strcasecmp(oci_frametype, "SAQueryResp") == 0 ||
15304 strcasecmp(oci_frametype, "Reassocreq") == 0)) {
15305 if (wcn_sta_override_oci(dut, intf, oci_frametype,
15306 oci_freq)) {
15307 send_resp(dut, conn, SIGMA_ERROR,
15308 "errorCode,Failed to override OCI");
15309 return STATUS_SENT_ERROR;
15310 }
15311 return SUCCESS_SEND_STATUS;
15312 }
15313
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015314 if (strcasecmp(oci_frametype, "eapolM2") == 0) {
15315 snprintf(buf, sizeof(buf),
15316 "SET oci_freq_override_eapol %d", oci_freq);
15317 } else if (strcasecmp(oci_frametype, "SAQueryReq") == 0) {
15318 snprintf(buf, sizeof(buf),
15319 "SET oci_freq_override_saquery_req %d",
15320 oci_freq);
15321 } else if (strcasecmp(oci_frametype, "SAQueryResp") == 0) {
15322 snprintf(buf, sizeof(buf),
15323 "SET oci_freq_override_saquery_resp %d",
15324 oci_freq);
Veerendranath Jakkam76a845c2020-07-14 13:19:40 +053015325 } else if (strcasecmp(oci_frametype, "GrpKeyM2") == 0) {
15326 snprintf(buf, sizeof(buf),
15327 "SET oci_freq_override_eapol_g2 %d",
15328 oci_freq);
15329 } else if (strcasecmp(oci_frametype, "Reassocreq") == 0) {
15330 snprintf(buf, sizeof(buf),
15331 "SET oci_freq_override_ft_assoc %d",
15332 oci_freq);
Vamsi Krishnad29bc762020-05-08 23:23:30 +053015333 } else {
15334 send_resp(dut, conn, SIGMA_ERROR,
15335 "errorCode,Unsupported OCIFrameType");
15336 return STATUS_SENT_ERROR;
15337 }
15338 if (wpa_command(intf, buf) < 0) {
15339 send_resp(dut, conn, SIGMA_ERROR,
15340 "errorCode,Failed to set oci_freq_override");
15341 return STATUS_SENT_ERROR;
15342 }
15343 return SUCCESS_SEND_STATUS;
15344 }
15345
Veerendranath Jakkam50d5c782020-07-22 01:59:01 +053015346 val = get_param(cmd, "IgnoreCSA");
15347 if (val && atoi(val) == 1) {
15348 if (wifi_chip_type == DRIVER_WCN) {
15349 if (wcn_sta_ignore_csa(dut, intf, 1)) {
15350 send_resp(dut, conn, SIGMA_ERROR,
15351 "errorCode,Failed to set ignore CSA");
15352 return STATUS_SENT_ERROR;
15353 }
15354 return SUCCESS_SEND_STATUS;
15355 }
15356 }
15357
Veerendranath Jakkam1e1e5fd2020-09-10 07:12:37 +053015358 val = get_param(cmd, "Deauth_Per_SAQueryResp");
15359 if (val && atoi(val) == 0) {
15360 if (wifi_chip_type == DRIVER_WCN) {
15361 if (wcn_sta_ignore_sa_query_timeout(dut, intf, 1)) {
15362 send_resp(dut, conn, SIGMA_ERROR,
15363 "errorCode,Failed to set ignore SA Query timeout");
15364 return STATUS_SENT_ERROR;
15365 }
15366 return SUCCESS_SEND_STATUS;
15367 }
15368 }
15369
Jouni Malinen6250cb02020-04-15 13:54:45 +030015370 send_resp(dut, conn, SIGMA_ERROR,
15371 "errorCode,Unsupported WPA3 rfeature");
15372 return STATUS_SENT_ERROR;
15373}
15374
15375
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015376static enum sigma_cmd_result
15377cmd_sta_set_rfeature_qm(const char *intf, struct sigma_dut *dut,
15378 struct sigma_conn *conn, struct sigma_cmd *cmd)
15379{
15380 const char *val;
15381
15382 val = get_param(cmd, "DomainName_Domain");
15383 if (val) {
15384 if (strlen(val) >= sizeof(dut->qm_domain_name))
15385 return ERROR_SEND_STATUS;
15386
15387 strlcpy(dut->qm_domain_name, val, sizeof(dut->qm_domain_name));
15388 return SUCCESS_SEND_STATUS;
15389 }
15390
Veerendranath Jakkam1bf1bd62021-09-12 16:35:55 +053015391 val = get_param(cmd, "DSCPPolicy_PolicyID");
15392 if (val) {
15393 unsigned int i;
15394 int policy_id = atoi(val);
15395
15396 val = get_param(cmd, "DSCPPolicy_RequestType");
15397
15398 if (!policy_id || !val)
15399 return INVALID_SEND_STATUS;
15400
15401 if (dut->num_dscp_status >= ARRAY_SIZE(dut->dscp_status)) {
15402 send_resp(dut, conn, SIGMA_ERROR,
15403 "errorCode,DSCP status list full");
15404 return STATUS_SENT_ERROR;
15405 }
15406
15407 for (i = 0; i < dut->num_dscp_status; i++)
15408 if (dut->dscp_status[i].id == policy_id)
15409 break;
15410
15411 /* New policy configured */
15412 if (i == dut->num_dscp_status) {
15413 dut->dscp_status[i].id = policy_id;
15414 dut->num_dscp_status++;
15415 }
15416
15417 dut->dscp_status[i].status = strcasecmp(val, "Remove") ?
15418 DSCP_POLICY_SUCCESS : DSCP_POLICY_REJECT;
15419
15420 return SUCCESS_SEND_STATUS;
15421 }
15422
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015423 send_resp(dut, conn, SIGMA_ERROR,
15424 "errorCode,Unsupported QM rfeature");
15425 return STATUS_SENT_ERROR;
15426}
15427
15428
Jouni Malinenf7222712019-06-13 01:50:21 +030015429static enum sigma_cmd_result cmd_sta_set_rfeature(struct sigma_dut *dut,
15430 struct sigma_conn *conn,
15431 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015432{
15433 const char *intf = get_param(cmd, "Interface");
15434 const char *prog = get_param(cmd, "Prog");
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015435 const char *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015436
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015437 if (!prog)
15438 prog = get_param(cmd, "Program");
15439
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015440 if (intf == NULL || prog == NULL)
15441 return -1;
15442
Ashwini Patil5acd7382017-04-13 15:55:04 +053015443 /* BSS Transition candidate list for BTM query */
15444 val = get_param(cmd, "Nebor_BSSID");
15445 if (val && btm_query_candidate_list(dut, conn, cmd) == 0)
15446 return 0;
15447
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015448 if (strcasecmp(prog, "TDLS") == 0)
15449 return cmd_sta_set_rfeature_tdls(intf, dut, conn, cmd);
15450
15451 if (strcasecmp(prog, "VHT") == 0)
15452 return cmd_sta_set_rfeature_vht(intf, dut, conn, cmd);
15453
Amarnath Hullur Subramanyam42c25a02018-01-31 04:02:27 -080015454 if (strcasecmp(prog, "HE") == 0)
15455 return cmd_sta_set_rfeature_he(intf, dut, conn, cmd);
15456
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015457 if (strcasecmp(prog, "MBO") == 0) {
15458 val = get_param(cmd, "Cellular_Data_Cap");
15459 if (val &&
15460 mbo_set_cellular_data_capa(dut, conn, intf, atoi(val)) == 0)
15461 return 0;
Ashwini Patil00402582017-04-13 12:29:39 +053015462
15463 val = get_param(cmd, "Ch_Pref");
15464 if (val && mbo_set_non_pref_ch_list(dut, conn, intf, cmd) == 0)
15465 return 0;
15466
Ashwini Patil68d02cd2017-01-10 15:39:16 +053015467 return 1;
15468 }
15469
Alexei Avshalom Lazarbc180dc2018-12-18 16:01:14 +020015470 if (strcasecmp(prog, "60GHz") == 0)
15471 return cmd_sta_set_rfeature_60g(intf, dut, conn, cmd);
15472
Jouni Malinen6250cb02020-04-15 13:54:45 +030015473 if (strcasecmp(prog, "WPA3") == 0)
15474 return cmd_sta_set_rfeature_wpa3(intf, dut, conn, cmd);
Veerendranath Jakkam329a3cd2021-09-11 18:10:13 +053015475 if (strcasecmp(prog, "QM") == 0)
15476 return cmd_sta_set_rfeature_qm(intf, dut, conn, cmd);
Jouni Malinen6250cb02020-04-15 13:54:45 +030015477
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015478 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported Prog");
15479 return 0;
15480}
15481
15482
Jouni Malinenf7222712019-06-13 01:50:21 +030015483static enum sigma_cmd_result cmd_sta_set_radio(struct sigma_dut *dut,
15484 struct sigma_conn *conn,
15485 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015486{
15487 const char *intf = get_param(cmd, "Interface");
15488 const char *mode = get_param(cmd, "Mode");
15489 int res;
15490
15491 if (intf == NULL || mode == NULL)
15492 return -1;
15493
15494 if (strcasecmp(mode, "On") == 0)
15495 res = wpa_command(intf, "SET radio_disabled 0");
15496 else if (strcasecmp(mode, "Off") == 0)
15497 res = wpa_command(intf, "SET radio_disabled 1");
15498 else
15499 return -1;
15500
15501 if (res) {
15502 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15503 "radio mode");
15504 return 0;
15505 }
15506
15507 return 1;
15508}
15509
15510
Jouni Malinenf7222712019-06-13 01:50:21 +030015511static enum sigma_cmd_result cmd_sta_set_pwrsave(struct sigma_dut *dut,
15512 struct sigma_conn *conn,
15513 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015514{
15515 const char *intf = get_param(cmd, "Interface");
15516 const char *mode = get_param(cmd, "Mode");
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015517 const char *prog = get_param(cmd, "program");
15518 const char *powersave = get_param(cmd, "powersave");
15519 int res = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015520
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015521 if (intf == NULL)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015522 return -1;
15523
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015524 if (prog && strcasecmp(prog, "60GHz") == 0) {
15525 /*
15526 * The CAPI mode parameter does not exist in 60G
15527 * unscheduled PS.
15528 */
Hu Wang5dc3ff12019-06-14 15:14:26 +080015529 if (powersave && strcasecmp(powersave, "unscheduled") == 0)
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015530 res = set_ps(intf, dut, 1);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020015531 } else if (prog && get_driver_type(dut) == DRIVER_WCN &&
Alexei Avshalom Lazar2f6fdb42019-02-04 14:16:08 +020015532 strcasecmp(prog, "HE") == 0) {
15533 return cmd_sta_set_power_save_he(intf, dut, conn, cmd);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020015534 } else {
15535 if (mode == NULL)
15536 return -1;
15537
15538 if (strcasecmp(mode, "On") == 0)
15539 res = set_ps(intf, dut, 1);
15540 else if (strcasecmp(mode, "Off") == 0)
15541 res = set_ps(intf, dut, 0);
15542 else
15543 return -1;
15544 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015545
15546 if (res) {
15547 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to change "
15548 "power save mode");
15549 return 0;
15550 }
15551
15552 return 1;
15553}
15554
15555
Jouni Malinenf7222712019-06-13 01:50:21 +030015556static enum sigma_cmd_result cmd_sta_bssid_pool(struct sigma_dut *dut,
15557 struct sigma_conn *conn,
15558 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015559{
15560 const char *intf = get_param(cmd, "Interface");
15561 const char *val, *bssid;
15562 int res;
15563 char *buf;
15564 size_t buf_len;
15565
15566 val = get_param(cmd, "BSSID_FILTER");
15567 if (val == NULL)
15568 return -1;
15569
15570 bssid = get_param(cmd, "BSSID_List");
15571 if (atoi(val) == 0 || bssid == NULL) {
15572 /* Disable BSSID filter */
15573 if (wpa_command(intf, "SET bssid_filter ")) {
15574 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed "
15575 "to disable BSSID filter");
15576 return 0;
15577 }
15578
15579 return 1;
15580 }
15581
15582 buf_len = 100 + strlen(bssid);
15583 buf = malloc(buf_len);
15584 if (buf == NULL)
15585 return -1;
15586
15587 snprintf(buf, buf_len, "SET bssid_filter %s", bssid);
15588 res = wpa_command(intf, buf);
15589 free(buf);
15590 if (res) {
15591 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to enable "
15592 "BSSID filter");
15593 return 0;
15594 }
15595
15596 return 1;
15597}
15598
15599
Jouni Malinenf7222712019-06-13 01:50:21 +030015600static enum sigma_cmd_result cmd_sta_reset_parm(struct sigma_dut *dut,
15601 struct sigma_conn *conn,
15602 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015603{
15604 const char *intf = get_param(cmd, "Interface");
15605 const char *val;
15606
15607 /* TODO: ARP */
15608
15609 val = get_param(cmd, "HS2_CACHE_PROFILE");
15610 if (val && strcasecmp(val, "All") == 0)
15611 hs2_clear_credentials(intf);
15612
15613 return 1;
15614}
15615
15616
Jouni Malinenf7222712019-06-13 01:50:21 +030015617static enum sigma_cmd_result cmd_sta_get_key(struct sigma_dut *dut,
15618 struct sigma_conn *conn,
15619 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015620{
15621 const char *intf = get_param(cmd, "Interface");
15622 const char *key_type = get_param(cmd, "KeyType");
15623 char buf[100], resp[200];
15624
15625 if (key_type == NULL)
15626 return -1;
15627
15628 if (strcasecmp(key_type, "GTK") == 0) {
15629 if (wpa_command_resp(intf, "GET gtk", buf, sizeof(buf)) < 0 ||
15630 strncmp(buf, "FAIL", 4) == 0) {
15631 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15632 "not fetch current GTK");
15633 return 0;
15634 }
15635 snprintf(resp, sizeof(resp), "KeyValue,%s", buf);
15636 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15637 return 0;
15638 } else {
15639 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Unsupported "
15640 "KeyType");
15641 return 0;
15642 }
15643
15644 return 1;
15645}
15646
15647
15648static int hs2_set_policy(struct sigma_dut *dut)
15649{
15650#ifdef ANDROID
15651 system("ip rule del prio 23000");
15652 if (system("ip rule add from all lookup main prio 23000") != 0) {
15653 sigma_dut_print(dut, DUT_MSG_ERROR,
15654 "Failed to run:ip rule add from all lookup main prio");
15655 return -1;
15656 }
15657 if (system("ip route flush cache") != 0) {
15658 sigma_dut_print(dut, DUT_MSG_ERROR,
15659 "Failed to run ip route flush cache");
15660 return -1;
15661 }
15662 return 1;
15663#else /* ANDROID */
15664 return 0;
15665#endif /* ANDROID */
15666}
15667
15668
Jouni Malinenf7222712019-06-13 01:50:21 +030015669static enum sigma_cmd_result cmd_sta_hs2_associate(struct sigma_dut *dut,
15670 struct sigma_conn *conn,
15671 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015672{
15673 const char *intf = get_param(cmd, "Interface");
15674 const char *val = get_param(cmd, "Ignore_blacklist");
Jouni Malinen439352d2018-09-13 03:42:23 +030015675 const char *band = get_param(cmd, "Band");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015676 struct wpa_ctrl *ctrl;
Jouni Malinen3aa72862019-05-29 23:14:51 +030015677 int res, r;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015678 char bssid[20], ssid[40], resp[100], buf[100], blacklisted[100];
15679 int tries = 0;
15680 int ignore_blacklist = 0;
15681 const char *events[] = {
15682 "CTRL-EVENT-CONNECTED",
15683 "INTERWORKING-BLACKLISTED",
15684 "INTERWORKING-NO-MATCH",
15685 NULL
15686 };
15687
15688 start_sta_mode(dut);
15689
Jouni Malinen439352d2018-09-13 03:42:23 +030015690 if (band) {
15691 if (strcmp(band, "2.4") == 0) {
15692 wpa_command(intf, "SET setband 2G");
15693 } else if (strcmp(band, "5") == 0) {
15694 wpa_command(intf, "SET setband 5G");
15695 } else {
15696 send_resp(dut, conn, SIGMA_ERROR,
15697 "errorCode,Unsupported band");
15698 return 0;
15699 }
15700 }
15701
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015702 blacklisted[0] = '\0';
15703 if (val && atoi(val))
15704 ignore_blacklist = 1;
15705
15706try_again:
15707 ctrl = open_wpa_mon(intf);
15708 if (ctrl == NULL) {
15709 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
15710 "wpa_supplicant monitor connection");
15711 return -2;
15712 }
15713
15714 tries++;
15715 if (wpa_command(intf, "INTERWORKING_SELECT auto")) {
15716 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start "
15717 "Interworking connection");
15718 wpa_ctrl_detach(ctrl);
15719 wpa_ctrl_close(ctrl);
15720 return 0;
15721 }
15722
15723 buf[0] = '\0';
15724 while (1) {
15725 char *pos;
15726 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15727 pos = strstr(buf, "INTERWORKING-BLACKLISTED");
15728 if (!pos)
15729 break;
15730 pos += 25;
15731 sigma_dut_print(dut, DUT_MSG_DEBUG, "Found blacklisted AP: %s",
15732 pos);
15733 if (!blacklisted[0])
15734 memcpy(blacklisted, pos, strlen(pos) + 1);
15735 }
15736
15737 if (ignore_blacklist && blacklisted[0]) {
15738 char *end;
15739 end = strchr(blacklisted, ' ');
15740 if (end)
15741 *end = '\0';
15742 sigma_dut_print(dut, DUT_MSG_DEBUG, "Try to connect to a blacklisted network: %s",
15743 blacklisted);
Jouni Malinen3aa72862019-05-29 23:14:51 +030015744 r = snprintf(buf, sizeof(buf), "INTERWORKING_CONNECT %s",
15745 blacklisted);
15746 if (r < 0 || r >= sizeof(buf) || wpa_command(intf, buf)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015747 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Failed to start Interworking connection to blacklisted network");
15748 wpa_ctrl_detach(ctrl);
15749 wpa_ctrl_close(ctrl);
15750 return 0;
15751 }
15752 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
15753 buf, sizeof(buf));
15754 }
15755
15756 wpa_ctrl_detach(ctrl);
15757 wpa_ctrl_close(ctrl);
15758
15759 if (res < 0) {
15760 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15761 "connect");
15762 return 0;
15763 }
15764
15765 if (strstr(buf, "INTERWORKING-NO-MATCH") ||
15766 strstr(buf, "INTERWORKING-BLACKLISTED")) {
15767 if (tries < 2) {
15768 sigma_dut_print(dut, DUT_MSG_INFO, "No match found - try again to verify no APs were missed in the scan");
15769 goto try_again;
15770 }
15771 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,No network with "
15772 "matching credentials found");
15773 return 0;
15774 }
15775
15776 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
15777 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
15778 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Could not "
15779 "get current BSSID/SSID");
15780 return 0;
15781 }
15782
15783 snprintf(resp, sizeof(resp), "SSID,%s,BSSID,%s", ssid, bssid);
15784 send_resp(dut, conn, SIGMA_COMPLETE, resp);
15785 hs2_set_policy(dut);
15786 return 0;
15787}
15788
15789
Jouni Malinenf7222712019-06-13 01:50:21 +030015790static enum sigma_cmd_result cmd_sta_hs2_venue_info(struct sigma_dut *dut,
15791 struct sigma_conn *conn,
15792 struct sigma_cmd *cmd)
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015793{
15794 const char *intf = get_param(cmd, "Interface");
15795 const char *display = get_param(cmd, "Display");
15796 struct wpa_ctrl *ctrl;
15797 char buf[300], params[400], *pos;
15798 char bssid[20];
15799 int info_avail = 0;
15800 unsigned int old_timeout;
15801 int res;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015802 const char *events[] = { "RX-VENUE-URL", "ANQP-QUERY-DONE", NULL };
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015803
15804 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0) {
15805 send_resp(dut, conn, SIGMA_ERROR,
15806 "ErrorCode,Could not get current BSSID");
15807 return 0;
15808 }
15809 ctrl = open_wpa_mon(intf);
15810 if (!ctrl) {
15811 sigma_dut_print(dut, DUT_MSG_ERROR,
15812 "Failed to open wpa_supplicant monitor connection");
15813 return -2;
15814 }
15815
15816 snprintf(buf, sizeof(buf), "ANQP_GET %s 277", bssid);
15817 wpa_command(intf, buf);
15818
15819 res = get_wpa_cli_event(dut, ctrl, "GAS-QUERY-DONE", buf, sizeof(buf));
15820 if (res < 0) {
15821 send_resp(dut, conn, SIGMA_ERROR,
15822 "ErrorCode,Could not complete GAS query");
15823 goto fail;
15824 }
15825
15826 old_timeout = dut->default_timeout;
15827 dut->default_timeout = 2;
Jouni Malinen960aa7c2022-01-27 00:25:10 +020015828 for (;;) {
15829 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
15830 if (res < 0)
15831 break;
15832 if (strstr(buf, "ANQP-QUERY-DONE") != NULL) {
15833 res = -1;
15834 break;
15835 }
15836 pos = strchr(buf, ' ');
15837 if (!pos)
15838 continue;
15839 pos++;
15840 pos = strchr(pos, ' ');
15841 if (!pos)
15842 continue;
15843 pos++;
15844
15845 if (strncmp(pos, "https://", 8) == 0)
15846 break;
15847
15848 sigma_dut_print(dut, DUT_MSG_DEBUG,
15849 "Ignore non-HTTPS venue URL: %s", pos);
15850 }
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015851 dut->default_timeout = old_timeout;
15852 if (res < 0)
15853 goto done;
Jouni Malinenb639f1c2018-09-13 02:39:46 +030015854 info_avail = 1;
15855 snprintf(params, sizeof(params), "browser %s", pos);
15856
15857 if (display && strcasecmp(display, "Yes") == 0) {
15858 pid_t pid;
15859
15860 pid = fork();
15861 if (pid < 0) {
15862 perror("fork");
15863 return -1;
15864 }
15865
15866 if (pid == 0) {
15867 run_hs20_osu(dut, params);
15868 exit(0);
15869 }
15870 }
15871
15872done:
15873 snprintf(buf, sizeof(buf), "Info_available,%s",
15874 info_avail ? "Yes" : "No");
15875 send_resp(dut, conn, SIGMA_COMPLETE, buf);
15876fail:
15877 wpa_ctrl_detach(ctrl);
15878 wpa_ctrl_close(ctrl);
15879 return 0;
15880}
15881
15882
Jouni Malinencd4e3c32015-10-29 12:39:56 +020015883static int sta_add_credential_uname_pwd(struct sigma_dut *dut,
15884 struct sigma_conn *conn,
15885 const char *ifname,
15886 struct sigma_cmd *cmd)
15887{
15888 const char *val;
15889 int id;
15890
15891 id = add_cred(ifname);
15892 if (id < 0)
15893 return -2;
15894 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
15895
15896 val = get_param(cmd, "prefer");
15897 if (val && atoi(val) > 0)
15898 set_cred(ifname, id, "priority", "1");
15899
15900 val = get_param(cmd, "REALM");
15901 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
15902 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15903 "realm");
15904 return 0;
15905 }
15906
15907 val = get_param(cmd, "HOME_FQDN");
15908 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
15909 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15910 "home_fqdn");
15911 return 0;
15912 }
15913
15914 val = get_param(cmd, "Username");
15915 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
15916 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15917 "username");
15918 return 0;
15919 }
15920
15921 val = get_param(cmd, "Password");
15922 if (val && set_cred_quoted(ifname, id, "password", val) < 0) {
15923 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
15924 "password");
15925 return 0;
15926 }
15927
15928 val = get_param(cmd, "ROOT_CA");
15929 if (val) {
15930 char fname[200];
15931 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
15932#ifdef __linux__
15933 if (!file_exists(fname)) {
15934 char msg[300];
15935 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
15936 "file (%s) not found", fname);
15937 send_resp(dut, conn, SIGMA_ERROR, msg);
15938 return 0;
15939 }
15940#endif /* __linux__ */
15941 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
15942 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
15943 "not set root CA");
15944 return 0;
15945 }
15946 }
15947
15948 return 1;
15949}
15950
15951
15952static int update_devdetail_imsi(struct sigma_dut *dut, const char *imsi)
15953{
15954 FILE *in, *out;
15955 char buf[500];
15956 int found = 0;
15957
15958 in = fopen("devdetail.xml", "r");
15959 if (in == NULL)
15960 return -1;
15961 out = fopen("devdetail.xml.tmp", "w");
15962 if (out == NULL) {
15963 fclose(in);
15964 return -1;
15965 }
15966
15967 while (fgets(buf, sizeof(buf), in)) {
15968 char *pos = strstr(buf, "<IMSI>");
15969 if (pos) {
15970 sigma_dut_print(dut, DUT_MSG_INFO, "Updated DevDetail IMSI to %s",
15971 imsi);
15972 pos += 6;
15973 *pos = '\0';
15974 fprintf(out, "%s%s</IMSI>\n", buf, imsi);
15975 found++;
15976 } else {
15977 fprintf(out, "%s", buf);
15978 }
15979 }
15980
15981 fclose(out);
15982 fclose(in);
15983 if (found)
15984 rename("devdetail.xml.tmp", "devdetail.xml");
15985 else
15986 unlink("devdetail.xml.tmp");
15987
15988 return 0;
15989}
15990
15991
15992static int sta_add_credential_sim(struct sigma_dut *dut,
15993 struct sigma_conn *conn,
15994 const char *ifname, struct sigma_cmd *cmd)
15995{
15996 const char *val, *imsi = NULL;
15997 int id;
15998 char buf[200];
15999 int res;
16000 const char *pos;
16001 size_t mnc_len;
16002 char plmn_mcc[4];
16003 char plmn_mnc[4];
16004
16005 id = add_cred(ifname);
16006 if (id < 0)
16007 return -2;
16008 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16009
16010 val = get_param(cmd, "prefer");
16011 if (val && atoi(val) > 0)
16012 set_cred(ifname, id, "priority", "1");
16013
16014 val = get_param(cmd, "PLMN_MCC");
16015 if (val == NULL) {
16016 send_resp(dut, conn, SIGMA_ERROR,
16017 "errorCode,Missing PLMN_MCC");
16018 return 0;
16019 }
16020 if (strlen(val) != 3) {
16021 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MCC");
16022 return 0;
16023 }
16024 snprintf(plmn_mcc, sizeof(plmn_mcc), "%s", val);
16025
16026 val = get_param(cmd, "PLMN_MNC");
16027 if (val == NULL) {
16028 send_resp(dut, conn, SIGMA_ERROR,
16029 "errorCode,Missing PLMN_MNC");
16030 return 0;
16031 }
16032 if (strlen(val) != 2 && strlen(val) != 3) {
16033 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Invalid MNC");
16034 return 0;
16035 }
16036 snprintf(plmn_mnc, sizeof(plmn_mnc), "%s", val);
16037
16038 val = get_param(cmd, "IMSI");
16039 if (val == NULL) {
16040 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Missing SIM "
16041 "IMSI");
16042 return 0;
16043 }
16044
16045 imsi = pos = val;
16046
16047 if (strncmp(plmn_mcc, pos, 3) != 0) {
16048 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MCC mismatch");
16049 return 0;
16050 }
16051 pos += 3;
16052
16053 mnc_len = strlen(plmn_mnc);
16054 if (mnc_len < 2) {
16055 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC not set");
16056 return 0;
16057 }
16058
16059 if (strncmp(plmn_mnc, pos, mnc_len) != 0) {
16060 send_resp(dut, conn, SIGMA_ERROR, "errorCode,MNC mismatch");
16061 return 0;
16062 }
16063 pos += mnc_len;
16064
16065 res = snprintf(buf, sizeof(buf), "%s%s-%s",plmn_mcc, plmn_mnc, pos);
16066 if (res < 0 || res >= (int) sizeof(buf))
16067 return -1;
16068 if (set_cred_quoted(ifname, id, "imsi", buf) < 0) {
16069 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16070 "not set IMSI");
16071 return 0;
16072 }
16073
16074 val = get_param(cmd, "Password");
16075 if (val && set_cred_quoted(ifname, id, "milenage", val) < 0) {
16076 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16077 "not set password");
16078 return 0;
16079 }
16080
Jouni Malinen9a742ff2022-01-27 00:43:14 +020016081 if (dut->program == PROGRAM_HS2_R2 || dut->program == PROGRAM_HS2_R3 ||
16082 dut->program == PROGRAM_HS2_R4) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016083 /*
16084 * Set provisioning_sp for the test cases where SIM/USIM
16085 * provisioning is used.
16086 */
16087 if (val && set_cred_quoted(ifname, id, "provisioning_sp",
16088 "wi-fi.org") < 0) {
16089 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16090 "not set provisioning_sp");
16091 return 0;
16092 }
16093
16094 update_devdetail_imsi(dut, imsi);
16095 }
16096
16097 return 1;
16098}
16099
16100
16101static int sta_add_credential_cert(struct sigma_dut *dut,
16102 struct sigma_conn *conn,
16103 const char *ifname,
16104 struct sigma_cmd *cmd)
16105{
16106 const char *val;
16107 int id;
16108
16109 id = add_cred(ifname);
16110 if (id < 0)
16111 return -2;
16112 sigma_dut_print(dut, DUT_MSG_DEBUG, "Adding credential %d", id);
16113
16114 val = get_param(cmd, "prefer");
16115 if (val && atoi(val) > 0)
16116 set_cred(ifname, id, "priority", "1");
16117
16118 val = get_param(cmd, "REALM");
16119 if (val && set_cred_quoted(ifname, id, "realm", val) < 0) {
16120 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16121 "realm");
16122 return 0;
16123 }
16124
16125 val = get_param(cmd, "HOME_FQDN");
16126 if (val && set_cred_quoted(ifname, id, "domain", val) < 0) {
16127 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16128 "home_fqdn");
16129 return 0;
16130 }
16131
16132 val = get_param(cmd, "Username");
16133 if (val && set_cred_quoted(ifname, id, "username", val) < 0) {
16134 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not set "
16135 "username");
16136 return 0;
16137 }
16138
16139 val = get_param(cmd, "clientCertificate");
16140 if (val) {
16141 char fname[200];
16142 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16143#ifdef __linux__
16144 if (!file_exists(fname)) {
16145 char msg[300];
16146 snprintf(msg, sizeof(msg),
16147 "ErrorCode,clientCertificate "
16148 "file (%s) not found", fname);
16149 send_resp(dut, conn, SIGMA_ERROR, msg);
16150 return 0;
16151 }
16152#endif /* __linux__ */
16153 if (set_cred_quoted(ifname, id, "client_cert", fname) < 0) {
16154 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16155 "not set client_cert");
16156 return 0;
16157 }
16158 if (set_cred_quoted(ifname, id, "private_key", fname) < 0) {
16159 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16160 "not set private_key");
16161 return 0;
16162 }
16163 }
16164
16165 val = get_param(cmd, "ROOT_CA");
16166 if (val) {
16167 char fname[200];
16168 snprintf(fname, sizeof(fname), "%s/%s", sigma_cert_path, val);
16169#ifdef __linux__
16170 if (!file_exists(fname)) {
16171 char msg[300];
16172 snprintf(msg, sizeof(msg), "ErrorCode,ROOT_CA "
16173 "file (%s) not found", fname);
16174 send_resp(dut, conn, SIGMA_ERROR, msg);
16175 return 0;
16176 }
16177#endif /* __linux__ */
16178 if (set_cred_quoted(ifname, id, "ca_cert", fname) < 0) {
16179 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could "
16180 "not set root CA");
16181 return 0;
16182 }
16183 }
16184
16185 return 1;
16186}
16187
16188
Jouni Malinenf7222712019-06-13 01:50:21 +030016189static enum sigma_cmd_result cmd_sta_add_credential(struct sigma_dut *dut,
16190 struct sigma_conn *conn,
16191 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016192{
16193 const char *intf = get_param(cmd, "Interface");
16194 const char *type;
16195
16196 start_sta_mode(dut);
16197
16198 type = get_param(cmd, "Type");
16199 if (!type)
16200 return -1;
16201
16202 if (strcasecmp(type, "uname_pwd") == 0)
16203 return sta_add_credential_uname_pwd(dut, conn, intf, cmd);
16204
16205 if (strcasecmp(type, "sim") == 0)
16206 return sta_add_credential_sim(dut, conn, intf, cmd);
16207
16208 if (strcasecmp(type, "cert") == 0)
16209 return sta_add_credential_cert(dut, conn, intf, cmd);
16210
16211 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,Unsupported credential "
16212 "type");
16213 return 0;
16214}
16215
16216
Jouni Malinenf7222712019-06-13 01:50:21 +030016217static enum sigma_cmd_result cmd_sta_scan(struct sigma_dut *dut,
16218 struct sigma_conn *conn,
16219 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016220{
16221 const char *intf = get_param(cmd, "Interface");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016222 const char *val, *bssid, *ssid, *scan_freq, *short_ssid;
Veerendranathdc581b52020-08-10 03:29:08 -070016223 char buf[4096], scan_res[20];
vamsi krishna89ad8c62017-09-19 12:51:18 +053016224 char ssid_hex[65];
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016225 int wildcard_ssid = 0;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016226 int res;
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016227 enum sigma_cmd_result status;
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016228 struct wpa_ctrl *ctrl = NULL;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016229
Jouni Malinen8c1abeb2019-11-06 18:48:34 +020016230 start_sta_mode(dut);
16231
Arif Hussain66a4af02019-02-07 15:04:51 -080016232 val = get_param(cmd, "GetParameter");
16233 if (val && strcmp(val, "SSID_BSSID") == 0) {
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016234 if (get_wpa_ssid_bssid(dut, get_station_ifname(dut),
Arif Hussain66a4af02019-02-07 15:04:51 -080016235 buf, sizeof(buf)) < 0) {
16236 sigma_dut_print(dut, DUT_MSG_ERROR,
16237 "Could not get ssid bssid");
16238 return ERROR_SEND_STATUS;
16239 }
16240
16241 sigma_dut_print(dut, DUT_MSG_INFO, "%s", buf);
16242 send_resp(dut, conn, SIGMA_COMPLETE, buf);
16243 return STATUS_SENT;
16244 }
16245
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016246 val = get_param(cmd, "HESSID");
16247 if (val) {
16248 res = snprintf(buf, sizeof(buf), "SET hessid %s", val);
16249 if (res < 0 || res >= (int) sizeof(buf))
16250 return -1;
16251 wpa_command(intf, buf);
16252 }
16253
16254 val = get_param(cmd, "ACCS_NET_TYPE");
16255 if (val) {
16256 res = snprintf(buf, sizeof(buf), "SET access_network_type %s",
16257 val);
16258 if (res < 0 || res >= (int) sizeof(buf))
16259 return -1;
16260 wpa_command(intf, buf);
16261 }
16262
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016263 if (get_param(cmd, "RxMac"))
16264 sta_set_scan_unicast_probe(dut, intf, 1);
16265
vamsi krishna89ad8c62017-09-19 12:51:18 +053016266 bssid = get_param(cmd, "Bssid");
16267 ssid = get_param(cmd, "Ssid");
Kiran Kumar Lokere69d89952021-08-08 23:41:46 -070016268 if (!bssid)
16269 bssid = get_param(cmd, "RxMac");
vamsi krishna89ad8c62017-09-19 12:51:18 +053016270
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016271 if (ssid && strcasecmp(ssid, "ZeroLength") == 0 &&
16272 dut->device_type == STA_testbed) {
16273 ssid = NULL;
16274 wildcard_ssid = 1;
16275 }
16276
vamsi krishna89ad8c62017-09-19 12:51:18 +053016277 if (ssid) {
16278 if (2 * strlen(ssid) >= sizeof(ssid_hex)) {
16279 send_resp(dut, conn, SIGMA_ERROR,
16280 "ErrorCode,Too long SSID");
16281 return 0;
16282 }
16283 ascii2hexstr(ssid, ssid_hex);
16284 }
16285
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016286 short_ssid = get_param(cmd, "ShortSSID");
16287 if (short_ssid) {
16288 uint32_t short_ssid_hex;
16289
16290 short_ssid_hex = strtoul(short_ssid, NULL, 16);
16291 short_ssid_hex = ((short_ssid_hex & 0xFF) << 24) |
16292 (((short_ssid_hex >> 8) & 0xFF) << 16) |
16293 (((short_ssid_hex >> 16) & 0xFF) << 8) |
16294 ((short_ssid_hex >> 24) & 0xFF);
16295
16296 res = snprintf(buf, sizeof(buf),
16297 "VENDOR_ELEM_ADD 14 ff053a%08x",
16298 short_ssid_hex);
16299 if (res < 0 || res >= (int) sizeof(buf) ||
16300 wpa_command(intf, buf)) {
16301 send_resp(dut, conn, SIGMA_ERROR,
16302 "errorCode,Failed to add short SSID");
16303 return STATUS_SENT_ERROR;
16304 }
16305 }
16306
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016307 scan_freq = get_param(cmd, "ChnlFreq");
Veerendranath Jakkam132c4b42020-08-10 00:29:03 +053016308 if (scan_freq) {
16309 if (strcasecmp(scan_freq, "2G") == 0)
16310 scan_freq = "2412-2462";
16311 else if (strcasecmp(scan_freq, "5G") == 0)
16312 scan_freq = "5180-5925";
16313 }
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016314
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016315 val = get_param(cmd, "WaitCompletion");
16316 if (val && atoi(val) == 1) {
16317 ctrl = open_wpa_mon(intf);
16318 if (!ctrl) {
16319 send_resp(dut, conn, SIGMA_ERROR,
16320 "errorCode,Failed to open monitor socket");
16321 return STATUS_SENT_ERROR;
16322 }
16323 }
16324
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016325 res = snprintf(buf, sizeof(buf), "SCAN%s%s%s%s%s%s%s",
vamsi krishna89ad8c62017-09-19 12:51:18 +053016326 bssid ? " bssid=": "",
16327 bssid ? bssid : "",
16328 ssid ? " ssid " : "",
Kiran Kumar Lokere3399af22020-03-04 16:31:56 -080016329 ssid ? ssid_hex : "",
Kiran Kumar Lokerec0deb482020-03-04 16:35:06 -080016330 wildcard_ssid ? " wildcard_ssid=1" : "",
16331 scan_freq ? " freq=" : "",
16332 scan_freq ? scan_freq : "");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016333 if (res < 0 || res >= (int) sizeof(buf)) {
16334 send_resp(dut, conn, SIGMA_ERROR,
16335 "errorCode,Could not build scan command");
16336 status = STATUS_SENT_ERROR;
16337 goto remove_s_ssid;
16338 }
vamsi krishna89ad8c62017-09-19 12:51:18 +053016339
Veerendranathdc581b52020-08-10 03:29:08 -070016340 res = wpa_command_resp(intf, buf, scan_res, sizeof(scan_res));
16341 if (strncmp(scan_res, "FAIL-BUSY", 9) == 0) {
16342 sigma_dut_print(dut, DUT_MSG_DEBUG,
16343 "Scan request rejected with busy status, abort ongoing scan and try again");
16344 wpa_command(intf, "ABORT_SCAN");
16345 res = wpa_command(intf, buf);
16346 }
16347
16348 if (res < 0) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016349 send_resp(dut, conn, SIGMA_ERROR, "errorCode,Could not start "
16350 "scan");
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016351 status = STATUS_SENT_ERROR;
16352 } else {
16353 status = SUCCESS_SEND_STATUS;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016354 }
16355
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016356remove_s_ssid:
16357 if (short_ssid && wpa_command(intf, "VENDOR_ELEM_REMOVE 14 *"))
16358 sigma_dut_print(dut, DUT_MSG_ERROR,
16359 "Failed to delete vendor element");
16360
Jouni Malinen228a2fc2020-06-22 23:37:45 +030016361 if (ctrl) {
16362 if (status == SUCCESS_SEND_STATUS) {
16363 res = get_wpa_cli_event(dut, ctrl,
16364 "CTRL-EVENT-SCAN-RESULTS",
16365 buf, sizeof(buf));
16366 if (res < 0) {
16367 send_resp(dut, conn, SIGMA_ERROR,
16368 "ErrorCode,scan did not complete");
16369 status = STATUS_SENT_ERROR;
16370 }
16371 }
16372
16373 wpa_ctrl_detach(ctrl);
16374 wpa_ctrl_close(ctrl);
16375 }
16376
Kiran Kumar Lokere0044a872020-03-04 16:38:06 -080016377 return status;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016378}
16379
16380
Jouni Malinenf7222712019-06-13 01:50:21 +030016381static enum sigma_cmd_result cmd_sta_scan_bss(struct sigma_dut *dut,
16382 struct sigma_conn *conn,
16383 struct sigma_cmd *cmd)
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020016384{
16385 const char *intf = get_param(cmd, "Interface");
16386 const char *bssid;
16387 char buf[4096], *pos;
16388 int freq, chan;
16389 char *ssid;
16390 char resp[100];
16391 int res;
16392 struct wpa_ctrl *ctrl;
16393
16394 bssid = get_param(cmd, "BSSID");
16395 if (!bssid) {
16396 send_resp(dut, conn, SIGMA_INVALID,
16397 "errorCode,BSSID argument is missing");
16398 return 0;
16399 }
16400
16401 ctrl = open_wpa_mon(intf);
16402 if (!ctrl) {
16403 sigma_dut_print(dut, DUT_MSG_ERROR,
16404 "Failed to open wpa_supplicant monitor connection");
16405 return -1;
16406 }
16407
16408 if (wpa_command(intf, "SCAN TYPE=ONLY")) {
16409 send_resp(dut, conn, SIGMA_ERROR,
16410 "errorCode,Could not start scan");
16411 wpa_ctrl_detach(ctrl);
16412 wpa_ctrl_close(ctrl);
16413 return 0;
16414 }
16415
16416 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
16417 buf, sizeof(buf));
16418
16419 wpa_ctrl_detach(ctrl);
16420 wpa_ctrl_close(ctrl);
16421
16422 if (res < 0) {
16423 send_resp(dut, conn, SIGMA_ERROR,
16424 "errorCode,Scan did not complete");
16425 return 0;
16426 }
16427
16428 snprintf(buf, sizeof(buf), "BSS %s", bssid);
16429 if (wpa_command_resp(intf, buf, buf, sizeof(buf)) < 0 ||
16430 strncmp(buf, "id=", 3) != 0) {
16431 send_resp(dut, conn, SIGMA_ERROR,
16432 "errorCode,Specified BSSID not found");
16433 return 0;
16434 }
16435
16436 pos = strstr(buf, "\nfreq=");
16437 if (!pos) {
16438 send_resp(dut, conn, SIGMA_ERROR,
16439 "errorCode,Channel not found");
16440 return 0;
16441 }
16442 freq = atoi(pos + 6);
16443 chan = freq_to_channel(freq);
16444
16445 pos = strstr(buf, "\nssid=");
16446 if (!pos) {
16447 send_resp(dut, conn, SIGMA_ERROR,
16448 "errorCode,SSID not found");
16449 return 0;
16450 }
16451 ssid = pos + 6;
16452 pos = strchr(ssid, '\n');
16453 if (pos)
16454 *pos = '\0';
16455 snprintf(resp, sizeof(resp), "ssid,%s,bsschannel,%d", ssid, chan);
16456 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16457 return 0;
16458}
16459
16460
Jouni Malinenf7222712019-06-13 01:50:21 +030016461static enum sigma_cmd_result cmd_sta_set_systime(struct sigma_dut *dut,
16462 struct sigma_conn *conn,
16463 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016464{
16465#ifdef __linux__
16466 struct timeval tv;
16467 struct tm tm;
16468 time_t t;
16469 const char *val;
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016470 int v;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016471
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016472 wpa_command(get_station_ifname(dut), "PMKSA_FLUSH");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016473
16474 memset(&tm, 0, sizeof(tm));
16475 val = get_param(cmd, "seconds");
16476 if (val)
16477 tm.tm_sec = atoi(val);
16478 val = get_param(cmd, "minutes");
16479 if (val)
16480 tm.tm_min = atoi(val);
16481 val = get_param(cmd, "hours");
16482 if (val)
16483 tm.tm_hour = atoi(val);
16484 val = get_param(cmd, "date");
16485 if (val)
16486 tm.tm_mday = atoi(val);
16487 val = get_param(cmd, "month");
Pradeep Reddy POTTETI429c69e2016-10-13 17:22:03 +053016488 if (val) {
16489 v = atoi(val);
16490 if (v < 1 || v > 12) {
16491 send_resp(dut, conn, SIGMA_INVALID,
16492 "errorCode,Invalid month");
16493 return 0;
16494 }
16495 tm.tm_mon = v - 1;
16496 }
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016497 val = get_param(cmd, "year");
16498 if (val) {
16499 int year = atoi(val);
16500#ifdef ANDROID
16501 if (year > 2035)
16502 year = 2035; /* years beyond 2035 not supported */
16503#endif /* ANDROID */
16504 tm.tm_year = year - 1900;
16505 }
16506 t = mktime(&tm);
16507 if (t == (time_t) -1) {
16508 send_resp(dut, conn, SIGMA_ERROR,
16509 "errorCode,Invalid date or time");
16510 return 0;
16511 }
16512
16513 memset(&tv, 0, sizeof(tv));
16514 tv.tv_sec = t;
16515
16516 if (settimeofday(&tv, NULL) < 0) {
16517 sigma_dut_print(dut, DUT_MSG_INFO, "settimeofday failed: %s",
16518 strerror(errno));
16519 send_resp(dut, conn, SIGMA_ERROR,
16520 "errorCode,Failed to set time");
16521 return 0;
16522 }
16523
16524 return 1;
16525#endif /* __linux__ */
16526
16527 return -1;
16528}
16529
16530
Jouni Malinenf7222712019-06-13 01:50:21 +030016531static enum sigma_cmd_result cmd_sta_osu(struct sigma_dut *dut,
16532 struct sigma_conn *conn,
16533 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016534{
16535 const char *intf = get_param(cmd, "Interface");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016536 const char *name, *osu_ssid, *val;
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016537 int prod_ess_assoc = 1;
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016538 char buf[300], bssid[100], ssid[100];
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016539 int res;
16540 struct wpa_ctrl *ctrl;
16541
16542 name = get_param(cmd, "osuFriendlyName");
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016543 osu_ssid = get_param(cmd, "osu_ssid");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016544
16545 val = get_param(cmd, "ProdESSAssoc");
16546 if (val)
16547 prod_ess_assoc = atoi(val);
16548
16549 kill_dhcp_client(dut, intf);
16550 if (start_dhcp_client(dut, intf) < 0)
16551 return -2;
16552
16553 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger OSU");
16554 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16555 res = snprintf(buf, sizeof(buf),
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016556 "%s %s%s%s %s%s%s signup osu-ca.pem",
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016557 prod_ess_assoc ? "" : "-N",
16558 name ? "-O'" : "", name ? name : "",
Jouni Malinen4c8681c2018-09-12 23:28:11 +030016559 name ? "'" : "",
16560 osu_ssid ? "-o'" : "", osu_ssid ? osu_ssid : "",
16561 osu_ssid ? "'" : "");
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016562
Kanchanapally, Vidyullatha12b66762015-12-31 16:46:42 +053016563 hs2_set_policy(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016564 if (run_hs20_osu(dut, buf) < 0) {
16565 FILE *f;
16566
16567 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to complete OSU");
16568
16569 f = fopen("hs20-osu-client.res", "r");
16570 if (f) {
16571 char resp[400], res[300], *pos;
16572 if (!fgets(res, sizeof(res), f))
16573 res[0] = '\0';
16574 pos = strchr(res, '\n');
16575 if (pos)
16576 *pos = '\0';
16577 fclose(f);
16578 sigma_dut_summary(dut, "hs20-osu-client provisioning failed: %s",
16579 res);
16580 snprintf(resp, sizeof(resp), "notify-send '%s'", res);
16581 if (system(resp) != 0) {
16582 }
16583 snprintf(resp, sizeof(resp),
16584 "SSID,,BSSID,,failureReason,%s", res);
16585 send_resp(dut, conn, SIGMA_COMPLETE, resp);
16586 return 0;
16587 }
16588
16589 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16590 return 0;
16591 }
16592
16593 if (!prod_ess_assoc)
16594 goto report;
16595
16596 ctrl = open_wpa_mon(intf);
16597 if (ctrl == NULL) {
16598 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16599 "wpa_supplicant monitor connection");
16600 return -1;
16601 }
16602
16603 res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-CONNECTED",
16604 buf, sizeof(buf));
16605
16606 wpa_ctrl_detach(ctrl);
16607 wpa_ctrl_close(ctrl);
16608
16609 if (res < 0) {
16610 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to connect to "
16611 "network after OSU");
16612 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16613 return 0;
16614 }
16615
16616report:
16617 if (get_wpa_status(intf, "bssid", bssid, sizeof(bssid)) < 0 ||
16618 get_wpa_status(intf, "ssid", ssid, sizeof(ssid)) < 0) {
16619 sigma_dut_print(dut, DUT_MSG_INFO, "Failed to get BSSID/SSID");
16620 send_resp(dut, conn, SIGMA_COMPLETE, "SSID,,BSSID,");
16621 return 0;
16622 }
16623
16624 snprintf(buf, sizeof(buf), "SSID,%s,BSSID,%s", ssid, bssid);
16625 send_resp(dut, conn, SIGMA_COMPLETE, buf);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016626 return 0;
16627}
16628
16629
Jouni Malinenf7222712019-06-13 01:50:21 +030016630static enum sigma_cmd_result cmd_sta_policy_update(struct sigma_dut *dut,
16631 struct sigma_conn *conn,
16632 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016633{
16634 const char *val;
16635 int timeout = 120;
16636
16637 val = get_param(cmd, "PolicyUpdate");
16638 if (val == NULL || atoi(val) == 0)
16639 return 1; /* No operation requested */
16640
16641 val = get_param(cmd, "Timeout");
16642 if (val)
16643 timeout = atoi(val);
16644
16645 if (timeout) {
16646 /* TODO: time out the command and return
16647 * PolicyUpdateStatus,TIMEOUT if needed. */
16648 }
16649
16650 sigma_dut_print(dut, DUT_MSG_DEBUG, "Trigger policy update");
16651 mkdir("Logs", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
16652 if (run_hs20_osu(dut, "pol_upd fqdn=wi-fi.org") < 0) {
16653 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,FAIL");
16654 return 0;
16655 }
16656
16657 send_resp(dut, conn, SIGMA_COMPLETE, "PolicyUpdateStatus,SUCCESS");
16658 return 0;
16659}
16660
16661
Jouni Malinenf7222712019-06-13 01:50:21 +030016662static enum sigma_cmd_result cmd_sta_er_config(struct sigma_dut *dut,
16663 struct sigma_conn *conn,
16664 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016665{
16666 struct wpa_ctrl *ctrl;
16667 const char *intf = get_param(cmd, "Interface");
16668 const char *bssid = get_param(cmd, "Bssid");
16669 const char *ssid = get_param(cmd, "SSID");
16670 const char *security = get_param(cmd, "Security");
16671 const char *passphrase = get_param(cmd, "Passphrase");
16672 const char *pin = get_param(cmd, "PIN");
16673 char buf[1000];
16674 char ssid_hex[200], passphrase_hex[200];
16675 const char *keymgmt, *cipher;
16676
16677 if (intf == NULL)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016678 intf = get_main_ifname(dut);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016679
16680 if (!bssid) {
16681 send_resp(dut, conn, SIGMA_ERROR,
16682 "ErrorCode,Missing Bssid argument");
16683 return 0;
16684 }
16685
16686 if (!ssid) {
16687 send_resp(dut, conn, SIGMA_ERROR,
16688 "ErrorCode,Missing SSID argument");
16689 return 0;
16690 }
16691
16692 if (!security) {
16693 send_resp(dut, conn, SIGMA_ERROR,
16694 "ErrorCode,Missing Security argument");
16695 return 0;
16696 }
16697
16698 if (!passphrase) {
16699 send_resp(dut, conn, SIGMA_ERROR,
16700 "ErrorCode,Missing Passphrase argument");
16701 return 0;
16702 }
16703
16704 if (!pin) {
16705 send_resp(dut, conn, SIGMA_ERROR,
16706 "ErrorCode,Missing PIN argument");
16707 return 0;
16708 }
16709
vamsi krishna8c9c1562017-05-12 15:51:46 +053016710 if (2 * strlen(ssid) >= sizeof(ssid_hex) ||
16711 2 * strlen(passphrase) >= sizeof(passphrase_hex)) {
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016712 send_resp(dut, conn, SIGMA_ERROR,
16713 "ErrorCode,Too long SSID/passphrase");
16714 return 0;
16715 }
16716
16717 ctrl = open_wpa_mon(intf);
16718 if (ctrl == NULL) {
16719 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16720 "wpa_supplicant monitor connection");
16721 return -2;
16722 }
16723
16724 if (strcasecmp(security, "wpa2-psk") == 0) {
16725 keymgmt = "WPA2PSK";
16726 cipher = "CCMP";
16727 } else {
16728 wpa_ctrl_detach(ctrl);
16729 wpa_ctrl_close(ctrl);
16730 send_resp(dut, conn, SIGMA_ERROR,
16731 "ErrorCode,Unsupported Security value");
16732 return 0;
16733 }
16734
16735 ascii2hexstr(ssid, ssid_hex);
16736 ascii2hexstr(passphrase, passphrase_hex);
16737 snprintf(buf, sizeof(buf), "WPS_REG %s %s %s %s %s %s",
16738 bssid, pin, ssid_hex, keymgmt, cipher, passphrase_hex);
16739
16740 if (wpa_command(intf, buf) < 0) {
16741 wpa_ctrl_detach(ctrl);
16742 wpa_ctrl_close(ctrl);
16743 send_resp(dut, conn, SIGMA_ERROR,
16744 "ErrorCode,Failed to start registrar");
16745 return 0;
16746 }
16747
16748 snprintf(dut->er_oper_bssid, sizeof(dut->er_oper_bssid), "%s", bssid);
16749 dut->er_oper_performed = 1;
16750
16751 return wps_connection_event(dut, conn, ctrl, intf, 0);
16752}
16753
16754
Jouni Malinenf7222712019-06-13 01:50:21 +030016755static enum sigma_cmd_result
16756cmd_sta_wps_connect_pw_token(struct sigma_dut *dut, struct sigma_conn *conn,
16757 struct sigma_cmd *cmd)
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016758{
16759 struct wpa_ctrl *ctrl;
16760 const char *intf = get_param(cmd, "Interface");
16761 const char *bssid = get_param(cmd, "Bssid");
16762 char buf[100];
16763
16764 if (!bssid) {
16765 send_resp(dut, conn, SIGMA_ERROR,
16766 "ErrorCode,Missing Bssid argument");
16767 return 0;
16768 }
16769
16770 ctrl = open_wpa_mon(intf);
16771 if (ctrl == NULL) {
16772 sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to open "
16773 "wpa_supplicant monitor connection");
16774 return -2;
16775 }
16776
16777 snprintf(buf, sizeof(buf), "WPS_NFC %s", bssid);
16778
16779 if (wpa_command(intf, buf) < 0) {
16780 wpa_ctrl_detach(ctrl);
16781 wpa_ctrl_close(ctrl);
16782 send_resp(dut, conn, SIGMA_ERROR,
16783 "ErrorCode,Failed to start registrar");
16784 return 0;
16785 }
16786
16787 return wps_connection_event(dut, conn, ctrl, intf, 0);
16788}
16789
16790
Jouni Malinenf7222712019-06-13 01:50:21 +030016791static enum sigma_cmd_result cmd_start_wps_registration(struct sigma_dut *dut,
16792 struct sigma_conn *conn,
16793 struct sigma_cmd *cmd)
vamsi krishna9b144002017-09-20 13:28:13 +053016794{
16795 struct wpa_ctrl *ctrl;
16796 const char *intf = get_param(cmd, "Interface");
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016797 const char *network_mode = get_param(cmd, "network_mode");
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016798 const char *config_method = get_param(cmd, "WPSConfigMethod");
16799 const char *role;
vamsi krishna9b144002017-09-20 13:28:13 +053016800 int res;
16801 char buf[256];
16802 const char *events[] = {
16803 "CTRL-EVENT-CONNECTED",
16804 "WPS-OVERLAP-DETECTED",
16805 "WPS-TIMEOUT",
16806 "WPS-FAIL",
16807 NULL
16808 };
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016809 int id = 0;
vamsi krishna9b144002017-09-20 13:28:13 +053016810
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016811 /* 60G WPS tests do not pass Interface parameter */
16812 if (!intf)
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016813 intf = get_main_ifname(dut);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020016814
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016815 if (dut->mode == SIGMA_MODE_AP)
16816 return ap_wps_registration(dut, conn, cmd);
16817
16818 if (config_method) {
16819 /* WFA_CS_WPS_PIN_KEYPAD mode is set when using the
16820 * sta_wps_enter_pin before calling start_wps_registration. */
16821 if (strcasecmp(config_method, "PBC") == 0)
16822 dut->wps_method = WFA_CS_WPS_PBC;
16823 }
16824 if (dut->wps_method == WFA_CS_WPS_NOT_READY) {
16825 send_resp(dut, conn, SIGMA_ERROR,
16826 "ErrorCode,WPS parameters not yet set");
16827 return STATUS_SENT;
16828 }
16829
16830 /* Make sure WPS is enabled (also for STA mode) */
16831 dut->wps_disable = 0;
16832
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016833 if (dut->band == WPS_BAND_60G && network_mode &&
16834 strcasecmp(network_mode, "PBSS") == 0) {
16835 sigma_dut_print(dut, DUT_MSG_DEBUG,
16836 "Set PBSS network mode, network id %d", id);
Jouni Malinen016ae6c2019-11-04 17:00:01 +020016837 if (set_network(get_station_ifname(dut), id, "pbss", "1") < 0)
Alexei Avshalom Lazard596b512018-12-18 16:00:59 +020016838 return -2;
16839 }
16840
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016841 if (dut->force_rsn_ie) {
16842 sigma_dut_print(dut, DUT_MSG_DEBUG, "Force RSN_IE: %d",
16843 dut->force_rsn_ie);
16844 if (sta_60g_force_rsn_ie(dut, dut->force_rsn_ie) < 0) {
16845 sigma_dut_print(dut, DUT_MSG_INFO,
16846 "Failed to force RSN_IE");
Jouni Malinen0e29cf22019-02-19 01:13:21 +020016847 return ERROR_SEND_STATUS;
Alexei Avshalom Lazarb094bf02018-12-18 16:00:53 +020016848 }
16849 }
16850
vamsi krishna9b144002017-09-20 13:28:13 +053016851 ctrl = open_wpa_mon(intf);
16852 if (!ctrl) {
16853 sigma_dut_print(dut, DUT_MSG_ERROR,
16854 "Failed to open wpa_supplicant monitor connection");
16855 return -2;
16856 }
16857
16858 role = get_param(cmd, "WpsRole");
16859 if (!role) {
16860 send_resp(dut, conn, SIGMA_INVALID,
16861 "ErrorCode,WpsRole not provided");
16862 goto fail;
16863 }
16864
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016865 if (strcasecmp(role, "Enrollee") != 0) {
16866 /* Registrar role for STA not supported */
16867 send_resp(dut, conn, SIGMA_ERROR,
16868 "ErrorCode,Unsupported WpsRole value");
16869 goto fail;
16870 }
16871
16872 if (is_60g_sigma_dut(dut)) {
16873 if (dut->wps_method == WFA_CS_WPS_PBC)
16874 snprintf(buf, sizeof(buf), "WPS_PBC");
16875 else /* WFA_CS_WPS_PIN_KEYPAD */
16876 snprintf(buf, sizeof(buf), "WPS_PIN any %s",
16877 dut->wps_pin);
16878 if (wpa_command(intf, buf) < 0) {
16879 send_resp(dut, conn, SIGMA_ERROR,
16880 "ErrorCode,Failed to start WPS");
vamsi krishna9b144002017-09-20 13:28:13 +053016881 goto fail;
16882 }
Alexei Avshalom Lazar043230b2019-02-04 14:11:24 +020016883 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16884 if (res < 0) {
16885 send_resp(dut, conn, SIGMA_ERROR,
16886 "ErrorCode,WPS connection did not complete");
16887 goto fail;
16888 }
16889 if (strstr(buf, "WPS-TIMEOUT")) {
16890 send_resp(dut, conn, SIGMA_COMPLETE, "WpsState,NoPeer");
16891 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16892 send_resp(dut, conn, SIGMA_COMPLETE,
16893 "WpsState,OverlapSession");
16894 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16895 send_resp(dut, conn, SIGMA_COMPLETE,
16896 "WpsState,Successful");
16897 } else {
16898 send_resp(dut, conn, SIGMA_COMPLETE,
16899 "WpsState,Failure");
16900 }
16901 } else {
16902 if (dut->wps_method == WFA_CS_WPS_PBC) {
vamsi krishna9b144002017-09-20 13:28:13 +053016903 if (wpa_command(intf, "WPS_PBC") < 0) {
16904 send_resp(dut, conn, SIGMA_ERROR,
16905 "ErrorCode,Failed to enable PBC");
16906 goto fail;
16907 }
16908 } else {
16909 /* TODO: PIN method */
16910 send_resp(dut, conn, SIGMA_ERROR,
16911 "ErrorCode,Unsupported WpsConfigMethod value");
16912 goto fail;
16913 }
16914 res = get_wpa_cli_events(dut, ctrl, events, buf, sizeof(buf));
16915 if (res < 0) {
16916 send_resp(dut, conn, SIGMA_ERROR,
16917 "ErrorCode,WPS connection did not complete");
16918 goto fail;
16919 }
16920 if (strstr(buf, "WPS-TIMEOUT")) {
16921 send_resp(dut, conn, SIGMA_ERROR, "ErrorCode,NoPeer");
16922 } else if (strstr(buf, "WPS-OVERLAP-DETECTED")) {
16923 send_resp(dut, conn, SIGMA_ERROR,
16924 "ErrorCode,OverlapSession");
16925 } else if (strstr(buf, "CTRL-EVENT-CONNECTED")) {
16926 send_resp(dut, conn, SIGMA_COMPLETE, "Successful");
16927 } else {
16928 send_resp(dut, conn, SIGMA_ERROR,
16929 "ErrorCode,WPS operation failed");
16930 }
vamsi krishna9b144002017-09-20 13:28:13 +053016931 }
16932
16933fail:
16934 wpa_ctrl_detach(ctrl);
16935 wpa_ctrl_close(ctrl);
16936 return 0;
16937}
16938
16939
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016940static int req_intf(struct sigma_cmd *cmd)
16941{
16942 return get_param(cmd, "interface") == NULL ? -1 : 0;
16943}
16944
16945
16946void sta_register_cmds(void)
16947{
16948 sigma_dut_reg_cmd("sta_get_ip_config", req_intf,
16949 cmd_sta_get_ip_config);
16950 sigma_dut_reg_cmd("sta_set_ip_config", req_intf,
16951 cmd_sta_set_ip_config);
16952 sigma_dut_reg_cmd("sta_get_info", req_intf, cmd_sta_get_info);
16953 sigma_dut_reg_cmd("sta_get_mac_address", req_intf,
16954 cmd_sta_get_mac_address);
16955 sigma_dut_reg_cmd("sta_is_connected", req_intf, cmd_sta_is_connected);
16956 sigma_dut_reg_cmd("sta_verify_ip_connection", req_intf,
16957 cmd_sta_verify_ip_connection);
16958 sigma_dut_reg_cmd("sta_get_bssid", req_intf, cmd_sta_get_bssid);
16959 sigma_dut_reg_cmd("sta_set_encryption", req_intf,
16960 cmd_sta_set_encryption);
16961 sigma_dut_reg_cmd("sta_set_psk", req_intf, cmd_sta_set_psk);
16962 sigma_dut_reg_cmd("sta_set_eaptls", req_intf, cmd_sta_set_eaptls);
16963 sigma_dut_reg_cmd("sta_set_eapttls", req_intf, cmd_sta_set_eapttls);
16964 sigma_dut_reg_cmd("sta_set_eapsim", req_intf, cmd_sta_set_eapsim);
16965 sigma_dut_reg_cmd("sta_set_peap", req_intf, cmd_sta_set_peap);
16966 sigma_dut_reg_cmd("sta_set_eapfast", req_intf, cmd_sta_set_eapfast);
16967 sigma_dut_reg_cmd("sta_set_eapaka", req_intf, cmd_sta_set_eapaka);
16968 sigma_dut_reg_cmd("sta_set_eapakaprime", req_intf,
16969 cmd_sta_set_eapakaprime);
16970 sigma_dut_reg_cmd("sta_set_security", req_intf, cmd_sta_set_security);
16971 sigma_dut_reg_cmd("sta_set_uapsd", req_intf, cmd_sta_set_uapsd);
16972 /* TODO: sta_set_ibss */
16973 /* TODO: sta_set_mode */
16974 sigma_dut_reg_cmd("sta_set_wmm", req_intf, cmd_sta_set_wmm);
16975 sigma_dut_reg_cmd("sta_associate", req_intf, cmd_sta_associate);
16976 /* TODO: sta_up_load */
16977 sigma_dut_reg_cmd("sta_preset_testparameters", req_intf,
16978 cmd_sta_preset_testparameters);
16979 /* TODO: sta_set_system */
16980 sigma_dut_reg_cmd("sta_set_11n", req_intf, cmd_sta_set_11n);
16981 /* TODO: sta_set_rifs_test */
16982 sigma_dut_reg_cmd("sta_set_wireless", req_intf, cmd_sta_set_wireless);
16983 sigma_dut_reg_cmd("sta_send_addba", req_intf, cmd_sta_send_addba);
16984 /* TODO: sta_send_coexist_mgmt */
16985 sigma_dut_reg_cmd("sta_disconnect", req_intf, cmd_sta_disconnect);
16986 sigma_dut_reg_cmd("sta_reassoc", req_intf, cmd_sta_reassoc);
16987 sigma_dut_reg_cmd("sta_reassociate", req_intf, cmd_sta_reassoc);
16988 sigma_dut_reg_cmd("sta_reset_default", req_intf,
16989 cmd_sta_reset_default);
16990 sigma_dut_reg_cmd("sta_send_frame", req_intf, cmd_sta_send_frame);
16991 sigma_dut_reg_cmd("sta_set_macaddr", req_intf, cmd_sta_set_macaddr);
16992 sigma_dut_reg_cmd("sta_set_rfeature", req_intf, cmd_sta_set_rfeature);
16993 sigma_dut_reg_cmd("sta_set_radio", req_intf, cmd_sta_set_radio);
16994 sigma_dut_reg_cmd("sta_set_pwrsave", req_intf, cmd_sta_set_pwrsave);
Alexei Avshalom Lazare49e3872018-12-23 17:26:57 +020016995 sigma_dut_reg_cmd("sta_set_power_save", req_intf, cmd_sta_set_pwrsave);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020016996 sigma_dut_reg_cmd("sta_bssid_pool", req_intf, cmd_sta_bssid_pool);
16997 sigma_dut_reg_cmd("sta_reset_parm", req_intf, cmd_sta_reset_parm);
16998 sigma_dut_reg_cmd("sta_get_key", req_intf, cmd_sta_get_key);
16999 sigma_dut_reg_cmd("sta_hs2_associate", req_intf,
17000 cmd_sta_hs2_associate);
Jouni Malinenb639f1c2018-09-13 02:39:46 +030017001 sigma_dut_reg_cmd("sta_hs2_venue_info", req_intf,
17002 cmd_sta_hs2_venue_info);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017003 sigma_dut_reg_cmd("sta_add_credential", req_intf,
17004 cmd_sta_add_credential);
17005 sigma_dut_reg_cmd("sta_scan", req_intf, cmd_sta_scan);
Jouni Malinen5e5d43d2018-01-10 17:29:33 +020017006 sigma_dut_reg_cmd("sta_scan_bss", req_intf, cmd_sta_scan_bss);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017007 sigma_dut_reg_cmd("sta_set_systime", NULL, cmd_sta_set_systime);
17008 sigma_dut_reg_cmd("sta_osu", req_intf, cmd_sta_osu);
17009 sigma_dut_reg_cmd("sta_policy_update", req_intf, cmd_sta_policy_update);
17010 sigma_dut_reg_cmd("sta_er_config", NULL, cmd_sta_er_config);
17011 sigma_dut_reg_cmd("sta_wps_connect_pw_token", req_intf,
17012 cmd_sta_wps_connect_pw_token);
Jouni Malinen82905202018-04-29 17:20:10 +030017013 sigma_dut_reg_cmd("sta_exec_action", NULL, cmd_sta_exec_action);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017014 sigma_dut_reg_cmd("sta_get_events", req_intf, cmd_sta_get_events);
17015 sigma_dut_reg_cmd("sta_get_parameter", req_intf, cmd_sta_get_parameter);
Alexei Avshalom Lazar35ab3832018-12-23 16:49:49 +020017016 sigma_dut_reg_cmd("start_wps_registration", NULL,
vamsi krishna9b144002017-09-20 13:28:13 +053017017 cmd_start_wps_registration);
Jouni Malinencd4e3c32015-10-29 12:39:56 +020017018}